|
|
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.