home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / winbase / debug / deb / debmain.c < prev    next >
C/C++ Source or Header  |  1997-10-05  |  34KB  |  951 lines

  1.  
  2. /******************************************************************************\
  3. *       This is a part of the Microsoft Source Code Samples. 
  4. *       Copyright (C) 1993-1997 Microsoft Corporation.
  5. *       All rights reserved. 
  6. *       This source code is only intended as a supplement to 
  7. *       Microsoft Development Tools and/or WinHelp documentation.
  8. *       See these sources for detailed information regarding the 
  9. *       Microsoft samples programs.
  10. \******************************************************************************/
  11.  
  12. // ************************************************************************
  13. // MODULE    : DEBMain.C
  14. // PURPOSE   : A Win32 Application demonstrating the Debug APIs
  15. // FUNCTIONS :
  16. //   WinMain()                 - application entry point
  17. //   MainWndProc()             - processes messages
  18. //   ProcessCommandsWndProc()  - processes WM_COMMAND messages
  19. //   PreferencesDlgProc()      - processes messages for "Preferences" dialog box
  20. //   AttachDlgProc()           - processes messages for "Attach" dialog box
  21. //   AboutDlgProc()            - processes messages for "About" dialog box
  22. //   NewListBoxWndProc()       - subclass procedure to prevent listbox moving
  23. //   TimerProc()               - timer procedure for animated icon
  24. // COMMENTS  :
  25. //
  26. // ************************************************************************
  27. #define   STRICT               // enable strict typing
  28. #include <Windows.H>           // required for all Windows applications
  29. #include "StdLib.H"            // __argc, __argv
  30.  
  31. #include "LinkList.H"          // double linked list package (OBJ)
  32. #include "DEBDebug.H"          // debugging support functions
  33. #include "DEBMisc.H"           // misc support functions
  34. #include "DEBMain.H"           // specific to this module
  35.  
  36. // global data
  37. // ------------------------------------------------------------------------
  38. GLOBAL  Global;                // various global data
  39. PROFILE Profile;               // various profile data
  40.  
  41. // internal data
  42. // ------------------------------------------------------------------------
  43. #define TIMEOUT_ANIMATED_ICON 150L // animated icon timeout
  44. static TCHAR szSourceFileName[] = TEXT(__FILE__);
  45.  
  46. // location of various files
  47. // ------------------------------------------------------------------------
  48. TCHAR   szPath[MAX_PATH];         // path where the running application
  49.                                   //  resides
  50. TCHAR   szExePathName[MAX_PATH];  // full pathname of the application
  51. TCHAR   szHelpPathName[MAX_PATH]; // full pathname of the application's
  52.                                   //  help file
  53. TCHAR   szIniPathName[MAX_PATH];  // full pathname of the application's
  54.                                   //  ini file
  55. // internal function prototypes
  56. // ------------------------------------------------------------------------
  57. LRESULT CALLBACK MainWndProc            ( HWND, UINT, WPARAM, LPARAM );
  58. LRESULT CALLBACK ProcessCommandsWndProc ( HWND, UINT, WPARAM, LPARAM );
  59. LRESULT CALLBACK NewListBoxWndProc      ( HWND, UINT, WPARAM, LPARAM );
  60. BOOL    CALLBACK PreferencesDlgProc     ( HWND, UINT, WPARAM, LPARAM );
  61. BOOL    CALLBACK AttachDlgProc          ( HWND, UINT, WPARAM, LPARAM );
  62. BOOL    CALLBACK AboutDlgProc           ( HWND, UINT, WPARAM, LPARAM );
  63. VOID    CALLBACK TimerProc              ( HWND, UINT, UINT, DWORD );
  64.  
  65.  
  66. // ************************************************************************
  67. // FUNCTION : WinMain( HINSTANCE, HINSTANCE, LPSTR, INT )
  68. // PURPOSE  : initialize the window, process the message dispatch loop
  69. // COMMENTS :
  70. //
  71. // ************************************************************************
  72. INT WINAPI
  73. WinMain( HINSTANCE hInstance, HINSTANCE hPrevInst, LPSTR lpCmdLine,
  74.   INT nCmdShow )
  75. {
  76.   MSG      Msg;
  77.   WNDCLASS WndClass;
  78.   HACCEL   hAccel;
  79.   OSVERSIONINFO osvi;
  80.  
  81.   LPCTSTR lpszIconName    = TEXT( "DebugIcon"  );
  82.   LPCTSTR lpszMenuName    = TEXT( "DebugMenu"  );
  83.   LPCTSTR lpszClassName   = TEXT( "DebugClass" );
  84.   LPCTSTR lpszAccelName   = TEXT( "DebugAccel" );
  85.   LPCTSTR lpszIniFileExt  = TEXT( "INI"        );
  86.   LPCTSTR lpszHelpFileExt = TEXT( "HLP"        );
  87.  
  88.   Global.hInstance = hInstance;
  89.   Global.dwActiveDebuggees = 0;
  90.  
  91.   //-- Load the "A Windows API Failed" resource string
  92.   {
  93.     TCHAR szApiFailed[] = TEXT( "A Windows API Failed" );
  94.  
  95.     if( !LoadString( Global.hInstance, IDS_API_FAILED_MSG,
  96.           Global.szApiFailed, sizeof(Global.szApiFailed) ) ) {
  97.       ErrorMessageBox( TEXT( "First LoadString()" ),
  98.         szApiFailed, szSourceFileName, __LINE__ );
  99.       lstrcpy( Global.szApiFailed, szApiFailed );
  100.     }
  101.   }
  102.  
  103.   //-- Load all other resource strings
  104.   if( !LoadString( Global.hInstance, IDS_APPNAME,  Global.szAppName,
  105.          sizeof(Global.szAppName) ) )
  106.     ErrorMessageBox( TEXT("LoadString()"),
  107.       Global.szApiFailed, szSourceFileName, __LINE__ );
  108.   if( !LoadString( Global.hInstance, IDS_SHORT_APPNAME,
  109.          Global.szShortAppName, sizeof(Global.szShortAppName) ) )
  110.     ErrorMessageBox( TEXT("LoadString()"),
  111.       Global.szApiFailed, szSourceFileName, __LINE__ );
  112.  
  113.   //-- if compiled for Win32 (Unicode) and not Win32s then display
  114.   //    notice and terminate
  115.  
  116.  
  117.   //
  118.   // Detect platform and exit gracefully if unsupported platform.
  119.   //
  120.  
  121.   osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
  122.   GetVersionEx (&osvi);
  123.   if (osvi.dwPlatformId == VER_PLATFORM_WIN32s) {
  124.     TCHAR szTitleBuffer[64];
  125.     TCHAR szTextBuffer[256];
  126.  
  127.     if( !LoadString( Global.hInstance, IDS_WINDOWS_NT_REQUIRED_TITLE,
  128.            szTitleBuffer, sizeof(szTitleBuffer) ) )
  129.       ErrorMessageBox( TEXT("LoadString()"),
  130.         Global.szApiFailed, szSourceFileName, __LINE__ );
  131.  
  132.     if( !LoadString( Global.hInstance, IDS_WINDOWS_NT_REQUIRED,
  133.            szTextBuffer, sizeof(szTextBuffer) ) )
  134.       ErrorMessageBox( TEXT("LoadString()"),
  135.         Global.szApiFailed, szSourceFileName, __LINE__ );
  136.  
  137.     MessageBox( NULL, szTextBuffer, szTitleBuffer,
  138.       MB_APPLMODAL | MB_ICONSTOP | MB_OK );
  139.     return( -1 );
  140.   }
  141.  
  142.   //-- register the debug event window class
  143.   WndClass.style         = CS_DBLCLKS;
  144.   WndClass.lpfnWndProc   = (WNDPROC) MainWndProc;
  145.   WndClass.cbClsExtra    = (INT) NULL;
  146.   WndClass.cbWndExtra    = (INT) NULL;
  147.   WndClass.hInstance     = Global.hInstance;
  148.   WndClass.hIcon         = LoadIcon( Global.hInstance, lpszIconName );
  149.   WndClass.hCursor       = LoadCursor( NULL, (LPTSTR) IDC_ARROW );
  150.   WndClass.hbrBackground = (HBRUSH) (COLOR_APPWORKSPACE+1);
  151.   WndClass.lpszMenuName  = lpszMenuName;
  152.   WndClass.lpszClassName = lpszClassName;
  153.  
  154.   if( !RegisterClass(&WndClass) ) {
  155.     ErrorMessageBox( TEXT("RegisterClass()"),
  156.       Global.szApiFailed, szSourceFileName, __LINE__ );
  157.     return( FALSE );
  158.   }
  159.  
  160.   //-- get application pathname and store the ini and help file pathname
  161.   //   (which is located in the same directory as the application)
  162.   GetModuleFileName( (HANDLE) NULL, szExePathName,
  163.     sizeof(szExePathName)/sizeof(TCHAR) );
  164.   GetPathFromFullPathName( szExePathName, szPath,
  165.     sizeof(szPath)/sizeof(TCHAR) );
  166.   wsprintf( szIniPathName,  TEXT( "%s\\%s.%s" ), szPath,
  167.     Global.szShortAppName, lpszIniFileExt  );
  168.   wsprintf( szHelpPathName, TEXT( "%s\\%s.%s" ), szPath,
  169.     Global.szShortAppName, lpszHelpFileExt );
  170.  
  171.   //-- retrieve stored default location from private profile data
  172.   GetPrivateProfileSettings( Global.szAppName, szIniPathName, &Profile );
  173.  
  174.   //-- Create a main window for this application instance
  175.   Global.hWndMain = CreateWindow( lpszClassName, Global.szAppName,
  176.                       WS_OVERLAPPEDWINDOW,
  177.                       Profile.xPos, Profile.yPos,
  178.                       Profile.nWidth, Profile.nHeight,
  179.                       NULL, NULL, Global.hInstance, NULL );
  180.  
  181.   //-- If window could not be created, return "failure"
  182.   if( !Global.hWndMain ) {
  183.     ErrorMessageBox( TEXT("CreateWindow()"),
  184.       Global.szApiFailed, szSourceFileName, __LINE__ );
  185.     return( FALSE );
  186.   }
  187.  
  188.   //-- Load main menu accelerators
  189.   if( !(hAccel = LoadAccelerators( Global.hInstance, lpszAccelName) ) ) {
  190.     ErrorMessageBox( TEXT("LoadAccelerators()"),
  191.       Global.szApiFailed, szSourceFileName, __LINE__ );
  192.     return( FALSE );
  193.   }
  194.  
  195.   //-- modify the menu to reflect saved settings
  196.   UpdateMenuSettings( Global.hWndMain );
  197.  
  198.   //-- Make the window visible; update its client area; and return "success"
  199.   if( Profile.fMaximized )
  200.     ShowWindow( Global.hWndMain, SW_SHOWMAXIMIZED );
  201.   else if ( Profile.fMinimized )
  202.     ShowWindow( Global.hWndMain, SW_SHOWMINIMIZED );
  203.   else
  204.     ShowWindow( Global.hWndMain, SW_SHOWDEFAULT );
  205.   UpdateWindow( Global.hWndMain );
  206.  
  207.   //-- Acquire and dispatch messages until a WM_QUIT message is received.
  208.   while( GetMessage( &Msg, NULL, 0, 0 ) ) {
  209.     if( !TranslateAccelerator( Global.hWndMain, hAccel, &Msg ) ) {
  210.       TranslateMessage( &Msg );
  211.       DispatchMessage( &Msg );
  212.     }
  213.   }
  214.  
  215.   return( Msg.wParam );
  216.   UNREFERENCED_PARAMETER( lpCmdLine );  // avoid warnings
  217.   UNREFERENCED_PARAMETER( hPrevInst );  // always NULL under Windows NT
  218.   UNREFERENCED_PARAMETER( nCmdShow  );  //
  219. }
  220.  
  221.  
  222. // ************************************************************************
  223. // FUNCTION : MainWndProc( HWND, UINT, WPARAM, LPARAM )
  224. // PURPOSE  : Processes uMsgs
  225. // MESSAGES :
  226. //   WM_COMMAND   - passed to ProcessCommandsWndProc()
  227. //   WM_DESTROY   - destroy window
  228. //    ...
  229. // COMMENTS :
  230. //
  231. // ************************************************************************
  232. LRESULT CALLBACK
  233. MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  234. {
  235.   #define TOP_BORDER      4
  236.   #define BOTTOM_BORDER   4
  237.   #define SIDE_BORDER     4
  238.   #define MIN_HEIGHT    128
  239.  
  240.   static HDC hDC;
  241.  
  242.   switch( uMsg ) {
  243.  
  244.     //-- forward all WM_COMMANDS to separate handler function
  245.     case WM_COMMAND:
  246.       return( ProcessCommandsWndProc( hWnd, uMsg, wParam, lParam) );
  247.  
  248.     //-- create debug event listbox
  249.     case UM_CREATE_LISTBOX: {
  250.       TCHAR  szWindowName[64];
  251.       HFONT  hFont;
  252.  
  253.       LoadString( Global.hInstance, IDS_DEBUG_EVENTS, szWindowName,
  254.         sizeof(szWindowName)/sizeof(TCHAR) );
  255.  
  256.       Global.hWndListBox = CreateWindow(
  257.                            TEXT( "ListBox" ),
  258.                            szWindowName,
  259.                            WS_CHILD             | WS_VISIBLE      |
  260.                            WS_CAPTION           | WS_VSCROLL      |
  261.                            WS_HSCROLL           | LBS_NOTIFY      |
  262.                            LBS_DISABLENOSCROLL  | LBS_USETABSTOPS |
  263.                            LBS_NOINTEGRALHEIGHT,
  264.                            (INT) SIDE_BORDER,
  265.                            (INT) (Profile.fToolBar
  266.                              ? (Global.ToolBarHeight + TOP_BORDER)
  267.                              : TOP_BORDER),
  268.                            (INT) Global.ListBoxSize.cx,
  269.                            (INT) Global.ListBoxSize.cy,
  270.                            hWnd, (HMENU) NULL, Global.hInstance, NULL );
  271.  
  272.       //-- Subclass the listbox so the user cannot move it
  273.       Global.OldListBoxWndProc = SubclassWindow( Global.hWndListBox,
  274.         (WNDPROC) NewListBoxWndProc );
  275.  
  276.       //-- set listbox font & background color
  277.       hDC = GetDC( Global.hWndListBox );
  278.       hFont = CreateFontIndirect( &(Profile.LogFont) );
  279.       SelectObject( hDC, hFont );
  280.       SendMessage( Global.hWndListBox, WM_CTLCOLORLISTBOX, (WPARAM) hDC,
  281.         (LPARAM) Global.hWndListBox );
  282.       SendMessage( Global.hWndListBox, WM_SETFONT, (WPARAM) hFont, TRUE );
  283.       ReleaseDC( Global.hWndListBox, hDC );
  284.  
  285.       //-- if command line contains a debuggee name then
  286.       //   start and detach the debug event processing thread
  287.       if( __argc == 2 )
  288.         StartDebuggee( (LPTSTR) __argv[1], Global.hWndListBox );
  289.  
  290.       return( FALSE );
  291.     }
  292.  
  293.     //-- create ToolBar & send message to create the Debug Events listbox
  294.     case WM_CREATE:
  295.       Global.hWndToolBar = CreateTextButtonBar( hWnd, &Global.ToolBarHeight );
  296.       if( Profile.fToolBar )
  297.         ShowWindow( Global.hWndToolBar, SW_SHOW );
  298.       PostMessage( hWnd, UM_CREATE_LISTBOX, 0, 0 );
  299.       return( FALSE );
  300.  
  301.     //-- resize the debug event listbox when the window size changes
  302.     case WM_SIZE:
  303.       Global.ClientSize.cx = LOWORD( lParam );
  304.       Global.ClientSize.cy = HIWORD( lParam );
  305.       Global.ListBoxSize.cx = Global.ClientSize.cx - ( 2*SIDE_BORDER );
  306.       Global.ListBoxSize.cy = max( Global.ClientSize.cy, MIN_HEIGHT
  307.                                 + TOP_BORDER )
  308.         - (TOP_BORDER + BOTTOM_BORDER);
  309.  
  310.       if( Profile.fToolBar )
  311.         Global.ListBoxSize.cy -= Global.ToolBarHeight;
  312.  
  313.       if( Global.hWndListBox != NULL)
  314.         MoveWindow( Global.hWndListBox,
  315.           (INT) SIDE_BORDER,
  316.           (INT) (Profile.fToolBar ? Global.ToolBarHeight + TOP_BORDER : TOP_BORDER),
  317.           (INT) Global.ListBoxSize.cx, (INT) Global.ListBoxSize.cy, TRUE );
  318.  
  319.       switch( wParam ) {
  320.  
  321.         case SIZE_RESTORED: {
  322.           RECT rect;
  323.  
  324.           Profile.fMaximized = FALSE;
  325.           Profile.fMinimized = FALSE;
  326.           GetWindowRect( Global.hWndMain, &rect );
  327.           Profile.nWidth  = (INT) (rect.right - rect.left);
  328.           Profile.nHeight = (INT) (rect.bottom - rect.top);
  329.           return( FALSE );
  330.         }
  331.  
  332.         case SIZE_MAXIMIZED:
  333.           Profile.fMaximized = TRUE;
  334.           Profile.fMinimized = FALSE;
  335.           Profile.xPos       = Global.xPosOld;
  336.           Profile.yPos       = Global.yPosOld;
  337.           return( FALSE );
  338.  
  339.         case SIZE_MINIMIZED:
  340.           Profile.fMinimized = TRUE;
  341.           Profile.fMaximized = FALSE;
  342.           Profile.xPos       = Global.xPosOld;
  343.           Profile.yPos       = Global.yPosOld;
  344.           return( FALSE );
  345.  
  346.       }
  347.       return( DefWindowProc(hWnd, uMsg, wParam, lParam) );
  348.  
  349.     //-- keep track of window position so it can be saved
  350.     case WM_MOVE: {
  351.       RECT rect;
  352.  
  353.       GetWindowRect( Global.hWndMain, &rect );
  354.       Global.xPosOld      = Profile.xPos;
  355.       Global.yPosOld      = Profile.yPos;
  356.       Profile.xPos = (INT) rect.left;
  357.       Profile.yPos = (INT) rect.top;
  358.       return( FALSE );
  359.     }
  360.  
  361.     //-- colorize the debug event listbox
  362.     case WM_CTLCOLORLISTBOX: {
  363.       LOGBRUSH LogBrush;
  364.  
  365.       LogBrush.lbStyle = BS_SOLID;
  366.       LogBrush.lbColor = Profile.rgbBackColor;
  367.       LogBrush.lbHatch = (LONG) NULL;
  368.  
  369.       SetTextColor( (HDC) wParam, Profile.rgbForeColor );
  370.       SetBkColor( (HDC) wParam, Profile.rgbBackColor );
  371.  
  372.       return( (LPARAM) CreateBrushIndirect( &LogBrush ) );
  373.     }
  374.  
  375.     //-- check if a debuggee is still active, save profile settings
  376.     case WM_CLOSE:
  377.       if( Global.dwActiveDebuggees ) {
  378.         TCHAR  szExitBoxTitle[64];
  379.         TCHAR  szExitBoxText[256];
  380.  
  381.         LoadString( Global.hInstance, IDS_EXIT_BOX_TITLE, szExitBoxTitle,
  382.           sizeof(szExitBoxTitle)/sizeof(TCHAR) );
  383.         LoadString( Global.hInstance, IDS_EXIT_BOX_TEXT, szExitBoxText,
  384.           sizeof(szExitBoxText)/sizeof(TCHAR) );
  385.         if ( MessageBox( hWnd, szExitBoxText, szExitBoxTitle,
  386.                MB_YESNO | MB_ICONEXCLAMATION ) == IDNO )
  387.           return( FALSE );
  388.       }
  389.  
  390.       //-- store location information to private profile data
  391.       WritePrivateProfileSettings( Global.szAppName, szIniPathName, &Profile );
  392.  
  393.       DestroyWindow( Global.hWndToolBar );
  394.       DestroyWindow( Global.hWndListBox );
  395.       DestroyWindow( Global.hWndMain );
  396.  
  397.       return( FALSE );
  398.  
  399.     case WM_DESTROY:
  400.       if( Global.fHelpUsed )
  401.         WinHelp( hWnd, szHelpPathName, (UINT) HELP_QUIT, (DWORD) NULL );
  402.       PostQuitMessage( 0 );
  403.       return( FALSE );
  404.  
  405.     default:               // Passes it on if unproccessed
  406.       return( DefWindowProc(hWnd, uMsg, wParam, lParam) );
  407.   }
  408.  
  409.   return( FALSE );
  410. }
  411.  
  412.  
  413. // ************************************************************************
  414. // FUNCTION : ProcessCommandsWndProc( HWND, UINT, WPARAM, LPARAM )
  415. // PURPOSE  : Processes WM_COMMAND messages for MainWndProc()
  416. // MESSAGES :
  417. //   WM_COMMAND         - application menu
  418. //     IDM_FILE_EXIT    - exit the application
  419. //     IDM_FILE_ABOUT   - About Dialog Box
  420. //    ...
  421. // COMMENTS :
  422. //
  423. // ************************************************************************
  424. LRESULT CALLBACK
  425. ProcessCommandsWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  426. {
  427.   static LPCTSTR  lpszAboutDlgBox       = TEXT( "AboutDlgBox"       );
  428.   static LPCTSTR  lpszAttachDlgBox      = TEXT( "AttachDlgBox"      );
  429.   static LPCTSTR  lpszPreferencesDlgBox = TEXT( "PreferencesDlgBox" );
  430.  
  431.   switch( LOWORD(wParam) ) {
  432.  
  433.     //-- user requests to open a new debuggee
  434.     case IDM_FILE_OPEN: {
  435.       static TCHAR szDebuggeeFileName[MAX_PATH];
  436.  
  437.       if( Global.dwActiveDebuggees ) {
  438.         MaxDebuggeesMessageBox( Global.hWndMain );
  439.         return( FALSE );
  440.       }
  441.       if( !GetDebuggeeFileName( szDebuggeeFileName, hWnd ) ) {
  442.         return( FALSE );
  443.       }
  444.       else {
  445.         if( Profile.fClearOnNew ) {
  446.           SendMessage( Global.hWndListBox, LB_RESETCONTENT, 0, 0 );
  447.           Global.MaxStrLen = 0;
  448.         }
  449.         StartDebuggee( szDebuggeeFileName, Global.hWndListBox );
  450.       }
  451.       return( FALSE );
  452.     }
  453.  
  454.     //-- user requests to attach to an existing process
  455.     case IDM_FILE_ATTACH:
  456.       if( Global.dwActiveDebuggees ) {
  457.         MaxDebuggeesMessageBox( Global.hWndMain );
  458.         return( FALSE );
  459.       }
  460.       if( !DialogBox( Global.hInstance, lpszAttachDlgBox, hWnd,
  461.             (DLGPROC) AttachDlgProc ) ) {
  462.         // handle cancel condition...
  463.       }
  464.       else {
  465.         if( Profile.fClearOnNew ) {
  466.           SendMessage( Global.hWndListBox, LB_RESETCONTENT, 0, 0 );
  467.           Global.MaxStrLen = 0;
  468.         }
  469.       }
  470.       return( FALSE );
  471.  
  472.     //-- copy listbox contents to the clipboard and clear the listbox
  473.     case IDM_EDIT_CUT:
  474.       CopyListBoxToClipboard( Global.hWndListBox, Global.MaxStrLen );
  475.       SendMessage( hWnd, WM_COMMAND, IDM_EDIT_DELETE, 0 );
  476.       return( FALSE );
  477.  
  478.     //-- copy listbox contents to the clipboard
  479.     case IDM_EDIT_COPY: {
  480.       CopyListBoxToClipboard( Global.hWndListBox, Global.MaxStrLen );
  481.       return( FALSE );
  482.     }
  483.  
  484.     //-- clear the contents of the listbox
  485.     case IDM_EDIT_DELETE:
  486.       SendMessage( Global.hWndListBox, LB_RESETCONTENT, 0, 0 );
  487.       Global.MaxStrLen = 0;
  488.       return( FALSE );
  489.  
  490.     //-- user requests a new font for the listbox
  491.     case IDM_OPTIONS_FONT:
  492.       if( !ChooseNewFont( Global.hWndListBox ) ) {
  493.         // handle cancel condition...
  494.       }
  495.       return( FALSE );
  496.  
  497.     //-- user requests a new background color for the listbox
  498.     case IDM_OPTIONS_COLOR:
  499.       ChooseNewBackColor( Global.hWndListBox );
  500.       return( FALSE );
  501.  
  502.     //-- invoke the preferences dialog box
  503.     case IDM_OPTIONS_PREFERENCES:
  504.       DialogBox( Global.hInstance, lpszPreferencesDlgBox, hWnd,
  505.         (DLGPROC) PreferencesDlgProc );
  506.       return( FALSE );
  507.  
  508.     //-- toggle the toolbar on or off
  509.     case IDM_OPTIONS_TOOLBAR:
  510.       if( Profile.fToolBar ) {
  511.         Profile.fToolBar = 0;
  512.         CheckMenuItem( GetMenu(Global.hWndMain), IDM_OPTIONS_TOOLBAR,
  513.           MF_UNCHECKED );
  514.         ShowWindow( Global.hWndToolBar, SW_HIDE );
  515.         SendWmSizeMessage( Global.hWndMain );
  516.       }
  517.       else {
  518.         Profile.fToolBar = 1;
  519.         CheckMenuItem( GetMenu(Global.hWndMain), IDM_OPTIONS_TOOLBAR,
  520.           MF_CHECKED );
  521.         ShowWindow( Global.hWndToolBar, SW_SHOW );
  522.         SendWmSizeMessage( Global.hWndMain );
  523.       }
  524.       return( FALSE );
  525.  
  526.     //-- toggles whether the used directory is used for the 'open' command
  527.     case IDM_OPTIONS_SAVEDDIR:
  528.       if( Profile.fSavedDirectory ) {
  529.         Profile.fSavedDirectory = 0;
  530.         CheckMenuItem( GetMenu(Global.hWndMain), IDM_OPTIONS_SAVEDDIR,
  531.           MF_UNCHECKED );
  532.       }
  533.       else {
  534.         Profile.fSavedDirectory = 1;
  535.         CheckMenuItem( GetMenu(Global.hWndMain), IDM_OPTIONS_SAVEDDIR,
  536.           MF_CHECKED );
  537.       }
  538.       return( FALSE );
  539.  
  540.     //-- toggles the 'save on exit' feature
  541.     case IDM_OPTIONS_SAVEONEXIT:
  542.       if( Profile.fSaveOnExit ) {
  543.         Profile.fSaveOnExit = 0;
  544.         CheckMenuItem( GetMenu(Global.hWndMain), IDM_OPTIONS_SAVEONEXIT,
  545.           MF_UNCHECKED );
  546.       }
  547.       else {
  548.         Profile.fSaveOnExit = 1;
  549.         CheckMenuItem( GetMenu(Global.hWndMain), IDM_OPTIONS_SAVEONEXIT,
  550.           MF_CHECKED );
  551.       }
  552.       return( FALSE );
  553.  
  554.     //-- store location information to private profile data now
  555.     case IDM_OPTIONS_SAVENOW: {
  556.       BOOL fOldSaveOnExit = Profile.fSaveOnExit;
  557.       BOOL fOldSavePreferences = Profile.fSavePreferences;
  558.  
  559.       Profile.fSaveOnExit = TRUE;
  560.       Profile.fSavePreferences = TRUE;
  561.       WritePrivateProfileSettings( Global.szAppName, szIniPathName, &Profile );
  562.       Profile.fSaveOnExit = fOldSaveOnExit;
  563.       Profile.fSavePreferences = fOldSavePreferences;
  564.       return( FALSE );
  565.     }
  566.  
  567.     //-- invoke help and display the contents panel
  568.     case IDM_HELP_CONTENTS:
  569.       Global.fHelpUsed = TRUE;
  570.       WinHelp( hWnd, (LPCTSTR) szHelpPathName, HELP_CONTENTS, (DWORD) NULL );
  571.       return( FALSE );
  572.  
  573.     //-- search the help indexes
  574.     case IDM_HELP_SEARCH:
  575.       Global.fHelpUsed = TRUE;
  576.       WinHelp( hWnd, (LPCTSTR) szHelpPathName, HELP_PARTIALKEY,
  577.         (DWORD) TEXT( "" ) );
  578.       return( FALSE );
  579.  
  580.     //-- invoke the main 'how to use' help panel
  581.     case IDM_HELP_HOWTOUSE:
  582.       Global.fHelpUsed = TRUE;
  583.       WinHelp( hWnd, (LPTSTR) NULL, HELP_HELPONHELP, (DWORD) NULL );
  584.       return( FALSE );
  585.  
  586.     //-- display the product information dialog box
  587.     case IDM_HELP_ABOUT:
  588.       DialogBox( Global.hInstance, lpszAboutDlgBox, hWnd,
  589.         (DLGPROC) AboutDlgProc );
  590.       return( FALSE );
  591.  
  592.     //-- the usr requests to terminate the app
  593.     case IDM_FILE_EXIT:
  594.       SendMessage( Global.hWndMain, WM_CLOSE, 0, 0 );
  595.       return( FALSE );
  596.  
  597.     default:
  598.       return( DefWindowProc(hWnd, uMsg, wParam, lParam) );
  599.   }
  600.  
  601.   return( FALSE );
  602. }
  603.  
  604.  
  605. // ************************************************************************
  606. // FUNCTION : PreferencesDlgProc( HWND, UINT, WPARAM, LPARAM )
  607. // PURPOSE  : Processes message for "Preferences" dialog box
  608. // MESSAGES :
  609. //   WM_INITDIALOG - initialize dialog box
  610. //   WM_COMMAND    - Input received
  611. // COMMENTS :
  612. //   Wait for user to click on "Ok" button, then close the dialog box.
  613. // ************************************************************************
  614. BOOL CALLBACK
  615. PreferencesDlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
  616. {
  617.   switch( uMsg ) {
  618.  
  619.     case WM_COMMAND:
  620.       switch( LOWORD(wParam) ) {
  621.  
  622.         case IDOK:
  623.  
  624.           //-- Debugger Setting Group
  625.           if( SendMessage( GetDlgItem( hDlg, IDC_DEBUG_PROCESS),
  626.                 BM_GETCHECK, 0, 0 ) )
  627.             Profile.DebugMode = DEBUG_PROCESS;
  628.           if( SendMessage( GetDlgItem( hDlg, IDC_DEBUG_ONLY_THIS_PROCESS),
  629.                 BM_GETCHECK, 0, 0 ) )
  630.             Profile.DebugMode = DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS;
  631.  
  632.           //-- Debuggee Priority Group
  633.           if( SendMessage( GetDlgItem( hDlg, IDC_IDLE_PRIORITY_CLASS),
  634.                 BM_GETCHECK, 0, 0 ) )
  635.             Profile.DebuggeePriority = IDLE_PRIORITY_CLASS;
  636.           if( SendMessage( GetDlgItem( hDlg, IDC_NORMAL_PRIORITY_CLASS),
  637.                 BM_GETCHECK, 0, 0 ) )
  638.             Profile.DebuggeePriority = NORMAL_PRIORITY_CLASS;
  639.           if( SendMessage( GetDlgItem( hDlg, IDC_HIGH_PRIORITY_CLASS),
  640.                 BM_GETCHECK, 0, 0 ) )
  641.             Profile.DebuggeePriority = HIGH_PRIORITY_CLASS;
  642.           if( SendMessage( GetDlgItem( hDlg, IDC_REALTIME_PRIORITY_CLASS),
  643.                 BM_GETCHECK, 0, 0 ) )
  644.             Profile.DebuggeePriority = REALTIME_PRIORITY_CLASS;
  645.  
  646.           //-- Miscellaneous Options Group
  647.           Profile.fClearOnNew  = (BOOL) SendMessage(
  648.                                           GetDlgItem( hDlg, IDC_CLEAR_ON_NEW),
  649.                                           BM_GETCHECK, 0 , 0 );
  650.           Profile.fVerbose     = (BOOL) SendMessage(
  651.                                           GetDlgItem( hDlg, IDC_VERBOSE),
  652.                                           BM_GETCHECK, 0 , 0 );
  653.  
  654. #ifdef SHOW_SYMBOLS
  655.           Profile.fShowSymbols = (BOOL) SendMessage(
  656.                                           GetDlgItem( hDlg, IDC_SHOW_SYMBOLS),
  657.                                           BM_GETCHECK, 0 , 0 );
  658. #endif
  659.  
  660.  
  661.           //- Debug Error Level Group
  662.           if( SendMessage( GetDlgItem( hDlg, IDC_DEBUG_MODE_NONE),
  663.                 BM_GETCHECK, 0, 0 ) )
  664.             Profile.DebugErrorLevel = 0;
  665.           if( SendMessage( GetDlgItem( hDlg, IDC_DEBUG_MODE_ERROR),
  666.                 BM_GETCHECK, 0, 0 ) )
  667.             Profile.DebugErrorLevel = SLE_ERROR;
  668.           if( SendMessage( GetDlgItem( hDlg, IDC_DEBUG_MODE_MINORERROR),
  669.                 BM_GETCHECK, 0, 0 ) )
  670.             Profile.DebugErrorLevel = SLE_MINORERROR;
  671.           if( SendMessage( GetDlgItem( hDlg, IDC_DEBUG_MODE_WARNING),
  672.                 BM_GETCHECK, 0, 0 ) )
  673.             Profile.DebugErrorLevel = SLE_WARNING;
  674.  
  675.           Profile.fSavePreferences = (BOOL) SendMessage(
  676.                                               GetDlgItem( hDlg,
  677.                                                 IDC_SAVE_PREFERENCES),
  678.                                               BM_GETCHECK, 0 , 0 );
  679.           EndDialog( hDlg, TRUE );
  680.           return( TRUE );
  681.  
  682.         case IDCANCEL:
  683.           EndDialog( hDlg, FALSE );
  684.           return( TRUE );
  685.  
  686.         case IDHELP:
  687.           return( TRUE );
  688.  
  689.       }
  690.       break;
  691.  
  692.     case WM_INITDIALOG:
  693.  
  694.       //-- Debugger Setting Group
  695.       switch( Profile.DebugMode ) {
  696.  
  697.         case DEBUG_PROCESS:
  698.           SendMessage( GetDlgItem( hDlg, IDC_DEBUG_PROCESS),
  699.             BM_SETCHECK, 1, 0);
  700.           break;
  701.  
  702.         case ( DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS ):
  703.           SendMessage( GetDlgItem( hDlg, IDC_DEBUG_ONLY_THIS_PROCESS),
  704.             BM_SETCHECK, 1, 0);
  705.           break;
  706.       }
  707.  
  708.       //-- Debuggee Priority Group
  709.       switch( Profile.DebuggeePriority ) {
  710.  
  711.         case IDLE_PRIORITY_CLASS:
  712.           SendMessage( GetDlgItem( hDlg, IDC_IDLE_PRIORITY_CLASS),
  713.             BM_SETCHECK, 1, 0);
  714.           break;
  715.  
  716.         case NORMAL_PRIORITY_CLASS:
  717.           SendMessage( GetDlgItem( hDlg, IDC_NORMAL_PRIORITY_CLASS),
  718.             BM_SETCHECK, 1, 0);
  719.           break;
  720.  
  721.         case HIGH_PRIORITY_CLASS:
  722.           SendMessage( GetDlgItem( hDlg, IDC_HIGH_PRIORITY_CLASS),
  723.             BM_SETCHECK, 1, 0);
  724.           break;
  725.  
  726.         case REALTIME_PRIORITY_CLASS:
  727.           SendMessage( GetDlgItem( hDlg, IDC_REALTIME_PRIORITY_CLASS),
  728.             BM_SETCHECK, 1, 0);
  729.           break;
  730.  
  731.       }
  732.  
  733.       //-- Miscellaneous Options Group
  734.       SendMessage( GetDlgItem( hDlg, IDC_CLEAR_ON_NEW),     BM_SETCHECK,
  735.         Profile.fClearOnNew, 0 );
  736.       SendMessage( GetDlgItem( hDlg, IDC_VERBOSE),          BM_SETCHECK,
  737.         Profile.fVerbose, 0 );
  738.       SendMessage( GetDlgItem( hDlg, IDC_SAVE_PREFERENCES), BM_SETCHECK,
  739.         Profile.fSavePreferences, 0 );
  740.  
  741. #ifdef SHOW_SYMBOLS
  742.       SendMessage( GetDlgItem( hDlg, IDC_SHOW_SYMBOLS),     BM_SETCHECK,
  743.         Profile.fShowSymbols, 0 );
  744. #endif
  745.  
  746.       //- Debug Error Level Group
  747.       switch( Profile.DebugErrorLevel ) {
  748.  
  749.         case 0:
  750.           SendMessage( GetDlgItem( hDlg, IDC_DEBUG_MODE_NONE),
  751.             BM_SETCHECK, 1, 0);
  752.           break;
  753.  
  754.         case SLE_ERROR:
  755.           SendMessage( GetDlgItem( hDlg, IDC_DEBUG_MODE_ERROR),
  756.             BM_SETCHECK, 1, 0);
  757.           break;
  758.  
  759.         case SLE_MINORERROR:
  760.           SendMessage( GetDlgItem( hDlg, IDC_DEBUG_MODE_MINORERROR),
  761.             BM_SETCHECK, 1, 0);
  762.           break;
  763.  
  764.         case SLE_WARNING:
  765.           SendMessage( GetDlgItem( hDlg, IDC_DEBUG_MODE_WARNING),
  766.             BM_SETCHECK, 1, 0);
  767.           break;
  768.  
  769.       }
  770.  
  771.       return( TRUE );
  772.   }
  773.  
  774.   return( FALSE );
  775.   UNREFERENCED_PARAMETER( lParam );
  776. }
  777.  
  778.  
  779. // ************************************************************************
  780. // FUNCTION : AttachDlgProc( HWND, UINT, WPARAM, LPARAM )
  781. // PURPOSE  : Processes messages for "Attach" dialog box
  782. // MESSAGES :
  783. //   WM_COMMAND    - Input received
  784. //   WM_INITDIALOG - initialize dialog box
  785. // COMMENTS :
  786. //   Wait for user to click on "Ok" button, then close the dialog box.
  787. // ************************************************************************
  788. BOOL CALLBACK
  789. AttachDlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
  790. {
  791.   static HWND hWndProcessList;
  792.  
  793.   switch( uMsg ) {
  794.  
  795.     case WM_COMMAND:
  796.       switch( LOWORD(wParam) ) {
  797.  
  798.         case IDOK: {
  799.           LONG  Index;
  800.           DWORD dwProcessId;
  801.  
  802.           Index = (UINT) SendMessage( hWndProcessList, LB_GETCURSEL,
  803.                          (WPARAM) NULL, (LPARAM) NULL );
  804.           dwProcessId = (DWORD) SendMessage( hWndProcessList,
  805.                                   LB_GETITEMDATA,
  806.                                   (WPARAM) Index, (LPARAM) NULL );
  807.           AttachToDebuggee( dwProcessId, Global.hWndListBox );
  808.           EndDialog( hDlg, TRUE );
  809.           return( TRUE );
  810.         }
  811.  
  812.         case IDCANCEL:
  813.           EndDialog( hDlg, FALSE );
  814.           return( TRUE );
  815.  
  816.         case IDHELP:
  817.           return( TRUE );
  818.  
  819.       }
  820.       switch( HIWORD( wParam ) ) {
  821.         case LBN_DBLCLK:
  822.           SendMessage( hDlg, WM_COMMAND, (WPARAM) IDOK, (LPARAM) 0L );
  823.           return( TRUE );
  824.       }
  825.       break;
  826.  
  827.     case WM_INITDIALOG:
  828.       hWndProcessList = GetDlgItem( hDlg, IDC_PROCESSLIST );
  829.       SendMessage( hWndProcessList, LB_RESETCONTENT, 0 , 0 );
  830.       for(; !EnumWindows( (WNDENUMPROC) EnumProcessListFunc,
  831.                (LPARAM) hWndProcessList ); )
  832.         ; // continue looping until done
  833.       return( TRUE );
  834.   }
  835.  
  836.   return( FALSE );
  837.   UNREFERENCED_PARAMETER( lParam );
  838. }
  839.  
  840.  
  841. // **************************************************************************
  842. // FUNCTION : AboutDlgProc( HWND, UINT, WPARAM, LPARAM )
  843. // PURPOSE  : Processes messages for "About" dialog box
  844. // MESSAGES :
  845. //   WM_COMMAND    - Input received
  846. //     IDOK        - OK button selected
  847. //     IDCANCEL    - Cancel button selected
  848. //     ...
  849. //   WM_INITDIALOG - initialize dialog box
  850. //   WM_CLOSE      - close the dialog box
  851. //   ...
  852. // COMMENTS:
  853. //   No initialization is needed for this particular dialog box.
  854. //   In this case, TRUE must be returned to Windows.
  855. //   Wait for user to click on "Ok" button, then close the dialog box.
  856. // **************************************************************************
  857. BOOL CALLBACK
  858. AboutDlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
  859. {
  860.   switch( uMsg ) {
  861.  
  862.     case WM_COMMAND:
  863.       switch( LOWORD(wParam) ) {
  864.  
  865.         case IDOK:
  866.           EndDialog( hDlg, TRUE );
  867.           return( TRUE );
  868.  
  869.         case IDCANCEL:
  870.           EndDialog( hDlg, FALSE );
  871.           return( FALSE );
  872.  
  873.       }
  874.       break;
  875.  
  876.     case WM_INITDIALOG:
  877.       SetTimer( hDlg, 1, TIMEOUT_ANIMATED_ICON, TimerProc );
  878.       return( TRUE );
  879.  
  880.     case WM_CLOSE:
  881.       EndDialog( hDlg, TRUE );
  882.       return( TRUE );
  883.  
  884.     case WM_DESTROY:
  885.       KillTimer( hDlg, 1 );
  886.       return( TRUE );
  887.   }
  888.  
  889.   return( FALSE );
  890.   UNREFERENCED_PARAMETER( lParam );
  891. }
  892.  
  893.  
  894. // ************************************************************************
  895. // FUNCTION : NewListBoxWndProc( HWND, UINT, WPARAM, LPARAM )
  896. // PURPOSE  : Processes messages for "LISTBOX" class.
  897. // COMMENTS : Prevents the user from moving the window
  898. //            by dragging the titlebar.
  899. // ************************************************************************
  900. LRESULT CALLBACK
  901. NewListBoxWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  902. {
  903.   switch( uMsg ) {
  904.  
  905.     case WM_NCLBUTTONDOWN:
  906.       if( wParam == HTCAPTION ) {
  907.         SetFocus( hWnd );
  908.         return( FALSE );
  909.       }
  910.       else
  911.         break;
  912.   }
  913.  
  914.   return( CallWindowProc( Global.OldListBoxWndProc, hWnd, uMsg, wParam, lParam) );
  915. }
  916.  
  917.  
  918. // ************************************************************************
  919. // FUNCTION : TimerProc( HWND, UINT, UINT, DWORD )
  920. // PURPOSE  : Timer callback fuction that changes the dialog's icon (thus
  921. //            a animated icon) for each timer message received.
  922. // COMMENTS :
  923. // ************************************************************************
  924. VOID CALLBACK
  925. TimerProc( HWND hDlg, UINT uMsg, UINT idEvent, DWORD dwTime )
  926. {
  927.  #define NUM_ICONS 8
  928.  
  929.  static UINT    uIconNumber = 0;
  930.  static HWND    hWndIcon    = NULL;
  931.  static HWND    hWndIconOld = NULL;
  932.  static LPCTSTR lpszIconNames[NUM_ICONS] = {
  933.                   TEXT( "DebugIcon1" ), TEXT( "DebugIcon2" ),
  934.                   TEXT( "DebugIcon3" ), TEXT( "DebugIcon4" ),
  935.                   TEXT( "DebugIcon5" ), TEXT( "DebugIcon6" ),
  936.                   TEXT( "DebugIcon7" ), TEXT( "DebugIcon8" ) };
  937.  
  938.  if( (++uIconNumber) >= NUM_ICONS )
  939.    uIconNumber = 0;
  940.  
  941.  hWndIconOld = hWndIcon;
  942.  hWndIcon = CreateIconWindow( hDlg, lpszIconNames[uIconNumber] );
  943.  if( hWndIcon != NULL )
  944.    DestroyWindow( hWndIconOld );
  945.  
  946.  return;
  947.  UNREFERENCED_PARAMETER( uMsg );
  948.  UNREFERENCED_PARAMETER( idEvent );
  949.  UNREFERENCED_PARAMETER( dwTime );
  950. }
  951.