|
|
1.1 ! root 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 CALLBACK SpyWindowsDlgProc(HWND, USHORT, MPARAM, MPARAM); ! 31: ! 32: ! 33: ! 34: ! 35: /***************************************************************************\ ! 36: * MRESULT CALLBACK SpyWindowsDlgProc(hwnd, msg, mp1, mp2) ! 37: * ! 38: * The Spy Windows Dialog procedure ! 39: \***************************************************************************/ ! 40: MRESULT CALLBACK 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 = (SHORT) 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 = (SHORT) 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 = (USHORT)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 = (SHORT)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)hwnd, level, szId); ! 261: item = (USHORT)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 = (USHORT)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)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)hwndParent); ! 466: WinSetDlgItemText(hwndDlg, DID_WPARENT, (PSZ)szTemp); ! 467: ! 468: hwndT = WinQueryWindow(hwnd, QW_TOP, FALSE); ! 469: sprintf(szTemp, "0x%04x", (SHORT)hwndT); ! 470: WinSetDlgItemText(hwndDlg, DID_WCHILD, (PSZ)szTemp); ! 471: ! 472: hwndT = WinQueryWindow(hwnd, QW_OWNER, FALSE); ! 473: sprintf(szTemp, "0x%04x", (SHORT)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)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)hwnd, wLevel, (SHORT)hwndParent, ! 726: (SHORT)hwndChild, (SHORT)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 < 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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.