|
|
1.1 ! root 1: /*++ ! 2: ! 3: Copyright (c) 1993 Microsoft Corporation ! 4: ! 5: Module Name: ! 6: ! 7: drwtsnui.c ! 8: ! 9: Abstract: ! 10: ! 11: This function implements the ui (dialog) that controls the ! 12: options maintenace for drwatson. ! 13: ! 14: Author: ! 15: ! 16: Wesley Witt (wesw) 1-May-1993 ! 17: ! 18: Environment: ! 19: ! 20: User Mode ! 21: ! 22: --*/ ! 23: ! 24: #include <windows.h> ! 25: #include <stdlib.h> ! 26: #include <stdio.h> ! 27: #include <string.h> ! 28: #include <mmsystem.h> ! 29: #include <direct.h> ! 30: #include <shellapi.h> ! 31: ! 32: #include "drwatson.h" ! 33: #include "proto.h" ! 34: #include "resource.h" ! 35: ! 36: ! 37: void InitializeDialog( HWND hwnd ); ! 38: void InitializeCrashList( HWND hwnd ); ! 39: BOOL GetDialogValues( HWND hwnd ); ! 40: BOOL CALLBACK LogFileViewerDialogProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); ! 41: LRESULT DrWatsonWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); ! 42: ! 43: ! 44: void ! 45: DrWatsonWinMain( void ) ! 46: ! 47: /*++ ! 48: ! 49: Routine Description: ! 50: ! 51: This is the entry point for DRWTSN32 ! 52: ! 53: Arguments: ! 54: ! 55: None. ! 56: ! 57: Return Value: ! 58: ! 59: None. ! 60: ! 61: --*/ ! 62: ! 63: { ! 64: HWND hwnd; ! 65: MSG msg; ! 66: WNDCLASS wndclass; ! 67: HINSTANCE hInst; ! 68: ! 69: ! 70: hInst = GetModuleHandle( NULL ); ! 71: wndclass.style = CS_HREDRAW | CS_VREDRAW; ! 72: wndclass.lpfnWndProc = DrWatsonWndProc; ! 73: wndclass.cbClsExtra = 0; ! 74: wndclass.cbWndExtra = DLGWINDOWEXTRA; ! 75: wndclass.hInstance = hInst; ! 76: wndclass.hIcon = LoadIcon( hInst, MAKEINTRESOURCE(APPICON) ); ! 77: wndclass.hCursor = LoadCursor( NULL, IDC_ARROW ); ! 78: wndclass.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1); ! 79: wndclass.lpszMenuName = NULL; ! 80: wndclass.lpszClassName = "DrWatsonDialog"; ! 81: RegisterClass( &wndclass ); ! 82: ! 83: hwnd = CreateDialog( hInst, ! 84: MAKEINTRESOURCE( DRWATSONDIALOG ), ! 85: 0, ! 86: DrWatsonWndProc ! 87: ); ! 88: ! 89: ShowWindow( hwnd, SW_SHOWNORMAL ); ! 90: ! 91: while (GetMessage (&msg, NULL, 0, 0)) { ! 92: if (!IsDialogMessage( hwnd, &msg )) { ! 93: TranslateMessage (&msg) ; ! 94: DispatchMessage (&msg) ; ! 95: } ! 96: } ! 97: ! 98: return; ! 99: } ! 100: ! 101: LRESULT ! 102: DrWatsonWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) ! 103: ! 104: /*++ ! 105: ! 106: Routine Description: ! 107: ! 108: Window procedure for the DRWTSN32.EXE main user interface. ! 109: ! 110: Arguments: ! 111: ! 112: hwnd - window handle to the dialog box ! 113: message - message number ! 114: wParam - first message parameter ! 115: lParam - second message parameter ! 116: ! 117: Return Value: ! 118: ! 119: TRUE - did not process the message ! 120: FALSE - did process the message ! 121: ! 122: --*/ ! 123: ! 124: { ! 125: DWORD helpId; ! 126: char szCurrDir[MAX_PATH]; ! 127: char szWave[MAX_PATH]; ! 128: char szHelpFileName[MAX_PATH]; ! 129: ! 130: switch (message) { ! 131: case WM_CREATE: ! 132: return 0; ! 133: ! 134: case WM_INITDIALOG: ! 135: SubclassControls( hwnd ); ! 136: InitializeDialog( hwnd ); ! 137: SetTimer( hwnd, 1, 50, NULL ); ! 138: return 1; ! 139: ! 140: case WM_TIMER: ! 141: if (GetKeyState(VK_F1) & 0x8000) { ! 142: switch (GetDlgCtrlID( GetFocus() )) { ! 143: case ID_LOGPATH: ! 144: helpId = IDH_LOGFILELOCATION; ! 145: break; ! 146: ! 147: case ID_BROWSE_LOGPATH: ! 148: helpId = IDH_LOGFILELOCATION; ! 149: break; ! 150: ! 151: case ID_WAVEFILE_TEXT: ! 152: helpId = IDH_WAVEFILE; ! 153: break; ! 154: ! 155: case ID_WAVE_FILE: ! 156: helpId = IDH_WAVEFILE; ! 157: break; ! 158: ! 159: case ID_BROWSE_WAVEFILE: ! 160: helpId = IDH_WAVEFILE; ! 161: break; ! 162: ! 163: case ID_TEST_WAVE: ! 164: helpId = IDH_WAVEFILE; ! 165: break; ! 166: ! 167: case ID_INSTRUCTIONS: ! 168: helpId = IDH_NUMBEROFINSTR; ! 169: break; ! 170: ! 171: case ID_NUM_CRASHES: ! 172: helpId = IDH_NUMBEROFCRASHES; ! 173: break; ! 174: ! 175: case ID_DUMPSYMBOLS: ! 176: helpId = IDH_DUMPSYMBOLS; ! 177: break; ! 178: ! 179: case ID_DUMPALLTHREADS: ! 180: helpId = IDH_DUMPALLTHREADS; ! 181: break; ! 182: ! 183: case ID_APPENDTOLOGFILE: ! 184: helpId = IDH_APPENDTOLOGFILE; ! 185: break; ! 186: ! 187: case ID_VISUAL: ! 188: helpId = IDH_VISUAL; ! 189: break; ! 190: ! 191: case ID_SOUND: ! 192: helpId = IDH_SOUND; ! 193: break; ! 194: ! 195: case ID_CRASHES: ! 196: helpId = IDH_APPERRORS; ! 197: break; ! 198: ! 199: case ID_LOGFILE_VIEW: ! 200: helpId = IDH_VIEW; ! 201: break; ! 202: ! 203: case ID_CLEAR: ! 204: helpId = IDH_CLEAR; ! 205: break; ! 206: ! 207: case IDOK: ! 208: helpId = IDH_INDEX; ! 209: break; ! 210: ! 211: case IDCANCEL: ! 212: helpId = IDH_INDEX; ! 213: break; ! 214: ! 215: case ID_HELP: ! 216: helpId = IDH_INDEX; ! 217: break; ! 218: ! 219: default: ! 220: helpId = IDH_INDEX; ! 221: break; ! 222: } ! 223: // ! 224: // call winhelp ! 225: // ! 226: GetHelpFileName( szHelpFileName, sizeof(szHelpFileName ) ); ! 227: WinHelp( hwnd, szHelpFileName, HELP_CONTEXT, helpId ); ! 228: } ! 229: return 1; ! 230: ! 231: case WM_ACTIVATEAPP: ! 232: case WM_SETFOCUS: ! 233: SetFocusToCurrentControl(); ! 234: return 0; ! 235: ! 236: case WM_SYSCOMMAND: ! 237: if (wParam == ID_ABOUT) { ! 238: char title[256]; ! 239: char extra[256]; ! 240: ! 241: strcpy( title, LoadRcString( IDS_ABOUT_TITLE ) ); ! 242: strcpy( extra, LoadRcString( IDS_ABOUT_EXTRA ) ); ! 243: ! 244: ShellAbout( hwnd, ! 245: title, ! 246: extra, ! 247: LoadIcon( GetModuleHandle(NULL), ! 248: MAKEINTRESOURCE(APPICON) ! 249: ) ! 250: ); ! 251: ! 252: return 0; ! 253: } ! 254: break; ! 255: ! 256: case WM_COMMAND: ! 257: switch (wParam) { ! 258: case IDOK: ! 259: if (GetDialogValues( hwnd )) { ! 260: PostQuitMessage( 0 ); ! 261: } ! 262: break; ! 263: ! 264: case IDCANCEL: ! 265: PostQuitMessage( 0 ); ! 266: break; ! 267: ! 268: case ID_BROWSE_LOGPATH: ! 269: GetDlgItemText( hwnd, ID_LOGPATH, szCurrDir, MAX_PATH ); ! 270: if (BrowseForDirectory( szCurrDir )) { ! 271: SetDlgItemText( hwnd, ID_LOGPATH, szCurrDir ); ! 272: } ! 273: SetFocus( GetDlgItem(hwnd, ID_BROWSE_LOGPATH) ); ! 274: return FALSE; ! 275: break; ! 276: ! 277: case ID_BROWSE_WAVEFILE: ! 278: szWave[0] = '\0'; ! 279: if (GetWaveFileName( szWave )) { ! 280: SetDlgItemText( hwnd, ID_WAVE_FILE, szWave ); ! 281: } ! 282: SetFocus( GetDlgItem(hwnd, ID_BROWSE_WAVEFILE) ); ! 283: return FALSE; ! 284: break; ! 285: ! 286: case ID_CLEAR: ! 287: ElClearAllEvents(); ! 288: InitializeCrashList( hwnd ); ! 289: break; ! 290: ! 291: case ID_TEST_WAVE: ! 292: GetDlgItemText( hwnd, ID_WAVE_FILE, szWave, sizeof(szWave) ); ! 293: PlaySound( szWave, NULL, SND_FILENAME ); ! 294: break; ! 295: ! 296: case ID_LOGFILE_VIEW: ! 297: DialogBoxParam( GetModuleHandle( NULL ), ! 298: MAKEINTRESOURCE( LOGFILEVIEWERDIALOG ), ! 299: hwnd, ! 300: LogFileViewerDialogProc, ! 301: SendMessage((HWND)GetDlgItem(hwnd,ID_CRASHES), ! 302: LB_GETCURSEL,0,0) ! 303: ); ! 304: break; ! 305: ! 306: case ID_HELP: ! 307: // ! 308: // call winhelp ! 309: // ! 310: GetHelpFileName( szHelpFileName, sizeof(szHelpFileName ) ); ! 311: WinHelp( hwnd, szHelpFileName, HELP_CONTEXT, IDH_INDEX ); ! 312: SetFocus( GetDlgItem(hwnd, ID_HELP) ); ! 313: break; ! 314: ! 315: default: ! 316: if (((HWND)lParam == GetDlgItem( hwnd, ID_CRASHES )) && ! 317: (HIWORD( wParam ) == LBN_DBLCLK)) { ! 318: DialogBoxParam( GetModuleHandle( NULL ), ! 319: MAKEINTRESOURCE( LOGFILEVIEWERDIALOG ), ! 320: hwnd, ! 321: LogFileViewerDialogProc, ! 322: SendMessage((HWND)lParam,LB_GETCURSEL,0,0) ! 323: ); ! 324: } ! 325: break; ! 326: } ! 327: break; ! 328: ! 329: case WM_DESTROY: ! 330: PostQuitMessage( 0 ); ! 331: return 0; ! 332: } ! 333: ! 334: return DefWindowProc( hwnd, message, wParam, lParam ); ! 335: } ! 336: ! 337: BOOL CALLBACK ! 338: EnumCrashes( PCRASHINFO crashInfo ) ! 339: ! 340: /*++ ! 341: ! 342: Routine Description: ! 343: ! 344: Enumeration function for crash records. This function is called ! 345: once for each crash record. This function places the formatted ! 346: crash data in a listbox. ! 347: ! 348: Arguments: ! 349: ! 350: crashInfo - pointer to a CRASHINFO structure ! 351: ! 352: Return Value: ! 353: ! 354: TRUE - caller should continue calling the enum procedure ! 355: FALSE - caller should stop calling the enum procedure ! 356: ! 357: --*/ ! 358: ! 359: { ! 360: SIZE size; ! 361: char buf[1024]; ! 362: ! 363: wsprintf( buf, "%s %08x %s(%08x)", ! 364: crashInfo->crash.szAppName, ! 365: crashInfo->crash.dwExceptionCode, ! 366: crashInfo->crash.szFunction, ! 367: crashInfo->crash.dwAddress ! 368: ); ! 369: SendMessage( crashInfo->hList, LB_ADDSTRING, 0, (LPARAM)buf ); ! 370: ! 371: ! 372: GetTextExtentPoint( crashInfo->hdc, buf, strlen(buf), &size ); ! 373: if (size.cx > (LONG)crashInfo->cxExtent) { ! 374: crashInfo->cxExtent = size.cx; ! 375: } ! 376: ! 377: return TRUE; ! 378: } ! 379: ! 380: ! 381: void ! 382: InitializeCrashList( HWND hwnd ) ! 383: ! 384: /*++ ! 385: ! 386: Routine Description: ! 387: ! 388: Initializes the listbox that contains the crash information. ! 389: ! 390: Arguments: ! 391: ! 392: None. ! 393: ! 394: Return Value: ! 395: ! 396: None. ! 397: ! 398: --*/ ! 399: ! 400: { ! 401: CRASHINFO crashInfo; ! 402: TEXTMETRIC tm; ! 403: HFONT hFont; ! 404: ! 405: crashInfo.hList = GetDlgItem( hwnd, ID_CRASHES ); ! 406: SendMessage( crashInfo.hList, LB_RESETCONTENT, FALSE, 0L ); ! 407: SendMessage( crashInfo.hList, WM_SETREDRAW, FALSE, 0L ); ! 408: crashInfo.hdc = GetDC( crashInfo.hList ); ! 409: crashInfo.cxExtent = 0; ! 410: ! 411: ElEnumCrashes( &crashInfo, EnumCrashes ); ! 412: ! 413: hFont = (HFONT)SendMessage( crashInfo.hList, WM_GETFONT, 0, 0L ); ! 414: if (hFont != NULL) { ! 415: SelectObject( crashInfo.hdc, hFont ); ! 416: } ! 417: GetTextMetrics( crashInfo.hdc, &tm ); ! 418: ReleaseDC( crashInfo.hList, crashInfo.hdc ); ! 419: SendMessage( crashInfo.hList, LB_SETHORIZONTALEXTENT, crashInfo.cxExtent, 0L ); ! 420: SendMessage( crashInfo.hList, WM_SETREDRAW, TRUE, 0L ); ! 421: ! 422: return; ! 423: } ! 424: ! 425: void ! 426: InitializeDialog( HWND hwnd ) ! 427: ! 428: /*++ ! 429: ! 430: Routine Description: ! 431: ! 432: Initializes the DRWTSN32 user interface dialog with the values ! 433: stored in the registry. ! 434: ! 435: Arguments: ! 436: ! 437: hwnd - window handle to the dialog ! 438: ! 439: Return Value: ! 440: ! 441: None. ! 442: ! 443: --*/ ! 444: ! 445: { ! 446: OPTIONS o; ! 447: char buf[256]; ! 448: HMENU hMenu; ! 449: ! 450: ! 451: RegInitialize( &o ); ! 452: SetDlgItemText( hwnd, ID_LOGPATH, o.szLogPath ); ! 453: SetDlgItemText( hwnd, ID_WAVE_FILE, o.szWaveFile ); ! 454: wsprintf( buf, "%d", o.dwMaxCrashes ); ! 455: SetDlgItemText( hwnd, ID_NUM_CRASHES, buf ); ! 456: wsprintf( buf, "%d", o.dwInstructions ); ! 457: SetDlgItemText( hwnd, ID_INSTRUCTIONS, buf ); ! 458: SendMessage( GetDlgItem( hwnd, ID_DUMPSYMBOLS ), BM_SETCHECK, o.fDumpSymbols, 0 ); ! 459: SendMessage( GetDlgItem( hwnd, ID_DUMPALLTHREADS ), BM_SETCHECK, o.fDumpAllThreads, 0 ); ! 460: SendMessage( GetDlgItem( hwnd, ID_APPENDTOLOGFILE ), BM_SETCHECK, o.fAppendToLogFile, 0 ); ! 461: SendMessage( GetDlgItem( hwnd, ID_VISUAL ), BM_SETCHECK, o.fVisual, 0 ); ! 462: SendMessage( GetDlgItem( hwnd, ID_SOUND ), BM_SETCHECK, o.fSound, 0 ); ! 463: ! 464: if (waveOutGetNumDevs() == 0) { ! 465: EnableWindow( GetDlgItem( hwnd, ID_WAVEFILE_TEXT ), FALSE ); ! 466: EnableWindow( GetDlgItem( hwnd, ID_WAVE_FILE ), FALSE ); ! 467: EnableWindow( GetDlgItem( hwnd, ID_BROWSE_WAVEFILE ), FALSE ); ! 468: } ! 469: ! 470: InitializeCrashList( hwnd ); ! 471: ! 472: if (SendMessage( GetDlgItem( hwnd, ID_CRASHES ), LB_GETCOUNT, 0 ,0 ) == 0) { ! 473: EnableWindow( GetDlgItem( hwnd, ID_CLEAR ), FALSE ); ! 474: EnableWindow( GetDlgItem( hwnd, ID_LOGFILE_VIEW ), FALSE ); ! 475: } ! 476: ! 477: hMenu = GetSystemMenu( hwnd, FALSE ); ! 478: if (hMenu != NULL) { ! 479: AppendMenu( hMenu, MF_SEPARATOR, 0, NULL ); ! 480: AppendMenu( hMenu, MF_STRING, ID_ABOUT, "About Dr. Watson..." ); ! 481: } ! 482: ! 483: return; ! 484: } ! 485: ! 486: BOOL ! 487: GetDialogValues( HWND hwnd ) ! 488: ! 489: /*++ ! 490: ! 491: Routine Description: ! 492: ! 493: Retrieves the values in the DRWTSN32 dialog controls and saves ! 494: them in the registry. ! 495: ! 496: Arguments: ! 497: ! 498: hwnd - window handle to the dialog ! 499: ! 500: Return Value: ! 501: ! 502: TRUE - all values were retrieved and saved ! 503: FALSE - an error occurred ! 504: ! 505: --*/ ! 506: ! 507: { ! 508: OPTIONS o; ! 509: char buf[256]; ! 510: DWORD dwFa; ! 511: ! 512: RegInitialize( &o ); ! 513: ! 514: GetDlgItemText( hwnd, ID_LOGPATH, buf, sizeof(buf) ); ! 515: dwFa = GetFileAttributes( buf ); ! 516: if ((dwFa == 0xffffffff) || (!(dwFa&FILE_ATTRIBUTE_DIRECTORY))) { ! 517: NonFatalError( LoadRcString(IDS_INVALID_PATH) ); ! 518: return FALSE; ! 519: } ! 520: ! 521: if (strlen(buf) > 0) { ! 522: strcpy( o.szLogPath, buf ); ! 523: } ! 524: ! 525: GetDlgItemText( hwnd, ID_WAVE_FILE, buf, sizeof(buf) ); ! 526: if (strlen(buf) > 0) { ! 527: dwFa = GetFileAttributes( buf ); ! 528: if ((dwFa == 0xffffffff) || (dwFa&FILE_ATTRIBUTE_DIRECTORY)) { ! 529: NonFatalError( LoadRcString(IDS_INVALID_WAVE) ); ! 530: return FALSE; ! 531: } ! 532: } ! 533: ! 534: strcpy( o.szWaveFile, buf ); ! 535: ! 536: GetDlgItemText( hwnd, ID_NUM_CRASHES, buf, sizeof(buf) ); ! 537: o.dwMaxCrashes = (DWORD) atol( buf ); ! 538: ! 539: GetDlgItemText( hwnd, ID_INSTRUCTIONS, buf, sizeof(buf) ); ! 540: o.dwInstructions = (DWORD) atol( buf ); ! 541: ! 542: o.fDumpSymbols = SendMessage( GetDlgItem( hwnd, ID_DUMPSYMBOLS ), BM_GETCHECK, 0, 0 ); ! 543: o.fDumpAllThreads = SendMessage( GetDlgItem( hwnd, ID_DUMPALLTHREADS ), BM_GETCHECK, 0, 0 ); ! 544: o.fAppendToLogFile = SendMessage( GetDlgItem( hwnd, ID_APPENDTOLOGFILE ), BM_GETCHECK, 0, 0 ); ! 545: o.fVisual = SendMessage( GetDlgItem( hwnd, ID_VISUAL ), BM_GETCHECK, 0, 0 ); ! 546: o.fSound = SendMessage( GetDlgItem( hwnd, ID_SOUND ), BM_GETCHECK, 0, 0 ); ! 547: ! 548: RegSave( &o ); ! 549: ! 550: return TRUE; ! 551: } ! 552: ! 553: BOOL CALLBACK ! 554: EnumCrashesForViewer( PCRASHINFO crashInfo ) ! 555: ! 556: /*++ ! 557: ! 558: Routine Description: ! 559: ! 560: Enumeration function for crash records. This function is called ! 561: once for each crash record. This function looks for s specific crash ! 562: that is identified by the crashIndex. ! 563: ! 564: Arguments: ! 565: ! 566: crashInfo - pointer to a CRASHINFO structure ! 567: ! 568: Return Value: ! 569: ! 570: TRUE - caller should continue calling the enum procedure ! 571: FALSE - caller should stop calling the enum procedure ! 572: ! 573: --*/ ! 574: ! 575: { ! 576: char *p; ! 577: ! 578: if ((crashInfo->dwIndex == crashInfo->dwIndexDesired) && ! 579: (crashInfo->dwCrashDataSize > 0) ) { ! 580: p = crashInfo->pCrashData; ! 581: crashInfo->pCrashData = malloc( crashInfo->dwCrashDataSize+10 ); ! 582: memcpy( crashInfo->pCrashData, p, crashInfo->dwCrashDataSize+10 ); ! 583: crashInfo->pCrashData[crashInfo->dwCrashDataSize] = 0; ! 584: return FALSE; ! 585: } ! 586: ! 587: crashInfo->dwIndex++; ! 588: ! 589: return TRUE; ! 590: } ! 591: ! 592: BOOL CALLBACK ! 593: LogFileViewerDialogProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) ! 594: ! 595: /*++ ! 596: ! 597: Routine Description: ! 598: ! 599: Window procedure for the log file viewer dialog box. ! 600: ! 601: Arguments: ! 602: ! 603: hwnd - window handle to the dialog box ! 604: message - message number ! 605: wParam - first message parameter ! 606: lParam - second message parameter ! 607: ! 608: Return Value: ! 609: ! 610: TRUE - did not process the message ! 611: FALSE - did process the message ! 612: ! 613: --*/ ! 614: ! 615: { ! 616: CRASHINFO crashInfo; ! 617: HFONT hFont; ! 618: ! 619: switch (message) { ! 620: case WM_INITDIALOG: ! 621: crashInfo.dwIndex = 0; ! 622: crashInfo.dwIndexDesired = lParam; ! 623: ElEnumCrashes( &crashInfo, EnumCrashesForViewer ); ! 624: if (crashInfo.dwIndex != crashInfo.dwIndexDesired) { ! 625: MessageBeep( 0 ); ! 626: EndDialog( hwnd, 0 ); ! 627: return FALSE; ! 628: } ! 629: SetDlgItemText( hwnd, ID_LOGFILE_VIEW, crashInfo.pCrashData ); ! 630: ! 631: hFont = GetStockObject( SYSTEM_FIXED_FONT ); ! 632: Assert( hFont != NULL ); ! 633: ! 634: SendDlgItemMessage( hwnd, ! 635: ID_LOGFILE_VIEW, ! 636: WM_SETFONT, ! 637: (WPARAM) hFont, ! 638: (LPARAM) FALSE ! 639: ); ! 640: return TRUE; ! 641: ! 642: case WM_COMMAND: ! 643: if (wParam == IDOK) { ! 644: free( crashInfo.pCrashData ); ! 645: EndDialog( hwnd, 0 ); ! 646: } ! 647: break; ! 648: } ! 649: ! 650: return FALSE; ! 651: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.