home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / sdktools / spy / app / spy.c < prev    next >
C/C++ Source or Header  |  1997-10-05  |  12KB  |  472 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. *
  14. * Module: spy.c
  15. *
  16. *   Main module for the Windows debugging Spy SDK applet.
  17. *
  18. * Functions:
  19. *
  20. *   WinMain()
  21. *   SpyWndProc()
  22. *   SpyInit()
  23. *   PutOptions()
  24. *   InitMenu()
  25. *   SpyCommand()
  26. *
  27. * Comments:
  28. *
  29. \*****************************************************************************/
  30.  
  31. #include "spy.h"
  32. #include <stdlib.h>
  33.  
  34.  
  35. #define WM_EXECINSTANCE     (WM_USER+100)
  36.  
  37.  
  38. /*
  39.  * Macros to simplify working with menus.
  40.  */
  41. #define MyEnableMenuItem(hMenu, wIDEnableItem, fEnable) \
  42.     EnableMenuItem((hMenu),(wIDEnableItem),(fEnable)?MF_ENABLED:MF_GRAYED)
  43.  
  44. #define MyCheckMenuItem(hMenu, wIDCheckItem, fCheck) \
  45.     CheckMenuItem((hMenu),(wIDCheckItem),(fCheck)?MF_CHECKED:MF_UNCHECKED)
  46.  
  47.  
  48. HANDLE ghInst;
  49. HWND ghwndSpyApp;
  50. HWND ghwndPrintf = NULL;
  51. HANDLE ghHookThread = NULL;
  52. HWND ghwndSpyHook = NULL;
  53. HWND ghwndSpyingOn = NULL;              // The window we are spying on.
  54. HFONT ghfontPrintf;
  55. INT gnLines;
  56. BOOL gfSpyOn = FALSE;
  57. BOOL gfSpyAll;
  58. BOOL gfOutputWin;
  59. BOOL gfOutputCom1;
  60. BOOL gfOutputFile;
  61. HFILE gfhFile;
  62. HANDLE gfhCom1;
  63. CHAR gszFile[MAXSTRING];
  64. INT gcxBorder;
  65. INT gcyBorder;
  66. BOOL gfMsgsUser;                        // TRUE to spy on all WM_USER messages.
  67. BOOL gfMsgsUnknown;                     // TRUE to spy on all unknown msgs.
  68. CHAR gszAppName[] = SPYAPPNAME;
  69. UCHAR gszWindowName[40];
  70. WINDOWPLACEMENT gwndpl;
  71.  
  72.  
  73. PRIVATE HANDLE ghaccelTbl;              // Accelerator table handle.
  74. PRIVATE CHAR gszSpyClassName[] = SPYCLASSNAME;
  75.  
  76.  
  77. PRIVATE BOOL SpyInit(HANDLE hInstance, INT nCmdShow);
  78. PRIVATE VOID PutOptions(VOID);
  79. PRIVATE VOID InitMenu(HMENU hmenu);
  80. PRIVATE LRESULT SpyCommand(HWND hwnd, INT nCmd, INT nNotifyCode);
  81.  
  82.  
  83.  
  84. /*****************************************************************************\
  85. * WinMain
  86. *
  87. * Main entry point for the Spy app.
  88. *
  89. \*****************************************************************************/
  90.  
  91. INT WINAPI
  92. WinMain(
  93.     HINSTANCE hInstance,
  94.     HINSTANCE hPrevInstance,
  95.     LPSTR lpCmdLine,
  96.     INT nCmdShow
  97.     )
  98. {
  99.     MSG msg;
  100.  
  101.     if (!SpyInit(hInstance, nCmdShow))
  102.         return FALSE;
  103.  
  104.     if (!CreateHookThread())
  105.         goto closespy;
  106.  
  107.     /*
  108.      * Polling messages from event queue
  109.      */
  110.     while (GetMessage(&msg, NULL, 0, 0))
  111.     {
  112.         if (!TranslateAccelerator(ghwndSpyApp, ghaccelTbl, &msg))
  113.         {
  114.             TranslateMessage(&msg);
  115.             DispatchMessage(&msg);
  116.         }
  117.     }
  118.  
  119. closespy:
  120.     if (IsWindow(ghwndSpyApp))
  121.     {
  122.         if (DestroyWindow(ghwndSpyApp))
  123.         {
  124.             ghwndSpyApp = NULL;
  125.         }
  126.     }
  127.  
  128.     if (IsWindow(ghwndPrintf))
  129.     {
  130.         if (DestroyWindow(ghwndPrintf))
  131.         {
  132.             ghwndPrintf = NULL;
  133.         }
  134.     }
  135.  
  136.     return (INT)msg.wParam;
  137. }
  138.  
  139.  
  140.  
  141. /*****************************************************************************\
  142. * SpyInit
  143. *
  144. * Initializes the Spy application.
  145. *
  146. * Arguments:
  147. *   HANDLE hInstance - handle to the instance of SPY.
  148. *   INT nCmdShow - show the window?
  149. *
  150. * Returns:
  151. *   TRUE if successful, FALSE otherwise.
  152. *
  153. \*****************************************************************************/
  154.  
  155. PRIVATE BOOL
  156. SpyInit(
  157.     HANDLE hInstance,
  158.     INT nCmdShow
  159.     )
  160. {
  161.     WNDCLASS wc;
  162.     HWND hwndT;
  163.     CHAR szClassName[40];
  164.     BOOL bFoundPrevSpy = FALSE;
  165.     INT i;
  166.     INT j;
  167.  
  168.     ghInst = hInstance;
  169.  
  170.     /*
  171.      * Loop through windows to find one of the spy class.
  172.      */
  173.     for (hwndT = GetWindow(GetDesktopWindow(), GW_CHILD); hwndT;
  174.         hwndT = GetWindow(hwndT, GW_HWNDNEXT))
  175.     {
  176.         if (GetClassName(hwndT, szClassName, 40))
  177.         {
  178.             if (!lstrcmpi(szClassName, gszSpyClassName))
  179.             {
  180.                 bFoundPrevSpy = TRUE;
  181.                 break;
  182.             }
  183.         }
  184.     }
  185.  
  186.     if (bFoundPrevSpy)
  187.     {
  188.         if (hwndT)
  189.             SendMessage(hwndT, WM_EXECINSTANCE, 0, 0);
  190.  
  191.         return FALSE;
  192.     }
  193.  
  194.     if (!(ghaccelTbl = LoadAccelerators(ghInst, "spy")))
  195.         return FALSE;
  196.  
  197.     ReadRegistry();
  198.  
  199.     gcxBorder = GetSystemMetrics(SM_CXBORDER);
  200.     gcyBorder = GetSystemMetrics(SM_CYBORDER);
  201.  
  202.     //
  203.     // Calculate the counts in the message groups.  This is best
  204.     // done at run time to be safe.
  205.     //
  206.     for (i = 0; i < gcMessages; i++)
  207.     {
  208.         //
  209.         // If this message belongs to a message group,
  210.         // increment the total for that group.
  211.         //
  212.         for (j = 0; j < gcMsgGroups; j++)
  213.         {
  214.             if (gaMsgGroup[j].flMask & gaMsgs[i].Flags)
  215.                 gaMsgGroup[j].cMsgs++;
  216.         }
  217.     }
  218.  
  219.     lstrcpy(gszWindowName,LoadResourceString(IDS_APPLICATION_NAME));
  220.  
  221.     wc.hCursor        = LoadCursor(NULL, IDC_ARROW);
  222.     wc.hIcon          = LoadIcon(hInstance, gszAppName);
  223.     wc.lpszMenuName   = gszAppName;
  224.     wc.lpszClassName  = gszSpyClassName;
  225.     wc.hbrBackground  = (HBRUSH)(COLOR_WINDOW + 1);
  226.     wc.hInstance      = hInstance;
  227.     wc.style          = CS_BYTEALIGNCLIENT;
  228.     wc.lpfnWndProc    = SpyWndProc;
  229.     wc.cbWndExtra     = 0;
  230.     wc.cbClsExtra     = 0;
  231.  
  232.     if (!RegisterClass(&wc))
  233.         return FALSE;
  234.  
  235.     ghwndSpyApp = CreateWindow(gszSpyClassName, gszWindowName,
  236.         WS_OVERLAPPEDWINDOW, 0, 0, 0, 0,
  237.         NULL, NULL, hInstance, NULL);
  238.  
  239.     if (!ghwndSpyApp)
  240.         return FALSE;
  241.  
  242.     if (nCmdShow != SW_SHOWNORMAL)
  243.         gwndpl.showCmd = nCmdShow;
  244.  
  245.     SetWindowPlacement(ghwndSpyApp, &gwndpl);
  246.  
  247.     return TRUE;
  248. }
  249.  
  250.  
  251.  
  252. /*****************************************************************************\
  253. * SpyWndProc
  254. *
  255. * Main window procedure for the spy app.
  256. *
  257. * Arguments:
  258. *    HWND hwnd - handle to the spy window
  259. *    UINT msg - message
  260. *    WPARAM wParam - message parameter
  261. *    LPARAM lParam - message parameter
  262. *
  263. * Returns:
  264. *   The value that the window proc should return, based on the processing
  265. *   of the specific WM_COMMAND message received.
  266. \*****************************************************************************/
  267.  
  268. LRESULT CALLBACK
  269. SpyWndProc(
  270.     HWND hwnd,
  271.     UINT msg,
  272.     WPARAM wParam,
  273.     LPARAM lParam
  274.     )
  275. {
  276.     switch (msg)
  277.     {
  278.         case WM_CREATE:
  279.             MyCreatePrintfWin(hwnd);
  280.             return 0;
  281.  
  282.         case WM_INITMENU:
  283.             if (GetMenu(ghwndSpyApp) == (HMENU)wParam)
  284.                 InitMenu((HMENU)wParam);
  285.  
  286.             break;
  287.  
  288.         case WM_COMMAND:
  289.             return SpyCommand(hwnd, LOWORD(wParam), HIWORD(wParam));
  290.  
  291.         case WM_ACTIVATE:
  292.             /*
  293.              * Set the focus to the printf window if we are being activated.
  294.              */
  295.             if (LOWORD(wParam))
  296.                 SetFocus(ghwndPrintf);
  297.  
  298.             break;
  299.  
  300.         case WM_SIZE:
  301.             /*
  302.              * Size the printf window to fit into the new client area size.
  303.              */
  304.             MoveWindow(ghwndPrintf, -gcxBorder, -gcyBorder,
  305.                 LOWORD(lParam) + (2 * gcxBorder),
  306.                 HIWORD(lParam) + (2 * gcyBorder), TRUE);
  307.             break;
  308.  
  309.         case WM_CLOSE:
  310.             SetSpyHook(FALSE);
  311.  
  312.             if (gfhCom1 != INVALID_HANDLE_VALUE)
  313.                 CloseHandle(gfhCom1);
  314.             if (gfhFile)
  315.                 _lclose(gfhFile);
  316.  
  317.             SendMessage(ghwndSpyHook, WM_CLOSE, 0, 0);
  318.             WriteRegistry();
  319.             WaitForSingleObject(ghHookThread, INFINITE);
  320.             DestroyWindow(ghwndSpyApp);
  321.             break;
  322.  
  323.         case WM_DESTROY:
  324.             PostQuitMessage(0);   /* Kill the main window */
  325.             ghwndSpyApp = NULL;
  326.             ghwndPrintf = NULL;
  327.             break;
  328.  
  329.         case WM_EXECINSTANCE:
  330.             /*
  331.              * another instance of spy has been started.
  332.              */
  333.             if (IsIconic(hwnd))
  334.                 ShowWindow(hwnd,SW_SHOWNORMAL);
  335.  
  336.             SetForegroundWindow(hwnd);
  337.             BringWindowToTop(hwnd);
  338.  
  339.             break;
  340.  
  341.         default:
  342.             return DefWindowProc(hwnd, msg, wParam, lParam);
  343.     }
  344.  
  345.     return 0;
  346. }
  347.  
  348.  
  349.  
  350. /*****************************************************************************\
  351. * InitMenu
  352. *
  353. * This function grays/enables and checks/unchecks the menu items
  354. * appropriately for the given state.
  355. *
  356. * Arguments:
  357. *   HMENU hmenu - The menu handle.
  358. *
  359. * Returns:
  360. *   VOID
  361. \*****************************************************************************/
  362.  
  363. PRIVATE VOID
  364. InitMenu(
  365.     HMENU hmenu
  366.     )
  367. {
  368.     BOOL fEnable = !IsPrintfEmpty();
  369.  
  370.     MyEnableMenuItem(hmenu, MENU_EDIT_CUT, fEnable);
  371.     MyEnableMenuItem(hmenu, MENU_EDIT_COPY, fEnable);
  372.     MyEnableMenuItem(hmenu, MENU_EDIT_CLEAR, fEnable);
  373. }
  374.  
  375.  
  376.  
  377. /*****************************************************************************\
  378. * SpyCommand
  379. *
  380. * Handles thw WM_COMMAND messages for the Spy app.
  381. *
  382. * Arguments:
  383. *   HWND hwnd       - Window handle of the main app window.
  384. *   INT nCmd        - Command value.
  385. *   INT nNotifyCode - The notify code.
  386. *
  387. * Returns:
  388. *   The value that the window proc should return, based on the processing
  389. *   of the specific WM_COMMAND message received.
  390. \*****************************************************************************/
  391.  
  392. PRIVATE LRESULT
  393. SpyCommand(
  394.     HWND hwnd,
  395.     INT nCmd,
  396.     INT nNotifyCode
  397.     )
  398. {
  399.     HMENU hmenu;
  400.  
  401.     switch (nCmd)
  402.     {
  403.         case MENU_SPY_SELECTWINDOW:
  404.             MyDialogBox(DID_SELECTWINDOW, SelectWindowDlgProc);
  405.             break;
  406.  
  407.         case MENU_SPY_ABOUT:
  408.             MyDialogBox(DID_ABOUT, AboutDlgProc);
  409.             break;
  410.  
  411.         case MENU_SPY_EXIT:
  412.             PostMessage(hwnd, WM_CLOSE, 0, 0);
  413.             break;
  414.  
  415.         case MENU_EDIT_CUT:
  416.             if (CopyToClipboard())
  417.                 ClearPrintfWindow(ghwndPrintf);
  418.  
  419.             break;
  420.  
  421.         case MENU_EDIT_COPY:
  422.             CopyToClipboard();
  423.             break;
  424.  
  425.         case MENU_EDIT_CLEAR:
  426.             ClearPrintfWindow(ghwndPrintf);
  427.             break;
  428.  
  429.         case MENU_OPTIONS_MESSAGES:
  430.             MyDialogBox(DID_MESSAGES, MessagesDlgProc);
  431.             break;
  432.  
  433.         case MENU_OPTIONS_FONT:
  434.             SelectFont();
  435.             break;
  436.  
  437.         case MENU_OPTIONS_OUTPUT:
  438.             MyDialogBox(DID_OUTPUT, OutputDlgProc);
  439.             break;
  440.  
  441.         case MENU_START:
  442.             if (SetSpyHook(TRUE))
  443.             {
  444.                 hmenu = GetMenu(hwnd);
  445.                 ModifyMenu(hmenu, MENUPOS_STARTSTOP, MF_BYPOSITION | MF_STRING,
  446.                     MENU_STOP, LoadResourceString(IDS_MENU_STOP));
  447.                 DrawMenuBar(hwnd);
  448.  
  449.                 SetSpyCaption();
  450.             }
  451.  
  452.             break;
  453.  
  454.         case MENU_STOP:
  455.             if (SetSpyHook(FALSE))
  456.             {
  457.                 hmenu = GetMenu(hwnd);
  458.                 ModifyMenu(hmenu, MENUPOS_STARTSTOP, MF_BYPOSITION | MF_STRING,
  459.                     MENU_START, LoadResourceString(IDS_MENU_START));
  460.                 DrawMenuBar(hwnd);
  461.  
  462.                 SetSpyCaption();
  463.             }
  464.  
  465.             break;
  466.     }
  467.  
  468.     return 0;
  469. }
  470.  
  471.  
  472.