home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / os2sdk / os2sdk12 / spy / window.c < prev   
Encoding:
C/C++ Source or Header  |  1990-07-10  |  26.4 KB  |  823 lines

  1. /***************************************************************************\
  2. * window.c - Spy Window dialog functions
  3. *
  4. * Created by Microsoft Corporation, 1989
  5. \***************************************************************************/
  6.  
  7. #define    INCL_WINDIALOGS
  8. #define    INCL_WINHEAP            /* needed for spy.h */
  9. #define    INCL_WININPUT
  10. #define    INCL_WINLISTBOXES
  11. #define    INCL_WINMESSAGEMGR
  12. #define    INCL_WINPOINTERS        /* needed for spy.h */
  13. #define    INCL_WINWINDOWMGR
  14. #include <os2.h>
  15. #include <stdio.h>
  16. #include <string.h>
  17. #include "spy.h"
  18. #include "spyhook.h"
  19. #include <time.h>
  20. #include <stdlib.h>
  21.  
  22.  
  23. /* Forward Declarations */
  24. void    InitWindowList(HWND, HWND, int);
  25. void    BuildWindowWatchList(void);
  26. void    DisplayWindowInfo(HWND, HWND);
  27. void    SelectWindowFromText(HWND);
  28. SHORT   DumpWindowInfo(HWND, SHORT);
  29. int cdecl    CompareHwnds(const void *, const void *);
  30. MRESULT    EXPENTRY SpyWindowsDlgProc(HWND, USHORT, MPARAM, MPARAM);
  31.  
  32.  
  33.  
  34.  
  35. /***************************************************************************\
  36. * MRESULT EXPENTRY SpyWindowsDlgProc(hwnd, msg, mp1, mp2)
  37. *
  38. * The Spy Windows Dialog procedure
  39. \***************************************************************************/
  40. MRESULT EXPENTRY SpyWindowsDlgProc(hwnd, msg, mp1, mp2)
  41. HWND hwnd;
  42. USHORT msg;
  43. MPARAM mp1;
  44. MPARAM mp2;
  45. {
  46.     BOOL        fSelect = TRUE;
  47.     SHORT       cWindows;
  48.     HWND        hwndPoint;
  49.     HWND        hwndItem;   /* from handle of list item */
  50.     USHORT      iItemFocus; /* Index to item that has the focus */
  51.  
  52.     switch (msg) {
  53.  
  54.     case WM_INITDLG:
  55.         /* Initialize the dialog items */
  56.         hwndWindowLB = WinWindowFromID(hwnd, DID_WINDOWLIST);
  57.         InitWindowList(hwnd, HWND_DESKTOP, 0);
  58.         InitWindowList(hwnd, HWND_OBJECT, -10);
  59.         hwndWinDlgDisp = NULL;
  60.         fTrackingListBox = TRUE;
  61.         break;
  62.  
  63.     case WM_CHAR:
  64.         /*
  65.          * Handle VK_ENTER and VK_NEWLINE if our Edit control has
  66.          * the focus and it is a keydown
  67.          */
  68.         if (!(SHORT1FROMMP(mp1) & KC_KEYUP) &&
  69.                 (SHORT1FROMMP(mp1) & KC_VIRTUALKEY) &&
  70.                 ( (SHORT2FROMMP(mp2) == VK_ENTER) ||
  71.                   (SHORT2FROMMP(mp2) == VK_NEWLINE) )) {
  72.  
  73.  
  74.             if (WinQueryFocus(HWND_DESKTOP, FALSE) ==
  75.                     WinWindowFromID(hwnd, DID_WHANDLE)) {
  76.                 SelectWindowFromText(hwnd);
  77.                 break;
  78.             }
  79.         }
  80.  
  81.         /* Normaly pass to dialog procedure to handle message */
  82.         return(WinDefDlgProc(hwnd, msg, mp1, mp2));
  83.         break;
  84.  
  85.     case WM_COMMAND:
  86.         switch (SHORT1FROMMP(mp1)) {
  87.         case DID_OK:
  88.             BuildWindowWatchList();
  89.         case DID_CANCEL:
  90.             /* Now dismiss the dialog */
  91.             WinDismissDlg(hwnd, SHORT1FROMMP(mp1));
  92.             break;
  93.         case DID_WUNSELALL:
  94.             fSelect = FALSE;
  95.         case DID_WSELALL:
  96.             cWindows = SHORT1FROMMR( WinSendMsg(hwndWindowLB, LM_QUERYITEMCOUNT,
  97.                 0L, 0L));
  98.  
  99.             fTrackingListBox = FALSE;
  100.             while (cWindows) {
  101.                 /* Loop through all windows, selecting or unselcting all */
  102.                 WinSendMsg(hwndWindowLB, LM_SELECTITEM, (MPARAM)--cWindows,
  103.                     (MPARAM)fSelect);
  104.             }
  105.             fTrackingListBox = TRUE;
  106.             break;
  107.  
  108.         case DID_WSELMOUSE:
  109.             /* Call function to track mouse, returns window handle */
  110.             hwndPoint = HwndSelWinWithMouse(hwnd, DisplayWindowInfo);
  111.             if (hwndPoint == NULL)
  112.         break;    /* No window to process */
  113.  
  114.             /*
  115.              * Now find the window in the list, Make the item visible
  116.              * and set the item as selected.
  117.              */
  118.             cWindows = SHORT1FROMMR(WinSendMsg(hwndWindowLB, LM_QUERYITEMCOUNT,
  119.                     0L, 0L));
  120.  
  121.             while (cWindows) {
  122.                 /*
  123.                  * Loop through all windows until we wind the right
  124.                  * one with the correct window handle
  125.                  */
  126.                 hwndItem = (HWND)WinSendMsg(hwndWindowLB, LM_QUERYITEMHANDLE,
  127.                         (MPARAM)--cWindows, 0L);
  128.  
  129.                 if (hwndItem == hwndPoint) {
  130.                     /* found the right item, move it to top */
  131.                     WinSendMsg(hwndWindowLB, LM_SETTOPINDEX, (MPARAM)cWindows, 0L);
  132.                     WinSendMsg(hwndWindowLB, LM_SELECTITEM, (MPARAM)cWindows,
  133.                             (MPARAM)TRUE);
  134.                     break;
  135.                 }
  136.             }
  137.             break;
  138.  
  139.         }
  140.         break;
  141.  
  142.  
  143.     default:
  144.         /*
  145.          * Default is to see if the listbox has changed its focus
  146.          * item number.  If it has, then we want to display the information
  147.          * about the window that the listbox cursor is over.  There is no
  148.          * legal way to do this, One approach appears to temporary set the
  149.          * listbox to be a single selection listbox, then query its selection
  150.          * and set it back into multiple selection mode.
  151.          */
  152.         if (fTrackingListBox && hwndWindowLB != NULL) {
  153.  
  154.             WinSetWindowBits(hwndWindowLB, QWL_STYLE, 0L, LS_MULTIPLESEL);
  155.             iItemFocus = SHORT1FROMMR(WinSendMsg(hwndWindowLB, LM_QUERYSELECTION,
  156.                     (MPARAM)LIT_FIRST, 0L));
  157.             WinSetWindowBits(hwndWindowLB, QWL_STYLE, LS_MULTIPLESEL,
  158.                     LS_MULTIPLESEL);
  159.  
  160.             if (iItemFocus != iCurItemFocus) {
  161.                 iCurItemFocus = iItemFocus;
  162.                 if (iItemFocus != (USHORT)-1) {
  163.  
  164.                     hwndItem = (HWND)WinSendMsg(hwndWindowLB, LM_QUERYITEMHANDLE,
  165.                             (MPARAM)iItemFocus, 0L);
  166.                     DisplayWindowInfo(hwnd, hwndItem);
  167.                 }
  168.             }
  169.         }
  170.         return(WinDefDlgProc(hwnd, msg, mp1, mp2));
  171.     }
  172.     return 0L;
  173. }
  174.  
  175.  
  176.  
  177.  
  178. /***************************************************************************\
  179. * void SelectWindowFromText(hwndDlg)
  180. *
  181. *   Updates the text that is displayed in the message text line
  182. \***************************************************************************/
  183. void SelectWindowFromText(hwndDlg)
  184. HWND    hwndDlg;
  185. {
  186.     char    szTemp[80];
  187.     HWND    hwndSelect;
  188.     SHORT   cItems;
  189.     SHORT   i;
  190.  
  191.  
  192.     /* First get the edit text from the string */
  193.     WinQueryDlgItemText(hwndDlg, DID_WHANDLE, sizeof(szTemp),
  194.             (PSZ)szTemp);
  195.  
  196.     hwndSelect = (HWND)UConvertStringToNum(szTemp);
  197.  
  198.     cItems =SHORT1FROMMR(WinSendMsg(hwndWindowLB, LM_QUERYITEMCOUNT,
  199.             0L, 0L));
  200.  
  201.     for (i=0; i < cItems; i++) {
  202.         if ((HWND)WinSendMsg(hwndWindowLB, LM_QUERYITEMHANDLE,
  203.                 (MPARAM)i, 0L) == hwndSelect)
  204.             break;  /* found it */
  205.     }
  206.  
  207.     if (i < cItems) {
  208.         /*
  209.          * found the hwnd, bring to top, and select it
  210.          */
  211.         WinSendMsg(hwndWindowLB, LM_SETTOPINDEX,
  212.                 MPFROMSHORT(i),  (MPARAM)0L);
  213.  
  214.         /* Always set it on */
  215.         WinSendMsg(hwndWindowLB, LM_SELECTITEM,
  216.                 MPFROMSHORT(i), MPFROMSHORT(TRUE));
  217.  
  218.     } else {
  219.         WinAlarm(HWND_DESKTOP, WA_WARNING);
  220.         WinSetDlgItemText(hwndDlg, DID_WHANDLE, (PSZ)"");
  221.     }
  222.  
  223. }
  224.  
  225.  
  226. /****************************************************************************\
  227. * InitWindowList (hwndDialog, hwnd, level)
  228. *
  229. * Builds the list of windows displayed in the windows dialog
  230. \***************************************************************************/
  231. void InitWindowList(hwndDialog, hwnd, level)
  232. HWND    hwndDialog;
  233. HWND    hwnd;
  234. int     level;
  235. {
  236.     char    szTemp[30];
  237.     char    szId[20];
  238.     HWND    hwndT;
  239.     USHORT  item;
  240.     USHORT  id;
  241.     int     i;
  242.  
  243.     /*
  244.      * We will first add this item to our list of
  245.      * items in the listbox, If the item is in our list of hwnds,
  246.      * set the item selected. To keep from getting into endless loops
  247.      * will not add spywindow client, and descendants.
  248.      */
  249.     if (hwnd != hwndSpy) {
  250.         id = (USHORT)WinQueryWindowUShort(hwnd, QWS_ID);
  251.         sprintf(szId, "ID: %x", id);
  252.  
  253.         for (i = 0; i < cToName; i++) {
  254.             if (id == rgidtoname[i].id) {
  255.                 strcpy (szId, rgidtoname[i].szIdName);
  256.                 break;
  257.             }
  258.         }
  259.  
  260.         sprintf(szTemp, "%04x(%d) - %s", (USHORT)(ULONG)hwnd, level, szId);
  261.         item = SHORT1FROMMR(WinSendMsg(hwndWindowLB, LM_INSERTITEM,
  262.                 (MPARAM)LIT_END, (MPARAM)(PSZ)szTemp));
  263.  
  264.         /* Set the item handle to the handle of the window */
  265.         WinSendMsg(hwndWindowLB, LM_SETITEMHANDLE, (MPARAM)item,
  266.                 (MPARAM)hwnd);
  267.  
  268.         if (SpyFWindowInList(hwnd, TRUE))
  269.             WinSendMsg(hwndWindowLB, LM_SELECTITEM, (MPARAM)item,
  270.                 (MPARAM)TRUE);
  271.  
  272.         /*
  273.          * Then we recurse with all of our children
  274.          */
  275.         if ((hwndT = WinQueryWindow(hwnd, QW_TOP, FALSE)) != NULL)
  276.             InitWindowList(hwndDialog, hwndT, level+1);
  277.     }
  278.  
  279.     /*
  280.      * Then go to our next sibling
  281.      */
  282.     if ((hwndT = WinQueryWindow(hwnd, QW_NEXT, FALSE)) != NULL)
  283.         InitWindowList(hwndDialog, hwndT, level);
  284. }
  285.  
  286.  
  287.  
  288. /***************************************************************************\
  289. * BuildWindowWatchList()
  290. *
  291. * Updates the list of windows to be watched from the listbox
  292. \***************************************************************************/
  293. void BuildWindowWatchList(void)
  294. {
  295.  
  296.     USHORT  itemPrevious;
  297.     USHORT  item;
  298.     HWND    hwnd;
  299.  
  300.     SHORT   chwnd;
  301.     HWND    rghwnd[MAXHWNDS];
  302.  
  303.     /*
  304.      * Simply loop through asking for the next selected item in the
  305.      * list.  Make sure not to overrun our list.
  306.      */
  307.     itemPrevious = (USHORT)LIT_FIRST;
  308.     chwnd = 0;
  309.  
  310.     while ((item = SHORT1FROMMR(WinSendMsg(hwndWindowLB, LM_QUERYSELECTION,
  311.             (MPARAM)itemPrevious, 0L))) != (USHORT)LIT_NONE) {
  312.         /*
  313.          * Get the items handle, which has the value of the window handle
  314.          */
  315.         hwnd = (HWND)WinSendMsg(hwndWindowLB, LM_QUERYITEMHANDLE,
  316.                 (MPARAM)item, 0L);
  317.  
  318.         rghwnd[chwnd++] = hwnd;
  319.         if (chwnd >= MAXHWNDS)
  320.             break;  /* Dont overflow array */
  321.         itemPrevious = item;    /* Where to cointinue the search */
  322.     }
  323.  
  324.     SpySetWindowList (chwnd, rghwnd);
  325. }
  326.  
  327.  
  328. /***************************************************************************\
  329. * HWND HwndSelWinWithMouse(HWND hwnd, void (*pfnDisplayInfo)(HWND, HWND))
  330. *
  331. *         This function is used to allow the user to select a window with
  332. *           the mouse.  If fDisplayInfo is TRUE, it will update the
  333. *           information in the dialog box, about the window that the
  334. *           mouse is currently over.
  335. \***************************************************************************/
  336. HWND HwndSelWinWithMouse(hwnd, pfnDisplayInfo)
  337. HWND hwnd;
  338. void (*pfnDisplayInfo)(HWND, HWND);
  339. {
  340.  
  341.     QMSG        qmsg;
  342.     HWND        hwndPoint;
  343.     char        szClassName[50];    /* Class name of window */
  344.     CLASSINFO   classinfo;          /* Information about class */
  345.  
  346.  
  347.     /*
  348.      * First set the capture to the specified window
  349.      */
  350.     WinSetCapture(HWND_DESKTOP, hwnd);
  351.     WinSetPointer (HWND_DESKTOP, hptrSelWin);
  352.  
  353.     /*
  354.      * Now loop through all of the messages that are sent, until
  355.      * we get our mouse 1 down message.  We will also filter out
  356.      * the WM_MOVE message, else we will dispatch the messages.
  357.      */
  358.     while (WinGetMsg(hab, &qmsg, NULL, 0, 0)) {
  359.         if (qmsg.msg == WM_MOUSEMOVE) {
  360.             if (pfnDisplayInfo != NULL) {
  361.                 hwndPoint = WinWindowFromPoint(HWND_DESKTOP,
  362.                     &qmsg.ptl, TRUE, FALSE);
  363.                 (*pfnDisplayInfo)(hwnd, hwndPoint);
  364.             }
  365.         }
  366.         else if (qmsg.msg == WM_BUTTON1DOWN)
  367.             break;
  368.         else
  369.             WinDispatchMsg(hab, &qmsg);
  370.     }
  371.  
  372.     WinSetPointer (HWND_DESKTOP, hptrArrow);
  373.     WinSetCapture(HWND_DESKTOP, NULL);
  374.  
  375.  
  376.     /*
  377.      * Map the point to the window,  If the CTRL-Key is down,
  378.      * we will go up through the parent chain until we get to
  379.      * a frame window or desktop.  Dont let hwndSpy through!!!
  380.      */
  381.     hwndPoint = WinWindowFromPoint(HWND_DESKTOP,
  382.         &qmsg.ptl, TRUE, FALSE);
  383.     if (WinGetKeyState(HWND_DESKTOP, VK_CTRL) & 0x8000) {
  384.         /* Asked for frame window */
  385.         for (;;) {
  386.             if (hwndPoint == NULL)
  387.                 return (NULL);         /* No frames available */
  388.             /* See if frame class */
  389.             WinQueryClassName(hwndPoint, sizeof(szClassName),
  390.                 (PSZ)szClassName);
  391.             if (WinQueryClassInfo(hab, (PSZ)szClassName, &classinfo) &&
  392.                     (classinfo.flClassStyle & CS_FRAME))
  393.                 break;  /* We have our frame */
  394.  
  395.             /* Not frame, go back to parent */
  396.             hwndPoint = WinQueryWindow(hwndPoint, QW_PARENT, FALSE);
  397.         }
  398.     }
  399.  
  400.     if (pfnDisplayInfo != NULL)
  401.         (*pfnDisplayInfo)(hwnd, hwndPoint);
  402.  
  403.     if (WinIsChild(hwndPoint, hwndSpy))
  404.         return (NULL);    /* Dont want to get in endless loops */
  405.  
  406.     return (hwndPoint);
  407. }
  408.  
  409.  
  410.  
  411. /***************************************************************************\
  412. * DisplayWindowInfo(HWND hwndDialog, HWND hwnd)
  413. *
  414. * Displays the information about the selected window in the dialog
  415. \***************************************************************************/
  416. void DisplayWindowInfo(hwndDlg, hwnd)
  417. HWND            hwndDlg;
  418. HWND            hwnd;
  419. {
  420.     HWND        hwndT;
  421.     HWND        hwndParent;
  422.     char        szTemp[50];
  423.     char        szTemp2[10];
  424.     CLASSINFO   classinfo;
  425.     RECTL       rcl;
  426.     USHORT      id;
  427.     ULONG       ul;
  428.     USHORT      us1;
  429.     USHORT      us2;
  430.     USHORT      us3;
  431.     USHORT      us4;
  432.     PID         pidWindow;
  433.     TID         tidWindow;
  434.  
  435.  
  436.     if (hwnd != hwndWinDlgDisp)
  437.     {
  438.         hwndWinDlgDisp = hwnd;
  439.  
  440.         /* This could be table driven */
  441.         sprintf(szTemp, "0x%04x", (SHORT)(ULONG) hwnd);
  442.         WinSetDlgItemText(hwndDlg, DID_WHANDLE, (PSZ)szTemp);
  443.  
  444.         WinQueryClassName(hwnd, sizeof(szTemp), (PSZ)szTemp);
  445.         if (!WinQueryClassInfo(hab, (PSZ)szTemp, &classinfo)) {
  446.             classinfo.flClassStyle = -1;    /* Let know error conditon */
  447.             classinfo.cbWindowData = 0;     /* Make sure we dont dump */
  448.         }
  449.  
  450.         WinSetDlgItemText(hwndDlg, DID_WCLASS, (PSZ)szTemp);
  451.  
  452.  
  453.         /*
  454.          * Warning, we only query the text if the window is not an object
  455.          * window.  If it is an object window, the message queue may not
  456.          * be processing messages, which could hang us
  457.          */
  458.         if (WinIsChild(hwnd, HWND_OBJECT))
  459.             szTemp[0] = '\0';   /* No text available */
  460.         else
  461.             WinQueryWindowText(hwnd, sizeof(szTemp), (PSZ)szTemp);
  462.         WinSetDlgItemText(hwndDlg, DID_WTEXT, (PSZ)szTemp);
  463.  
  464.         hwndParent = WinQueryWindow(hwnd, QW_PARENT, FALSE);
  465.         sprintf(szTemp, "0x%04x", (SHORT)(LONG)hwndParent);
  466.         WinSetDlgItemText(hwndDlg, DID_WPARENT, (PSZ)szTemp);
  467.  
  468.         hwndT = WinQueryWindow(hwnd, QW_TOP, FALSE);
  469.         sprintf(szTemp, "0x%04x", (SHORT)(LONG) hwndT);
  470.         WinSetDlgItemText(hwndDlg, DID_WCHILD, (PSZ)szTemp);
  471.  
  472.         hwndT = WinQueryWindow(hwnd, QW_OWNER, FALSE);
  473.         sprintf(szTemp, "0x%04x", (SHORT)(LONG) hwndT);
  474.         WinSetDlgItemText(hwndDlg, DID_WOWNER, (PSZ)szTemp);
  475.  
  476.         WinQueryWindowRect(hwnd, &rcl);
  477.         WinMapWindowPoints(hwnd, hwndParent, (PPOINTL)&rcl, 2);
  478.         sprintf(szTemp, "(%d, %d), (%d, %d)", (SHORT)rcl.xLeft,
  479.             (SHORT)rcl.yBottom, (SHORT)rcl.xRight, (SHORT)rcl.yTop);
  480.         WinSetDlgItemText(hwndDlg, DID_WRECT, (PSZ)szTemp);
  481.  
  482.         id = (USHORT)WinQueryWindowUShort(hwnd, QWS_ID);
  483.         sprintf(szTemp, "0x%04x", id);
  484.         WinSetDlgItemText(hwndDlg, DID_WID, (PSZ)szTemp);
  485.  
  486.         ul = (ULONG)WinQueryWindowULong(hwnd, QWL_STYLE);
  487.         sprintf(szTemp, "0x%08lx", ul);
  488.         WinSetDlgItemText(hwndDlg, DID_WSTYLE, (PSZ)szTemp);
  489.  
  490.         sprintf(szTemp, "0x%08lx", classinfo.flClassStyle);
  491.         WinSetDlgItemText(hwndDlg, DID_WCSTYLE, (PSZ)szTemp);
  492.  
  493.         ul = (ULONG)WinQueryWindowULong(hwnd, QWP_PFNWP);
  494.         sprintf(szTemp, "%p", ul);
  495.         WinSetDlgItemText(hwndDlg, DID_WPFNWP, (PSZ)szTemp);
  496.  
  497.         ul = (ULONG)WinQueryWindowULong(hwnd, QWL_HMQ);
  498.         sprintf(szTemp, "0x%04x", (SHORT)ul);
  499.         WinSetDlgItemText(hwndDlg, DID_WHMQ, (PSZ)szTemp);
  500.  
  501.         WinQueryWindowProcess(hwnd, &pidWindow, &tidWindow);
  502.         sprintf(szTemp, "%d", (SHORT)pidWindow);
  503.         WinSetDlgItemText(hwndDlg, DID_WPID, (PSZ)szTemp);
  504.         sprintf(szTemp, "%d", (SHORT)tidWindow);
  505.         WinSetDlgItemText(hwndDlg, DID_WTID, (PSZ)szTemp);
  506.  
  507.         /*
  508.          * We have four General purpose lines left, used only for
  509.          * frames now
  510.          */
  511.         if ((classinfo.flClassStyle & CS_FRAME) &&
  512.                     (classinfo.cbWindowData > QWL_HWNDFOCUSSAVE)) {
  513.             ul = (ULONG)WinQueryWindowULong(hwnd, QWL_HWNDFOCUSSAVE);
  514.             sprintf(szTemp, "Frame Focus: %p",ul);
  515.             WinSetDlgItemText(hwndDlg, DID_WOLINE1, (PSZ)szTemp);
  516.  
  517.             us1 = (USHORT)WinQueryWindowUShort(hwnd, QWS_FLAGS);
  518.             us2 = (USHORT)WinQueryWindowUShort(hwnd, QWS_RESULT);
  519.             sprintf(szTemp, "Flags: 0x%04x Rslt: 0x%04x", us1, us2);
  520.             WinSetDlgItemText(hwndDlg, DID_WOLINE2, (PSZ)szTemp);
  521.  
  522.             us1 = (USHORT)WinQueryWindowUShort(hwnd, QWS_XRESTORE);
  523.             us2 = (USHORT)WinQueryWindowUShort(hwnd, QWS_YRESTORE);
  524.             us3 = (USHORT)WinQueryWindowUShort(hwnd, QWS_CXRESTORE);
  525.             us4 = (USHORT)WinQueryWindowUShort(hwnd, QWS_CYRESTORE);
  526.             sprintf(szTemp, "Restore: (%d, %d, %d, %d)",us1, us2, us3, us4);
  527.             WinSetDlgItemText(hwndDlg, DID_WOLINE3, (PSZ)szTemp);
  528.  
  529.             us1 = (USHORT)WinQueryWindowUShort(hwnd, QWS_XMINIMIZE);
  530.             us2 = (USHORT)WinQueryWindowUShort(hwnd, QWS_YMINIMIZE);
  531.             sprintf(szTemp, "Minimize: (%d, %d)",us1, us2);
  532.             WinSetDlgItemText(hwndDlg, DID_WOLINE4, (PSZ)szTemp);
  533.         } else {
  534.             /*
  535.              * Nothing special to output for this window type, so lets
  536.              * dump the window extra words.
  537.              * Note: This code is sh.ty
  538.              */
  539.             us1 = 0;    /* Word offset */
  540.             for (id=DID_WOLINE1; id <= DID_WOLINE4; id++) {
  541.                 szTemp[0] = '\0';
  542.                 for (us2 = 0; us2 < 4; us2++) {
  543.                     if (us1 >= classinfo.cbWindowData)
  544.                         break;
  545.                     us3 = (USHORT)WinQueryWindowUShort(hwnd, us1);
  546.                     sprintf(szTemp2, "%04x ", us3);
  547.                     strcat(szTemp, szTemp2);
  548.                     us1 += 2;   /* Setup for next word */
  549.                 }
  550.  
  551.                 /* output this line */
  552.                 WinSetDlgItemText(hwndDlg, id, (PSZ)szTemp);
  553.             }
  554.         }
  555.     }
  556. }
  557.  
  558.  
  559.  
  560.  
  561. /***************************************************************************\
  562. * DumpOneWindowInfo()
  563. *
  564. * Dump the information about one window to the current outputs
  565. \***************************************************************************/
  566. void    DumpOneWindowInfo()
  567. {
  568.     HWND        hwndPoint;
  569.     HWND        hwndT;
  570.     SHORT       wLevel;
  571.  
  572.     hwndPoint = HwndSelWinWithMouse(hwndSpy, NULL);
  573.     if (hwndPoint == NULL)
  574.         return;    /* No window selected */
  575.  
  576.     /* Now see what level the window is at */
  577.     wLevel = 0;
  578.     hwndT = hwndPoint;
  579.     while (hwndT != NULL) {
  580.         wLevel++;
  581.         hwndT = WinQueryWindow(hwndT, QW_PARENT, FALSE);
  582.     };
  583.  
  584.  
  585.     DumpWindowInfo(hwndPoint, wLevel);
  586. }
  587.  
  588.  
  589. /****************************************************************************\
  590. * DumpAllWIndowsInfo (HWND hwnd, WORD wLevel)
  591. *
  592. * Dumps the complet window list out to the current output units.
  593. \***************************************************************************/
  594. SHORT DumpAllWindowsInfo(hwnd, wLevel)
  595. HWND    hwnd;
  596. SHORT   wLevel;
  597. {
  598.     HWND    hwndT;
  599.     SPWD    *pspwdT;
  600.     SHORT   cWindowBytes;
  601.  
  602.     pspwdT = pspwd + wDumpCount;
  603.  
  604.     cWindowBytes = DumpWindowInfo(hwnd, wLevel);
  605.  
  606.     pspwdT->hwnd = hwnd;
  607.     pspwdT->index = wDumpCount;
  608.  
  609.  
  610.     /*
  611.      * Then we recurse with all of our children
  612.      */
  613.     if ((hwndT = WinQueryWindow(hwnd, QW_TOP, FALSE)) != NULL)
  614.         cWindowBytes += DumpAllWindowsInfo(hwndT, wLevel+1);
  615.  
  616.     /*
  617.      * Then go to our next sibling
  618.      */
  619.     if ((hwndT = WinQueryWindow(hwnd, QW_NEXT, FALSE)) != NULL)
  620.         cWindowBytes += DumpAllWindowsInfo(hwndT, wLevel);
  621.  
  622.     return (cWindowBytes);
  623. }
  624.  
  625.  
  626.  
  627. /****************************************************************************\
  628. * DumpWindowIndex (void)
  629. *
  630. * Dump a sorted list of Hwnds and index into other list
  631. \***************************************************************************/
  632. void    DumpWindowIndex(cBytes)
  633. SHORT   cBytes;
  634. {
  635.     SHORT   cch;
  636.     char    szTemp[20];
  637.     char    szOutput[100];
  638.     SPWD    *pspwdT;
  639.     SHORT   i;
  640.  
  641.     /* Sort the hwnds first */
  642.     qsort((void *)pspwd, wDumpCount, sizeof(SPWD), CompareHwnds);
  643.     pspwdT = pspwd;
  644.  
  645.     strcpy (szOutput, "Index of Window Handles");
  646.     cch = strlen(szOutput);
  647.     for (i=0; i< wDumpCount; i++) {
  648.         if ((i & 3) == 0) {
  649.             /* 4 per row */
  650.             OutputString(szOutput, cch);
  651.             szOutput[0] = '\0';
  652.             cch = 0;
  653.         }
  654.  
  655.         cch += sprintf(szTemp, "%3d-%04x ",
  656.                 pspwdT->index,    (USHORT)(ULONG) pspwdT->hwnd);
  657.         strcat (szOutput, szTemp);
  658.         pspwdT++;
  659.     }
  660.  
  661.     OutputString(szOutput, cch);
  662.  
  663.     cch = sprintf(szOutput, "Number of Windows: %d, Approx heap size: %d",
  664.             wDumpCount, cBytes);
  665.     OutputString(szOutput, cch);
  666.  
  667.  
  668. }
  669.  
  670.  
  671. /****************************************************************************\
  672. * int  CompareHwnds(SPWD *pspwd1, SPWD *pspwd2)
  673. *
  674. * Compares two window handles
  675. \***************************************************************************/
  676. int  cdecl CompareHwnds(pspwd1, pspwd2)
  677. const void    *pspwd1;
  678. const void    *pspwd2;
  679. {
  680.     return (((SPWD *)pspwd1)->hwnd < ((SPWD *)pspwd2)->hwnd)? -1 : 1;
  681. }
  682.  
  683.  
  684.  
  685.  
  686. /***************************************************************************\
  687. * DumpWindowInfo(HWND hwnd, SHORT wLevel)
  688. *
  689. * Displays the information about the selected window in the dialog
  690. \***************************************************************************/
  691. SHORT DumpWindowInfo(hwnd, wLevel)
  692. HWND        hwnd;
  693. SHORT       wLevel;
  694. {
  695.     HWND    hwndParent;
  696.     HWND    hwndChild;
  697.     HWND    hwndOwner;
  698.  
  699.     char    szTemp[100];
  700.     char    szTemp2[20];
  701.     SHORT   cch;
  702.     char    szClass[30];
  703.     RECTL   rcl;
  704.     USHORT  id;
  705.     ULONG   ulStyle;
  706.     ULONG   ulPFNWP;
  707.     ULONG   ulHMQ;
  708.     SHORT   wOffsetClassData;
  709.     SHORT   wWindowWord;
  710.     PID     pidWindow;
  711.     TID     tidWindow;
  712.  
  713.     CLASSINFO   classinfo;
  714.  
  715.     hwndParent = WinQueryWindow(hwnd, QW_PARENT, FALSE);
  716.     hwndChild = WinQueryWindow(hwnd, QW_TOP, FALSE);
  717.     hwndOwner = WinQueryWindow(hwnd, QW_OWNER, FALSE);
  718.     id = (USHORT)WinQueryWindowUShort(hwnd, QWS_ID);
  719.     ulHMQ = (ULONG)WinQueryWindowULong(hwnd, QWL_HMQ);
  720.     WinQueryWindowRect(hwnd, &rcl);
  721.     WinMapWindowPoints(hwnd, hwndParent, (PPOINTL)&rcl, 2);
  722.  
  723.     cch = sprintf(szTemp,
  724.         "%d-H:%04x(%d) P:%04x C:%04x O:%04x ID:%04x MQ:%04x (%d, %d) (%d, %d)",
  725.         ++wDumpCount, (SHORT)(LONG)hwnd, wLevel, (SHORT)(LONG)hwndParent,
  726.         (SHORT)(LONG)hwndChild, (SHORT)(LONG)hwndOwner, id, (SHORT)ulHMQ,
  727.         (SHORT)rcl.xLeft, (SHORT)rcl.yBottom,
  728.         (SHORT)rcl.xRight, (SHORT)rcl.yTop);
  729.  
  730.     OutputString(szTemp, cch);
  731.  
  732.     ulStyle = (ULONG)WinQueryWindowULong(hwnd, QWL_STYLE);
  733.     ulPFNWP = (ULONG)WinQueryWindowULong(hwnd, QWP_PFNWP);
  734.     WinQueryClassName(hwnd, sizeof(szClass), (PSZ)szClass);
  735.     if (!WinQueryClassInfo(hab, (PSZ)szClass, &classinfo)) {
  736.         classinfo.flClassStyle = -1;    /* Let know error conditon */
  737.         classinfo.cbWindowData = 0;     /* Make sure we dont dump */
  738.     }
  739.  
  740.     WinQueryWindowProcess(hwnd, &pidWindow, &tidWindow);
  741.  
  742.     cch = sprintf(szTemp,
  743.         "          St:%08lx  PID:%d  TID:%d  Pfn:%p  Cl:%s",
  744.         ulStyle, pidWindow, tidWindow, ulPFNWP, szClass);
  745.     OutputString(szTemp, cch);
  746.  
  747.     /*
  748.      * Dump the window extra words out also.
  749.      */
  750.     strcpy (szTemp, "          ");
  751.     id = 8;
  752.     for (wOffsetClassData = 0; wOffsetClassData < (SHORT) classinfo.cbWindowData;
  753.             wOffsetClassData += 2) {
  754.  
  755.         wWindowWord = (USHORT)WinQueryWindowUShort(hwnd, wOffsetClassData);
  756.         sprintf(szTemp2, "%04x ", wWindowWord);
  757.         strcat(szTemp, szTemp2);
  758.         if (--id == 0) {
  759.             /* line full is full */
  760.             OutputString(szTemp, strlen(szTemp));
  761.             szTemp[10] = '\0';
  762.             id = 8;
  763.         }
  764.     }
  765.  
  766.     if (id != 8)
  767.         OutputString(szTemp, strlen(szTemp));
  768.  
  769.     /* Return the number of bytes associated with the window */
  770.     return ((SIZEOFWND + classinfo.cbWindowData + 3) & 0xfffc);
  771. }
  772.  
  773.  
  774.  
  775.  
  776. /***************************************************************************\
  777. * SelOrDeselWithMouse(BOOL fSelect)
  778. *
  779. * Fastway to add/or remove window from watch list
  780. \***************************************************************************/
  781.  
  782. void SelOrDeselWithMouse(fSelect)
  783. BOOL    fSelect;
  784. {
  785.     HWND    rghwnd[MAXHWNDS];
  786.     HWND    hwndPoint;
  787.     SHORT    chwnd;
  788.     BOOL    fWinCurInList;
  789.     SHORT    i;
  790.  
  791.     /* First get the window of interest */
  792.     hwndPoint = HwndSelWinWithMouse(hwndSpy, NULL);
  793.     if (hwndPoint == NULL)
  794.         return;    /* No window selected */
  795.     fWinCurInList = SpyFWindowInList(hwndPoint, TRUE);
  796.  
  797.     if ((fWinCurInList && fSelect)
  798.             || (!fWinCurInList && !fSelect))
  799.         return;        /* Alredy right state */
  800.  
  801.     chwnd = SpyGetWindowList(MAXHWNDS, (HWND FAR *)rghwnd);
  802.  
  803.     if (fSelect) {
  804.         /* Add window to end of list */
  805.         rghwnd[chwnd++] = hwndPoint;
  806.     } else {
  807.         /* find it in the list, and delete it out */
  808.         for (i=0; rghwnd[i] != hwndPoint; i++)
  809.             ;
  810.  
  811.         /* Now copy rest of them down */
  812.         chwnd--;    /* One less item */
  813.         for (;i < chwnd; i++ ) {
  814.             rghwnd[i] = rghwnd[i+1];
  815.         }
  816.     }
  817.  
  818.     /* Now call to update the list */
  819.     SpySetWindowList(chwnd, (HWND FAR *)rghwnd);
  820. }
  821.  
  822.  
  823.