1 /* fdebug.c : Defines the entry point for the application. */ 2 3 #include <tchar.h> 4 5 #include <windef.h> 6 #include <winbase.h> 7 #include <wingdi.h> 8 #include <winuser.h> 9 #include <commdlg.h> 10 #include <process.h> 11 12 #include "resource.h" 13 #include "rs232.h" 14 15 #define MAX_LOADSTRING 100 16 17 // Global Variables: 18 HINSTANCE hInst; // current instance 19 TCHAR szTitle[MAX_LOADSTRING]; // The title bar text 20 TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text 21 HWND hMainWnd; // The main window handle 22 HWND hDisplayWnd; // The window to display the incoming data 23 HWND hEditWnd; // The edit window to get input from the user 24 TCHAR strComPort[MAX_PATH] = TEXT("COM1"); // The COM port to use 25 TCHAR strBaudRate[MAX_PATH] = TEXT("115200"); // The baud rate to use 26 TCHAR strCaptureFileName[MAX_PATH] = TEXT(""); // The file name to capture to 27 BOOL bConnected = FALSE; // Tells us if we are currently connected 28 BOOL bCapturing = FALSE; // Tells us if we are currently capturing data 29 BOOL bLocalEcho = FALSE; // Tells us if local echo is currently enabled 30 HANDLE hCaptureFile; // Handle to the capture file 31 DWORD dwThreadId = 0; // Thread id of RS232 communication thread 32 33 // Forward declarations of functions included in this code module: 34 ATOM MyRegisterClass(HINSTANCE hInstance); 35 BOOL InitInstance(HINSTANCE, int); 36 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 37 LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM); 38 LRESULT CALLBACK ConnectionDialogProc(HWND, UINT, WPARAM, LPARAM); 39 LRESULT CALLBACK CaptureDialogProc(HWND, UINT, WPARAM, LPARAM); 40 VOID EnableFileMenuItemByID(UINT Id, BOOL Enable); 41 VOID CheckLocalEchoMenuItem(BOOL Checked); 42 VOID __cdecl Rs232Thread(VOID* Parameter); 43 44 int APIENTRY _tWinMain(HINSTANCE hInstance, 45 HINSTANCE hPrevInstance, 46 LPTSTR lpCmdLine, 47 int nCmdShow) 48 { 49 // TODO: Place code here. 50 MSG msg; 51 HACCEL hAccelTable; 52 53 UNREFERENCED_PARAMETER(lpCmdLine); 54 UNREFERENCED_PARAMETER(hPrevInstance); 55 56 // Initialize global strings 57 LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); 58 LoadString(hInstance, IDC_FDEBUG, szWindowClass, MAX_LOADSTRING); 59 MyRegisterClass(hInstance); 60 61 // Perform application initialization: 62 if (!InitInstance (hInstance, nCmdShow)) 63 { 64 return FALSE; 65 } 66 67 hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_FDEBUG); 68 69 // Main message loop: 70 while (GetMessage(&msg, NULL, 0, 0)) 71 { 72 if (!TranslateAccelerator(hMainWnd, hAccelTable, &msg)) 73 { 74 TranslateMessage(&msg); 75 DispatchMessage(&msg); 76 } 77 } 78 79 return (int)msg.wParam; 80 } 81 82 83 84 // 85 // FUNCTION: MyRegisterClass() 86 // 87 // PURPOSE: Registers the window class. 88 // 89 // COMMENTS: 90 // 91 // This function and its usage is only necessary if you want this code 92 // to be compatible with Win32 systems prior to the 'RegisterClassEx' 93 // function that was added to Windows 95. It is important to call this function 94 // so that the application will get 'well formed' small icons associated 95 // with it. 96 // 97 ATOM MyRegisterClass(HINSTANCE hInstance) 98 { 99 WNDCLASSEX wcex; 100 101 wcex.cbSize = sizeof(WNDCLASSEX); 102 103 wcex.style = CS_HREDRAW | CS_VREDRAW; 104 wcex.lpfnWndProc = WndProc; 105 wcex.cbClsExtra = 0; 106 wcex.cbWndExtra = 0; 107 wcex.hInstance = hInstance; 108 wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_FDEBUG)); 109 wcex.hCursor = LoadCursor(NULL, IDC_ARROW); 110 wcex.hbrBackground = NULL;//(HBRUSH)(COLOR_WINDOW+1); 111 wcex.lpszMenuName = MAKEINTRESOURCE(IDC_FDEBUG); 112 wcex.lpszClassName = szWindowClass; 113 wcex.hIconSm = (HICON)LoadImage(hInstance, 114 MAKEINTRESOURCE(IDI_FDEBUG), 115 IMAGE_ICON, 116 16, 117 16, 118 LR_SHARED); 119 120 return RegisterClassEx(&wcex); 121 } 122 123 // 124 // FUNCTION: InitInstance(HANDLE, int) 125 // 126 // PURPOSE: Saves instance handle and creates main window 127 // 128 // COMMENTS: 129 // 130 // In this function, we save the instance handle in a global variable and 131 // create and display the main program window. 132 // 133 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) 134 { 135 HWND hWnd; 136 137 hInst = hInstance; // Store instance handle in our global variable 138 139 hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, 140 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); 141 142 if (!hWnd) 143 { 144 return FALSE; 145 } 146 147 hMainWnd = hWnd; 148 149 ShowWindow(hWnd, nCmdShow); 150 UpdateWindow(hWnd); 151 152 return TRUE; 153 } 154 155 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 156 { 157 int wmId, wmEvent; 158 PAINTSTRUCT ps; 159 HDC hdc; 160 RECT rc; 161 TCHAR WndText[MAX_PATH]; 162 DWORD Index; 163 NONCLIENTMETRICS ncm; 164 HFONT hFont; 165 166 switch (message) 167 { 168 case WM_CREATE: 169 170 hEditWnd = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("EDIT"), TEXT(""), WS_CHILD|WS_VISIBLE|WS_VSCROLL|ES_AUTOHSCROLL|ES_LEFT|ES_MULTILINE, 0, 0, 0, 0, hWnd, NULL, hInst, NULL); 171 hDisplayWnd = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("EDIT"), TEXT(""), WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL|ES_MULTILINE, 0, 0, 0, 0, hWnd, NULL, hInst, NULL); 172 173 memset(&ncm, 0, sizeof(NONCLIENTMETRICS)); 174 ncm.cbSize = sizeof(NONCLIENTMETRICS); 175 SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0); 176 177 hFont = CreateFontIndirect(&ncm.lfMessageFont); 178 179 SendMessage(hEditWnd, WM_SETFONT, (WPARAM)hFont, TRUE); 180 SendMessage(hDisplayWnd, WM_SETFONT, (WPARAM)hFont, TRUE); 181 182 break; 183 case WM_COMMAND: 184 wmId = LOWORD(wParam); 185 wmEvent = HIWORD(wParam); 186 187 if (lParam == (LPARAM)hEditWnd && wmEvent == EN_CHANGE) 188 { 189 GetWindowText(hEditWnd, WndText, MAX_PATH); 190 191 if (_tcslen(WndText) > 0) 192 { 193 SetWindowText(hEditWnd, TEXT("")); 194 195 if (!bConnected) 196 { 197 MessageBox(hWnd, TEXT("You are not currently connected!"), TEXT("Error"), MB_OK|MB_ICONSTOP); 198 break; 199 } 200 201 for (Index=0; Index<_tcslen(WndText); Index++) 202 { 203 if (dwThreadId != 0) 204 { 205 PostThreadMessage(dwThreadId, WM_CHAR, (WPARAM)WndText[Index], (LPARAM)0); 206 } 207 } 208 } 209 } 210 211 // Parse the menu selections: 212 switch (wmId) 213 { 214 case IDM_ABOUT: 215 DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About); 216 break; 217 case IDM_EXIT: 218 DestroyWindow(hWnd); 219 break; 220 case IDM_FILE_CLEARDISPLAY: 221 SetWindowText(hDisplayWnd, TEXT("")); 222 break; 223 case IDM_FILE_CONNECT: 224 if (bConnected) 225 { 226 MessageBox(hWnd, TEXT("You are already connected!"), TEXT("Error"), MB_OK|MB_ICONSTOP); 227 } 228 else 229 { 230 if (DialogBox(hInst, (LPCTSTR)IDD_CONNECTION, hWnd, (DLGPROC)ConnectionDialogProc) == IDOK) 231 { 232 bConnected = TRUE; 233 EnableFileMenuItemByID(IDM_FILE_DISCONNECT, TRUE); 234 EnableFileMenuItemByID(IDM_FILE_CONNECT, FALSE); 235 _beginthread(Rs232Thread, 0, NULL); 236 } 237 } 238 break; 239 case IDM_FILE_DISCONNECT: 240 if (bConnected) 241 { 242 bConnected = FALSE; 243 EnableFileMenuItemByID(IDM_FILE_DISCONNECT, FALSE); 244 EnableFileMenuItemByID(IDM_FILE_CONNECT, TRUE); 245 } 246 else 247 { 248 MessageBox(hWnd, TEXT("You are not currently connected!"), TEXT("Error"), MB_OK|MB_ICONSTOP); 249 } 250 break; 251 case IDM_FILE_STARTCAPTURE: 252 if (DialogBox(hInst, (LPCTSTR)IDD_CAPTURE, hWnd, (DLGPROC)CaptureDialogProc) == IDOK) 253 { 254 bCapturing = TRUE; 255 EnableFileMenuItemByID(IDM_FILE_STOPCAPTURE, TRUE); 256 EnableFileMenuItemByID(IDM_FILE_STARTCAPTURE, FALSE); 257 hCaptureFile = CreateFile(strCaptureFileName, FILE_APPEND_DATA, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 258 } 259 break; 260 case IDM_FILE_STOPCAPTURE: 261 if (bCapturing) 262 { 263 bCapturing = FALSE; 264 EnableFileMenuItemByID(IDM_FILE_STOPCAPTURE, FALSE); 265 EnableFileMenuItemByID(IDM_FILE_STARTCAPTURE, TRUE); 266 CloseHandle(hCaptureFile); 267 hCaptureFile = NULL; 268 } 269 break; 270 case IDM_FILE_LOCALECHO: 271 if (bLocalEcho) 272 { 273 bLocalEcho = FALSE; 274 CheckLocalEchoMenuItem(bLocalEcho); 275 } 276 else 277 { 278 bLocalEcho = TRUE; 279 CheckLocalEchoMenuItem(bLocalEcho); 280 } 281 break; 282 default: 283 return DefWindowProc(hWnd, message, wParam, lParam); 284 } 285 break; 286 case WM_PAINT: 287 hdc = BeginPaint(hWnd, &ps); 288 (void)hdc; // FIXME 289 EndPaint(hWnd, &ps); 290 break; 291 case WM_SIZE: 292 293 GetClientRect(hWnd, &rc); 294 295 MoveWindow(hDisplayWnd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top - 20, TRUE); 296 MoveWindow(hEditWnd, rc.left, rc.bottom - 20, rc.right - rc.left, 20, TRUE); 297 298 break; 299 case WM_DESTROY: 300 PostQuitMessage(0); 301 break; 302 default: 303 return DefWindowProc(hWnd, message, wParam, lParam); 304 } 305 return 0; 306 } 307 308 LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 309 { 310 HWND hLicenseEditWnd; 311 TCHAR strLicense[0x1000]; 312 313 UNREFERENCED_PARAMETER(lParam); 314 315 switch (message) 316 { 317 case WM_INITDIALOG: 318 319 hLicenseEditWnd = GetDlgItem(hDlg, IDC_LICENSE_EDIT); 320 321 LoadString(hInst, IDS_LICENSE, strLicense, 0x1000); 322 323 SetWindowText(hLicenseEditWnd, strLicense); 324 325 return TRUE; 326 327 case WM_COMMAND: 328 if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 329 { 330 EndDialog(hDlg, LOWORD(wParam)); 331 return TRUE; 332 } 333 break; 334 } 335 return FALSE; 336 } 337 338 LRESULT CALLBACK ConnectionDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 339 { 340 UNREFERENCED_PARAMETER(lParam); 341 342 switch (message) 343 { 344 case WM_INITDIALOG: 345 346 SetWindowText(GetDlgItem(hDlg, IDC_COMPORT), strComPort); 347 SetWindowText(GetDlgItem(hDlg, IDC_BAUTRATE), strBaudRate); 348 349 return TRUE; 350 351 case WM_COMMAND: 352 if (LOWORD(wParam) == IDOK) 353 { 354 GetWindowText(GetDlgItem(hDlg, IDC_COMPORT), strComPort, MAX_PATH); 355 GetWindowText(GetDlgItem(hDlg, IDC_BAUTRATE), strBaudRate, MAX_PATH); 356 } 357 358 if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 359 { 360 EndDialog(hDlg, LOWORD(wParam)); 361 return TRUE; 362 } 363 break; 364 } 365 return FALSE; 366 } 367 368 LRESULT CALLBACK CaptureDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 369 { 370 OPENFILENAME ofn; 371 372 UNREFERENCED_PARAMETER(lParam); 373 374 switch (message) 375 { 376 case WM_INITDIALOG: 377 378 SetWindowText(GetDlgItem(hDlg, IDC_CAPTUREFILENAME), strCaptureFileName); 379 380 return TRUE; 381 382 case WM_COMMAND: 383 if (LOWORD(wParam) == IDC_BROWSE) 384 { 385 memset(&ofn, 0, sizeof(OPENFILENAME)); 386 ofn.lStructSize = sizeof(OPENFILENAME); 387 ofn.hwndOwner = hDlg; 388 ofn.hInstance = hInst; 389 ofn.lpstrFilter = NULL; 390 ofn.lpstrCustomFilter = NULL; 391 ofn.nMaxCustFilter = 0; 392 ofn.nFilterIndex = 0; 393 ofn.lpstrFile = strCaptureFileName; 394 ofn.nMaxFile = MAX_PATH; 395 ofn.lpstrFileTitle = NULL; 396 ofn.nMaxFileTitle = 0; 397 ofn.lpstrInitialDir = NULL; 398 ofn.lpstrTitle = NULL; 399 ofn.Flags = OFN_HIDEREADONLY|OFN_NOREADONLYRETURN; 400 401 if (GetOpenFileName(&ofn)) 402 { 403 SetWindowText(GetDlgItem(hDlg, IDC_CAPTUREFILENAME), strCaptureFileName); 404 } 405 } 406 407 if (LOWORD(wParam) == IDOK) 408 { 409 GetWindowText(GetDlgItem(hDlg, IDC_CAPTUREFILENAME), strCaptureFileName, MAX_PATH); 410 } 411 412 if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 413 { 414 EndDialog(hDlg, LOWORD(wParam)); 415 return TRUE; 416 } 417 break; 418 } 419 return FALSE; 420 } 421 422 VOID EnableFileMenuItemByID(UINT Id, BOOL Enable) 423 { 424 HMENU hMenuBar; 425 HMENU hFileMenu; 426 427 hMenuBar = GetMenu(hMainWnd); 428 hFileMenu = GetSubMenu(hMenuBar, 0); 429 EnableMenuItem(hFileMenu, Id, MF_BYCOMMAND|(Enable ? MF_ENABLED : MF_GRAYED)); 430 } 431 432 VOID CheckLocalEchoMenuItem(BOOL Checked) 433 { 434 HMENU hMenuBar; 435 HMENU hFileMenu; 436 437 hMenuBar = GetMenu(hMainWnd); 438 hFileMenu = GetSubMenu(hMenuBar, 0); 439 CheckMenuItem(hFileMenu, IDM_FILE_LOCALECHO, MF_BYCOMMAND|(Checked ? MF_CHECKED : MF_UNCHECKED)); 440 } 441 442 VOID __cdecl Rs232Thread(VOID* Parameter) 443 { 444 BYTE Byte; 445 TCHAR String[MAX_PATH]; 446 MSG msg; 447 DWORD dwNumberOfBytesWritten; 448 449 UNREFERENCED_PARAMETER(Parameter); 450 451 dwThreadId = GetCurrentThreadId(); 452 453 if (!Rs232OpenPortWin32(strComPort)) 454 { 455 MessageBox(hMainWnd, TEXT("Error opening port!"), TEXT("Error"), MB_OK|MB_ICONSTOP); 456 bConnected = FALSE; 457 return; 458 } 459 460 _stprintf(String, TEXT("%s,n,8,1"), strBaudRate); 461 if (!Rs232ConfigurePortWin32(String)) 462 { 463 MessageBox(hMainWnd, TEXT("Error configuring port!"), TEXT("Error"), MB_OK|MB_ICONSTOP); 464 bConnected = FALSE; 465 return; 466 } 467 468 while (bConnected) 469 { 470 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 471 { 472 if (msg.message == WM_CHAR) 473 { 474 Rs232WriteByteWin32((BYTE)msg.wParam); 475 476 if (bLocalEcho && msg.wParam != (WPARAM)TEXT('\r')) 477 { 478 PostMessage(hDisplayWnd, WM_CHAR, (WPARAM)msg.wParam, (LPARAM)0); 479 480 if (hCaptureFile) 481 { 482 WriteFile(hCaptureFile, &msg.wParam, sizeof(TCHAR), &dwNumberOfBytesWritten, NULL); 483 } 484 } 485 } 486 } 487 488 if (Rs232ReadByteWin32(&Byte)) 489 { 490 _stprintf(String, TEXT("%c"), Byte); 491 492 PostMessage(hDisplayWnd, WM_CHAR, (WPARAM)String[0], (LPARAM)0); 493 494 if (hCaptureFile) 495 { 496 WriteFile(hCaptureFile, &String[0], sizeof(TCHAR), &dwNumberOfBytesWritten, NULL); 497 } 498 } 499 } 500 501 dwThreadId = 0; 502 Rs232ClosePortWin32(); 503 } 504