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 / misc.c < prev    next >
C/C++ Source or Header  |  1997-10-05  |  13KB  |  507 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: misc.c
  15. *
  16. *   Contains miscellaneous routines for the Windows debugging Spy SDK applet.
  17. *
  18. * Functions:
  19. *
  20. *   ReadRegistry()
  21. *   WriteRegistry()
  22. *   Message()
  23. *   SetSpyCaption()
  24. *   GetWindowName()
  25. *   StripExtension()
  26. *
  27. * Comments:
  28. *
  29. \*****************************************************************************/
  30.  
  31. #include "spy.h"
  32. #include <string.h>
  33.  
  34.  
  35. //
  36. // Registry flags for the "Flags" value.
  37. //
  38. #define REGFLAG_OUTPUTWIN           0x00000001
  39. #define REGFLAG_OUTPUTCOM1          0x00000002
  40. #define REGFLAG_OUTPUTFILE          0x00000004
  41. #define REGFLAG_MSGSUSER            0x00000010
  42. #define REGFLAG_MSGSUNKNOWN         0x00000020
  43.  
  44.  
  45. PRIVATE HKEY ghkeySpy = NULL;
  46. PRIVATE CHAR gszSpyAppKey[] = "Software\\Microsoft\\Spy";
  47. PRIVATE CHAR gszKeyPosition[] = "Position";
  48. PRIVATE CHAR gszKeyFont[] = "Font";
  49. PRIVATE CHAR gszKeyMessages[] = "Messages";
  50. PRIVATE CHAR gszKeyFileName[] = "FileName";
  51. PRIVATE CHAR gszKeyLines[] = "Lines";
  52. PRIVATE CHAR gszKeyFlags[] = "Flags";
  53. PRIVATE CHAR gszDefFileName[] = "spy.log";
  54. PRIVATE BYTE BitTable[8] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
  55.  
  56.  
  57. PRIVATE VOID GetWindowName(HWND hwnd, PSTR sz);
  58. PRIVATE LPSTR StripExtension(LPSTR pszFileName);
  59.  
  60.  
  61.  
  62.  
  63. /*****************************************************************************\
  64. * ReadRegistry
  65. *
  66. * Opens (creates if necessary) the registry key for spy preferences and then
  67. * reads the last saved values.
  68. *
  69. * Arguments:
  70. *    none
  71. *
  72. * Returns:
  73. *    VOID
  74. \*****************************************************************************/
  75.  
  76. VOID
  77. ReadRegistry(
  78.     VOID
  79.     )
  80. {
  81.     LOGFONT lf;
  82.     BYTE abMsgs[128];
  83.     DWORD fFlags;
  84.     HDC hdc;
  85.     INT i;
  86.     DWORD dwType;
  87.     DWORD cbData;
  88.  
  89.     RegCreateKey(HKEY_CURRENT_USER, gszSpyAppKey, &ghkeySpy);
  90.  
  91.     cbData = gwndpl.length = sizeof(gwndpl);
  92.     if (!ghkeySpy || RegQueryValueEx(ghkeySpy, gszKeyPosition, NULL, &dwType,
  93.         (LPVOID)&gwndpl, &cbData) != ERROR_SUCCESS)
  94.     {
  95.         gwndpl.length = 0;
  96.     }
  97.  
  98.  
  99.     //
  100.     // If the spy process is killed while the registry key is open, the
  101.     //  position data can be indeterminant...  Here we catch the case that
  102.     //  the reg. data is not good, and we set sensible defaults.
  103.     //
  104.  
  105.     if (gwndpl.length != sizeof(gwndpl))
  106.     {
  107.  
  108.         gwndpl.length = sizeof(gwndpl);
  109.         gwndpl.flags = 0;
  110.         gwndpl.showCmd = SW_SHOWNORMAL;
  111.         gwndpl.ptMinPosition.x = 0;
  112.         gwndpl.ptMinPosition.y = 0;
  113.         gwndpl.ptMaxPosition.x = 0;
  114.         gwndpl.ptMaxPosition.y = 0;
  115.         gwndpl.rcNormalPosition.left = 10;
  116.         gwndpl.rcNormalPosition.top = 10;
  117.         gwndpl.rcNormalPosition.right =
  118.             10 + (GetSystemMetrics(SM_CXSCREEN) / 3);
  119.         gwndpl.rcNormalPosition.bottom =
  120.             10 + (GetSystemMetrics(SM_CYSCREEN) / 3);
  121.     }
  122.  
  123.     cbData = sizeof(lf);
  124.     if (!ghkeySpy || RegQueryValueEx(ghkeySpy, gszKeyFont, NULL, &dwType,
  125.         (LPVOID)&lf, &cbData) != ERROR_SUCCESS)
  126.     {
  127.         hdc = GetDC(NULL);
  128.         GetObject(GetStockObject(SYSTEM_FONT), sizeof(lf), &lf);
  129.         ReleaseDC(NULL, hdc);
  130.     }
  131.  
  132.     ghfontPrintf = CreateFontIndirect(&lf);
  133.  
  134.     cbData = sizeof(abMsgs);
  135.     if (!ghkeySpy || RegQueryValueEx(ghkeySpy, gszKeyMessages, NULL, &dwType,
  136.         (LPVOID)abMsgs, &cbData) != ERROR_SUCCESS)
  137.     {
  138.         //
  139.         // Select all messages by default
  140.         //
  141.         for (i = 0; i < gcMessages; i++)
  142.         {
  143.             gaMsgs[i].Flags |= MTF_SELECTED;
  144.         }
  145.     }
  146.     else
  147.     {
  148.         for (i = 0; i < gcMessages; i++)
  149.         {
  150.             if (abMsgs[gaMsgs[i].msg >> 3] & BitTable[gaMsgs[i].msg & 0x07])
  151.                 gaMsgs[i].Flags |= MTF_SELECTED;
  152.         }
  153.     }
  154.  
  155.     cbData = MAXSTRING * sizeof(TCHAR);
  156.     if (!ghkeySpy || RegQueryValueEx(ghkeySpy, gszKeyFileName, NULL, &dwType,
  157.         (LPVOID)gszFile, &cbData) != ERROR_SUCCESS)
  158.     {
  159.         lstrcpy(gszFile, gszDefFileName);
  160.     }
  161.  
  162.     cbData = sizeof(DWORD);
  163.     if (!ghkeySpy || RegQueryValueEx(ghkeySpy, gszKeyLines, NULL, &dwType,
  164.         (LPVOID)&gnLines, &cbData) != ERROR_SUCCESS ||
  165.         gnLines > LINES_MAX)
  166.     {
  167.         gnLines = LINES_MAX;
  168.     }
  169.  
  170.     cbData = sizeof(DWORD);
  171.     if (!ghkeySpy || RegQueryValueEx(ghkeySpy, gszKeyFlags, NULL, &dwType,
  172.         (LPVOID)&fFlags, &cbData) != ERROR_SUCCESS)
  173.     {
  174.         gfOutputWin = TRUE;
  175.         gfOutputCom1 = FALSE;
  176.         gfOutputFile = FALSE;
  177.         gfMsgsUser = TRUE;
  178.         gfMsgsUnknown = TRUE;
  179.     }
  180.     else
  181.     {
  182.         if (fFlags & REGFLAG_OUTPUTWIN)
  183.             gfOutputWin = TRUE;
  184.  
  185.         if (fFlags & REGFLAG_OUTPUTCOM1)
  186.             gfOutputCom1 = TRUE;
  187.  
  188.         if (fFlags & REGFLAG_OUTPUTFILE)
  189.             gfOutputFile = TRUE;
  190.  
  191.         if (fFlags & REGFLAG_MSGSUSER)
  192.             gfMsgsUser = TRUE;
  193.  
  194.         if (fFlags & REGFLAG_MSGSUNKNOWN)
  195.             gfMsgsUnknown = TRUE;
  196.     }
  197.  
  198.     if (gfOutputFile)
  199.     {
  200.         gfhFile = _lcreat(gszFile, 0);
  201.         if (gfhFile == (HFILE)-1)        //BUGBUG put up a message here.
  202.             gfhFile = 0;
  203.     }
  204.  
  205.     if (gfOutputCom1)
  206.     {
  207.         gfhCom1 = CreateFile(
  208.                 "com1",
  209.                 GENERIC_WRITE,
  210.                 0,                    // exclusive access
  211.                 NULL,                 // no security attrs
  212.                 OPEN_EXISTING,
  213.                 FILE_ATTRIBUTE_NORMAL,
  214.                 NULL);
  215.     }
  216. }
  217.  
  218.  
  219.  
  220. /*****************************************************************************\
  221. * WriteRegistry
  222. *
  223. * Writes out preference data to the registry when the app exits, then
  224. * closes the registry key.
  225. *
  226. * Arguments:
  227. *    none
  228. *
  229. * Returns:
  230. *    VOID
  231. \*****************************************************************************/
  232.  
  233. VOID
  234. WriteRegistry(
  235.     VOID
  236.     )
  237. {
  238.     LOGFONT lf;
  239.     BYTE abMsgs[128];
  240.     INT i;
  241.     DWORD fFlags;
  242.     WINDOWPLACEMENT wndpl;
  243.  
  244.     if (ghkeySpy)
  245.     {
  246.         wndpl.length = sizeof(WINDOWPLACEMENT);
  247.         GetWindowPlacement(ghwndSpyApp, &wndpl);
  248.         RegSetValueEx(ghkeySpy, gszKeyPosition, 0, REG_BINARY,
  249.             (LPBYTE)&wndpl, sizeof(wndpl));
  250.  
  251.         GetObject(ghfontPrintf, sizeof(lf), &lf);
  252.         RegSetValueEx(ghkeySpy, gszKeyFont, 0, REG_BINARY,
  253.             (LPBYTE)&lf, sizeof(lf));
  254.  
  255.         memset(abMsgs, 0, sizeof(abMsgs));
  256.         for (i = 0; i < gcMessages; i++)
  257.         {
  258.             if (gaMsgs[i].Flags & MTF_SELECTED)
  259.                 abMsgs[gaMsgs[i].msg >> 3] |= BitTable[gaMsgs[i].msg & 0x07];
  260.         }
  261.  
  262.         RegSetValueEx(ghkeySpy, gszKeyMessages, 0, REG_BINARY,
  263.             (LPBYTE)&abMsgs, sizeof(abMsgs));
  264.  
  265.         RegSetValueEx(ghkeySpy, gszKeyFileName, 0, REG_SZ,
  266.             (LPBYTE)gszFile, (lstrlen(gszFile) + 1) * sizeof(TCHAR));
  267.  
  268.         RegSetValueEx(ghkeySpy, gszKeyLines, 0, REG_DWORD,
  269.             (LPBYTE)&gnLines, sizeof(DWORD));
  270.  
  271.         fFlags = 0;
  272.         if (gfOutputWin)
  273.             fFlags |= REGFLAG_OUTPUTWIN;
  274.  
  275.         if (gfOutputCom1)
  276.             fFlags |= REGFLAG_OUTPUTCOM1;
  277.  
  278.         if (gfOutputFile)
  279.             fFlags |= REGFLAG_OUTPUTFILE;
  280.  
  281.         if (gfMsgsUser)
  282.             fFlags |= REGFLAG_MSGSUSER;
  283.  
  284.         if (gfMsgsUnknown)
  285.             fFlags |= REGFLAG_MSGSUNKNOWN;
  286.  
  287.         RegSetValueEx(ghkeySpy, gszKeyFlags, 0, REG_DWORD,
  288.             (LPBYTE)&fFlags, sizeof(DWORD));
  289.  
  290.         RegCloseKey(ghkeySpy);
  291.     }
  292. }
  293.  
  294.  
  295.  
  296. /*****************************************************************************\
  297. * Message
  298. *
  299. * Puts up a message box.
  300. *
  301. * Arguments:
  302. *   UINT fuStyle    - Flags for MessageBox (MB_YESNOCANCEL, etc).
  303. *   LPSTR pszFormat - Format string for the message.
  304. *
  305. * Returns:
  306. *   Whatever MessageBox returns.
  307. *
  308. \*****************************************************************************/
  309.  
  310. INT
  311. Message(
  312.     UINT fuStyle,
  313.     LPSTR pszFormat,
  314.     ...
  315.     )
  316. {
  317.     va_list marker;
  318.     INT RetCode;
  319.     TCHAR szT[MAXSTRING];
  320.  
  321.     va_start(marker, pszFormat);
  322.     wvsprintf(szT, pszFormat, marker);
  323.     RetCode = MessageBox(ghwndSpyApp, szT, gszWindowName, fuStyle|MB_TASKMODAL);
  324.     va_end(marker);
  325.  
  326.     return RetCode;
  327. }
  328.  
  329.  
  330.  
  331. /*****************************************************************************\
  332. * SetSpyCaption
  333. *
  334. * This routine sets the Spy app's caption bar to display info on the window
  335. * that is currently being spy'ed upon.
  336. *
  337. * Arguments:
  338. *    none
  339. *
  340. * Returns:
  341. *    VOID
  342. \*****************************************************************************/
  343.  
  344. VOID
  345. SetSpyCaption(
  346.     VOID
  347.     )
  348. {
  349.     CHAR szText[MAXSTRING];
  350.     CHAR szTemp[MAXSTRING];
  351.  
  352.     if (ghwndSpyingOn != NULL && ghwndSpyingOn != HWND_ALL)
  353.     {
  354.         GetWindowName(ghwndSpyingOn, szTemp);
  355.  
  356.         if (lstrlen(gszWindowName) + lstrlen(szTemp) + 3 > MAXSTRING)
  357.             szTemp[MAXSTRING - 3 - lstrlen(szTemp)] = 0;
  358.  
  359.         if (gfSpyOn)
  360.             wsprintf(szText, "%s - %s", gszWindowName, szTemp);
  361.         else
  362.             wsprintf(szText, "<%s - %s>", gszWindowName, szTemp);
  363.     }
  364.     else
  365.     {
  366.         lstrcpy(szText, gszWindowName);
  367.     }
  368.  
  369.     SetWindowText(ghwndSpyApp, szText);
  370. }
  371.  
  372.  
  373.  
  374. /*****************************************************************************\
  375. * GetWindowName
  376. *
  377. * Builds the name of the window being spy'd on in the specified buffer.
  378. * This will be something like "EXENAME!WindowText" or "EXENAME!Class".
  379. *
  380. * Arguments:
  381. *
  382. *    HWND hwnd - handle to the window being spy'd on.
  383. *    PSTR pstr - pointer to string to return.
  384. *
  385. * Returns:
  386. *    VOID
  387. \*****************************************************************************/
  388.  
  389. PRIVATE VOID
  390. GetWindowName(
  391.     HWND hwnd,
  392.     PSTR sz
  393.     )
  394. {
  395.     PSTR szSave = sz;
  396.  
  397.     if (hwnd != NULL && IsWindow(hwnd))
  398.     {
  399. #if 0
  400.         // THIS DOES NOT WORK ON NT SINCE HINST'S ARE NOT GLOBAL
  401.  
  402.         HINSTANCE hinst;
  403.  
  404.         SetLastError(0);
  405.         hinst = (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE);
  406.         GetLastError();
  407.  
  408.         /*
  409.          * Get the module name
  410.          */
  411. #ifdef JAPAN
  412.         //DBCS_FIX
  413.         if (GetModuleFileName((HANDLE)GetWindowLong(hwnd, GWL_HINSTANCE),
  414.             sz, MAXSTRING)) {
  415.             //Probably this function will fail on NT
  416. #else
  417.         SetLastError(0);
  418.         GetModuleFileName(hinst, sz, MAXSTRING);
  419.         GetLastError();
  420. #endif
  421.         lstrcpy(sz, StripExtension(sz));
  422.  
  423.         sz += lstrlen(sz);
  424.         *sz++ = '!';
  425. #ifdef Japan
  426.         }
  427. #endif
  428.         *sz = 0;
  429.  
  430.         GetWindowText(hwnd, sz, MAXSTRING - (sz - szSave));
  431. #else // !0
  432.         GetWindowText(hwnd, sz, MAXSTRING);
  433. #endif
  434.  
  435.         /*
  436.          * If the window has no caption string then use the Class name
  437.          */
  438.         if (*sz == 0)
  439.             GetClassName(hwnd, sz, MAXSTRING - (sz - szSave));
  440.     }
  441.     else
  442.     {
  443.         *sz = 0;
  444.     }
  445. }
  446.  
  447.  
  448.  
  449. /*****************************************************************************\
  450. * StripExtension
  451. *
  452. *   Strips the extension off of a filename.
  453. *
  454. * Arguments:
  455. *   LPSTR pszFileName - File name to process.
  456. *
  457. * Returns:
  458. *   Returns a pointer to the beginning of the filename.  The extension
  459. *   will have been stripped off.
  460. *
  461. \*****************************************************************************/
  462.  
  463. PRIVATE LPSTR
  464. StripExtension(
  465.     LPSTR pszFileName
  466.     )
  467. {
  468.     LPSTR p = pszFileName;
  469.  
  470.     while (*p)
  471.         p++;
  472.  
  473.     while (p > pszFileName && *p != '\\' && *p != ':') {
  474.         p = CharPrev(pszFileName, p);
  475.         if (*p == '.') {
  476.             *p = 0;
  477.         }
  478.     }
  479.     if (*p == '\\' || *p == ':') {
  480.         p++;
  481.     }
  482.     return p;
  483. }
  484.  
  485.  
  486. /*****************************************************************************\
  487. * LoadResourceString
  488. *
  489. *   Loads a resource string from SPY and returns a pointer to the string.
  490. *
  491. * Arguments:
  492. *   wId        - resource string id
  493. *
  494. * Returns:
  495. *   Returns a pointer to the string.
  496. *
  497. \*****************************************************************************/
  498. LPTSTR
  499. LoadResourceString( UINT wId )
  500. {
  501.     static TCHAR lpBuf[1024];
  502.  
  503.     LoadString( GetModuleHandle(NULL), wId, lpBuf, sizeof(lpBuf) );
  504.  
  505.     return lpBuf;
  506. }
  507.