// Version 2.0.1 November 2007 // Change resizing algorithm // Version 2.0.2 January 2008 // Restore Checked state of Bells and AutoConnect Flags // Call CheckTimer on startup (for new Initialisation Scheme for perl) // Version 2.0.3 July 2008 // Display lines received without a terminaing CR // Version 2.0.4 November 2008 // Add option to remove a Line Feed following a CR // Add Logging Option // Version 2.0.5 January 2009 // Add Start Minimized Option // Version 2.0.6 June 2009 // Add Option to send *** Disconnnected on disconnect // Add line wrap code // Add option not to monitor NODES broadcasts // Version 2.0.7 October 2009 // Add input buffer scrollback. // Fix monitoring when PORTNUM specified // Version 2.0.8 December 2009 // Fix use of numeric keypad 2 and 8 (were treated as up and down) // Version 2.0.9 March 2010 // Add colour for monitor and BPQ Chat // Version 2.0.0 October 2010 // Add Chat Terminal Mode (sends keepalives) // Version 2.1.0 August 2011 // Add Copy/Paste capability to output window. // Add Font Selection // Get Registry Tree from BPQ32.dll // Add Command to reset Monitor/Output window split // Version 2.1.1 October 2011 // Wrap overlong lines // Version 2.1.2 Jan 2012 // Call CloseBPQ32 on exit // Fix ClearOutputWindow // Save MonitorNodes flag #define _CRT_SECURE_NO_DEPRECATE #include "compatbits.h" #include "AsmStrucs.h" #include #include #include #define DllImport __declspec(dllimport) #include "bpq32.h" // BPQ32 API Defines #define BPQTermMDI #ifndef MDIKERNEL #include "Versions.h" #include "GetVersion.h" #define BGCOLOUR RGB(236,233,216) #endif HBRUSH bgBrush; #include "BpqTermMDI.h" extern BOOL FrameMaximized; char RTFHeader[4000]; int RTFHddrLen; struct ConsoleInfo * ConsHeader = NULL; struct ConsoleInfo MonWindow; struct ConsoleInfo InitHeader; // Dummy for before window is created HKEY FAR WINAPI GetRegistryKey(); char * FAR WINAPI GetRegistryKeyText(); VOID __cdecl Debugprintf(const char * format, ...); #ifndef MDIKERNEL HKEY REGTREE = HKEY_LOCAL_MACHINE; // Default VOID __cdecl Debugprintf(const char * format, ...) { char Mess[1000]; va_list(arglist);int Len; va_start(arglist, format); Len = vsprintf_s(Mess, sizeof(Mess), format, arglist); strcat(Mess, "\r\n"); OutputDebugString(Mess); return; } #else extern HKEY REGTREE; extern int OffsetH, OffsetW; #endif HINSTANCE hInst; char ClassName[] = "BPQMAINWINDOW"; char Title[80]; // Foward declarations of functions included in this code module: ATOM MyRegisterClass(CONST WNDCLASS*); BOOL InitApplication(HINSTANCE); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK FrameWndProc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM); extern RECT FRect; // Frame int NewLine(); int ProcessBuff(char * readbuff,int len); int EnableConnectMenu(HWND hWnd); int EnableDisconnectMenu(HWND hWnd); int DisableConnectMenu(HWND hWnd); int DisableDisconnectMenu(HWND hWnd); int ToggleRestoreWindows(); int ToggleAppl(HWND hWnd, int Item, int mask); int DoReceivedData(int Stream); int DoStateChange(int Stream); int ToggleFlags(HWND hWnd, int Item, int mask); int CopyScreentoBuffer(char * buff); int DoMonData(int Stream); int TogglePort(HWND hWnd, int Item, int mask); int ToggleMTX(HWND hWnd); int ToggleMCOM(HWND hWnd); int ToggleParam(HMENU hMenu, BOOL * Param, int Item); int ToggleChat(HWND hWnd); void MoveWindows(struct ConsoleInfo * Cinfo); void CopyListToClipboard(HWND hWnd); void CopyRichTextToClipboard(HWND hWnd); BOOL OpenMonitorLogfile(); void WriteMonitorLine(char * Msg, int MsgLen); int WritetoOutputWindow(struct ConsoleInfo * Cinfo, char * Msg, int len, BOOL Refresh); VOID DoRefresh(struct ConsoleInfo * Cinfo); INT_PTR CALLBACK FontConfigWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); struct ConsoleInfo * CreateChildWindow(int Stream, BOOL DuringInit); BOOL CreateMonitorWindow(char * MonSize); VOID SaveMDIWindowPos(HWND hWnd, char * RegKey, char * Value, BOOL Minimized); int ToggleMON_UI_ONLY(HWND hWnd); COLORREF Colours[256] = {0, RGB(0,0,0), RGB(0,0,128), RGB(0,0,192), RGB(0,0,255), // 1 - 4 RGB(0,64,0), RGB(0,64,128), RGB(0,64,192), RGB(0,64,255), // 5 - 8 RGB(0,128,0), RGB(0,128,128), RGB(0,128,192), RGB(0,128,255), // 9 - 12 RGB(0,192,0), RGB(0,192,128), RGB(0,192,192), RGB(0,192,255), // 13 - 16 RGB(0,255,0), RGB(0,255,128), RGB(0,255,192), RGB(0,255,255), // 17 - 20 RGB(64,0,0), RGB(64,0,128), RGB(64,0,192), RGB(0,0,255), // 21 RGB(64,64,0), RGB(64,64,128), RGB(64,64,192), RGB(64,64,255), RGB(64,128,0), RGB(64,128,128), RGB(64,128,192), RGB(64,128,255), RGB(64,192,0), RGB(64,192,128), RGB(64,192,192), RGB(64,192,255), RGB(64,255,0), RGB(64,255,128), RGB(64,255,192), RGB(64,255,255), RGB(128,0,0), RGB(128,0,128), RGB(128,0,192), RGB(128,0,255), // 41 RGB(128,64,0), RGB(128,64,128), RGB(128,64,192), RGB(128,64,255), RGB(128,128,0), RGB(128,128,128), RGB(128,128,192), RGB(128,128,255), RGB(128,192,0), RGB(128,192,128), RGB(128,192,192), RGB(128,192,255), RGB(128,255,0), RGB(128,255,128), RGB(128,255,192), RGB(128,255,255), RGB(192,0,0), RGB(192,0,128), RGB(192,0,192), RGB(192,0,255), // 61 RGB(192,64,0), RGB(192,64,128), RGB(192,64,192), RGB(192,64,255), RGB(192,128,0), RGB(192,128,128), RGB(192,128,192), RGB(192,128,255), RGB(192,192,0), RGB(192,192,128), RGB(192,192,192), RGB(192,192,255), RGB(192,255,0), RGB(192,255,128), RGB(192,255,192), RGB(192,255,255), RGB(255,0,0), RGB(255,0,128), RGB(255,0,192), RGB(255,0,255), // 81 RGB(255,64,0), RGB(255,64,128), RGB(255,64,192), RGB(255,64,255), RGB(255,128,0), RGB(255,128,128), RGB(255,128,192), RGB(255,128,255), RGB(255,192,0), RGB(255,192,128), RGB(255,192,192), RGB(255,192,255), RGB(255,255,0), RGB(255,255,128), RGB(255,255,192), RGB(255,255,255) }; LRESULT APIENTRY InputProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) ; LRESULT APIENTRY MonProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) ; extern CMDX COMMANDS[]; extern int APPL1; static HMENU trayMenu; int xsize,ysize; // Screen size at startup double Split=0.5; int SplitPos=300; #define SplitBarHeight 5 #define InputBoxHeight 25 RECT MonRect; RECT OutputRect; RECT SplitRect; int OutputBoxHeight; int maxlinelen = 80; int CharWidth = 8; int ClientHeight, ClientWidth; #define MAXLINES 1000 #define LINELEN 200 char RTFHeader[4000]; int RTFHddrLen; char FontName[100] = "FixedSys"; int FontSize = 20; int FontWidth = 8; int CodePage = 1252; int CharSet = 0; int CurrentHost = 0; int CfgNo = 0; SOCKET sock; BOOL MonData = FALSE; static char Key[80]; int portmask=1; int mtxparam=1; int mcomparam=1; int monUI=0; char kbbuf[160]; int kbptr=0; char readbuff[100000]; // for stupid bbs programs int ptr=0; int Stream, Stream2; // Stream2 for SYSOP Chat session int len,count; static UINT APPLMASK = 0x80000000; int applflags = 2; // Message to Uset and Application int Sessno = 0; int PartLinePtr=0; int PartLineIndex=0; // Listbox index of (last) incomplete line BOOL Bells = FALSE; BOOL StripLF = FALSE; BOOL LogMonitor = FALSE; BOOL LogOutput = FALSE; BOOL SendDisconnected = TRUE; BOOL MonitorNODES = TRUE; BOOL MonitorColour = TRUE; BOOL ChatMode = FALSE; BOOL RestoreWindows = TRUE; BOOL MonitorAPRS = FALSE; BOOL WarnWrap = TRUE; BOOL WrapInput = TRUE; BOOL FlashOnBell = FALSE; HANDLE MonHandle=INVALID_HANDLE_VALUE; HCURSOR DragCursor; HCURSOR Cursor; AUTOCONNECT=TRUE; LOGFONT LF; HFONT hFont ; BOOL MinimizetoTray; VOID CALLBACK tTimerProc(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime ); TIMERPROC tTimerFunc = (TIMERPROC) tTimerProc; int tTimerHandle = 0; BOOL WINE; // HMENU hTermMenu; // handle of menu extern HMENU hTermActMenu, hTermCfgMenu, hTermEdtMenu, hTermHlpMenu; extern HMENU hMonActMenu, hMonCfgMenu, hMonEdtMenu, hMonHlpMenu; extern HMENU hWndMenu, hMainFrameMenu, hBaseMenu; extern HWND ClientWnd, FrameWnd; extern HANDLE hInstance; extern byte MCOM; extern char MTX; extern ULONG MMASK; extern byte MUIONLY; HMENU hPopMenu1; #define AUTO -1 #define CP437 437 #define CP1251 1251 #define CP1252 1252 int RXMode = AUTO; //CP1252; int TXMode = CP_UTF8; int APRSWriteLog(char * msg); VOID MonitorAPRSIS(char * Msg, int MsgLen, BOOL TX) { char Line[300]; char Copy[300]; int Len; struct tm * TM; time_t NOW; if (MonWindow.hConsole == NULL || MonitorAPRS == 0) return; if (MsgLen > 250) return; NOW = _time32(NULL); TM = gmtime(&NOW); // Mustn't change Msg memcpy(Copy, Msg, MsgLen); Copy[MsgLen] = 0; if (strchr(Copy, 13)) Len = sprintf_s(Line, 299, "%02d:%02d:%02d%c %s", TM->tm_hour, TM->tm_min, TM->tm_sec, (TX)? 'T': 'R', Copy); else Len = sprintf_s(Line, 299, "%02d:%02d:%02d%c %s\r", TM->tm_hour, TM->tm_min, TM->tm_sec, (TX)? 'T': 'R', Copy); if (TX) MonWindow.CurrentColour = 0; else MonWindow.CurrentColour = 64; WritetoOutputWindow(&MonWindow, Line, Len, FALSE); MonWindow.NeedRefresh = TRUE; APRSWriteLog(Line); } VOID CALLBACK tTimerProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime) { // entered every 1 sec struct ConsoleInfo * Cinfo = &MonWindow; if (Cinfo->NeedRefresh) { Cinfo->NeedRefresh = FALSE; DoRefresh(Cinfo); } for (Cinfo = ConsHeader; Cinfo; Cinfo = Cinfo->next) { if (Cinfo->CONNECTED && ChatMode) { Cinfo->SlowTimer++; if (Cinfo->SlowTimer > 500) // About 9 mins { Cinfo->SlowTimer = 0; SendMsg(Cinfo->BPQStream, "\0", 1); } } } } // // FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int) // // PURPOSE: Entry point for the application. // // COMMENTS: // // This function initializes the application and processes the // message loop. // VOID SetupRTFHddr() { int i, n; char RTFColours[3000]; char Temp[1000]; // Set up RTF Header, including Colours String; memcpy(RTFColours, "{\\colortbl ;", 12); n = 12; for (i = 1; i < 100; i++) { COLORREF Colour = Colours[i]; n += sprintf(&RTFColours[n], "\\red%d\\green%d\\blue%d;", GetRValue(Colour), GetGValue(Colour),GetBValue(Colour)); } RTFColours[n++] = '}'; RTFColours[n] = 0; // strcpy(RTFHeader, "{\\rtf1\\deff0{\\fonttbl{\\f0\\fmodern\\fprq1\\fcharset204 ;}}"); sprintf(RTFHeader, "{\\rtf1\\deff0{\\fonttbl{\\f0\\fprq1\\cpg%d\\fcharset%d %s;}}", CodePage, CharSet, FontName); strcat(RTFHeader, RTFColours); sprintf(Temp, "\\viewkind4\\uc1\\pard\\f0\\fs%d", FontSize); strcat(RTFHeader, Temp); RTFHddrLen = strlen(RTFHeader); } #ifdef MDIKERNEL extern int SessHandle; VOID CALLBACK SetupTermSessions(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime) { int i, n, tempmask=0xffff; char msg[50]; int retCode,Type,Vallen; HKEY hKey=0; char Size[80]; int Sessions = 0; struct PORTCONTROL * PORT; KillTimer(NULL,SessHandle); tTimerHandle = SetTimer(NULL, 0, 1000, tTimerFunc); // See if running under WINE retCode = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine", 0, KEY_QUERY_VALUE, &hKey); if (retCode == ERROR_SUCCESS) { RegCloseKey(hKey); WINE = TRUE; Debugprintf("Running under WINE"); } BPQMsg = RegisterWindowMessage(BPQWinMsg); SetupRTFHddr(); trayMenu = CreatePopupMenu(); AppendMenu(trayMenu, MF_STRING, RTFCOPY, "Copy"); Stream = FindFreeStream(); // For Monitoring /Inbound if (Stream == 255) { MessageBox(NULL,"No free streams available",NULL,MB_OK); return; } BPQSetHandle(Stream, FrameWnd); // Get config from Registry sprintf(Key, "SOFTWARE\\G8BPQ\\BPQ32\\BPQTermMDI"); retCode = RegOpenKeyEx (REGTREE, Key, 0, KEY_QUERY_VALUE, &hKey); if (retCode == ERROR_SUCCESS) { Vallen=4; retCode = RegQueryValueEx(hKey,"Sessions",0, (ULONG *)&Type,(UCHAR *)&Sessions,(ULONG *)&Vallen); Vallen=4; retCode = RegQueryValueEx(hKey,"MTX",0, (ULONG *)&Type,(UCHAR *)&mtxparam,(ULONG *)&Vallen); Vallen=4; retCode = RegQueryValueEx(hKey,"MCOM",0, (ULONG *)&Type,(UCHAR *)&mcomparam,(ULONG *)&Vallen); Vallen=4; retCode = RegQueryValueEx(hKey,"MONUIONLY",0, (ULONG *)&Type,(UCHAR *)&monUI,(ULONG *)&Vallen); Vallen=4; retCode = RegQueryValueEx(hKey,"PortMask",0, (ULONG *)&Type,(UCHAR *)&tempmask,(ULONG *)&Vallen); Vallen=4; retCode = RegQueryValueEx(hKey,"ChatMode",0, (ULONG *)&Type,(UCHAR *)&ChatMode, (ULONG *)&Vallen); Vallen=4; retCode = RegQueryValueEx(hKey,"MONColour",0, (ULONG *)&Type,(UCHAR *)&MonitorColour,(ULONG *)&Vallen); Vallen=4; retCode = RegQueryValueEx(hKey,"MonitorNODES",0, (ULONG *)&Type,(UCHAR *)&MonitorNODES,(ULONG *)&Vallen); Vallen=4; retCode = RegQueryValueEx(hKey,"MonitorAPRS",0, (ULONG *)&Type,(UCHAR *)&MonitorAPRS,(ULONG *)&Vallen); Vallen=4; retCode = RegQueryValueEx(hKey,"Bells",0, (ULONG *)&Type,(UCHAR *)&Bells,(ULONG *)&Vallen); Vallen=4; retCode = RegQueryValueEx(hKey,"StripLF",0, (ULONG *)&Type,(UCHAR *)&StripLF,(ULONG *)&Vallen); Vallen=4; retCode = RegQueryValueEx(hKey, "SendDisconnected",0, (ULONG *)&Type,(UCHAR *)&SendDisconnected,(ULONG *)&Vallen); Vallen=4; RegQueryValueEx(hKey,"WarnWrap",0, (ULONG *)&Type,(UCHAR *)&WarnWrap,(ULONG *)&Vallen); Vallen=4; RegQueryValueEx(hKey,"WrapInput",0, (ULONG *)&Type,(UCHAR *)&WrapInput,(ULONG *)&Vallen); Vallen=4; RegQueryValueEx(hKey,"FlashOnBell",0, (ULONG *)&Type,(UCHAR *)&FlashOnBell,(ULONG *)&Vallen); Vallen=99; retCode = RegQueryValueEx(hKey, "FontName", 0, &Type, FontName, &Vallen); if (FontName[0] == 0) strcpy(FontName, "FixedSys"); Vallen=4; retCode = RegQueryValueEx(hKey, "CharSet", 0, &Type, (UCHAR *)&CharSet, &Vallen); Vallen=4; retCode = RegQueryValueEx(hKey, "CodePage", 0, &Type, (UCHAR *)&CodePage, &Vallen); Vallen=4; retCode = RegQueryValueEx(hKey, "FontSize", 0, &Type, (UCHAR *)&FontSize, &Vallen); Vallen=4; retCode = RegQueryValueEx(hKey, "FontWidth", 0, &Type, (UCHAR *)&FontWidth, &Vallen); Vallen=4; retCode = RegQueryValueEx(hKey, "RestoreWindows", 0, &Type, (UCHAR *)&RestoreWindows, &Vallen); Vallen=80; RegQueryValueEx(hKey, "MonSize", 0 , &Type, &Size[0], &Vallen); } // hPopMenu1 = GetSubMenu(hMonCfgMenu, 1); portmask = tempmask; for (n=1; n <= GetNumberofPorts(); n++) { PORT = GetPortTableEntryFromSlot(n); i = PORT->PORTNUMBER; sprintf(msg,"Port %d %s ",i, PORT->PORTDESCRIPTION); if (tempmask & (1<<(i-1))) AppendMenu(hMonCfgMenu,MF_STRING | MF_CHECKED,BPQBASE + i,msg); else AppendMenu(hMonCfgMenu,MF_STRING | MF_UNCHECKED,BPQBASE + i,msg); } if (mtxparam & 1) CheckMenuItem(hMonCfgMenu,BPQMTX,MF_CHECKED); else CheckMenuItem(hMonCfgMenu,BPQMTX,MF_UNCHECKED); if (mcomparam & 1) CheckMenuItem(hMonCfgMenu,BPQMCOM,MF_CHECKED); else CheckMenuItem(hMonCfgMenu,BPQMCOM,MF_UNCHECKED); if (monUI & 1) CheckMenuItem(hMonCfgMenu,MON_UI_ONLY,MF_CHECKED); else CheckMenuItem(hMonCfgMenu,MON_UI_ONLY,MF_UNCHECKED); if (RestoreWindows) { CheckMenuItem(hMonCfgMenu,ID_WINDOWS_RESTORE,MF_CHECKED); CheckMenuItem(hTermCfgMenu,ID_WINDOWS_RESTORE,MF_CHECKED); } else { CheckMenuItem(hMonCfgMenu, ID_WINDOWS_RESTORE, MF_UNCHECKED); CheckMenuItem(hTermCfgMenu, ID_WINDOWS_RESTORE, MF_UNCHECKED); } if (Bells & 1) CheckMenuItem(hTermCfgMenu,BPQBELLS, MF_CHECKED); else CheckMenuItem(hTermCfgMenu,BPQBELLS, MF_UNCHECKED); if (SendDisconnected & 1) CheckMenuItem(hTermCfgMenu,BPQSendDisconnected, MF_CHECKED); else CheckMenuItem(hTermCfgMenu,BPQSendDisconnected, MF_UNCHECKED); if (StripLF & 1) CheckMenuItem(hTermCfgMenu,BPQStripLF, MF_CHECKED); else CheckMenuItem(hTermCfgMenu,BPQStripLF, MF_UNCHECKED); CheckMenuItem(hTermCfgMenu, ID_WARNWRAP, (WarnWrap) ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(hTermCfgMenu, ID_WRAP, (WrapInput) ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(hTermCfgMenu, ID_FLASHONBELL, (FlashOnBell) ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(hMonCfgMenu,BPQMNODES, (MonitorNODES) ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(hMonCfgMenu,MONITORAPRS, (MonitorAPRS) ? MF_CHECKED : MF_UNCHECKED); DrawMenuBar(FrameWnd); if (portmask) applflags |= 0x80; MCOM = mcomparam; MTX = mtxparam; MMASK = portmask; MUIONLY = monUI; if (COMMANDS[APPL1 + 31].String[0] == '*') // No Host App { SetAppl(Stream, 0x80, 0); } else { SetAppl(Stream, applflags, APPLMASK); // Allocate another incoming stream Stream2 = FindFreeStream();; BPQSetHandle(Stream2, FrameWnd); SetAppl(Stream2, 2, APPLMASK); } // CreateMonitorWindow(Size); if (RestoreWindows) { struct ConsoleInfo * Cinfo; int i; for (i = 1; i <= Sessions; i++) { Cinfo = CreateChildWindow(0, TRUE); } } } SaveHostSessions() { int Sessions = 0; struct ConsoleInfo * Cinfo; int i, disp; char Item[80]; BOOL NeedPause = FALSE; HKEY hKey; // Save config RegCreateKeyEx(REGTREE, Key, 0, 0, 0, KEY_ALL_ACCESS, NULL, &hKey, &disp); RegSetValueEx(hKey,"ChatMode",0,REG_DWORD,(BYTE *)&ChatMode,4); RegSetValueEx(hKey,"PortMask",0,REG_DWORD,(BYTE *)&portmask,4); RegSetValueEx(hKey,"Bells",0,REG_DWORD,(BYTE *)&Bells,4); RegSetValueEx(hKey,"StripLF",0,REG_DWORD,(BYTE *)&StripLF,4); RegSetValueEx(hKey,"SendDisconnected",0,REG_DWORD,(BYTE *)&SendDisconnected,4); RegSetValueEx(hKey,"RestoreWindows",0,REG_DWORD,(BYTE *)&RestoreWindows,4); RegSetValueEx(hKey,"MTX",0,REG_DWORD,(BYTE *)&mtxparam,4); RegSetValueEx(hKey,"MCOM",0,REG_DWORD,(BYTE *)&mcomparam,4); RegSetValueEx(hKey,"MONUIONLY",0,REG_DWORD,(BYTE *)&monUI,4); RegSetValueEx(hKey,"MONColour",0,REG_DWORD,(BYTE *)&MonitorColour,4); RegSetValueEx(hKey,"MonitorNODES",0,REG_DWORD,(BYTE *)&MonitorNODES,4); RegSetValueEx(hKey,"MonitorAPRS",0,REG_DWORD,(BYTE *)&MonitorAPRS,4); RegSetValueEx(hKey,"WarnWrap",0,REG_DWORD,(BYTE *)&WarnWrap,4); RegSetValueEx(hKey,"WrapInput",0,REG_DWORD,(BYTE *)&WrapInput,4); RegSetValueEx(hKey,"FlashOnBell",0,REG_DWORD,(BYTE *)&FlashOnBell,4); // Close any sessions i = 0; for (Cinfo = ConsHeader; Cinfo; Cinfo = Cinfo->next) { i++; sprintf(Item, "SessSize%d", i); SaveMDIWindowPos(Cinfo->hConsole, "BPQTermMDI", Item, Cinfo->Minimized); } RegSetValueEx(hKey,"Sessions",0,REG_DWORD,(BYTE *)&i,4); RegCloseKey(hKey); SaveMDIWindowPos(MonWindow.hConsole, "BPQTermMDI", "MonSize", MonWindow.Minimized); } CloseHostSessions() { struct ConsoleInfo * Cinfo; int i; BOOL NeedPause = FALSE; i = 0; for (Cinfo = ConsHeader; Cinfo; Cinfo = Cinfo->next) { i++; if (Cinfo->CONNECTED) { SessionControl(Cinfo->BPQStream, 2, 0); NeedPause = TRUE; } } if (NeedPause) Sleep(1500); } #else int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG msg; sscanf(lpCmdLine,"%d %x",&Sessno, &applflags); if (!InitInstance(hInstance, nCmdShow)) return (FALSE); // Main message loop: while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } KillTimer(NULL, tTimerHandle); CloseBPQ32(); // Close Ext Drivers if last bpq32 process return (msg.wParam); } // // // FUNCTION: InitApplication(HANDLE) // // PURPOSE: Initializes window data and registers window class // // COMMENTS: // // In this function, we initialize a window class by filling out a data // structure of type WNDCLASS and calling either RegisterClass or // the internal MyRegisterClass. // HMENU hTermCfgMenu, hMonMenu, hPopMenu1, hPopMenu2, hPopMenu3; // handle of menu HINSTANCE hInstance = NULL; TCHAR gszSigmaFrameClassName[] = TEXT("SigmaMdiFrame"); TCHAR gszAppName[] = TEXT("Sigma"); HWND ghMDIClientArea = NULL; //This stores the MDI client area window handle HWND FrameWnd = NULL; // This will hold the main frame window handle HMENU ghMainFrameMenu = NULL; HANDLE ghSystemInfoMutex = NULL; HMENU ghSysInfoMenu = NULL; BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { INITCOMMONCONTROLSEX dICC; BOOL bInitCommonControlLib; WNDCLASSEX wndclassMainFrame; int i, n, tempmask=0xffff; char msg[20]; int retCode,Type,Vallen; HKEY hKey=0; char Size[80]; int Sessions = 0; hInstance = hInstance; hInst = hInstance; // Store instance handle in our global variable // See if running under WINE retCode = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine", 0, KEY_QUERY_VALUE, &hKey); if (retCode == ERROR_SUCCESS) { RegCloseKey(hKey); WINE = TRUE; Debugprintf("Running under WINE"); } REGTREE = GetRegistryKey(); MinimizetoTray=GetMinimizetoTrayFlag(); dICC.dwSize = sizeof(INITCOMMONCONTROLSEX); dICC.dwICC = ICC_TREEVIEW_CLASSES | ICC_BAR_CLASSES; // Initialize common control library bInitCommonControlLib = InitCommonControlsEx(&dICC); if(!bInitCommonControlLib) { MessageBox(NULL, TEXT("Unable to load Common Controls!"), gszAppName, MB_ICONERROR); } LoadLibrary("riched20.dll"); SetupRTFHddr(); wndclassMainFrame.cbSize = sizeof(WNDCLASSEX); wndclassMainFrame.style = CS_HREDRAW | CS_VREDRAW; wndclassMainFrame.lpfnWndProc = FrameWndProc; wndclassMainFrame.cbClsExtra = 0; wndclassMainFrame.cbWndExtra = 0; wndclassMainFrame.hInstance = hInstance; wndclassMainFrame.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE(BPQICON)); wndclassMainFrame.hCursor = LoadCursor(NULL, IDC_ARROW); wndclassMainFrame.hbrBackground = (HBRUSH) GetStockObject(GRAY_BRUSH); wndclassMainFrame.lpszMenuName = NULL; wndclassMainFrame.lpszClassName = gszSigmaFrameClassName; wndclassMainFrame.hIconSm = NULL; //Register MainFrame window if(!RegisterClassEx(&wndclassMainFrame)) { DWORD derror = GetLastError(); MessageBox(NULL, TEXT("This program requires Windows NT!"), gszAppName, MB_ICONERROR); return 0; } ghMainFrameMenu = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MAINFRAME_MENU)); hTermCfgMenu = LoadMenu(hInstance, MAKEINTRESOURCE(TERM_MENU)); hMonMenu = LoadMenu(hInstance, MAKEINTRESOURCE(MON_MENU)); //Create the main MDI frame window FrameWnd = CreateWindow(gszSigmaFrameClassName, gszAppName, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, CW_USEDEFAULT, // allows system choose an x position CW_USEDEFAULT, // allows system choose a y position CW_USEDEFAULT, // width, CW_USEDEFAULT allows system to choose height and width CW_USEDEFAULT, // height, CW_USEDEFAULT ignores heights as this is set by setting // CW_USEDEFAULT in width above. NULL, // handle to parent window ghMainFrameMenu, // handle to menu hInstance, // handle to the instance of module NULL); // Long pointer to a value to be passed to the window through the // CREATESTRUCT structure passed in the lParam parameter the WM_CREATE message nCmdShow = SW_SHOW; // To show the window ShowWindow(FrameWnd, nCmdShow); UpdateWindow(FrameWnd); trayMenu = CreatePopupMenu(); AppendMenu(trayMenu, MF_STRING, RTFCOPY, "Copy"); // Create font for input line LF.lfHeight = 12; LF.lfWidth = 8; LF.lfOutPrecision = OUT_DEFAULT_PRECIS; LF.lfClipPrecision = CLIP_DEFAULT_PRECIS; LF.lfQuality = DEFAULT_QUALITY; LF.lfPitchAndFamily = FIXED_PITCH; strcpy(LF.lfFaceName, "FIXEDSYS"); hFont = CreateFontIndirect(&LF); CheckTimer(); tTimerHandle = SetTimer(NULL, 0, 10000, lptTimerFunc); Stream=FindFreeStream(); if (Stream == 255) { MessageBox(NULL,"No free streams available",NULL,MB_OK); return (FALSE); } // // Register message for posting by BPQDLL // BPQMsg = RegisterWindowMessage(BPQWinMsg); // // Enable Async notification // BPQSetHandle(Stream, FrameWnd); GetVersionInfo(NULL); sprintf(Title,"BPQTerminal Version %s", VersionString); SetWindowText(FrameWnd, Title); // Get config from Registry sprintf(Key, "SOFTWARE\\G8BPQ\\BPQ32\\BPQTermMDI"); retCode = RegOpenKeyEx (REGTREE, Key, 0, KEY_QUERY_VALUE, &hKey); if (retCode == ERROR_SUCCESS) { Vallen=4; retCode = RegQueryValueEx(hKey,"Sessions",0, (ULONG *)&Type,(UCHAR *)&Sessions,(ULONG *)&Vallen); Vallen=4; retCode = RegQueryValueEx(hKey,"MTX",0, (ULONG *)&Type,(UCHAR *)&mtxparam,(ULONG *)&Vallen); Vallen=4; retCode = RegQueryValueEx(hKey,"MCOM",0, (ULONG *)&Type,(UCHAR *)&mcomparam,(ULONG *)&Vallen); Vallen=4; retCode = RegQueryValueEx(hKey,"PortMask",0, (ULONG *)&Type,(UCHAR *)&tempmask,(ULONG *)&Vallen); Vallen=4; retCode = RegQueryValueEx(hKey,"ChatMode",0, (ULONG *)&Type,(UCHAR *)&ChatMode, (ULONG *)&Vallen); Vallen=4; retCode = RegQueryValueEx(hKey,"MONColour",0, (ULONG *)&Type,(UCHAR *)&MonitorColour,(ULONG *)&Vallen); Vallen=4; retCode = RegQueryValueEx(hKey,"MonitorNODES",0, (ULONG *)&Type,(UCHAR *)&MonitorNODES,(ULONG *)&Vallen); Vallen=4; retCode = RegQueryValueEx(hKey,"Bells",0, (ULONG *)&Type,(UCHAR *)&Bells,(ULONG *)&Vallen); Vallen=4; retCode = RegQueryValueEx(hKey,"StripLF",0, (ULONG *)&Type,(UCHAR *)&StripLF,(ULONG *)&Vallen); Vallen=4; retCode = RegQueryValueEx(hKey, "SendDisconnected",0, (ULONG *)&Type,(UCHAR *)&SendDisconnected,(ULONG *)&Vallen); Vallen=80; retCode = RegQueryValueEx(hKey,"Size",0, (ULONG *)&Type,(UCHAR *)&Size,(ULONG *)&Vallen); sscanf(Size,"%d,%d,%d,%d",&Rect.left,&Rect.right,&Rect.top,&Rect.bottom); Vallen=99; retCode = RegQueryValueEx(hKey, "FontName", 0, &Type, FontName, &Vallen); if (FontName[0] == 0) strcpy(FontName, "FixedSys"); Vallen=4; retCode = RegQueryValueEx(hKey, "CharSet", 0, &Type, (UCHAR *)&CharSet, &Vallen); Vallen=4; retCode = RegQueryValueEx(hKey, "CodePage", 0, &Type, (UCHAR *)&CodePage, &Vallen); Vallen=4; retCode = RegQueryValueEx(hKey, "FontSize", 0, &Type, (UCHAR *)&FontSize, &Vallen); Vallen=4; retCode = RegQueryValueEx(hKey, "FontWidth", 0, &Type, (UCHAR *)&FontWidth, &Vallen); Vallen=4; retCode = RegQueryValueEx(hKey, "RestoreWindows", 0, &Type, (UCHAR *)&RestoreWindows, &Vallen); } // OutputData.CharWidth = FontWidth; if (Rect.right < 100 || Rect.bottom < 100) { GetWindowRect(FrameWnd, &Rect); } MoveWindow(FrameWnd, Rect.left, Rect.top, Rect.right-Rect.left, Rect.bottom-Rect.top, TRUE); hPopMenu1 = GetSubMenu(hMonMenu, 1); for (n=1; n <= GetNumberofPorts(); n++) { i = GetPortNumber(n); sprintf(msg,"Port %d",i); if (tempmask & (1<<(i-1))) { AppendMenu(hPopMenu1,MF_STRING | MF_CHECKED,BPQBASE + i,msg); portmask |= (1<<(i-1)); } else AppendMenu(hPopMenu1,MF_STRING | MF_UNCHECKED,BPQBASE + i,msg); } if (mtxparam & 1) CheckMenuItem(hMonMenu,BPQMTX,MF_CHECKED); else CheckMenuItem(hMonMenu,BPQMTX,MF_UNCHECKED); if (mcomparam & 1) CheckMenuItem(hMonMenu,BPQMCOM,MF_CHECKED); else CheckMenuItem(hMonMenu,BPQMCOM,MF_UNCHECKED); if (RestoreWindows) { CheckMenuItem(hMonMenu,ID_WINDOWS_RESTORE,MF_CHECKED); CheckMenuItem(hTermCfgMenu,ID_WINDOWS_RESTORE,MF_CHECKED); } else { CheckMenuItem(hMonMenu, ID_WINDOWS_RESTORE, MF_UNCHECKED); CheckMenuItem(hTermCfgMenu, ID_WINDOWS_RESTORE, MF_UNCHECKED); } if (Bells & 1) CheckMenuItem(hTermCfgMenu,BPQBELLS, MF_CHECKED); else CheckMenuItem(hTermCfgMenu,BPQBELLS, MF_UNCHECKED); if (SendDisconnected & 1) CheckMenuItem(hTermCfgMenu,BPQSendDisconnected, MF_CHECKED); else CheckMenuItem(hTermCfgMenu,BPQSendDisconnected, MF_UNCHECKED); if (StripLF & 1) CheckMenuItem(hTermCfgMenu,BPQStripLF, MF_CHECKED); else CheckMenuItem(hTermCfgMenu,BPQStripLF, MF_UNCHECKED); CheckMenuItem(hMonMenu,BPQMNODES, (MonitorNODES) ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(hMonMenu,MONCOLOUR, (MonitorColour) ? MF_CHECKED : MF_UNCHECKED); DrawMenuBar(FrameWnd); if (portmask) applflags |= 0x80; SetAppl(Stream, applflags, APPLMASK); SetTraceOptionsEx(portmask,mtxparam,mcomparam, monUI); if (MinimizetoTray) { // Set up Tray ICON sprintf(Title, "BPQTermMDI"); AddTrayMenuItem(FrameWnd, Title); } if ((nCmdShow == SW_SHOWMINIMIZED) || (nCmdShow == SW_SHOWMINNOACTIVE)) if (MinimizetoTray) ShowWindow(FrameWnd, SW_HIDE); else ShowWindow(FrameWnd, nCmdShow); else ShowWindow(FrameWnd, nCmdShow); UpdateWindow(FrameWnd); // Allocate another incoming stream Stream2 = FindFreeStream(); if (Stream2 < 255) { BPQSetHandle(Stream2, FrameWnd); SetAppl(Stream2, 2, APPLMASK); } Vallen=80; RegQueryValueEx(hKey, "MonSize", 0 , &Type, &Size[0], &Vallen); CreateMonitorWindow(Size); if (RestoreWindows) { int OffsetH, OffsetW; struct ConsoleInfo * Cinfo; int i; char Item[20]; GetWindowRect(FrameWnd, &Rect); OffsetH = Rect.bottom - Rect.top; OffsetW = Rect.right - Rect.left; GetClientRect(FrameWnd, &Rect); OffsetH -= Rect.bottom; OffsetW -= Rect.right; for (i = 1; i <= Sessions; i++) { Cinfo = CreateChildWindow(0); if (Cinfo) { sprintf(Item, "SessSize%d", i); Vallen=80; RegQueryValueEx(hKey, Item, 0 , &Type, &Size[0], &Vallen); sscanf(Size,"%d,%d,%d,%d", &Cinfo->Left, &Cinfo->Height, &Cinfo->Top, &Cinfo->Width); if (Cinfo->Height < 30) { //Was probably minimized. Set to a sensible size and minimize it MoveWindow(Cinfo->hConsole, i * 50 , i * 50, (Rect.right * 2)/3, (Rect.bottom * 2 /3), TRUE); ShowWindow(Cinfo->hConsole, SW_SHOWMINIMIZED); } else { MoveWindow(Cinfo->hConsole, Cinfo->Left - OffsetW/2 + 4, Cinfo->Top - OffsetH, Cinfo->Width, Cinfo->Height, TRUE); MoveWindows(Cinfo); } } } } RegCloseKey(hKey); return TRUE; } #endif /* BOOL InitInstancex(HINSTANCE hInstance, int nCmdShow) { int i, n, tempmask=0xffff; char msg[20]; int retCode,Type,Vallen; HKEY hKey=0; char Size[80]; TEXTMETRIC tm; HDC dc; struct RTFTerm * OPData; hInst = hInstance; // Store instance handle in our global variable // See if running under WINE retCode = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "SOFTWARE\\Wine", 0, KEY_QUERY_VALUE, &hKey); if (retCode == ERROR_SUCCESS) { RegCloseKey(hKey); WINE = TRUE; Debugprintf("Running under WINE"); } REGTREE = GetRegistryKey(); MinimizetoTray=GetMinimizetoTrayFlag(); // Create a dialog box as the main window hWnd=CreateDialog(hInst,ClassName,0,NULL); if (!hWnd) return (FALSE); MainWnd=hWnd; // Retrieve the handlse to the edit controls. hwndInput = GetDlgItem(hWnd, 118); // hwndOutput = GetDlgItem(hWnd, 117); hwndSplit = GetDlgItem(hWnd, 119); hwndMon = GetDlgItem(hWnd, 116); // Set our own WndProcs for the controls. wpOrigInputProc = (WNDPROC) SetWindowLong(hwndInput, GWL_WNDPROC, (LONG) InputProc); wpOrigMonProc = (WNDPROC)SetWindowLong(hwndMon, GWL_WNDPROC, (LONG)MonProc); // Get config from Registry sprintf(Key,"SOFTWARE\\G8BPQ\\BPQ32\\BPQTerminal\\Session%d",Sessno); retCode = RegOpenKeyEx (REGTREE, Key, 0, KEY_QUERY_VALUE, &hKey); if (retCode == ERROR_SUCCESS) { Vallen=4; retCode = RegQueryValueEx(hKey,"APPLMASK",0, (ULONG *)&Type,(UCHAR *)&APPLMASK,(ULONG *)&Vallen); Vallen=4; retCode = RegQueryValueEx(hKey,"MTX",0, (ULONG *)&Type,(UCHAR *)&mtxparam,(ULONG *)&Vallen); Vallen=4; retCode = RegQueryValueEx(hKey,"MCOM",0, (ULONG *)&Type,(UCHAR *)&mcomparam,(ULONG *)&Vallen); Vallen=4; retCode = RegQueryValueEx(hKey,"PortMask",0, (ULONG *)&Type,(UCHAR *)&tempmask,(ULONG *)&Vallen); Vallen=4; retCode = RegQueryValueEx(hKey,"AutoConnect",0, (ULONG *)&Type,(UCHAR *)&AUTOCONNECT,(ULONG *)&Vallen); Vallen=4; retCode = RegQueryValueEx(hKey,"MONColour",0, (ULONG *)&Type,(UCHAR *)&MonitorColour,(ULONG *)&Vallen); Vallen=4; retCode = RegQueryValueEx(hKey,"MonitorNODES",0, (ULONG *)&Type,(UCHAR *)&MonitorNODES,(ULONG *)&Vallen); Vallen=4; retCode = RegQueryValueEx(hKey,"Bells",0, (ULONG *)&Type,(UCHAR *)&Bells,(ULONG *)&Vallen); Vallen=4; retCode = RegQueryValueEx(hKey,"StripLF",0, (ULONG *)&Type,(UCHAR *)&StripLF,(ULONG *)&Vallen); Vallen=4; retCode = RegQueryValueEx(hKey, "SendDisconnected",0, (ULONG *)&Type,(UCHAR *)&StripLF,(ULONG *)&Vallen); Vallen=8; retCode = RegQueryValueEx(hKey,"Split",0, (ULONG *)&Type,(UCHAR *)&Split,(ULONG *)&Vallen); Vallen=80; retCode = RegQueryValueEx(hKey,"Size",0, (ULONG *)&Type,(UCHAR *)&Size,(ULONG *)&Vallen); sscanf(Size,"%d,%d,%d,%d",&Rect.left,&Rect.right,&Rect.top,&Rect.bottom); Vallen=99; retCode = RegQueryValueEx(hKey, "FontName", 0, &Type, FontName, &Vallen); if (FontName[0] == 0) strcpy(FontName, "FixedSys"); Vallen=4; retCode = RegQueryValueEx(hKey, "CharSet", 0, &Type, (UCHAR *)&CharSet, &Vallen); Vallen=4; retCode = RegQueryValueEx(hKey, "CodePage", 0, &Type, (UCHAR *)&CodePage, &Vallen); Vallen=4; retCode = RegQueryValueEx(hKey, "FontSize", 0, &Type, (UCHAR *)&FontSize, &Vallen); Vallen=4; retCode = RegQueryValueEx(hKey, "FontWidth", 0, &Type, (UCHAR *)&FontWidth, &Vallen); RegCloseKey(hKey); } OutputData.CharWidth = FontWidth; if (Rect.right < 100 || Rect.bottom < 100) { GetWindowRect(hWnd, &Rect); } Height = Rect.bottom-Rect.top; Width = Rect.right-Rect.left; #pragma warning(push) #pragma warning(disable:4244) SplitPos=Height*Split; #pragma warning(pop) SetupRTFHddr(); // Create a Rich Text Control OPData = &OutputData; OPData->SendHeader = TRUE; OPData->Finished = TRUE; OPData->CurrentColour = 1; LoadLibrary("riched20.dll"); hwndOutput = CreateWindowEx(WS_EX_CLIENTEDGE, RICHEDIT_CLASS, "", WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_NOHIDESEL | WS_VSCROLL | ES_READONLY, 6,145,290,130, MainWnd, NULL, hInstance, NULL); // Register for Mouse Events for Copy/Paste SendMessage(hwndOutput, EM_SETEVENTMASK, (WPARAM)0, (LPARAM)ENM_MOUSEEVENTS | ENM_SCROLLEVENTS | ENM_KEYEVENTS); SendMessage(hwndOutput, EM_EXLIMITTEXT, 0, MAXLINES * LINELEN); trayMenu = CreatePopupMenu(); AppendMenu(trayMenu,MF_STRING,40000,"Copy"); MoveWindow(hWnd,Rect.left,Rect.top, Rect.right-Rect.left, Rect.bottom-Rect.top, TRUE); MoveWindows(); Stream=FindFreeStream(); if (Stream == 255) { MessageBox(NULL,"No free streams available",NULL,MB_OK); return (FALSE); } // // Register message for posting by BPQDLL // BPQMsg = RegisterWindowMessage(BPQWinMsg); // // Enable Async notification // BPQSetHandle(Stream, hWnd); GetVersionInfo(NULL); sprintf(Title,"BPQTerminal Version %s - using stream %d", VersionString, Stream); SetWindowText(hWnd,Title); // Sets Application Flags and Mask for stream. (BPQHOST function 1) // AH = 1 Set application mask to value in DL (or even DX if 16 // applications are ever to be supported). // // Set application flag(s) to value in CL (or CX). // whether user gets connected/disconnected messages issued // by the node etc. // // Top bit of flags controls monitoring // if (APPLMASK & 0x01) CheckMenuItem(hMenu,BPQAPPL1,MF_CHECKED); if (APPLMASK & 0x02) CheckMenuItem(hTermCfgMenu,BPQCHAT,MF_CHECKED); // if (APPLMASK & 0x04) CheckMenuItem(hMenu,BPQAPPL3,MF_CHECKED); // if (APPLMASK & 0x08) CheckMenuItem(hMenu,BPQAPPL4,MF_CHECKED); // if (APPLMASK & 0x10) CheckMenuItem(hMenu,BPQAPPL5,MF_CHECKED); // if (APPLMASK & 0x20) CheckMenuItem(hMenu,BPQAPPL6,MF_CHECKED); // if (APPLMASK & 0x40) CheckMenuItem(hMenu,BPQAPPL7,MF_CHECKED); // if (APPLMASK & 0x80) CheckMenuItem(hMenu,BPQAPPL8,MF_CHECKED); // CMD_TO_APPL EQU 1B ; PASS COMMAND TO APPLICATION // MSG_TO_USER EQU 10B ; SEND 'CONNECTED' TO USER // MSG_TO_APPL EQU 100B ; SEND 'CONECTED' TO APPL // 0x40 = Send Keepalives // if (applflags & 0x01) CheckMenuItem(hMenu,BPQFLAGS1,MF_CHECKED); // if (applflags & 0x02) CheckMenuItem(hMenu,BPQFLAGS2,MF_CHECKED); // if (applflags & 0x04) CheckMenuItem(hMenu,BPQFLAGS3,MF_CHECKED); // if (applflags & 0x40) CheckMenuItem(hMenu,BPQFLAGS4,MF_CHECKED); hPopMenu1=GetSubMenu(hMonMenu,1); for (n=1;n <= GetNumberofPorts();n++) { i = GetPortNumber(n); sprintf(msg,"Port %d",i); if (tempmask & (1<<(i-1))) { AppendMenu(hPopMenu1,MF_STRING | MF_CHECKED,BPQBASE + i,msg); portmask |= (1<<(i-1)); } else AppendMenu(hPopMenu1,MF_STRING | MF_UNCHECKED,BPQBASE + i,msg); } if (mtxparam & 1) CheckMenuItem(hMonMenu,BPQMTX,MF_CHECKED); else CheckMenuItem(hMonMenu,BPQMTX,MF_UNCHECKED); if (mcomparam & 1) CheckMenuItem(hMonMenu,BPQMCOM,MF_CHECKED); else CheckMenuItem(hMonMenu,BPQMCOM,MF_UNCHECKED); if (AUTOCONNECT) CheckMenuItem(hTermCfgMenu,BPQAUTOCONNECT,MF_CHECKED); else CheckMenuItem(hTermCfgMenu,BPQAUTOCONNECT,MF_UNCHECKED); if (Bells & 1) CheckMenuItem(hTermCfgMenu,BPQBELLS, MF_CHECKED); else CheckMenuItem(hTermCfgMenu,BPQBELLS, MF_UNCHECKED); if (SendDisconnected & 1) CheckMenuItem(hTermCfgMenu,BPQSendDisconnected, MF_CHECKED); else CheckMenuItem(hTermCfgMenu,BPQSendDisconnected, MF_UNCHECKED); if (StripLF & 1) CheckMenuItem(hTermCfgMenu,BPQStripLF, MF_CHECKED); else CheckMenuItem(hTermCfgMenu,BPQStripLF, MF_UNCHECKED); CheckMenuItem(hMonMenu,BPQMNODES, (MonitorNODES) ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(hMonMenu,MONCOLOUR, (MonitorColour) ? MF_CHECKED : MF_UNCHECKED); DrawMenuBar(hWnd); if (portmask) applflags |= 0x80; SetAppl(Stream, applflags, APPLMASK); SetTraceOptionsEx(portmask,mtxparam,mcomparam, monUI); DragCursor = LoadCursor(hInstance, "IDC_DragSize"); Cursor = LoadCursor(NULL, IDC_ARROW); GetCallsign(Stream, callsign); if (MinimizetoTray) { // Set up Tray ICON sprintf(Title,"BPQTerminal Stream %d",Stream); AddTrayMenuItem(hWnd, Title); } if ((nCmdShow == SW_SHOWMINIMIZED) || (nCmdShow == SW_SHOWMINNOACTIVE)) if (MinimizetoTray) ShowWindow(hWnd, SW_HIDE); else ShowWindow(hWnd, nCmdShow); else ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); CheckTimer(); TimerHandle = SetTimer(NULL, 0, 10000, lpTimerFunc); dc = GetDC(hwndOutput); GetTextMetrics(dc, &tm); return (TRUE); } */ // // FUNCTION: WndProc(HWND, unsigned, WORD, LONG) // // PURPOSE: Processes messages for the main window. // LRESULT CALLBACK MonWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { struct ConsoleInfo * Cinfo = &MonWindow; LPRECT lprc; int wmId, wmEvent; int i; RECT Rect; switch(message) { case WM_CREATE: break; case WM_VSCROLL: break; case WM_NOTIFY: { const MSGFILTER * pF = (MSGFILTER *)lParam; POINT pos; CHARRANGE Range; if(pF->nmhdr.hwndFrom == Cinfo->hwndOutput) { if(pF->msg == WM_VSCROLL) { // int Command = LOWORD(pF->wParam); // int Pos = HIWORD(pF->wParam); // Cinfo->Thumb = SendMessage(Cinfo->hwndOutput, EM_GETTHUMB, 0, 0); DoRefresh(Cinfo); break; } if(pF->msg == WM_KEYUP) { if (pF->wParam == VK_PRIOR || pF->wParam == VK_NEXT) { // Cinfo->Thumb = SendMessage(Cinfo->hwndOutput, EM_GETTHUMB, 0, 0); DoRefresh(Cinfo); } } if(pF->msg == WM_RBUTTONDOWN) { // Only allow popup if something is selected SendMessage(Cinfo->hwndOutput, EM_EXGETSEL , 0, (WPARAM)&Range); if (Range.cpMin == Range.cpMax) return TRUE; GetCursorPos(&pos); TrackPopupMenu(trayMenu, 0, pos.x, pos.y, 0, hWnd, 0); return TRUE; } } break; } case WM_MDIACTIVATE: if (lParam == (LPARAM) hWnd) { RECT Rect; RemoveMenu(hBaseMenu, 1, MF_BYPOSITION); AppendMenu(hBaseMenu, MF_STRING + MF_POPUP, (UINT)hMonCfgMenu, "Config"); AppendMenu(hBaseMenu, MF_STRING + MF_POPUP, (UINT)hMonEdtMenu, "Edit"); AppendMenu(hBaseMenu, MF_STRING + MF_POPUP, (UINT)hMonHlpMenu, "Help"); SendMessage(ClientWnd, WM_MDISETMENU, (WPARAM) hBaseMenu, (LPARAM)hWndMenu); // Check Window is visible GetWindowRect(FrameWnd, &FRect); if (GetWindowRect(hWnd, &Rect)) { if (Rect.top > FRect.bottom || Rect.left > FRect.right) MoveWindow(hWnd, FRect.top + 100, FRect.left+ 100, 300, 200, 1); } } else { RemoveMenu(hBaseMenu, 3, MF_BYPOSITION); RemoveMenu(hBaseMenu, 2, MF_BYPOSITION); SendMessage(ClientWnd, WM_MDISETMENU, (WPARAM) hMainFrameMenu, (LPARAM) NULL); } DrawMenuBar(FrameWnd); return TRUE; //DefMDIChildProc(hWnd, message, wParam, lParam); case WM_SIZING: lprc = (LPRECT) lParam; Cinfo->Height = lprc->bottom-lprc->top; Cinfo->Width = lprc->right-lprc->left; Cinfo->Top = lprc->top; Cinfo->Left = lprc->left; MoveWindows(Cinfo); break; case WM_SIZE: MoveWindows(Cinfo); // Drop through to Move case WM_MOVE: GetWindowRect(hWnd, &Rect); Cinfo->Height = Rect.bottom-Rect.top; Cinfo->Width = Rect.right-Rect.left; Cinfo->Top = Rect.top; Cinfo->Left = Rect.left; // Male relative to Frame GetWindowRect(FrameWnd, &Rect); Cinfo->Top -= Rect.top ; Cinfo->Left -= Rect.left; break; case WM_COMMAND: wmId = LOWORD(wParam); // Remember, these are... wmEvent = HIWORD(wParam); // ...different for Win32! if (wmId > BPQBASE && wmId < BPQBASE + 33) { TogglePort(hWnd, wmId, 0x1 << (wmId - (BPQBASE + 1))); break; } switch (wmId) { case StopALLMon: for (i=1; i <= GetNumberofPorts();i++) { CheckMenuItem(hMonCfgMenu, BPQBASE + GetPortNumber(i), MF_UNCHECKED); } portmask = 0; applflags &= 0x7f; SetAppl(Stream,applflags,APPLMASK); break; case RTFCOPY: { int len=0; HGLOBAL hMem; char * ptr; CHARRANGE Range; // Copy Rich Text Selection to Clipboard SendMessage(Cinfo->hwndOutput, EM_EXGETSEL , 0, (WPARAM)&Range); hMem=GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, Range.cpMax - Range.cpMin + 1); if (hMem != 0) { ptr=GlobalLock(hMem); if (OpenClipboard(Cinfo->hConsole)) { len = SendMessage(Cinfo->hwndOutput, EM_GETSELTEXT , 0, (WPARAM)ptr); GlobalUnlock(hMem); EmptyClipboard(); SetClipboardData(CF_TEXT,hMem); CloseClipboard(); } } else GlobalFree(hMem); SetFocus(Cinfo->hwndInput); break; } case BPQMTX: ToggleMTX(hWnd); break; case BPQMCOM: ToggleMCOM(hWnd); break; case MON_UI_ONLY: ToggleMON_UI_ONLY(hWnd); break; case BPQMNODES: ToggleParam(hMonCfgMenu, &MonitorNODES, BPQMNODES); break; case MONITORAPRS: ToggleParam(hMonCfgMenu, &MonitorAPRS, MONITORAPRS); break; case MONCOLOUR: ToggleParam(hMonCfgMenu, &MonitorColour, MONCOLOUR); break; case BPQLogMonitor: ToggleParam(hMonCfgMenu, &LogMonitor, BPQLogMonitor); break; case BPQCLEARMON: for (i = 0; i < MAXLINES; i++) { Cinfo->OutputScreen[i][0] = 0; } Cinfo->CurrentLine = 0; DoRefresh(Cinfo); break; case BPQCOPYMON: CopyRichTextToClipboard(Cinfo->hwndOutput); break; case ID_WINDOWS_RESTORE: ToggleRestoreWindows(); break; } case WM_SYSCOMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); switch (wmId) { case SC_RESTORE: Cinfo->Minimized = FALSE; SendMessage(ClientWnd, WM_MDIRESTORE, (WPARAM)hWnd, 0); DoRefresh(Cinfo); break; case SC_MINIMIZE: Cinfo->Minimized = TRUE; break; } return DefMDIChildProc(hWnd, message, wParam, lParam); } return DefMDIChildProc(hWnd, message, wParam, lParam); //Frame window calls DefFrameProc rather than DefWindowProc } struct ConsoleInfo * FontCinfo; LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { struct ConsoleInfo * Cinfo; struct ConsoleInfo * last = NULL; LPRECT lprc; int wmId, wmEvent; int i; RECT Rect; // MINMAXINFO * mmi; for (Cinfo = ConsHeader; Cinfo; Cinfo = Cinfo->next) { if (Cinfo->hConsole == hWnd) break; } if (Cinfo == NULL) Cinfo = &InitHeader; switch(message) { /* case WM_GETMINMAXINFO: mmi = (MINMAXINFO *)lParam; mmi->ptMaxSize.x = 800; mmi->ptMaxSize.y = 600; mmi->ptMaxTrackSize.x = 800; mmi->ptMaxTrackSize.y = 600; return DefMDIChildProc(hWnd, message, wParam, lParam); */ case WM_CTLCOLOREDIT: if (Cinfo->Scrolled) { HDC hdcStatic = (HDC)wParam; SetBkMode(hdcStatic, TRANSPARENT); return (LONG)GetStockObject(LTGRAY_BRUSH); } return DefMDIChildProc(hWnd, message, wParam, lParam); case WM_NOTIFY: { const MSGFILTER * pF = (MSGFILTER *)lParam; POINT pos; CHARRANGE Range; if(pF->nmhdr.hwndFrom == Cinfo->hwndOutput) { if(pF->msg == WM_VSCROLL) { // int Command = LOWORD(pF->wParam); // int Pos = HIWORD(pF->wParam); // Cinfo->Thumb = SendMessage(Cinfo->hwndOutput, EM_GETTHUMB, 0, 0); DoRefresh(Cinfo); break; } if(pF->msg == WM_KEYUP) { if (pF->wParam == VK_PRIOR || pF->wParam == VK_NEXT) { // Cinfo->Thumb = SendMessage(Cinfo->hwndOutput, EM_GETTHUMB, 0, 0); DoRefresh(Cinfo); } } if(pF->msg == WM_RBUTTONDOWN) { // Only allow popup if something is selected SendMessage(Cinfo->hwndOutput, EM_EXGETSEL , 0, (WPARAM)&Range); if (Range.cpMin == Range.cpMax) return TRUE; GetCursorPos(&pos); TrackPopupMenu(trayMenu, 0, pos.x, pos.y, 0, hWnd, 0); return TRUE; } } break; } case WM_MDIACTIVATE: // Set the system info menu when getting activated if (lParam == (LPARAM) hWnd) { // Activate Cinfo->Active = TRUE; RemoveMenu(hBaseMenu, 1, MF_BYPOSITION); AppendMenu(hBaseMenu, MF_STRING + MF_POPUP, (UINT)hTermActMenu, "Actions"); AppendMenu(hBaseMenu, MF_STRING + MF_POPUP, (UINT)hTermCfgMenu, "Config"); AppendMenu(hBaseMenu, MF_STRING + MF_POPUP, (UINT)hTermEdtMenu, "Edit"); AppendMenu(hBaseMenu, MF_STRING + MF_POPUP, (UINT)hTermHlpMenu, "Help"); SendMessage(ClientWnd, WM_MDISETMENU, (WPARAM) hBaseMenu, (LPARAM)hWndMenu); if (Cinfo->CONNECTED) { EnableDisconnectMenu(hWnd); DisableConnectMenu(hWnd); } else { DisableDisconnectMenu(hWnd); EnableConnectMenu(hWnd); } SetFocus(Cinfo->hwndInput); } else { // Deactivate Cinfo->Active = FALSE; RemoveMenu(hBaseMenu, 4, MF_BYPOSITION); RemoveMenu(hBaseMenu, 3, MF_BYPOSITION); RemoveMenu(hBaseMenu, 2, MF_BYPOSITION); SendMessage(ClientWnd, WM_MDISETMENU, (WPARAM) hMainFrameMenu, (LPARAM) NULL); } DrawMenuBar(FrameWnd); return TRUE; //DefMDIChildProc(hWnd, message, wParam, lParam); case WM_SIZING: lprc = (LPRECT) lParam; Cinfo->Height = lprc->bottom-lprc->top; Cinfo->Width = lprc->right-lprc->left; Cinfo->Top = lprc->top; Cinfo->Left = lprc->left; MoveWindows(Cinfo); return DefMDIChildProc(hWnd, message, wParam, lParam); case WM_SIZE: MoveWindows(Cinfo); // Drop through to Move case WM_MOVE: GetWindowRect(hWnd, &Rect); Cinfo->Height = Rect.bottom-Rect.top; Cinfo->Width = Rect.right-Rect.left; Cinfo->Top = Rect.top; Cinfo->Left = Rect.left; // Male relative to Frame GetWindowRect(FrameWnd, &Rect); Cinfo->Top -= Rect.top ; Cinfo->Left -= Rect.left; return DefMDIChildProc(hWnd, message, wParam, lParam); case WM_COMMAND: wmId = LOWORD(wParam); // Remember, these are... wmEvent = HIWORD(wParam); // ...different for Win32! switch (wmId) { case RTFCOPY: { int len=0; HGLOBAL hMem; char * ptr; CHARRANGE Range; // Copy Rich Text Selection to Clipboard SendMessage(Cinfo->hwndOutput, EM_EXGETSEL , 0, (WPARAM)&Range); hMem=GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, Range.cpMax - Range.cpMin + 1); if (hMem != 0) { ptr=GlobalLock(hMem); if (OpenClipboard(Cinfo->hConsole)) { len = SendMessage(Cinfo->hwndOutput, EM_GETSELTEXT , 0, (WPARAM)ptr); GlobalUnlock(hMem); EmptyClipboard(); SetClipboardData(CF_TEXT,hMem); CloseClipboard(); } } else GlobalFree(hMem); SetFocus(Cinfo->hwndInput); break; } case BPQCONNECT: SessionControl(Cinfo->BPQStream, 1, 0); break; case BPQDISCONNECT: SessionControl(Cinfo->BPQStream, 2, 0); break; case BPQHELP: ShellExecute(hWnd,"open", "http://www.cantab.net/users/john.wiseman/Documents/BPQTerminal.htm", "", NULL, SW_SHOWNORMAL); break; case ID_WINDOWS_RESTORE: ToggleRestoreWindows(); break; case ID_SETUP_FONT: FontCinfo = Cinfo; DialogBox(hInst, MAKEINTRESOURCE(IDD_FONT), hWnd, FontConfigWndProc); i = GetLastError(); break; case BPQCLEAROUT: for (i = 0; i < MAXLINES; i++) { Cinfo->OutputScreen[i][0] = 0; } Cinfo->CurrentLine = 0; DoRefresh(Cinfo); break; case BPQCOPYOUT: CopyRichTextToClipboard(Cinfo->hwndOutput); break; case BPQBELLS: ToggleParam(hTermCfgMenu, &Bells, BPQBELLS); break; case BPQStripLF: ToggleParam(hTermCfgMenu, &StripLF, BPQStripLF); break; case BPQLogOutput: ToggleParam(hTermCfgMenu, &LogOutput, BPQLogOutput); break; case CHATTERM: ToggleParam(hTermCfgMenu, &ChatMode, CHATTERM); break; case BPQSendDisconnected: ToggleParam(hTermCfgMenu, &SendDisconnected, BPQSendDisconnected); break; case ID_WARNWRAP: ToggleParam(hTermCfgMenu, &WarnWrap, ID_WARNWRAP); break; case ID_WRAP: ToggleParam(hTermCfgMenu, &WrapInput, ID_WRAP); break; case ID_FLASHONBELL: ToggleParam(hTermCfgMenu, &FlashOnBell, ID_FLASHONBELL); break; } break; case WM_SYSCOMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); switch (wmId) { case SC_RESTORE: Cinfo->Minimized = FALSE; SendMessage(ClientWnd, WM_MDIRESTORE, (WPARAM)hWnd, 0); DoRefresh(Cinfo); break; case SC_MINIMIZE: Cinfo->Minimized = TRUE; break; } return DefMDIChildProc(hWnd, message, wParam, lParam); case WM_CLOSE: break; // Go on to call DefMDIChildProc case WM_DESTROY: // Close session and release stream #define GWL_WNDPROC (-4) SetWindowLong(Cinfo->hwndInput, GWL_WNDPROC, (LONG) Cinfo->wpOrigInputProc); SessionControl(Cinfo->BPQStream, 2, 0); if (Cinfo->Incoming == FALSE) DeallocateStream(Cinfo->BPQStream); // Free Scrollback for (i = 0; i < MAXSTACK ; i++) { if (Cinfo->KbdStack[i]) { free(Cinfo->KbdStack[i]); Cinfo->KbdStack[i] = NULL; } } Sleep(500); if (Cinfo->readbuff) free(Cinfo->readbuff); // Remove from List for (Cinfo = ConsHeader; Cinfo; last = Cinfo, Cinfo = Cinfo->next) { if (Cinfo->hConsole == hWnd) { if (last) { last->next = Cinfo->next; free(Cinfo); return 0; } else { // First in list ConsHeader = Cinfo->next; free(Cinfo); return 0; } } } return DefMDIChildProc(hWnd, message, wParam, lParam); } return DefMDIChildProc(hWnd, message, wParam, lParam); } #ifndef MDIKERNEL LRESULT CALLBACK FrameWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; UCHAR Buffer[1000]; UCHAR * buf = Buffer; CLIENTCREATESTRUCT MDIClientCreateStruct; // Structure to be used for MDI client area HWND m_hwndSystemInformation = 0; struct ConsoleInfo * Cinfo; int i, disp; HKEY hKey=0; char Size[80], Item[20]; if (message == BPQMsg) { if (lParam & BPQDataAvail) DoReceivedData(wParam); if (lParam & BPQMonitorAvail) DoMonData(wParam); if (lParam & BPQStateChange) DoStateChange(wParam); return (0); } switch (message) { case WM_CREATE: // On creation of main frame, create the MDI client area MDIClientCreateStruct.hWindowMenu = NULL; MDIClientCreateStruct.idFirstChild = IDM_FIRSTCHILD; ghMDIClientArea = CreateWindow(TEXT("MDICLIENT"), // predefined value for MDI client area NULL, // no caption required WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE, 0, // No need to give any x/y or height/width since this client // will just be used to get client windows created, effectively // in the main window we will be seeing the mainframe window client area itself. 0, 0, 0, hWnd, NULL, hInstance, (void *) &MDIClientCreateStruct); return 0; case WM_COMMAND: switch(LOWORD(wParam)) { case ID_NEWWINDOW: CreateChildWindow(0); break; case ID_HELP_ABOUT: MessageBox(FrameWnd, TEXT("Sigma by Sharath C V"), TEXT("Sigma"), MB_OK); break; case ID_FILE_EXIT: PostQuitMessage(0); break; case ID_WINDOWS_CASCADE: SendMessage(ghMDIClientArea, WM_MDICASCADE, 0, 0); return 0; case ID_WINDOWS_TILE: SendMessage(ghMDIClientArea, WM_MDITILE , MDITILE_HORIZONTAL, 0); return 0; // Handle MDI Window commands default: { if(LOWORD(wParam) >= IDM_FIRSTCHILD) { DefFrameProc(hWnd, ghMDIClientArea, message, wParam, lParam); } else { HWND hChild = (HWND)SendMessage(ghMDIClientArea, WM_MDIGETACTIVE,0,0); if(hChild) SendMessage(hChild, WM_COMMAND, wParam, lParam); } } break; } case WM_SYSCOMMAND: wmId = LOWORD(wParam); // Remember, these are... wmEvent = HIWORD(wParam); // ...different for Win32! switch (wmId) { case SC_MINIMIZE: if (MinimizetoTray) return ShowWindow(hWnd, SW_HIDE); default: return (DefFrameProc(hWnd, ghMDIClientArea, message, wParam, lParam)); } case WM_DESTROY: GetWindowRect(hWnd, &Rect); // For save soutine PostQuitMessage(0); if (MinimizetoTray) DeleteTrayMenuItem(hWnd); // Save config RegCreateKeyEx(REGTREE, Key, 0, 0, 0, KEY_ALL_ACCESS, NULL, &hKey, &disp); RegSetValueEx(hKey,"ChatMode",0,REG_DWORD,(BYTE *)&ChatMode,4); RegSetValueEx(hKey,"PortMask",0,REG_DWORD,(BYTE *)&portmask,4); RegSetValueEx(hKey,"Bells",0,REG_DWORD,(BYTE *)&Bells,4); RegSetValueEx(hKey,"StripLF",0,REG_DWORD,(BYTE *)&StripLF,4); RegSetValueEx(hKey,"SendDisconnected",0,REG_DWORD,(BYTE *)&SendDisconnected,4); RegSetValueEx(hKey,"RestoreWindows",0,REG_DWORD,(BYTE *)&RestoreWindows,4); RegSetValueEx(hKey,"MTX",0,REG_DWORD,(BYTE *)&mtxparam,4); RegSetValueEx(hKey,"MCOM",0,REG_DWORD,(BYTE *)&mcomparam,4); RegSetValueEx(hKey,"MONColour",0,REG_DWORD,(BYTE *)&MonitorColour,4); RegSetValueEx(hKey,"MonitorNODES",0,REG_DWORD,(BYTE *)&MonitorNODES,4); sprintf(Size,"%d,%d,%d,%d",Rect.left,Rect.right,Rect.top,Rect.bottom); RegSetValueEx(hKey,"Size",0,REG_SZ,(BYTE *)&Size, strlen(Size)); // Close any sessions i = 0; for (Cinfo = ConsHeader; Cinfo; Cinfo = Cinfo->next) { i++; sprintf(Size, "%d,%d,%d,%d", Cinfo->Left, Cinfo->Height, Cinfo->Top, Cinfo->Width); sprintf(Item, "SessSize%d", i); RegSetValueEx(hKey, Item, 0, REG_SZ, (BYTE *)&Size, strlen(Size)); SessionControl(Cinfo->BPQStream, 2, 0); DeallocateStream(Cinfo->BPQStream); } RegSetValueEx(hKey,"Sessions",0,REG_DWORD,(BYTE *)&i,4); sprintf(Size, "%d,%d,%d,%d", MonWindow.Left, MonWindow.Height, MonWindow.Top, MonWindow.Width); RegSetValueEx(hKey, "MonSize", 0, REG_SZ, (BYTE *)&Size, strlen(Size)); RegCloseKey(hKey); break; default: return (DefFrameProc(hWnd, ghMDIClientArea, message, wParam, lParam)); } return (0); } #endif /* LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; LPRECT lprc; UCHAR Buffer[1000]; UCHAR * buf = Buffer; TEXTMETRIC tm; int y; LPMEASUREITEMSTRUCT lpmis; LPDRAWITEMSTRUCT lpdis; HWND m_hwndSystemInformation = 0; if (message == BPQMsg) { if (lParam & BPQDataAvail) DoReceivedData(wParam); if (lParam & BPQMonitorAvail) DoMonData(wParam); if (lParam & BPQStateChange) DoStateChange(wParam); return (0); } switch (message) { case WM_CTLCOLOREDIT: if (OutputData.Scrolled) { HDC hdcStatic = (HDC)wParam; SetBkMode(hdcStatic, TRANSPARENT); return (LONG)GetStockObject(LTGRAY_BRUSH); } return (DefWindowProc(hWnd, message, wParam, lParam)); case WM_MEASUREITEM: lpmis = (LPMEASUREITEMSTRUCT) lParam; // Set the height of the list box items. // lpmis->itemHeight = 15; return TRUE; case WM_DRAWITEM: lpdis = (LPDRAWITEMSTRUCT) lParam; // If there are no list box items, skip this message. if (lpdis->itemID == -1) { return TRUE; } switch (lpdis->itemAction) { case ODA_SELECT: case ODA_DRAWENTIRE: // if Chat Console, and message has a colour eacape, action it SendMessage(lpdis->hwndItem, LB_GETTEXT, lpdis->itemID, (LPARAM) Buffer); GetTextMetrics(lpdis->hDC, &tm); if (lpdis->hwndItem == hwndOutput) { CharWidth = tm.tmAveCharWidth; maxlinelen = ClientWidth/CharWidth - 1; } y = (lpdis->rcItem.bottom + lpdis->rcItem.top - tm.tmHeight) / 2; if (Buffer[0] == 0x1b) { SetTextColor(lpdis->hDC, Colours[Buffer[1] - 10]); buf += 2; } // SetBkColor(lpdis->hDC, 0); TextOut(lpdis->hDC, 6, y, buf, strlen(buf)); // SetTextColor(lpdis->hDC, OldColour); break; } return TRUE; case WM_ACTIVATE: //fActive = LOWORD(wParam); // activation flag //fMinimized = (BOOL) HIWORD(wParam); // minimized flag // hwnd = (HWND) lParam; // window handle SetFocus(hwndInput); break; case WM_COMMAND: wmId = LOWORD(wParam); // Remember, these are... wmEvent = HIWORD(wParam); // ...different for Win32! //Parse the menu selections: if (wmId > BPQBASE && wmId < BPQBASE + 32) { TogglePort(hWnd,wmId,0x1 << (wmId - (BPQBASE + 1))); break; } switch (wmId) { case 40000: { int len=0; HGLOBAL hMem; char * ptr; CHARRANGE Range; // Copy Rich Text Selection to Clipboard SendMessage(hwndOutput, EM_EXGETSEL , 0, (WPARAM)&Range); hMem=GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, Range.cpMax - Range.cpMin + 1); if (hMem != 0) { ptr=GlobalLock(hMem); if (OpenClipboard(MainWnd)) { len = SendMessage(hwndOutput, EM_GETSELTEXT , 0, (WPARAM)ptr); GlobalUnlock(hMem); EmptyClipboard(); SetClipboardData(CF_TEXT,hMem); CloseClipboard(); } } else GlobalFree(hMem); SetFocus(hwndInput); return TRUE; } case ID_SETUP_FONT: // DialogBox(hInst, MAKEINTRESOURCE(IDD_FONT), hWnd, FontConfigWndProc); break; case BPQMTX: ToggleMTX(hWnd); break; case BPQMCOM: ToggleMCOM(hWnd); break; case BPQCONNECT: SessionControl(Stream, 1, 0); break; case BPQDISCONNECT: SessionControl(Stream, 2, 0); break; case ID_ACTION_RESETWINDOWSPLIT: Split = 0.5; SplitPos=Height*Split; MoveWindows(); break; case BPQAUTOCONNECT: ToggleAutoConnect(hWnd); break; case BPQAPPL1: ToggleAppl(hWnd,BPQAPPL1,0x1); break; case BPQAPPL2: ToggleAppl(hWnd,BPQAPPL2,0x2); break; case BPQAPPL3: ToggleAppl(hWnd,BPQAPPL3,0x4); break; case BPQAPPL4: ToggleAppl(hWnd,BPQAPPL4,0x8); break; case BPQAPPL5: ToggleAppl(hWnd,BPQAPPL5,0x10); break; case BPQAPPL6: ToggleAppl(hWnd,BPQAPPL6,0x20); break; case BPQAPPL7: ToggleAppl(hWnd,BPQAPPL7,0x40); break; case BPQAPPL8: ToggleAppl(hWnd,BPQAPPL8,0x80); break; case BPQFLAGS1: ToggleFlags(hWnd,BPQFLAGS1,0x01); break; case BPQFLAGS2: ToggleFlags(hWnd,BPQFLAGS2,0x02); break; case BPQFLAGS3: ToggleFlags(hWnd,BPQFLAGS3,0x04); break; case BPQFLAGS4: ToggleFlags(hWnd,BPQFLAGS4,0x40); break; case BPQBELLS: ToggleParam(hTermCfgMenu, &Bells, BPQBELLS); break; case BPQStripLF: ToggleParam(hTermCfgMenu, &StripLF, BPQStripLF); break; case BPQLogOutput: ToggleParam(hTermCfgMenu, &LogOutput, BPQLogOutput); break; case CHATTERM: ToggleParam(hTermCfgMenu, &ChatMode, CHATTERM); break; case BPQSendDisconnected: ToggleParam(hTermCfgMenu, &SendDisconnected, BPQSendDisconnected); break; case BPQMNODES: ToggleParam(hTermCfgMenu, &MonitorNODES, BPQMNODES); break; case MONCOLOUR: ToggleParam(hTermCfgMenu, &MonitorColour, MONCOLOUR); break; case BPQLogMonitor: ToggleParam(hTermCfgMenu, &LogMonitor, BPQLogMonitor); break; case BPQCHAT: ToggleChat(hWnd); break; case BPQCLEARMON: SendMessage(hwndMon,LB_RESETCONTENT, 0, 0); break; case BPQCLEAROUT: for (i = 0; i < MAXLINES; i++) { Cinfo->OutputScreen[i][0] = 0; } Cinfo->CurrentLine = 0; DoRefresh(Cinfo); break; case BPQCOPYMON: CopyListToClipboard(hwndMon); break; case BPQCOPYOUT: CopyRichTextToClipboard(hwndOutput); break; case BPQHELP: ShellExecute(hWnd,"open", "http://www.cantab.net/users/john.wiseman/Documents/BPQTerminal.htm", "", NULL, SW_SHOWNORMAL); break; default: return 0; } case WM_SYSCOMMAND: wmId = LOWORD(wParam); // Remember, these are... wmEvent = HIWORD(wParam); // ...different for Win32! switch (wmId) { case SC_MINIMIZE: if (MinimizetoTray) return ShowWindow(hWnd, SW_HIDE); default: return (DefWindowProc(hWnd, message, wParam, lParam)); } case WM_SIZING: lprc = (LPRECT) lParam; Height = lprc->bottom-lprc->top; Width = lprc->right-lprc->left; SplitPos=Height*Split; MoveWindows(); return TRUE; case WM_SIZE: MoveWindows(); return TRUE; case WM_DESTROY: // Remove the subclass from the edit control. GetWindowRect(hWnd, &Rect); // For save soutine SetWindowLong(hwndInput, GWL_WNDPROC, (LONG) wpOrigInputProc); SessionControl(Stream, 2, 0); DeallocateStream(Stream); PostQuitMessage(0); if (MinimizetoTray) DeleteTrayMenuItem(hWnd); break; default: return (DefWindowProc(hWnd, message, wParam, lParam)); } return (0); } */ //static char * KbdStack[20]; //int StackIndex=0; LRESULT APIENTRY InputProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { int i; unsigned int TextLen; struct ConsoleInfo * Cinfo; for (Cinfo = ConsHeader; Cinfo; Cinfo = Cinfo->next) { if (Cinfo->hwndInput == hwnd) break; } if (Cinfo == NULL) Cinfo = &InitHeader; if (uMsg == WM_KEYUP) { unsigned int i; // Debugprintf("5%x", LOBYTE(HIWORD(lParam))); if (LOBYTE(HIWORD(lParam)) == 0x48 && wParam == 0x26) { // Scroll up if (Cinfo->KbdStack[Cinfo->StackIndex] == NULL) return TRUE; SendMessage(Cinfo->hwndInput, WM_SETTEXT,0,(LPARAM)(LPCSTR) Cinfo->KbdStack[Cinfo->StackIndex]); for (i = 0; i < strlen(Cinfo->KbdStack[Cinfo->StackIndex]); i++) { SendMessage(Cinfo->hwndInput, WM_KEYDOWN, VK_RIGHT, 0); SendMessage(Cinfo->hwndInput, WM_KEYUP, VK_RIGHT, 0); } Cinfo->StackIndex++; if (Cinfo->StackIndex == 20) Cinfo->StackIndex = 19; return TRUE; } if (LOBYTE(HIWORD(lParam)) == 0x50 && wParam == 0x28) { // Scroll up Cinfo->StackIndex--; if (Cinfo->StackIndex < 0) Cinfo->StackIndex = 0; if (Cinfo->KbdStack[Cinfo->StackIndex] == NULL) return TRUE; SendMessage(Cinfo->hwndInput,WM_SETTEXT,0,(LPARAM)(LPCSTR) Cinfo->KbdStack[Cinfo->StackIndex]); for (i = 0; i < strlen(Cinfo->KbdStack[Cinfo->StackIndex]); i++) { SendMessage(Cinfo->hwndInput, WM_KEYDOWN, VK_RIGHT, 0); SendMessage(Cinfo->hwndInput, WM_KEYUP, VK_RIGHT, 0); } return TRUE; } } if (uMsg == WM_CHAR) { TextLen = SendMessage(Cinfo->hwndInput,WM_GETTEXTLENGTH, 0, 0); if (TextLen > INPUTLEN-10) Beep(220, 150); if(WarnWrap || WrapInput) { TextLen = SendMessage(Cinfo->hwndInput,WM_GETTEXTLENGTH, 0, 0); if (WarnWrap) if (TextLen == Cinfo->WarnLen) Beep(220, 150); if (WrapInput) if ((wParam == 0x20) && (TextLen > Cinfo->WrapLen)) wParam = 13; // Replace space with Enter } if (wParam == 13) { // if not connected, and autoconnect is // enabled, connect now if (!Cinfo->CONNECTED) { if (Cinfo->Incoming) // Incoming call window MessageBox(NULL, "Session is for Incoming Calls", "BPQTerm", MB_OK); else SessionControl(Cinfo->BPQStream, 1, 0); } Cinfo->kbptr=SendMessage(Cinfo->hwndInput, WM_GETTEXT, INPUTLEN-1, (LPARAM) (LPCSTR)Cinfo->kbbuf); Cinfo->StackIndex = 0; // Stack it if (Cinfo->KbdStack[19]) free(Cinfo->KbdStack[19]); for (i = 18; i >= 0; i--) { Cinfo->KbdStack[i+1] = Cinfo->KbdStack[i]; } Cinfo->KbdStack[0] = _strdup(Cinfo->kbbuf); Cinfo->kbbuf[Cinfo->kbptr]=13; // Echo Cinfo->CurrentColour = 64; WritetoOutputWindow(Cinfo, Cinfo->kbbuf, Cinfo->kbptr+1, TRUE); Cinfo->CurrentColour = 1; if (Cinfo->Scrolled) { POINT Point; Point.x = 0; Point.y = 25000; // Should be plenty for any font SendMessage(Cinfo->hwndOutput, EM_SETSCROLLPOS, 0, (LPARAM) &Point); Cinfo->Scrolled = FALSE; } DoRefresh(Cinfo); // ProcessLine(Cinfo, &Cinfo->kbbuf[0], Cinfo->kbptr+1); SendMsg(Cinfo->BPQStream, &Cinfo->kbbuf[0], Cinfo->kbptr+1); SendMessage(Cinfo->hwndInput,WM_SETTEXT,0,(LPARAM)(LPCSTR) ""); return 0; } if (wParam == 0x1a) // Ctrl/Z { Cinfo->kbbuf[0]=0x1a; Cinfo->kbbuf[1]=13; // ProcessLine(Cinfo, &Cinfo->kbbuf[0], 2); SendMsg(Cinfo->BPQStream, &Cinfo->kbbuf[0], 2); SendMessage(Cinfo->hwndInput,WM_SETTEXT,0,(LPARAM)(LPCSTR) ""); return 0; } } return CallWindowProc(Cinfo->wpOrigInputProc, hwnd, uMsg, wParam, lParam); } /*LRESULT APIENTRY InputProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { char DisplayLine[200] = "\x1b\xb"; struct ConsoleInfo * Cinfo; for (Cinfo = ConsHeader[0]; Cinfo; Cinfo = Cinfo->next) { if (Cinfo->hwndInput == hwnd) break; } if (Cinfo == NULL) Cinfo = InitHeader; if (uMsg == WM_CTLCOLOREDIT) { HBRUSH Brush = CreateSolidBrush(RGB(0, 255, 0)); HDC hdcStatic = (HDC)wParam; SetTextColor(hdcStatic, RGB(0, 0, 0)); SetBkMode(hdcStatic, TRANSPARENT); return (LONG)Brush; } if (uMsg == WM_KEYUP) { unsigned int i; // Debugprintf("5%x", LOBYTE(HIWORD(lParam))); if (LOBYTE(HIWORD(lParam)) == 0x48 && wParam == 0x26) { // Scroll up if (KbdStack[StackIndex] == NULL) return TRUE; SendMessage(hwndInput, WM_SETTEXT,0,(LPARAM)(LPCSTR) KbdStack[StackIndex]); for (i = 0; i < strlen(KbdStack[StackIndex]); i++) { SendMessage(hwndInput, WM_KEYDOWN, VK_RIGHT, 0); SendMessage(hwndInput, WM_KEYUP, VK_RIGHT, 0); } StackIndex++; if (StackIndex == 20) StackIndex = 19; return TRUE; } if (LOBYTE(HIWORD(lParam)) == 0x50 && wParam == 0x28) { // Scroll up StackIndex--; if (StackIndex < 0) StackIndex = 0; if (KbdStack[StackIndex] == NULL) return TRUE; SendMessage(hwndInput,WM_SETTEXT,0,(LPARAM)(LPCSTR) KbdStack[StackIndex]); for (i = 0; i < strlen(KbdStack[StackIndex]); i++) { SendMessage(hwndInput, WM_KEYDOWN, VK_RIGHT, 0); SendMessage(hwndInput, WM_KEYUP, VK_RIGHT, 0); } return TRUE; } } if (uMsg == WM_CHAR) { if (wParam == 13) { int i; // // if not connected, and autoconnect is // enabled, connect now if (!CONNECTED && AUTOCONNECT) SessionControl(Stream, 1, 0); kbptr=SendMessage(Cinfo->hwndInput,WM_GETTEXT,159,(LPARAM) (LPCSTR) kbbuf); // Stack it StackIndex = 0; if (KbdStack[19]) free(KbdStack[19]); for (i = 18; i >= 0; i--) { KbdStack[i+1] = KbdStack[i]; } KbdStack[0] = _strdup(kbbuf); kbbuf[kbptr]=13; SlowTimer = 0; // Echo, with set Black escape memcpy(&DisplayLine[2], kbbuf, kbptr+1); if (OutputData.Scrolled) { POINT Point; Point.x = 0; Point.y = 25000; // Should be plenty for any font SendMessage(hwndOutput, EM_SETSCROLLPOS, 0, (LPARAM) &Point); OutputData.Scrolled = FALSE; } WritetoOutputWindow(&OutputData, DisplayLine, kbptr+3); DoRefresh(&OutputData); // Replace null with CR, and send to Node SendMsg(Stream, &kbbuf[0], kbptr+1); SendMessage(hwndInput,WM_SETTEXT,0,(LPARAM)(LPCSTR) ""); return 0; } if (wParam == 0x1a) // Ctrl/Z { // // if not connected, and autoconnect is // enabled, connect now if (!CONNECTED && AUTOCONNECT) SessionControl(Stream, 1, 0); kbbuf[0]=0x1a; kbbuf[1]=13; SendMsg(Stream, &kbbuf[0], 2); SendMessage(hwndInput,WM_SETTEXT,0,(LPARAM)(LPCSTR) ""); return 0; } } return CallWindowProc(Cinfo->wpOrigInputProc, hwnd, uMsg, wParam, lParam); } */ DoStateChange(int Stream) { int port, sesstype, paclen, maxframe, l4window, len; int state, change; struct ConsoleInfo * Cinfo = NULL; char callsign[11] = ""; char Msg[80]; for (Cinfo = ConsHeader; Cinfo; Cinfo = Cinfo->next) { if (Cinfo->BPQStream == Stream) break; } // Get current Session State. Any state changed is ACK'ed // automatically. See BPQHOST functions 4 and 5. SessionState(Stream, &state, &change); if (change == 1) { if (state == 1) { // Connected if (Cinfo == NULL) { // Incoming connect. Create a window for it Cinfo = CreateChildWindow(Stream, FALSE); Cinfo->Incoming = TRUE; Cinfo->Minimized = FALSE; SendMessage(ClientWnd, WM_MDIACTIVATE, (WPARAM)Cinfo->hConsole, 0); } Cinfo->CONNECTED = TRUE; Cinfo->SlowTimer = 0; GetConnectionInfo(Stream, callsign, &port, &sesstype, &paclen, &maxframe, &l4window); if (Cinfo->Incoming == TRUE) { char conMsg[] = "Send ^D to disconnect\r"; SendMsg(Stream, conMsg, strlen(conMsg)); len = sprintf(Msg, "*** Incoming Call from %s\r", callsign); WritetoOutputWindow(Cinfo, Msg, len, TRUE); PlaySound("IncomingCall", hInstance, SND_RESOURCE | SND_ASYNC); ShowWindow(FrameWnd, SW_SHOWNA); if (FrameMaximized == TRUE) PostMessage(FrameWnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0); else PostMessage(FrameWnd, WM_SYSCOMMAND, SW_SHOWNA, 0); } sprintf(Title,"Stream %d - Connected to %s", Stream, callsign); SetWindowText(Cinfo->hConsole, Title); DisableConnectMenu(FrameWnd); EnableDisconnectMenu(FrameWnd); } else { if (Cinfo == NULL) return 0; Cinfo->CONNECTED=FALSE; sprintf(Title,"Stream %d - Disconnected", Stream); SetWindowText(Cinfo->hConsole,Title); DisableDisconnectMenu(FrameWnd); EnableConnectMenu(FrameWnd); if (SendDisconnected) { WritetoOutputWindow(Cinfo, "*** Disconnected\r", 17, TRUE); } } } return (0); } DoReceivedData(int Stream) { char Msg[300]; struct ConsoleInfo * Cinfo; for (Cinfo = ConsHeader; Cinfo; Cinfo = Cinfo->next) { if (Cinfo->BPQStream == Stream) break; } if (Cinfo == NULL) return 0; if (RXCount(Cinfo->BPQStream) > 0) { do { GetMsg(Cinfo->BPQStream, &Msg[0],&len,&count); if (len == 1 && Msg[0] == 0) continue; if (GetApplNum(Cinfo->BPQStream) == 32) // Host Appl { // Check for ^D to disconnect if (_memicmp(Msg, "^d\r", 3) == 0) { SessionControl(Cinfo->BPQStream, 2, 0); } } WritetoOutputWindow(Cinfo, Msg, len, FALSE); Cinfo->SlowTimer = 0; if (Cinfo->Active == FALSE) FlashWindow(Cinfo->hConsole, TRUE); // Beep(440,250); } while (count > 0); DoRefresh(Cinfo); } return (0); } VOID wcstoRTF(char * out, WCHAR * in) { WCHAR * ptr1 = in; char * ptr2 = out; int val = *ptr1++; while (val) { // May be Code Page or Unicode { if (val > 255 || val < -255 ) ptr2 += sprintf(ptr2, "\\u%d ", val); else if (val > 127 || val < -128) ptr2 += sprintf(ptr2, "\\'%02X", val); else *(ptr2++) = val; } val = *ptr1++; } *ptr2 = 0; } DWORD CALLBACK EditStreamCallback(struct ConsoleInfo * Cinfo, LPBYTE lpBuff, LONG cb, PLONG pcb) { int ReqLen = cb; int i; int Line; int NewLen; int err; char LineB[12048]; WCHAR LineW[12048]; // if (cb != 4092) // return 0; if (Cinfo->SendHeader) { // Return header memcpy(lpBuff, RTFHeader, RTFHddrLen); *pcb = RTFHddrLen; Cinfo->SendHeader = FALSE; Cinfo->Finished = FALSE; Cinfo->Index = 0; return 0; } if (Cinfo->Finished) { *pcb = 0; return 0; } /* if (BufferLen > cb) { memcpy(lpBuff, &Buffer[Offset], cb); BufferLen -= cb; Offset += cb; *pcb = cb; return 0; } memcpy(lpBuff, &Buffer[Offset], BufferLen); *pcb = BufferLen; */ // Return 10 line at a time for (i = 0; i < 10; i++); { Line = Cinfo->Index++ + Cinfo->CurrentLine - MAXLINES; if (Line <0) Line = Line + MAXLINES; sprintf(lpBuff, "\\cf%d ", Cinfo->Colourvalue[Line]); // Handle UTF-8 NewLen = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, Cinfo->OutputScreen[Line], -1, LineW, 2000); err = GetLastError(); if (err == ERROR_NO_UNICODE_TRANSLATION) { // Input isn't UTF 8. Juat use default 8 bit set# strcat(lpBuff, Cinfo->OutputScreen[Line]); } else { if (LineW[0] != 0) { wcstoRTF(LineB, LineW); strcat(lpBuff, LineB); } } } strcat(lpBuff, "\\line"); if (Cinfo->Index == MAXLINES) { Cinfo->Finished = TRUE; strcat(lpBuff, "}"); i = 10; } *pcb = strlen(lpBuff); return 0; } VOID DoRefresh(struct ConsoleInfo * Cinfo) { EDITSTREAM es = {0}; int Min, Max, Pos; POINT Point; SCROLLINFO ScrollInfo; int LoopTrap = 0; HWND hwndOutput = Cinfo->hwndOutput; if(WINE) Cinfo->Thumb = 30000; else Cinfo->Thumb = SendMessage(Cinfo->hwndOutput, EM_GETTHUMB, 0, 0); Pos = Cinfo->Thumb + Cinfo->ClientHeight; if ((Cinfo->Thumb + Cinfo->ClientHeight) > Cinfo->RTFHeight - 10) // Don't bother writing to screen if scrolled back { es.pfnCallback = (EDITSTREAMCALLBACK)EditStreamCallback; es.dwCookie = (DWORD_PTR)Cinfo; Cinfo->SendHeader = TRUE; SendMessage(hwndOutput, EM_STREAMIN, SF_RTF, (LPARAM)&es); } GetScrollRange(hwndOutput, SB_VERT, &Min, &Max); ScrollInfo.cbSize = sizeof(ScrollInfo); ScrollInfo.fMask = SIF_ALL; GetScrollInfo(hwndOutput, SB_VERT, &ScrollInfo); // Debugprintf("Pos %d Max %d Min %d nMax %d ClientH %d", Pos, Min, Max, ScrollInfo.nMax, Cinfo->ClientHeight); if (Cinfo->FirstTime == FALSE) { // RTF Controls don't immediately scroll to end - don't know why. Cinfo->FirstTime = TRUE; Point.x = 0; Point.y = 25000; // Should be plenty for any font while (LoopTrap++ < 20) { SendMessage(hwndOutput, EM_SETSCROLLPOS, 0, (LPARAM) &Point); } GetScrollRange(hwndOutput, SB_VERT, &Min, &Max); // Get Actual Height Cinfo->RTFHeight = Max; Point.x = 0; Point.y = Cinfo->RTFHeight - ScrollInfo.nPage; SendMessage(hwndOutput, EM_SETSCROLLPOS, 0, (LPARAM) &Point); Cinfo->Thumb = SendMessage(hwndOutput, EM_GETTHUMB, 0, 0); } Point.x = 0; Point.y = Cinfo->RTFHeight - ScrollInfo.nPage; if (Cinfo->Thumb > (Point.y - 10)) // Don't Scroll if user has scrolled back { SendMessage(hwndOutput, EM_SETSCROLLPOS, 0, (LPARAM) &Point); if (Cinfo->Scrolled) { Cinfo->Scrolled = FALSE; InvalidateRect(Cinfo->hwndInput, NULL, TRUE); } return; } if (!Cinfo->Scrolled) { Cinfo->Scrolled = TRUE; InvalidateRect(Cinfo->hwndInput, NULL, TRUE); } } /*VOID DoRefresh(struct RTFTerm * OPData) { EDITSTREAM es = {0}; int Min, Max, Pos; POINT Point; SCROLLINFO ScrollInfo; int LoopTrap = 0; if(WINE) OPData->Thumb = 30000; else OPData->Thumb = SendMessage(hwndOutput, EM_GETTHUMB, 0, 0); Pos = OPData->Thumb + OutputBoxHeight; if (Pos > OPData->RTFHeight - 10) // Don't bother writing to screen if scrolled back { es.pfnCallback = EditStreamCallback; es.dwCookie = (DWORD_PTR)OPData; OPData->SendHeader = TRUE; SendMessage(hwndOutput, EM_STREAMIN, SF_RTF, (LPARAM)&es); } // else // Debugprintf("Pos %d RTFHeight %d - Not refreshing", Pos, OPData->RTFHeight); GetScrollRange(hwndOutput, SB_VERT, &Min, &Max); ScrollInfo.cbSize = sizeof(ScrollInfo); ScrollInfo.fMask = SIF_ALL; GetScrollInfo(hwndOutput, SB_VERT, &ScrollInfo); // Debugprintf("Thumb %d Pos %d Min %d Max %d nMax %d ClientH %d RTFHeight %d", // OPData->Thumb, Pos, Min, Max, ScrollInfo.nMax, OutputBoxHeight, OPData->RTFHeight); if (OPData->FirstTime == FALSE) { // RTF Controls don't immediately scroll to end - don't know why. OPData->FirstTime = TRUE; Point.x = 0; Point.y = 25000; // Should be plenty for any font while (LoopTrap++ < 20) { SendMessage(hwndOutput, EM_SETSCROLLPOS, 0, (LPARAM) &Point); } GetScrollRange(hwndOutput, SB_VERT, &Min, &Max); // Get Actual Height OPData->RTFHeight = Max; Point.x = 0; Point.y = OPData->RTFHeight - ScrollInfo.nPage; SendMessage(hwndOutput, EM_SETSCROLLPOS, 0, (LPARAM) &Point); OPData->Thumb = SendMessage(hwndOutput, EM_GETTHUMB, 0, 0); } Point.x = 0; Point.y = OPData->RTFHeight - ScrollInfo.nPage; if (OPData->Thumb > (Point.y - 10)) // Don't Scroll if user has scrolled back { // Debugprintf("Scrolling to %d", Point.y); SendMessage(hwndOutput, EM_SETSCROLLPOS, 0, (LPARAM) &Point); if (OPData->Scrolled) { OPData->Scrolled = FALSE; InvalidateRect(hwndInput, NULL, TRUE); } return; } // Debugprintf("Thumb = %d Point.y = %d - Not Scrolling", OPData->Thumb, Point.y); if (!OPData->Scrolled) { OPData->Scrolled = TRUE; InvalidateRect(hwndInput, NULL, TRUE); } } */ VOID AddLinetoWindow(struct ConsoleInfo * Cinfo, char * Line) { int Len = strlen(Line); char * ptr1 = Line; char * ptr2; int l, Index; char LineCopy[LINELEN * 2]; if (strlen(Line) > 200) { Line[199] = 0; } if (Line[0] == 0x1b && Len > 1) { // Save Colour Char Cinfo->CurrentColour = Line[1] - 10; ptr1 +=2; Len -= 2; } strcpy(Cinfo->OutputScreen[Cinfo->CurrentLine], ptr1); // Look for chars we need to escape (\ { }) ptr1 = Cinfo->OutputScreen[Cinfo->CurrentLine]; Index = 0; ptr2 = strchr(ptr1, '\\'); // Look for Backslash first, as we may add some later if (ptr2) { while (ptr2) { l = ++ptr2 - ptr1; memcpy(&LineCopy[Index], ptr1, l); // Copy Including found char Index += l; LineCopy[Index++] = '\\'; Len++; ptr1 = ptr2; ptr2 = strchr(ptr1, '\\'); } strcpy(&LineCopy[Index], ptr1); // Copy in rest strcpy(Cinfo->OutputScreen[Cinfo->CurrentLine], LineCopy); } ptr1 = Cinfo->OutputScreen[Cinfo->CurrentLine]; Index = 0; ptr2 = strchr(ptr1, '{'); if (ptr2) { while (ptr2) { l = ptr2 - ptr1; memcpy(&LineCopy[Index], ptr1, l); Index += l; LineCopy[Index++] = '\\'; LineCopy[Index++] = '{'; Len++; ptr1 = ++ptr2; ptr2 = strchr(ptr1, '{'); } strcpy(&LineCopy[Index], ptr1); // Copy in rest strcpy(Cinfo->OutputScreen[Cinfo->CurrentLine], LineCopy); } ptr1 = Cinfo->OutputScreen[Cinfo->CurrentLine]; Index = 0; ptr2 = strchr(ptr1, '}'); // Look for Backslash first, as we may add some later if (ptr2) { while (ptr2) { l = ptr2 - ptr1; memcpy(&LineCopy[Index], ptr1, l); // Copy Index += l; LineCopy[Index++] = '\\'; LineCopy[Index++] = '}'; Len++; ptr1 = ++ptr2; ptr2 = strchr(ptr1, '}'); } strcpy(&LineCopy[Index], ptr1); // Copy in rest strcpy(Cinfo->OutputScreen[Cinfo->CurrentLine], LineCopy); } Cinfo->Colourvalue[Cinfo->CurrentLine] = Cinfo->CurrentColour; Cinfo->LineLen[Cinfo->CurrentLine++] = Len; if (Cinfo->CurrentLine >= MAXLINES) Cinfo->CurrentLine = 0; } int WritetoConsoleWindowSupport(struct ConsoleInfo * Cinfo, char * Msg, int len); int WritetoOutputWindow(struct ConsoleInfo * Cinfo, char * Msg, int len, BOOL Refresh) { WritetoConsoleWindowSupport(Cinfo, Msg, len); if (Cinfo->Minimized) return 0; if (Refresh) DoRefresh(Cinfo); else Cinfo->NeedRefresh = TRUE; return 0; } int WritetoConsoleWindowSupport(struct ConsoleInfo * Cinfo, char * Msg, int len) { char * ptr1, * ptr2; if (len + Cinfo->PartLinePtr > Cinfo->readbufflen) { Cinfo->readbufflen += len + Cinfo->PartLinePtr; Cinfo->readbuff = realloc(Cinfo->readbuff, Cinfo->readbufflen + 100); } if (Cinfo->PartLinePtr != 0) { Cinfo->CurrentLine--; // Overwrite part line in buffer if (Cinfo->CurrentLine < 0) Cinfo->CurrentLine = MAXLINES - 1; if (Msg[0] == 0x1b && len > 1) { Msg += 2; // Remove Colour Escape len -= 2; } } memcpy(&Cinfo->readbuff[Cinfo->PartLinePtr], Msg, len); len=len+Cinfo->PartLinePtr; ptr1=&Cinfo->readbuff[0]; Cinfo->readbuff[len]=0; if (Bells) { do { ptr2=memchr(ptr1,7,len); if (ptr2) { *(ptr2)=32; if (FlashOnBell) FlashWindow(Cinfo->hConsole, TRUE); else Beep(440,250); } } while (ptr2); } lineloop: if (len > 0) { // copy text to control a line at a time ptr2=memchr(ptr1,13,len); if (ptr2 == 0) { // no newline. Move data to start of buffer and Save pointer Cinfo->PartLinePtr=len; memmove(Cinfo->readbuff,ptr1,len); AddLinetoWindow(Cinfo, ptr1); // InvalidateRect(Cinfo->hwndOutput, NULL, FALSE); return (0); } *(ptr2++)=0; // If len is greater that screen with, fold if (Cinfo == &MonWindow) { if (LogMonitor) WriteMonitorLine(ptr1, ptr2 - ptr1); } else if (LogOutput) WriteMonitorLine(ptr1, ptr2 - ptr1); if ((ptr2 - ptr1) > Cinfo->maxlinelen) { char * ptr3; char * saveptr1 = ptr1; int linelen = ptr2 - ptr1; int foldlen; char save; foldloop: ptr3 = ptr1 + Cinfo->maxlinelen; while(*ptr3!= 0x20 && ptr3 > ptr1) { ptr3--; } foldlen = ptr3 - ptr1 ; if (foldlen == 0) { // No space before, so split at width foldlen = Cinfo->maxlinelen; ptr3 = ptr1 + Cinfo->maxlinelen; } else { ptr3++ ; // Omit space linelen--; } save = ptr1[foldlen]; ptr1[foldlen] = 0; AddLinetoWindow(Cinfo, ptr1); ptr1[foldlen] = save; linelen -= foldlen; ptr1 = ptr3; if (linelen > Cinfo->maxlinelen) goto foldloop; AddLinetoWindow(Cinfo, ptr1); ptr1 = saveptr1; } else AddLinetoWindow(Cinfo, ptr1); Cinfo->PartLinePtr=0; len-=(ptr2-ptr1); ptr1=ptr2; if ((len > 0) && Cinfo->StripLF) { if (*ptr1 == 0x0a) // Line Feed { ptr1++; len--; } } goto lineloop; } return (0); } /* VOID AddLinetoWindow(struct RTFTerm * OPData, char * Line) { int Len = strlen(Line); char * ptr1 = Line; char * ptr2; int l, Index; char LineCopy[LINELEN * 2]; if (Line[0] == 0x1b && Len > 1) { // Save Colour Char OPData->CurrentColour = Line[1] - 10; ptr1 +=2; Len -= 2; } strcpy(OPData->OutputScreen[OPData->CurrentLine], ptr1); // Look for chars we need to escape (\ { }) ptr1 = OPData->OutputScreen[OPData->CurrentLine]; Index = 0; ptr2 = strchr(ptr1, '\\'); // Look for Backslash first, as we may add some later if (ptr2) { while (ptr2) { l = ++ptr2 - ptr1; memcpy(&LineCopy[Index], ptr1, l); // Copy Including found char Index += l; LineCopy[Index++] = '\\'; Len++; ptr1 = ptr2; ptr2 = strchr(ptr1, '\\'); } strcpy(&LineCopy[Index], ptr1); // Copy in rest strcpy(OPData->OutputScreen[OPData->CurrentLine], LineCopy); } ptr1 = OPData->OutputScreen[OPData->CurrentLine]; Index = 0; ptr2 = strchr(ptr1, '{'); if (ptr2) { while (ptr2) { l = ptr2 - ptr1; memcpy(&LineCopy[Index], ptr1, l); Index += l; LineCopy[Index++] = '\\'; LineCopy[Index++] = '{'; Len++; ptr1 = ++ptr2; ptr2 = strchr(ptr1, '{'); } strcpy(&LineCopy[Index], ptr1); // Copy in rest strcpy(OPData->OutputScreen[OPData->CurrentLine], LineCopy); } ptr1 = OPData->OutputScreen[OPData->CurrentLine]; Index = 0; ptr2 = strchr(ptr1, '}'); // Look for Backslash first, as we may add some later if (ptr2) { while (ptr2) { l = ptr2 - ptr1; memcpy(&LineCopy[Index], ptr1, l); // Copy Index += l; LineCopy[Index++] = '\\'; LineCopy[Index++] = '}'; Len++; ptr1 = ++ptr2; ptr2 = strchr(ptr1, '}'); } strcpy(&LineCopy[Index], ptr1); // Copy in rest strcpy(OPData->OutputScreen[OPData->CurrentLine], LineCopy); } OPData->Colourvalue[OPData->CurrentLine] = OPData->CurrentColour; OPData->LineLen[OPData->CurrentLine++] = Len; if (OPData->CurrentLine >= MAXLINES) OPData->CurrentLine = 0; } VOID WritetoOutputWindow(struct RTFTerm * OPData, char * Msg, int len) { char * ptr1, * ptr2; if (PartLinePtr > LINELEN) Msg[len++] = 13; // Force a newline if (PartLinePtr != 0) { OPData->CurrentLine--; // Overwrite part line in buffer if (Msg[0] == 0x1b && len > 1) { Msg += 2; // Remove Colour Escape len -= 2; } } memcpy(&readbuff[PartLinePtr], Msg, len); len += PartLinePtr; ptr1=&readbuff[0]; readbuff[len]=0; if (Bells) { do { ptr2=memchr(ptr1,7,len); if (ptr2) { *(ptr2)=32; Beep(440,250); } } while (ptr2); } lineloop: if (len > 0) { // copy text to buffer a line at a time ptr2=memchr(ptr1,13,len); if (ptr2 == 0) { // no newline. Move data to start of buffer and Save pointer PartLinePtr = len; memmove(readbuff,ptr1,len); AddLinetoWindow(Cinfo, ptr1); return; } *(ptr2++)=0; if (LogOutput) WriteMonitorLine(ptr1, ptr2 - ptr1); // If len is greater that screen with, fold if ((ptr2 - ptr1) > maxlinelen) { char * ptr3; char * saveptr1 = ptr1; int linelen = ptr2 - ptr1; int foldlen; char save; foldloop: ptr3 = ptr1 + maxlinelen; while(*ptr3!= 0x20 && ptr3 > ptr1) { ptr3--; } foldlen = ptr3 - ptr1 ; if (foldlen == 0) { // No space before, so split at width foldlen = maxlinelen; ptr3 = ptr1 + maxlinelen; } else { ptr3++ ; // Omit space linelen--; } save = ptr1[foldlen]; ptr1[foldlen] = 0; AddLinetoWindow(Cinfo, ptr1); ptr1[foldlen] = save; linelen -= foldlen; ptr1 = ptr3; if (linelen > maxlinelen) goto foldloop; AddLinetoWindow(Cinfo, ptr1); ptr1 = saveptr1; } else AddLinetoWindow(Cinfo, ptr1); PartLinePtr=0; len-=(ptr2-ptr1); ptr1=ptr2; if ((len > 0) && StripLF) { if (*ptr1 == 0x0a) // Line Feed { ptr1++; len--; } } goto lineloop; } } */ DoMonData(int Stream) { char * ptr1, * ptr2; int stamp; int len; unsigned char buffer[1024] = "\x1b\xb", monbuff[512]; struct ConsoleInfo * Cinfo; // Monitor data uses the first stream Cinfo = &MonWindow; if (MONCount(Stream) > 0) { do { stamp=GetRaw(Stream, monbuff,&len,&count); if (MonitorColour) { if (monbuff[4] & 0x80) // TX buffer[1] = 91; else buffer[1] = 17; } // See if a NODES if (!MonitorNODES && monbuff[21] == 3 && monbuff[22] == 0xcf && monbuff[23] == 0xff) len = 0; else { len=DecodeFrame(monbuff,&buffer[2],stamp); len +=2; } ptr1=&buffer[0]; lineloop: if (len > 0) { // copy text to control a line at a time ptr2=memchr(ptr1,13,len); if (ptr2 == 0) { // no newline. Move data to start of buffer and Save pointer memmove(buffer,ptr1,len); return (0); } else { ptr2++; WritetoOutputWindow(Cinfo, ptr1, ptr2 - ptr1, FALSE); len-=(ptr2-ptr1); ptr1=ptr2; goto lineloop; } } } while (count > 0); Cinfo->NeedRefresh = TRUE; } return (0); } int DisableConnectMenu(HWND hWnd) { HMENU hMenu; // handle of menu hMenu=GetMenu(FrameWnd); EnableMenuItem(hMenu,BPQCONNECT,MF_GRAYED); return (0); } int DisableDisconnectMenu(HWND hWnd) { HMENU hMenu; // handle of menu hMenu=GetMenu(FrameWnd); EnableMenuItem(hMenu,BPQDISCONNECT,MF_GRAYED); return (0); } int EnableConnectMenu(HWND hWnd) { HMENU hMenu; // handle of menu hMenu=GetMenu(FrameWnd); EnableMenuItem(hMenu,BPQCONNECT,MF_ENABLED); return (0); } int EnableDisconnectMenu(HWND hWnd) { HMENU hMenu; // handle of menu hMenu=GetMenu(FrameWnd); EnableMenuItem(hMenu,BPQDISCONNECT,MF_ENABLED); return (0); } int ToggleRestoreWindows() { RestoreWindows = !RestoreWindows; if (RestoreWindows) { CheckMenuItem(hMonCfgMenu,ID_WINDOWS_RESTORE,MF_CHECKED); CheckMenuItem(hTermCfgMenu,ID_WINDOWS_RESTORE,MF_CHECKED); } else { CheckMenuItem(hMonCfgMenu, ID_WINDOWS_RESTORE, MF_UNCHECKED); CheckMenuItem(hTermCfgMenu, ID_WINDOWS_RESTORE, MF_UNCHECKED); } return (0); } /* int ToggleAppl(HWND hWnd, int Item, int mask) { HMENU hMenu; // handle of menu hMenu=GetMenu(hWnd); APPLMASK = APPLMASK ^ mask; if (APPLMASK & mask) CheckMenuItem(hMenu,Item,MF_CHECKED); else CheckMenuItem(hMenu,Item,MF_UNCHECKED); SetAppl(Stream,applflags,APPLMASK); return (0); } int ToggleFlags(HWND hWnd, int Item, int mask) { HMENU hMenu; // handle of menu hMenu=GetMenu(hWnd); applflags ^= mask; if (applflags & mask) CheckMenuItem(hMenu,Item,MF_CHECKED); else CheckMenuItem(hMenu,Item,MF_UNCHECKED); return (0); } */ static CopyScreentoBuffer(char * buff) { return (0); } int TogglePort(HWND hWnd, int Item, int mask) { portmask ^= mask; if (portmask & mask) CheckMenuItem(hMonCfgMenu,Item,MF_CHECKED); else CheckMenuItem(hMonCfgMenu,Item,MF_UNCHECKED); if (portmask) applflags |= 0x80; else applflags &= 0x7f; SetAppl(Stream,applflags,APPLMASK); SetTraceOptionsEx(portmask,mtxparam,mcomparam, monUI); return (0); } int ToggleMTX(HWND hWnd) { mtxparam = mtxparam ^ 1; if (mtxparam & 1) CheckMenuItem(hMonCfgMenu,BPQMTX,MF_CHECKED); else CheckMenuItem(hMonCfgMenu,BPQMTX,MF_UNCHECKED); SetTraceOptionsEx(portmask,mtxparam,mcomparam, monUI); return (0); } int ToggleMCOM(HWND hWnd) { mcomparam = mcomparam ^ 1; if (mcomparam & 1) CheckMenuItem(hMonCfgMenu,BPQMCOM,MF_CHECKED); else CheckMenuItem(hMonCfgMenu,BPQMCOM,MF_UNCHECKED); SetTraceOptionsEx(portmask,mtxparam,mcomparam, monUI); return (0); } int ToggleMON_UI_ONLY(HWND hWnd) { monUI = monUI ^ 1; if (monUI & 1) CheckMenuItem(hMonCfgMenu,MON_UI_ONLY,MF_CHECKED); else CheckMenuItem(hMonCfgMenu,MON_UI_ONLY,MF_UNCHECKED); SetTraceOptionsEx(portmask,mtxparam,mcomparam, monUI); return (0); } int ToggleParam(HMENU hMenu, BOOL * Param, int Item) { *Param = !(*Param); CheckMenuItem(hMenu, Item, (*Param) ? MF_CHECKED : MF_UNCHECKED); return (0); } int ToggleChat(HWND hWnd) { APPLMASK = APPLMASK ^ 02; if (APPLMASK & 02) CheckMenuItem(hTermCfgMenu,BPQCHAT,MF_CHECKED); else CheckMenuItem(hTermCfgMenu,BPQCHAT,MF_UNCHECKED); SetAppl(Stream,applflags,APPLMASK); return (0); } /* void MoveWindows() { RECT rcMain, rcClient; int ClientHeight, ClientWidth; if (hWnd == 0) return; GetWindowRect(hWnd, &rcMain); GetClientRect(hWnd, &rcClient); ClientHeight = rcClient.bottom; ClientWidth = rcClient.right; if (ClientWidth == 0) // Minimized return; OutputBoxHeight = ClientHeight - SplitPos - InputBoxHeight - SplitBarHeight - SplitBarHeight; MoveWindow(hwndMon,2, 0, ClientWidth-4, SplitPos, TRUE); MoveWindow(hwndOutput,2, SplitPos+SplitBarHeight, ClientWidth-4, OutputBoxHeight, TRUE); MoveWindow(hwndInput,2, ClientHeight-InputBoxHeight-2, ClientWidth-4, InputBoxHeight, TRUE); MoveWindow(hwndSplit,0, SplitPos, ClientWidth, SplitBarHeight, TRUE); GetClientRect(hwndOutput, &rcClient); ClientHeight = rcClient.bottom; ClientWidth = rcClient.right; if (ClientWidth > 16) maxlinelen = ClientWidth/OutputData.CharWidth - 1; InvalidateRect(hWnd, NULL, TRUE); } */ static void MoveWindows(struct ConsoleInfo * Cinfo) { RECT rcClient= {0,0,0,0}; int ClientWidth; GetClientRect(Cinfo->hConsole, &rcClient); if (rcClient.bottom == 0) // Minimised return; Cinfo->ClientHeight = rcClient.bottom; ClientWidth = rcClient.right; if (Cinfo->hwndInput) { MoveWindow(Cinfo->hwndOutput,2, 2, ClientWidth-4, Cinfo->ClientHeight-InputBoxHeight-4, TRUE); MoveWindow(Cinfo->hwndInput,2, Cinfo->ClientHeight-InputBoxHeight-2, ClientWidth-4, InputBoxHeight, TRUE); } else MoveWindow(Cinfo->hwndOutput,2, 2, ClientWidth-4, Cinfo->ClientHeight-4, TRUE); GetClientRect(Cinfo->hwndOutput, &rcClient); Cinfo->ClientHeight = rcClient.bottom; ClientWidth = rcClient.right; Cinfo->WarnLen = ClientWidth/8 - 1; Cinfo->WrapLen = Cinfo->WarnLen; Cinfo->maxlinelen = Cinfo->WarnLen; } void CopyRichTextToClipboard(HWND hWnd) { int len=0; HGLOBAL hMem; char * ptr; // Copy Rich Text to Clipboard len = SendMessage(hWnd, WM_GETTEXTLENGTH, 0, 0); hMem = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, len + 1); if (hMem != 0) { ptr=GlobalLock(hMem); if (OpenClipboard(FrameWnd)) { len = SendMessage(hWnd, WM_GETTEXT , len, (LPARAM)ptr); GlobalUnlock(hMem); EmptyClipboard(); SetClipboardData(CF_TEXT,hMem); CloseClipboard(); } } else GlobalFree(hMem); } BOOL OpenMonitorLogfile() { UCHAR * BPQDirectory=GetBPQDirectory(); UCHAR FN[MAX_PATH]; if (BPQDirectory[0] == 0) sprintf(FN,"BPQTerm.log"); else sprintf(FN,"%s\\BPQTerm.log", BPQDirectory); MonHandle = CreateFile(FN, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); SetFilePointer(MonHandle, 0, 0, FILE_END); return (MonHandle != INVALID_HANDLE_VALUE); } void WriteMonitorLine(char * Msg, int MsgLen) { int cnt; char CRLF[2] = {0x0d,0x0a}; if (MonHandle == INVALID_HANDLE_VALUE) OpenMonitorLogfile(); if (MonHandle == INVALID_HANDLE_VALUE) return; WriteFile(MonHandle ,Msg , MsgLen, &cnt, NULL); WriteFile(MonHandle ,CRLF , 2, &cnt, NULL); } INT_PTR CALLBACK FontConfigWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { POINT Point; int Min, Max; int retCode, disp; HKEY hKey=0; switch (message) { case WM_INITDIALOG: SetDlgItemText(hDlg, IDC_FONTNAME, FontName); SetDlgItemInt(hDlg, IDC_CHARSET, CharSet, FALSE); SetDlgItemInt(hDlg, IDC_CODEPAGE, CodePage, FALSE); SetDlgItemInt(hDlg, IDC_FONTSIZE, FontSize, FALSE); SetDlgItemInt(hDlg, IDC_FONTWIDTH, FontWidth, FALSE); return (INT_PTR)TRUE; case WM_CTLCOLORDLG: return (LONG)bgBrush; case WM_CTLCOLORSTATIC: { HDC hdcStatic = (HDC)wParam; SetTextColor(hdcStatic, RGB(0, 0, 0)); SetBkMode(hdcStatic, TRANSPARENT); return (LONG)bgBrush; } case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: GetDlgItemText(hDlg, IDC_FONTNAME, FontName, 99); CharSet = GetDlgItemInt(hDlg, IDC_CHARSET, NULL, FALSE); CodePage = GetDlgItemInt(hDlg, IDC_CODEPAGE, NULL, FALSE); FontSize = GetDlgItemInt(hDlg, IDC_FONTSIZE, NULL, FALSE); FontWidth = GetDlgItemInt(hDlg, IDC_FONTWIDTH, NULL, FALSE); // SaveStringValue("FontName", FontName); // SaveIntValue("CharSet", CharSet); // SaveIntValue("CodePage", CodePage); // SaveIntValue("FontSize", FontSize); // SaveIntValue("FontWidth", FontWidth); // Save Config retCode = RegCreateKeyEx(REGTREE, Key, 0, // Reserved 0, // Class 0, // Options KEY_ALL_ACCESS, NULL, // Security Attrs &hKey, &disp); if (retCode == ERROR_SUCCESS) { retCode = RegSetValueEx(hKey,"FontWidth",0,REG_DWORD,(BYTE *)&FontWidth,4); retCode = RegSetValueEx(hKey,"FontSize",0,REG_DWORD,(BYTE *)&FontSize,4); retCode = RegSetValueEx(hKey,"CodePage",0,REG_DWORD,(BYTE *)&CodePage,4); retCode = RegSetValueEx(hKey,"CharSet",0,REG_DWORD,(BYTE *)&CharSet,4); retCode = RegSetValueEx(hKey,"FontName",0,REG_SZ,(BYTE *)&FontName, strlen(FontName)); RegCloseKey(hKey); } FontCinfo->CharWidth = FontWidth; FontCinfo->FirstTime = FALSE; SetupRTFHddr(); Point.x = 0; Point.y = 25000; // Should be plenty for any font SendMessage(FontCinfo->hwndOutput, EM_SETSCROLLPOS, 0, (LPARAM) &Point); FontCinfo->Scrolled = FALSE; GetScrollRange(FontCinfo->hwndOutput, SB_VERT, &Min, &Max); // Get Actual Height FontCinfo->RTFHeight = Max; DoRefresh(FontCinfo); EndDialog(hDlg, LOWORD(wParam)); case IDCANCEL: EndDialog(hDlg, LOWORD(wParam)); return TRUE; } } return FALSE; } struct ConsoleInfo * CreateChildWindow(int Stream, BOOL DuringInit) { WNDCLASS wc; HWND ChildWnd = 0; struct ConsoleInfo * Cinfo; struct ConsoleInfo * last = NULL; int i = 1; int retCode, Type, Vallen; HKEY hKey=0; char Size[80]=""; char Item[80]; RECT Rect= {100, 100, 800, 600}; char Title[80]; if (Stream == 0) Stream = FindFreeStream(); if (Stream == 255) { MessageBox(NULL,"No free streams available",NULL,MB_OK); return (FALSE); } // Find end of session chain for (Cinfo = ConsHeader; Cinfo; last = Cinfo, i++, Cinfo = Cinfo->next); Cinfo = malloc(sizeof(struct ConsoleInfo)); memset(Cinfo, 0, sizeof(struct ConsoleInfo)); if (last) last->next = Cinfo; else ConsHeader = Cinfo; Cinfo->BPQStream = Stream; BPQSetHandle(Cinfo->BPQStream, FrameWnd); // BPQMsg = RegisterWindowMessage(BPQWinMsg); sprintf(Title, "Stream %d", Cinfo->BPQStream); wc.style = CS_HREDRAW | CS_VREDRAW; wc.cbWndExtra = DLGWINDOWEXTRA; wc.lpfnWndProc = (WNDPROC)ChildWndProc; wc.cbClsExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE(BPQICON)); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wc.lpszMenuName = 0; wc.lpszClassName = "ChildWnd"; if(!RegisterClass(&wc)) { // return if RegisterClassEx fails DWORD dw_LastError = GetLastError(); if(ERROR_CLASS_ALREADY_EXISTS != dw_LastError) { // return if the error is other than "error class already exists" Debugprintf("Reg Class Failed %d", dw_LastError); // return NULL; } } ChildWnd = CreateMDIWindow("ChildWnd", Title, 0, 0,0,0,0, ClientWnd, hInstance, 1234); Cinfo->hConsole = ChildWnd; // return if its not possible to create the child window if(NULL == ChildWnd) { DWORD dw_LastError = GetLastError(); Debugprintf("Create Child Failed %d", dw_LastError); return NULL; } Cinfo->SendHeader = TRUE; Cinfo->Finished = TRUE; Cinfo->CurrentColour = 1; Cinfo->WarnLen = Cinfo->WrapLen = Cinfo->maxlinelen = 100; // In case doesn't get set up Cinfo->hwndOutput = CreateWindowEx(WS_EX_CLIENTEDGE, RICHEDIT_CLASS, "", WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_NOHIDESEL | WS_VSCROLL | ES_READONLY, 2,2,500,300, ChildWnd, NULL, hInstance, NULL); // Register for Mouse Events for Copy/Paste SendMessage(Cinfo->hwndOutput, EM_SETEVENTMASK, (WPARAM)0, (LPARAM)ENM_MOUSEEVENTS | ENM_SCROLLEVENTS | ENM_KEYEVENTS); SendMessage(Cinfo->hwndOutput, EM_EXLIMITTEXT, 0, MAXLINES * LINELEN); Cinfo->hwndInput = CreateWindowEx(WS_EX_CLIENTEDGE, "Edit", "", WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL | ES_NOHIDESEL, 2,200,290,20, ChildWnd, NULL, hInstance, NULL); SendMessage(Cinfo->hwndInput, WM_SETFONT, (WPARAM)hFont, 0); // Set our own WndProcs for the controls. Cinfo->wpOrigInputProc = (WNDPROC) SetWindowLong(Cinfo->hwndInput, GWL_WNDPROC, (LONG) InputProc); sprintf(Item, "SessSize%d", i); retCode = RegOpenKeyEx (REGTREE, Key, 0, KEY_QUERY_VALUE, &hKey); Vallen=80; RegQueryValueEx(hKey, Item, 0 , &Type, &Size[0], &Vallen); sscanf(Size,"%d,%d,%d,%d,%d", &Rect.left, &Rect.right, &Rect.top, &Rect.bottom, &Cinfo->Minimized); if (Rect.top < - 500 || Rect.left < - 500) { Rect.left = 100; Rect.top = 100; Rect.right = 600; Rect.bottom = 400; } if (Rect.top < OffsetH) // Make sure not off top of MDI frame { int Error = OffsetH - Rect.top; Rect.top += Error; Rect.bottom += Error; } MoveWindow(Cinfo->hConsole, Rect.left - (OffsetW /2), Rect.top - OffsetH, Rect.right-Rect.left, Rect.bottom-Rect.top, TRUE); MoveWindows(Cinfo); SetFocus(Cinfo->hwndInput); if (Cinfo->Minimized && DuringInit) ShowWindow(ChildWnd, SW_SHOWMINIMIZED); else ShowWindow(ChildWnd, SW_RESTORE); return Cinfo; } BOOL CreateMonitorWindow(char * MonSize) { WNDCLASSEX wndclassMainFrame; HWND ChildWnd = 0; struct ConsoleInfo * Cinfo = &MonWindow; RECT Rect = {0,0,0,0}; char Size[80]; HKEY hKey; int retCode,Type,Vallen; memset(Cinfo, 0, sizeof(struct ConsoleInfo)); Cinfo->WarnLen = Cinfo->WrapLen = Cinfo->maxlinelen = 100; // In case doesn't get set up Cinfo->StripLF = TRUE; wndclassMainFrame.cbSize = sizeof(WNDCLASSEX); wndclassMainFrame.style = CS_HREDRAW | CS_VREDRAW | CS_NOCLOSE;; wndclassMainFrame.lpfnWndProc = MonWndProc; wndclassMainFrame.cbClsExtra = 0; wndclassMainFrame.cbWndExtra = 0; wndclassMainFrame.hInstance = hInstance; wndclassMainFrame.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(BPQICON)); wndclassMainFrame.hCursor = LoadCursor(NULL, IDC_ARROW); wndclassMainFrame.hbrBackground = (HBRUSH) GetStockObject(GRAY_BRUSH); wndclassMainFrame.lpszMenuName = NULL; wndclassMainFrame.lpszClassName = "MonWnd"; wndclassMainFrame.hIconSm = NULL; if(!RegisterClassEx(&wndclassMainFrame)) { // return if RegisterClassEx fails DWORD dw_LastError = GetLastError(); if(ERROR_CLASS_ALREADY_EXISTS != dw_LastError) { // return if the error is other than "error class already exists" return 0; } } // Create Window if(NULL != ChildWnd) { return 0; } sprintf(Key, "SOFTWARE\\G8BPQ\\BPQ32\\BPQTermMDI"); retCode = RegOpenKeyEx (REGTREE, Key, 0, KEY_QUERY_VALUE, &hKey); Vallen=80; RegQueryValueEx(hKey, "MonSize", 0 , &Type, &Size[0], &Vallen); sscanf(Size,"%d,%d,%d,%d,%d",&Rect.left, &Rect.right, &Rect.top, &Rect.bottom, &Cinfo->Minimized); if (Rect.right < 100 || Rect.bottom < 100) { Rect.right = 400; Rect.bottom = 400; } if (Rect.top < OffsetH) // Make sure not off top of MDI frame { int Error = OffsetH - Rect.top; Rect.top += Error; Rect.bottom += Error; } ChildWnd = CreateMDIWindow("MonWnd", "Monitor", 0, Rect.left, Rect.top, Rect.right - Rect.left, Rect.bottom - Rect.top, ClientWnd, hInstance, 1234); Cinfo->hConsole = ChildWnd; // return if its not possible to create the child window if(NULL == ChildWnd) { return 0; } Cinfo->SendHeader = TRUE; Cinfo->Finished = TRUE; Cinfo->CurrentColour = 1; Cinfo->hwndOutput = CreateWindowEx(WS_EX_CLIENTEDGE, RICHEDIT_CLASS, "", WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_NOHIDESEL | WS_VSCROLL | ES_READONLY, 2,2,500,300, ChildWnd, NULL, hInstance, NULL); // Register for Mouse Events for Copy/Paste SendMessage(Cinfo->hwndOutput, EM_SETEVENTMASK, (WPARAM)0, (LPARAM)ENM_MOUSEEVENTS | ENM_SCROLLEVENTS | ENM_KEYEVENTS); SendMessage(Cinfo->hwndOutput, EM_EXLIMITTEXT, 0, MAXLINES * LINELEN); Cinfo = &MonWindow; // MoveWindow(Cinfo->hConsole, Rect.left - (OffsetW /2), Rect.top - OffsetH, // Rect.right-Rect.left, Rect.bottom-Rect.top, TRUE); MoveWindows(Cinfo); if (Cinfo->Minimized) ShowWindow(ChildWnd, SW_SHOWMINIMIZED); else ShowWindow(ChildWnd, SW_RESTORE); return TRUE; }