|
|
1.1 ! root 1: /****************************** Module Header ******************************\ ! 2: * Module Name: spy.c - Spy application ! 3: * ! 4: * Created by Microsoft Corporation, 1987 ! 5: * ! 6: \***************************************************************************/ ! 7: ! 8: #define INCL_PM ! 9: #define INCL_WINSYS ! 10: #define INCL_DOSPROCESS ! 11: #include "os2.h" ! 12: #include "stdio.h" ! 13: #include "string.h" ! 14: #include "spy.h" ! 15: #include "spyhook.h" ! 16: #include "time.h" ! 17: #include "stdlib.h" ! 18: ! 19: ! 20: /************* GLOBAL VARIABLES */ ! 21: ! 22: char szSpyClass[] = "Spy"; ! 23: char szTitle[] = "Spy"; ! 24: ! 25: HAB hab; ! 26: HMQ hmqSpy; ! 27: HWND hwndSpy; ! 28: HWND hwndSpyFrame; ! 29: HWND hwndSpyList = NULL; ! 30: HWND hwndWindowLB; ! 31: HWND hwndMessageLB; ! 32: HHEAP hHeap; ! 33: ! 34: HPOINTER hptrArrow; ! 35: HPOINTER hptrSelWin; ! 36: ! 37: USHORT iCurItemFocus; /* Index to item that has the focus */ ! 38: BOOL fSpyActive = MIA_CHECKED; /* Any non-zero is true */ ! 39: BOOL fTrackingWindows = FALSE; /* Tracking windows active ? */ ! 40: BOOL fAllFrames = 0; /* Are we processing all frames ? */ ! 41: fAllWindows = 0; /* Are we processing all windows ? */ ! 42: ! 43: ! 44: USHORT bHooks = SPYH_INPUT | SPYH_SENDMSG; /* Default to both hooks */ ! 45: HWND hwndWinDlgDisp = NULL; /* hwnds info in Window Dialog */ ! 46: ! 47: /* Define memory semaphore to have second thread sleep on */ ! 48: ULONG semThread = 0L; /* Thread to wait on */ ! 49: int AboutCount = 0; ! 50: ! 51: /* ! 52: * simple structure for sorting Hwnds in dumping ! 53: */ ! 54: typedef struct _spwd { ! 55: HWND hwnd; ! 56: SHORT index; ! 57: } SPWD; ! 58: ! 59: SHORT wDumpCount = 0; /* Count of which window is being dumped */ ! 60: SPWD *pspwd = NULL; ! 61: #define MAXSPYDUMP 1000 /* Max of a thousand windows */ ! 62: ! 63: ! 64: ! 65: ! 66: /************* PROCEDURE DECLARATIONS */ ! 67: MRESULT FAR PASCAL SpyWndProc(); ! 68: MRESULT FAR PASCAL SpyMsgDlgProc(); ! 69: MRESULT FAR PASCAL SpyOutputsDlgProc(); ! 70: MRESULT FAR PASCAL SpyWindowsDlgProc(); ! 71: MRESULT FAR PASCAL SpySaveListDlgProc(); ! 72: MRESULT FAR PASCAL AboutWndProc(); ! 73: ! 74: void InitWindowList(HWND, HWND, int); ! 75: void BuildWindowWatchList(HWND); ! 76: void DisplayWindowInfo(HWND, HWND); ! 77: void DumpWindowInfo(HWND, SHORT); ! 78: void DumpWindowIndex(void); ! 79: int cdecl CompareHwnds(const void *, const void *); ! 80: ! 81: void DumpOneWindowInfo(void); ! 82: void DumpAllWindowsInfo(HWND, SHORT); ! 83: ! 84: void FAR ProcHookThread(void); /* will process the hook messages */ ! 85: MSGI *PmsgiFromMsg(USHORT); ! 86: ! 87: void UpdMsgsLBSels (HWND, USHORT, BOOL); ! 88: void UpdMsgTblFromLB (HWND); ! 89: void UpdateHooksMsgTable(void); ! 90: void ProcessQueueMsg(QMSG *); ! 91: HWND HwndSelWinWithMouse(HWND, BOOL); ! 92: void SelOrDeselWithMouse(BOOL); ! 93: void EnableOrDisableMsg(BOOL); ! 94: void OutputString(char [], SHORT); /* Output string to output devices */ ! 95: ! 96: ! 97: ! 98: /**************************** Public Function ******************************\ ! 99: * int cdecl main (argc, argv) ! 100: * ! 101: * Effects: Spy Main function ! 102: * ! 103: * Return value: ! 104: \***************************************************************************/ ! 105: int cdecl main(argc, argv) ! 106: int argc; ! 107: char **argv; ! 108: { ! 109: ULONG flCreateFlags; ! 110: QMSG qmsg; ! 111: RECTL rcl; ! 112: TID tid; ! 113: char *prgStack; ! 114: ! 115: while (argc > 1) { ! 116: argv++; /* get beyond the program name */ ! 117: ! 118: /* Test for send message flag */ ! 119: if (!strcmp(*argv, "/s") || !strcmp(*argv, "/S")) ! 120: bHooks |= SPYH_SENDMSG; ! 121: ! 122: argc--; ! 123: } ! 124: ! 125: hab = WinInitialize(0); ! 126: ! 127: hmqSpy = WinCreateMsgQueue(hab, 0); ! 128: ! 129: if (!WinRegisterClass((HAB)NULL, szSpyClass, (PFNWP)SpyWndProc, ! 130: CS_SIZEREDRAW, 0)) { ! 131: WinAlarm(HWND_DESKTOP, 0xffff); ! 132: return(0); ! 133: } ! 134: ! 135: /* ! 136: * Create a heap for the program ! 137: */ ! 138: hHeap = WinCreateHeap(0, 0, 0, 0, 0, 0); ! 139: ! 140: /* ! 141: * Create a stack for the thread - also initialize the stack by zeroing ! 142: * the first 32 bytes, and filling the remainder with a known value ! 143: * ! 144: */ ! 145: prgStack = WinAllocMem(hHeap, CBSTACK); ! 146: if (prgStack == NULL) ! 147: goto Abort; ! 148: memset(prgStack, '\0', 32); /* Init first 32 bytes to zero */ ! 149: memset(prgStack+32,'\345', CBSTACK-32); /* Remainder to known value */ ! 150: ! 151: hptrArrow = WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, TRUE); ! 152: hptrSelWin = WinQuerySysPointer(HWND_DESKTOP, SPTR_MOVE, TRUE); ! 153: ! 154: ! 155: ! 156: SpyInstallHook(hab, hmqSpy, bHooks); ! 157: SpySetAllWindowOpt (fAllWindows); ! 158: SpySetAllFrameOpt (fAllFrames); ! 159: ! 160: flCreateFlags = FCF_TITLEBAR | FCF_SYSMENU | FCF_MENU | FCF_SIZEBORDER ! 161: | FCF_MINMAX; ! 162: hwndSpyFrame = WinCreateStdWindow(HWND_DESKTOP, ! 163: WS_VISIBLE | FS_ICON | FS_ACCELTABLE, ! 164: (VOID FAR *)&flCreateFlags, ! 165: szSpyClass, szTitle, ! 166: WS_VISIBLE, ! 167: (HMODULE)NULL, IDR_SPY, ! 168: (HWND FAR *)&hwndSpy); ! 169: ! 170: WinQueryWindowRect(hwndSpy, &rcl); ! 171: hwndSpyList = WinCreateWindow (hwndSpy, WC_LISTBOX, "", ! 172: WS_VISIBLE | LS_NOADJUSTPOS, ! 173: 0, 0, (SHORT)(rcl.xRight - rcl.xLeft), ! 174: (SHORT)(rcl.yTop - rcl.yBottom), ! 175: hwndSpy, HWND_TOP, DID_SPYLIST, NULL, NULL); ! 176: ! 177: WinSetFocus(HWND_DESKTOP, hwndSpyList); ! 178: ! 179: ! 180: /* Start the thread that will process the messages from the hook */ ! 181: DosCreateThread(ProcHookThread, (PTID)&tid, ! 182: (PBYTE)(prgStack + CBSTACK - 1)); ! 183: ! 184: UpdateHooksMsgTable(); /* Set Spys Msg table */ ! 185: SpyHookOnOrOff (TRUE); /* Turn the hook on */ ! 186: ! 187: while (WinGetMsg(NULL, (PQMSG)&qmsg, NULL, 0, 0)) { ! 188: WinDispatchMsg(NULL, (PQMSG)&qmsg); ! 189: } ! 190: ! 191: SpyReleaseHook (TRUE); /* Release input hook */ ! 192: ! 193: WinDestroyWindow(hwndSpyFrame); ! 194: ! 195: WinDestroyPointer(hptrArrow); ! 196: WinDestroyPointer(hptrSelWin); ! 197: ! 198: Abort: ! 199: WinDestroyMsgQueue(hmqSpy); ! 200: WinTerminate(hab); ! 201: ! 202: /* If the spy output file is open, close it now */ ! 203: if (spyopt.hfileSpy != NULL) ! 204: DosClose(spyopt.hfileSpy); ! 205: ! 206: DosExit(EXIT_PROCESS, 0); ! 207: } ! 208: ! 209: ! 210: /**************************** Public Function ******************************\ ! 211: * MRESULT FAR PASCAL SpyWndProc(hwnd, msg, mp1, mp2) ! 212: * ! 213: * Effects: Spy Client window procedure ! 214: * ! 215: * ! 216: * Return value: ! 217: \***************************************************************************/ ! 218: MRESULT FAR PASCAL SpyWndProc(hwnd, msg, mp1, mp2) ! 219: HWND hwnd; ! 220: USHORT msg; ! 221: MPARAM mp1; ! 222: MPARAM mp2; ! 223: { ! 224: HPS hps; ! 225: QMSG qmsg; ! 226: RECTL rclPaint; ! 227: VOID SpyPaint(); ! 228: SHORT cItems; ! 229: ! 230: switch (msg) { ! 231: case WM_CREATE: ! 232: /* Set up this global first thing in case we need it elsewhere */ ! 233: hwndSpy = hwnd; ! 234: break; ! 235: ! 236: case WM_SEM2: ! 237: /* ! 238: * Other thread told use there are some messages out there. Loop ! 239: * through and process all of the pending messages, and output ! 240: * the listbox position at the end. Also make sure to flush ! 241: * the file buffer before we go back to sleep. ! 242: */ ! 243: while (SpyGetNextMessage(&qmsg, 0L)) { ! 244: ProcessQueueMsg(&qmsg); ! 245: } ! 246: ! 247: if (spyopt.fFile) ! 248: DosBufReset(spyopt.hfileSpy); ! 249: ! 250: DosSemClear((HSEM)(PULONG)&semThread); ! 251: ! 252: break; ! 253: ! 254: case WM_COMMAND: ! 255: switch (SHORT1FROMMP(mp1)) { ! 256: case CMD_ACTIVE: ! 257: ! 258: /* ! 259: * THe active menu item was selected, we will toggle the ! 260: * the selection by setting active to 0 or MIA_CHECKED. ! 261: * Call the hook, and then update the checkmark on the menu ! 262: */ ! 263: fSpyActive ^= MIA_CHECKED; /* Toggle on or off */ ! 264: SpyHookOnOrOff (fSpyActive); ! 265: WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU), ! 266: MM_SETITEMATTR, MPFROM2SHORT(CMD_ACTIVE, TRUE), ! 267: MPFROM2SHORT(MIA_CHECKED, fSpyActive)); ! 268: ! 269: break; ! 270: case CMD_ABOUT: ! 271: if (AboutCount == 4) { ! 272: AboutCount = 0; ! 273: WinDlgBox(HWND_DESKTOP, hwnd, (PFNWP)AboutWndProc, NULL, About2Dlg, (PCH)NULL); ! 274: } else { ! 275: AboutCount++; ! 276: WinDlgBox(HWND_DESKTOP, hwnd, (PFNWP)AboutWndProc, NULL, About1Dlg, (PCH)NULL); ! 277: } ! 278: break; ! 279: ! 280: case CMD_EXIT: ! 281: WinPostMsg(NULL, WM_QUIT, 0L, 0L); ! 282: break; ! 283: ! 284: case CMD_CLRWIN: ! 285: /* ! 286: * Delete all items in the list. Simply do this ! 287: * By deleting the first item, until the count goes to ! 288: * zero ! 289: */ ! 290: WinSendMsg(hwndSpyList, LM_DELETEALL, 0L, 0L); ! 291: break; ! 292: ! 293: case CMD_SAVEWIN: ! 294: SpyHookOnOrOff (FALSE); ! 295: WinDlgBox(HWND_DESKTOP, hwndSpyFrame, ! 296: (PFNWP)SpySaveListDlgProc, (HMODULE)NULL, ! 297: SaveListDlg, (PCH)NULL); ! 298: SpyHookOnOrOff (fSpyActive); ! 299: break; ! 300: ! 301: case CMD_WINDOWS: ! 302: SpyHookOnOrOff (FALSE); ! 303: hwndWindowLB = NULL; ! 304: iCurItemFocus = (USHORT)-1; ! 305: WinDlgBox(HWND_DESKTOP, hwndSpyFrame, ! 306: (PFNWP)SpyWindowsDlgProc, (HMODULE)NULL, ! 307: WindowsDlg, (PCH)NULL); ! 308: ! 309: SpyHookOnOrOff (fSpyActive); ! 310: break; ! 311: ! 312: case CMD_WNMSSEL: ! 313: case CMD_WNMSDSL: ! 314: SpyHookOnOrOff (FALSE); ! 315: SelOrDeselWithMouse(SHORT1FROMMP(mp1) == CMD_WNMSSEL); ! 316: SpyHookOnOrOff (fSpyActive); ! 317: break; ! 318: ! 319: case CMD_ALLWNDWS: ! 320: ! 321: /* ! 322: * The user selected the ALLFRAMES, toggle the state, and ! 323: * update the menu and the hook state. ! 324: */ ! 325: fAllWindows ^= MIA_CHECKED; /* Toggle on or off */ ! 326: SpySetAllWindowOpt (fAllWindows); ! 327: WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU), ! 328: MM_SETITEMATTR, MPFROM2SHORT(CMD_ALLWNDWS, TRUE), ! 329: MPFROM2SHORT(MIA_CHECKED, fAllWindows)); ! 330: break; ! 331: ! 332: case CMD_ALLFRAMES: ! 333: ! 334: /* ! 335: * The user selected the ALLFRAMES, toggle the state, and ! 336: * update the menu and the hook state. ! 337: */ ! 338: fAllFrames ^= MIA_CHECKED; /* Toggle on or off */ ! 339: SpySetAllFrameOpt (fAllFrames); ! 340: WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU), ! 341: MM_SETITEMATTR, MPFROM2SHORT(CMD_ALLFRAMES, TRUE), ! 342: MPFROM2SHORT(MIA_CHECKED, fAllFrames)); ! 343: break; ! 344: ! 345: case CMD_WNDPWIN: ! 346: wDumpCount = 0; ! 347: DumpOneWindowInfo(); ! 348: break; ! 349: case CMD_WNDPALL: ! 350: wDumpCount = 0; ! 351: pspwd = (SPWD *)WinAllocMem(hHeap, sizeof(SPWD)* MAXSPYDUMP); ! 352: DumpAllWindowsInfo(HWND_DESKTOP, 0); ! 353: DumpAllWindowsInfo(HWND_OBJECT, -10); /* Make it show up */ ! 354: DumpWindowIndex(); ! 355: WinFreeMem(hHeap, (char *)pspwd, sizeof(SPWD)* MAXSPYDUMP); ! 356: break; ! 357: ! 358: case CMD_MESSAGES: ! 359: SpyHookOnOrOff (FALSE); ! 360: WinDlgBox(HWND_DESKTOP, hwndSpyFrame, ! 361: (PFNWP)SpyMsgDlgProc, (HMODULE)NULL, ! 362: MessagesDlg, (PCH)NULL); ! 363: SpyHookOnOrOff (fSpyActive); ! 364: break; ! 365: ! 366: case CMD_OUTPUTS: ! 367: SpyHookOnOrOff (FALSE); ! 368: WinDlgBox(HWND_DESKTOP, hwndSpyFrame, ! 369: (PFNWP)SpyOutputsDlgProc, (HMODULE)NULL, ! 370: OutputsDlg, (PCH)NULL); ! 371: SpyHookOnOrOff (fSpyActive); ! 372: break; ! 373: ! 374: case CMD_MGDABLE: ! 375: case CMD_MGEABLE: ! 376: EnableOrDisableMsg(SHORT1FROMMP(mp1) == CMD_MGEABLE); ! 377: break; ! 378: } ! 379: ! 380: break; ! 381: ! 382: case WM_SIZE: ! 383: /* We need to resize the listbox, if it exists */ ! 384: if (hwndSpyList != NULL) { ! 385: WinSetWindowPos(hwndSpyList, HWND_TOP, 0, 0, ! 386: SHORT1FROMMP(mp2), SHORT2FROMMP(mp2), SWP_SIZE); ! 387: } ! 388: ! 389: /* Now fall through to process the message */ ! 390: default: ! 391: return(WinDefWindowProc(hwnd, msg, mp1, mp2)); ! 392: break; ! 393: } ! 394: return(0L); ! 395: } ! 396: ! 397: ! 398: ! 399: /**************************** Public Function ******************************\ ! 400: * MRESULT FAR PASCAL SpyMsgDlgProc (hwnd, msg, mp1, mp2) ! 401: * ! 402: * Effects: Message List dialog procedure ! 403: * ! 404: * ! 405: * Return value: ! 406: \***************************************************************************/ ! 407: MRESULT FAR PASCAL SpyMsgDlgProc(hwnd, msg, mp1, mp2) ! 408: HWND hwnd; ! 409: USHORT msg; ! 410: MPARAM mp1; ! 411: MPARAM mp2; ! 412: { ! 413: SHORT i; ! 414: MSGI *pmsgi; ! 415: USHORT item; ! 416: SHORT bHooksNew; ! 417: USHORT wAction; ! 418: ! 419: switch (msg) { ! 420: ! 421: case WM_INITDLG: ! 422: /* ! 423: * Initialize the list box with the list of messages that are ! 424: * defined in our message table ! 425: */ ! 426: pmsgi = rgmsgi; /* Point to start of list */ ! 427: hwndMessageLB = WinWindowFromID(hwnd, DID_OMSGLIST); ! 428: for (i = 0; i < cmsgi; i++) { ! 429: pmsgi->iListBox = item = (USHORT)WinSendMsg(hwndMessageLB, ! 430: LM_INSERTITEM, ! 431: #if 0 ! 432: (MPARAM)LIT_SORTASCENDING, ! 433: #else ! 434: (MPARAM)LIT_END, ! 435: #endif ! 436: (MPARAM)(PSZ)pmsgi->szMsg); ! 437: WinSendMsg(hwndMessageLB, LM_SETITEMHANDLE, (MPARAM)item, ! 438: (MPARAM)i); ! 439: if (pmsgi->wOptions & MSGI_ENABLED) { ! 440: WinSendMsg(hwndMessageLB, LM_SELECTITEM, (MPARAM)item, ! 441: (MPARAM)TRUE); ! 442: } ! 443: pmsgi++; ! 444: } ! 445: ! 446: /* Initialize the Hook type record */ ! 447: WinSendDlgItemMsg(hwnd, DID_OINPUT, BM_SETCHECK, ! 448: (MPARAM)(bHooks & SPYH_INPUT)?1 : 0, 0L); ! 449: ! 450: WinSendDlgItemMsg(hwnd, DID_OSENDMSG, BM_SETCHECK, ! 451: (MPARAM)(bHooks & SPYH_SENDMSG)?1 : 0, 0L); ! 452: ! 453: break; ! 454: ! 455: case WM_COMMAND: ! 456: switch (SHORT1FROMMP(mp1)) { ! 457: case DID_OK: ! 458: ! 459: /* ! 460: * Call to update the Message table select bits ! 461: */ ! 462: ! 463: UpdMsgTblFromLB (hwnd); ! 464: ! 465: /* Setup new hook options */ ! 466: bHooksNew = 0; ! 467: ! 468: if ((BOOL)WinSendDlgItemMsg(hwnd, ! 469: DID_OINPUT, BM_QUERYCHECK, 0L, 0L)) ! 470: bHooksNew = SPYH_INPUT; ! 471: ! 472: if ((BOOL)WinSendDlgItemMsg(hwnd, ! 473: DID_OSENDMSG, BM_QUERYCHECK, 0L, 0L)) ! 474: bHooksNew |= SPYH_SENDMSG; ! 475: ! 476: if (bHooksNew != bHooks) { ! 477: SpyReleaseHook (FALSE); /* Dont clear queue */ ! 478: bHooks = bHooksNew; ! 479: SpyInstallHook(hab, hmqSpy, bHooks); /* Install hook again */ ! 480: } ! 481: ! 482: /* Fall through to DID_CANCEL */ ! 483: case DID_CANCEL: ! 484: /* Now dismiss the dialog */ ! 485: WinDismissDlg(hwnd, SHORT1FROMMP(mp1)); ! 486: break; ! 487: ! 488: /* ! 489: * These case simply update the listbox with which messages are ! 490: * enabled ! 491: */ ! 492: case DID_MALL: ! 493: UpdMsgsLBSels (hwnd, 0, TRUE); ! 494: break; ! 495: case DID_MNONE: ! 496: UpdMsgsLBSels (hwnd, 0, FALSE); ! 497: break; ! 498: case DID_MCON: ! 499: UpdMsgsLBSels (hwnd, MSGI_KEY, TRUE); ! 500: break; ! 501: case DID_MCOFF: ! 502: UpdMsgsLBSels (hwnd, MSGI_KEY, FALSE); ! 503: break; ! 504: case DID_MMON: ! 505: UpdMsgsLBSels (hwnd, MSGI_MOUSE, TRUE); ! 506: break; ! 507: case DID_MMOFF: ! 508: UpdMsgsLBSels (hwnd, MSGI_MOUSE, FALSE); ! 509: break; ! 510: case DID_MFON: ! 511: UpdMsgsLBSels (hwnd, MSGI_FREQ, TRUE); ! 512: break; ! 513: case DID_MFOFF: ! 514: UpdMsgsLBSels (hwnd, MSGI_FREQ, FALSE); ! 515: break; ! 516: } ! 517: break; ! 518: ! 519: default: ! 520: return(WinDefDlgProc(hwnd, msg, mp1, mp2)); ! 521: break; ! 522: } ! 523: return 0L; ! 524: } ! 525: ! 526: ! 527: ! 528: /**************************** Public Function ******************************\ ! 529: * MRESULT FAR PASCAL SpyOutputsDlgProc (hwnd, msg, mp1, mp2) ! 530: * ! 531: * Effects: Output Options dialog procedure ! 532: * ! 533: * ! 534: * Return value: ! 535: \***************************************************************************/ ! 536: MRESULT FAR PASCAL SpyOutputsDlgProc(hwnd, msg, mp1, mp2) ! 537: HWND hwnd; ! 538: USHORT msg; ! 539: MPARAM mp1; ! 540: MPARAM mp2; ! 541: { ! 542: SHORT i; ! 543: MSGI *pmsgi; ! 544: USHORT item; ! 545: SHORT bHooksNew; ! 546: USHORT wAction; ! 547: ! 548: switch (msg) { ! 549: ! 550: case WM_INITDLG: ! 551: /* ! 552: * Now initialize the output options in the dialog ! 553: */ ! 554: WinSendDlgItemMsg(hwnd, DID_WINDOW, BM_SETCHECK, ! 555: (MPARAM)spyopt.fWindow, 0L); ! 556: WinSendDlgItemMsg(hwnd, DID_FILE, BM_SETCHECK, ! 557: (MPARAM)spyopt.fFile, 0L); ! 558: ! 559: WinSetDlgItemShort(hwnd, DID_WINDOWLINES, spyopt.cWindowLines, FALSE); ! 560: WinSetDlgItemText(hwnd, DID_FILENAME, spyopt.szFileName); ! 561: ! 562: ! 563: break; ! 564: ! 565: case WM_COMMAND: ! 566: switch (SHORT1FROMMP(mp1)) { ! 567: case DID_OK: ! 568: ! 569: /* ! 570: * Now retrieve the output options from the ! 571: * dialog ! 572: */ ! 573: spyopt.fWindow = (BOOL)WinSendDlgItemMsg(hwnd, ! 574: DID_WINDOW, BM_QUERYCHECK, 0L, 0L); ! 575: spyopt.fFile = (BOOL)WinSendDlgItemMsg(hwnd, ! 576: DID_FILE, BM_QUERYCHECK, 0L, 0L); ! 577: ! 578: WinQueryDlgItemShort(hwnd, DID_WINDOWLINES, &spyopt.cWindowLines, FALSE); ! 579: WinQueryDlgItemText(hwnd, DID_FILENAME, ! 580: sizeof(spyopt.szFileName), spyopt.szFileName); ! 581: ! 582: /* ! 583: * Now take care of file operations ! 584: * If a file is already active, we will continue to use it, and ! 585: * ignore the case where the user may have changed file names ! 586: * Will truncate any file. ! 587: */ ! 588: if (spyopt.fFile) { ! 589: if (spyopt.hfileSpy == NULL) ! 590: if (DosOpen((PSZ)spyopt.szFileName, &spyopt.hfileSpy, ! 591: (USHORT far *)&wAction, 0L, 0, ! 592: 0x0012, 0x00C1, 0L) != 0) ! 593: spyopt.hfileSpy = NULL; /* Failed on open */ ! 594: } else { ! 595: if (spyopt.hfileSpy != NULL) { ! 596: /* file open, not outputing, close it now */ ! 597: DosClose (spyopt.hfileSpy); ! 598: spyopt.hfileSpy = NULL; ! 599: } ! 600: } ! 601: /* Fall through to DID_CANCEL */ ! 602: case DID_CANCEL: ! 603: /* Now dismiss the dialog */ ! 604: WinDismissDlg(hwnd, SHORT1FROMMP(mp1)); ! 605: break; ! 606: } ! 607: break; ! 608: ! 609: default: ! 610: return(WinDefDlgProc(hwnd, msg, mp1, mp2)); ! 611: break; ! 612: } ! 613: return 0L; ! 614: } ! 615: ! 616: ! 617: ! 618: /**************************** Public Function ******************************\ ! 619: * void UpdMsgsLBSels (HWND hwndDialog, USHORT uMask, fOnOrOff); ! 620: * ! 621: * Effects: Will update the selected items in the message listbox, that is ! 622: * displayed in the options dialog ! 623: * ! 624: * Return value: none ! 625: \***************************************************************************/ ! 626: void UpdMsgsLBSels (hwndDialog, uMask, fOnOrOff) ! 627: HWND hwndDialog; ! 628: USHORT uMask; ! 629: BOOL fOnOrOff; ! 630: { ! 631: ! 632: SHORT i; ! 633: MSGI *pmsgi; ! 634: ! 635: /* ! 636: * Loop through all of the items in our list, if the mask is 0 or ! 637: * the bit is on in the item, then update the select state in listbox ! 638: * defined in our message table ! 639: */ ! 640: pmsgi = rgmsgi; /* Point to start of list */ ! 641: for (i = 0; i < cmsgi; i++) { ! 642: if ((uMask == 0) || (pmsgi->wOptions & uMask)) { ! 643: WinSendMsg(hwndMessageLB, LM_SELECTITEM, ! 644: (MPARAM)pmsgi->iListBox, (MPARAM)fOnOrOff); ! 645: } ! 646: pmsgi++; ! 647: } ! 648: } ! 649: ! 650: /**************************** Public Function ******************************\ ! 651: * void UpdMsgsLBSels (HWND hwndDialog, USHORT uMask, fOnOrOff); ! 652: * ! 653: * Effects: Will update the selected items in the message listbox, that is ! 654: * displayed in the options dialog ! 655: * ! 656: * Return value: none ! 657: \***************************************************************************/ ! 658: void UpdMsgTblFromLB (hwndDialog) ! 659: HWND hwndDialog; ! 660: { ! 661: ! 662: USHORT i; ! 663: register MSGI *pmsgi; ! 664: USHORT itemSel; ! 665: ! 666: /* ! 667: * Loop through all of the items in the list and update the selection ! 668: * status depending of if the item is selected in the list box or ! 669: * not. ! 670: */ ! 671: /* First simply turn off all of the bits */ ! 672: pmsgi = rgmsgi; ! 673: for (i = 0; i < cmsgi; i++) { ! 674: pmsgi->wOptions &= ~MSGI_ENABLED; ! 675: pmsgi++; ! 676: } ! 677: ! 678: /* Then turn on all of the selected items */ ! 679: itemSel = (USHORT)LIT_FIRST; ! 680: ! 681: while ((itemSel = (USHORT)WinSendMsg(hwndMessageLB, LM_QUERYSELECTION, ! 682: (MPARAM)itemSel, 0L)) != (USHORT)LIT_NONE) { ! 683: ! 684: /* The item handle contains index in our array */ ! 685: i = (USHORT)WinSendMsg(hwndMessageLB, LM_QUERYITEMHANDLE, ! 686: (MPARAM)itemSel, 0L); ! 687: ! 688: rgmsgi[i].wOptions |= MSGI_ENABLED; ! 689: } ! 690: ! 691: /* Now call function to update the hooks message list */ ! 692: UpdateHooksMsgTable(); ! 693: } ! 694: /**************************** Public Function ******************************\ ! 695: * void UpdateHooksMsgTable(void) ! 696: * ! 697: * Effects: Set the message bitmask to the hook, for interested messages. ! 698: * displayed in the options dialog ! 699: * ! 700: * Return value: none ! 701: \***************************************************************************/ ! 702: void UpdateHooksMsgTable() ! 703: { ! 704: MSGI *pmsgi; ! 705: char rgb[MAXMSGFILTERBYTES]; ! 706: int i; ! 707: char *prgb; ! 708: unsigned char mask; ! 709: ! 710: /* ! 711: * First zero the bitmask ! 712: */ ! 713: memset(rgb,'\0', MAXMSGFILTERBYTES); ! 714: mask = 1; ! 715: prgb = rgb; ! 716: ! 717: /* ! 718: * Quick and dirty loop to set the bits ! 719: */ ! 720: pmsgi = rgmsgi; ! 721: for (i = 0; i <= MAXMSGFILTER; i++) { ! 722: /* If enabled, set bit in bit table */ ! 723: ! 724: if (pmsgi->msg == i) { ! 725: if (pmsgi->wOptions & MSGI_ENABLED) ! 726: *prgb |= mask; ! 727: ! 728: pmsgi++; ! 729: } else { ! 730: /* Hole in range, set it true */ ! 731: *prgb |= mask; ! 732: } ! 733: ! 734: ! 735: /* Setup next mask */ ! 736: mask <<= 1; ! 737: if (mask == 0) { ! 738: mask = 1; ! 739: prgb++; ! 740: } ! 741: } ! 742: ! 743: /* Now call the hook function with the new mask */ ! 744: SpySetMessageList((char far *)rgb); ! 745: } ! 746: ! 747: ! 748: ! 749: ! 750: /**************************** Public Function ******************************\ ! 751: * MRESULT FAR PASCAL SpyWindowsDlgProc(hwnd, msg, mp1, mp2) ! 752: * ! 753: * Effects: The Spy Windows Dialog procedure ! 754: * ! 755: * Return value: none ! 756: \***************************************************************************/ ! 757: MRESULT FAR PASCAL SpyWindowsDlgProc(hwnd, msg, mp1, mp2) ! 758: HWND hwnd; ! 759: USHORT msg; ! 760: MPARAM mp1; ! 761: MPARAM mp2; ! 762: { ! 763: BOOL fSelect = TRUE; ! 764: SHORT cWindows; ! 765: QMSG qmsg; ! 766: HWND hwndPoint; ! 767: HWND hwndItem; /* from handle of list item */ ! 768: USHORT iItemFocus; /* Index to item that has the focus */ ! 769: ! 770: switch (msg) { ! 771: ! 772: case WM_INITDLG: ! 773: /* Initialize the dialog items */ ! 774: hwndWindowLB = WinWindowFromID(hwnd, DID_WINDOWLIST); ! 775: InitWindowList(hwnd, HWND_DESKTOP, 0); ! 776: hwndWinDlgDisp = NULL; ! 777: fTrackingWindows = TRUE; ! 778: break; ! 779: ! 780: case WM_COMMAND: ! 781: switch (SHORT1FROMMP(mp1)) { ! 782: case DID_OK: ! 783: BuildWindowWatchList(hwnd); ! 784: case DID_CANCEL: ! 785: /* Now dismiss the dialog */ ! 786: WinDismissDlg(hwnd, SHORT1FROMMP(mp1)); ! 787: break; ! 788: case DID_WUNSELALL: ! 789: fSelect = FALSE; ! 790: case DID_WSELALL: ! 791: cWindows = (SHORT) WinSendMsg(hwndWindowLB, LM_QUERYITEMCOUNT, ! 792: 0L, 0L); ! 793: ! 794: fTrackingWindows = FALSE; ! 795: while (cWindows) { ! 796: /* Loop through all windows, selecting or unselcting all */ ! 797: WinSendMsg(hwndWindowLB, LM_SELECTITEM, (MPARAM)--cWindows, ! 798: (MPARAM)fSelect); ! 799: } ! 800: fTrackingWindows = TRUE; ! 801: break; ! 802: ! 803: case DID_WSELMOUSE: ! 804: /* Call function to track mouse, returns window handle */ ! 805: hwndPoint = HwndSelWinWithMouse(hwnd, TRUE); ! 806: if (hwndPoint == NULL) ! 807: break; /* No window to process */ ! 808: ! 809: /* ! 810: * Now find the window in the list, Make the item visible ! 811: * and set the item as selected. ! 812: */ ! 813: cWindows = (SHORT) WinSendMsg(hwndWindowLB, LM_QUERYITEMCOUNT, ! 814: 0L, 0L); ! 815: ! 816: while (cWindows) { ! 817: /* ! 818: * Loop through all windows until we wind the right ! 819: * one with the correct window handle ! 820: */ ! 821: hwndItem = (HWND)WinSendMsg(hwndWindowLB, LM_QUERYITEMHANDLE, ! 822: (MPARAM)--cWindows, 0L); ! 823: ! 824: if (hwndItem == hwndPoint) { ! 825: /* found the right item, move it to top */ ! 826: WinSendMsg(hwndWindowLB, LM_SETTOPINDEX, (MPARAM)cWindows, 0L); ! 827: WinSendMsg(hwndWindowLB, LM_SELECTITEM, (MPARAM)cWindows, ! 828: (MPARAM)TRUE); ! 829: break; ! 830: } ! 831: } ! 832: break; ! 833: ! 834: } ! 835: break; ! 836: ! 837: ! 838: default: ! 839: /* ! 840: * Default is to see if the listbox has changed its focus ! 841: * item number. If it has, then we want to display the information ! 842: * about the window that the listbox cursor is over. There is no ! 843: * legal way to do this, so I am trying to extract data out of the ! 844: * extended bytes of the listbox data structure. ! 845: * DONT DO THIS !!! ! 846: */ ! 847: if (fTrackingWindows && hwndWindowLB != NULL) { ! 848: iItemFocus = WinQueryWindowUShort(hwndWindowLB, 10); ! 849: if (iItemFocus != iCurItemFocus) { ! 850: iCurItemFocus = iItemFocus; ! 851: if (iItemFocus != (USHORT)-1) { ! 852: hwndItem = (HWND)WinSendMsg(hwndWindowLB, LM_QUERYITEMHANDLE, ! 853: (MPARAM)iItemFocus, 0L); ! 854: DisplayWindowInfo(hwnd, hwndItem); ! 855: } ! 856: } ! 857: } ! 858: return(WinDefDlgProc(hwnd, msg, mp1, mp2)); ! 859: } ! 860: return 0L; ! 861: } ! 862: ! 863: ! 864: ! 865: /**************************** Private Function ******************************\ ! 866: * InitWindowList (hwndDialog, hwnd, level) ! 867: * ! 868: * Effects: Builds the list of windows displayed in the windows dialog ! 869: * ! 870: * ! 871: * Return value: ! 872: \***************************************************************************/ ! 873: void InitWindowList(hwndDialog, hwnd, level) ! 874: HWND hwndDialog; ! 875: HWND hwnd; ! 876: int level; ! 877: { ! 878: char szTemp[30]; ! 879: char szId[20]; ! 880: HWND hwndT; ! 881: USHORT item; ! 882: USHORT id; ! 883: int i; ! 884: ! 885: /* ! 886: * We will first add this item to our list of ! 887: * items in the listbox, If the item is in our list of hwnds, ! 888: * set the item selected. To keep from getting into endless loops ! 889: * will not add spywindow client, and descendants. ! 890: */ ! 891: if (hwnd != hwndSpy) { ! 892: id = (USHORT)WinQueryWindowUShort(hwnd, QWS_ID); ! 893: sprintf(szId, "ID: %x", id); ! 894: ! 895: for (i = 0; i < cToName; i++) { ! 896: if (id == rgidtoname[i].id) { ! 897: strcpy (szId, rgidtoname[i].szIdName); ! 898: break; ! 899: } ! 900: } ! 901: ! 902: sprintf(szTemp, "0x%04x(%d) - %s", (USHORT)hwnd, level, szId); ! 903: item = (USHORT)WinSendMsg(hwndWindowLB, LM_INSERTITEM, ! 904: (MPARAM)LIT_END, (MPARAM)(PSZ)szTemp); ! 905: ! 906: /* Set the item handle to the handle of the window */ ! 907: WinSendMsg(hwndWindowLB, LM_SETITEMHANDLE, (MPARAM)item, ! 908: (MPARAM)hwnd); ! 909: ! 910: if (SpyFWindowInList(hwnd)) ! 911: WinSendMsg(hwndWindowLB, LM_SELECTITEM, (MPARAM)item, ! 912: (MPARAM)TRUE); ! 913: ! 914: /* ! 915: * Then we recurse with all of our children ! 916: */ ! 917: if ((hwndT = WinQueryWindow(hwnd, QW_TOP, FALSE)) != NULL) ! 918: InitWindowList(hwndDialog, hwndT, level+1); ! 919: } ! 920: ! 921: /* ! 922: * Then go to our next sibling ! 923: */ ! 924: if ((hwndT = WinQueryWindow(hwnd, QW_NEXT, FALSE)) != NULL) ! 925: InitWindowList(hwndDialog, hwndT, level); ! 926: } ! 927: ! 928: ! 929: ! 930: /**************************** Private Function *****************************\ ! 931: * BuildWindowWatchList(hwndDialog) ! 932: * ! 933: * Effects: Updates the list of windows to be watched from the listbox ! 934: * ! 935: * ! 936: * Return value: ! 937: \***************************************************************************/ ! 938: void BuildWindowWatchList(hwndDialog) ! 939: HWND hwndDialog; ! 940: { ! 941: ! 942: USHORT itemPrevious; ! 943: USHORT item; ! 944: HWND hwnd; ! 945: ! 946: SHORT chwnd; ! 947: HWND rghwnd[MAXHWNDS]; ! 948: ! 949: /* ! 950: * Simply loop through asking for the next selected item in the ! 951: * list. Make sure not to overrun our list. ! 952: */ ! 953: itemPrevious = (USHORT)LIT_FIRST; ! 954: chwnd = 0; ! 955: ! 956: while ((item = (USHORT)WinSendMsg(hwndWindowLB, LM_QUERYSELECTION, ! 957: (MPARAM)itemPrevious, 0L)) != (USHORT)LIT_NONE) { ! 958: /* ! 959: * Get the items handle, which has the value of the window handle ! 960: */ ! 961: hwnd = (HWND)WinSendMsg(hwndWindowLB, LM_QUERYITEMHANDLE, ! 962: (MPARAM)item, 0L); ! 963: ! 964: rghwnd[chwnd++] = hwnd; ! 965: if (chwnd >= MAXHWNDS) ! 966: break; /* Dont overflow array */ ! 967: itemPrevious = item; /* Where to cointinue the search */ ! 968: } ! 969: ! 970: SpySetWindowList (chwnd, rghwnd); ! 971: } ! 972: ! 973: ! 974: /**************************** Public Function ******************************\ ! 975: * HWND HwndSelWinWithMouse(HWND hwnd, BOOL fDisplayInfo) ! 976: * ! 977: * Effects: This function is used to allow the user to select a window with ! 978: * the mouse. If fDisplayInfo is TRUE, it will update the ! 979: * information in the dialog box, about the window that the ! 980: * mouse is currently over. ! 981: * ! 982: * Return value: none ! 983: \***************************************************************************/ ! 984: HWND HwndSelWinWithMouse(hwnd, fDisplayInfo) ! 985: HWND hwnd; ! 986: BOOL fDisplayInfo; ! 987: { ! 988: ! 989: QMSG qmsg; ! 990: HWND hwndPoint; ! 991: char szClassName[50]; /* Class name of window */ ! 992: CLASSINFO classinfo; /* Information about class */ ! 993: ! 994: ! 995: /* ! 996: * First set the capture to the specified window ! 997: */ ! 998: WinSetCapture(HWND_DESKTOP, hwnd); ! 999: WinSetPointer (HWND_DESKTOP, hptrSelWin); ! 1000: ! 1001: /* ! 1002: * Now loop through all of the messages that are sent, until ! 1003: * we get our mouse 1 down message. We will also filter out ! 1004: * the WM_MOVE message, else we will dispatch the messages. ! 1005: */ ! 1006: while (WinGetMsg(hab, &qmsg, NULL, 0, 0)) { ! 1007: if (qmsg.msg == WM_MOUSEMOVE) { ! 1008: if (fDisplayInfo) { ! 1009: hwndPoint = WinWindowFromPoint(HWND_DESKTOP, ! 1010: &qmsg.ptl, TRUE, FALSE); ! 1011: DisplayWindowInfo(hwnd, hwndPoint); ! 1012: } ! 1013: } ! 1014: else if (qmsg.msg == WM_BUTTON1DOWN) ! 1015: break; ! 1016: else ! 1017: WinDispatchMsg(hab, &qmsg); ! 1018: } ! 1019: ! 1020: WinSetPointer (HWND_DESKTOP, hptrArrow); ! 1021: WinSetCapture(HWND_DESKTOP, NULL); ! 1022: ! 1023: ! 1024: /* ! 1025: * Map the point to the window, If the CTRL-Key is down, ! 1026: * we will go up through the parent chain until we get to ! 1027: * a frame window or desktop. Dont let hwndSpy through!!! ! 1028: */ ! 1029: hwndPoint = WinWindowFromPoint(HWND_DESKTOP, ! 1030: &qmsg.ptl, TRUE, FALSE); ! 1031: if (WinGetKeyState(HWND_DESKTOP, VK_CTRL) & 0x8000) { ! 1032: /* Asked for frame window */ ! 1033: for (;;) { ! 1034: if (hwndPoint == NULL) ! 1035: return (NULL); /* No frames available */ ! 1036: /* See if frame class */ ! 1037: WinQueryClassName(hwndPoint, sizeof(szClassName), ! 1038: (PSZ)szClassName); ! 1039: WinQueryClassInfo(hab, (PSZ)szClassName, ! 1040: &classinfo); ! 1041: if (classinfo.flClassStyle & CS_FRAME) ! 1042: break; /* We have our frame */ ! 1043: ! 1044: /* Not frame, go back to parent */ ! 1045: hwndPoint = WinQueryWindow(hwndPoint, QW_PARENT, FALSE); ! 1046: } ! 1047: } ! 1048: ! 1049: if (fDisplayInfo) ! 1050: DisplayWindowInfo(hwnd, hwndPoint); ! 1051: ! 1052: if (WinIsChild(hwndPoint, hwndSpy)) ! 1053: return (NULL); /* Dont want to get in endless loops */ ! 1054: ! 1055: return (hwndPoint); ! 1056: } ! 1057: ! 1058: ! 1059: ! 1060: /**************************** Private Function *****************************\ ! 1061: * DisplayWindowInfo(HWND hwndDialog, HWND hwnd) ! 1062: * ! 1063: * Effects: Displays the information about the selected window in the dialog ! 1064: * ! 1065: * ! 1066: * Return value: ! 1067: \***************************************************************************/ ! 1068: void DisplayWindowInfo(hwndDlg, hwnd) ! 1069: HWND hwndDlg; ! 1070: HWND hwnd; ! 1071: { ! 1072: HWND hwndT; ! 1073: char szTemp[50]; ! 1074: RECTL rcl; ! 1075: USHORT id; ! 1076: ULONG ul; ! 1077: ! 1078: if (hwnd != hwndWinDlgDisp) ! 1079: { ! 1080: hwndWinDlgDisp = hwnd; ! 1081: ! 1082: /* This could be table driven */ ! 1083: sprintf(szTemp, "0x%04x", (SHORT)hwnd); ! 1084: WinSetDlgItemText(hwndDlg, DID_WHANDLE, (PSZ)szTemp); ! 1085: ! 1086: WinQueryClassName(hwnd, sizeof(szTemp), (PSZ)szTemp); ! 1087: WinSetDlgItemText(hwndDlg, DID_WCLASS, (PSZ)szTemp); ! 1088: ! 1089: ! 1090: hwndT = WinQueryWindow(hwnd, QW_PARENT, FALSE); ! 1091: sprintf(szTemp, "0x%04x", (SHORT)hwndT); ! 1092: WinSetDlgItemText(hwndDlg, DID_WPARENT, (PSZ)szTemp); ! 1093: ! 1094: hwndT = WinQueryWindow(hwnd, QW_TOP, FALSE); ! 1095: sprintf(szTemp, "0x%04x", (SHORT)hwndT); ! 1096: WinSetDlgItemText(hwndDlg, DID_WCHILD, (PSZ)szTemp); ! 1097: ! 1098: hwndT = WinQueryWindow(hwnd, QW_OWNER, FALSE); ! 1099: sprintf(szTemp, "0x%04x", (SHORT)hwndT); ! 1100: WinSetDlgItemText(hwndDlg, DID_WOWNER, (PSZ)szTemp); ! 1101: ! 1102: WinQueryWindowRect(hwnd, &rcl); ! 1103: sprintf(szTemp, "(%d, %d), (%d, %d)", (SHORT)rcl.xLeft, ! 1104: (SHORT)rcl.yBottom, (SHORT)rcl.xRight, (SHORT)rcl.yTop); ! 1105: WinSetDlgItemText(hwndDlg, DID_WRECT, (PSZ)szTemp); ! 1106: ! 1107: id = (USHORT)WinQueryWindowUShort(hwnd, QWS_ID); ! 1108: sprintf(szTemp, "0x%04x", id); ! 1109: WinSetDlgItemText(hwndDlg, DID_WID, (PSZ)szTemp); ! 1110: ! 1111: ul = (ULONG)WinQueryWindowULong(hwnd, QWL_STYLE); ! 1112: sprintf(szTemp, "0x%08lx", ul); ! 1113: WinSetDlgItemText(hwndDlg, DID_WSTYLE, (PSZ)szTemp); ! 1114: ! 1115: ul = (ULONG)WinQueryWindowULong(hwnd, QWP_PFNWP); ! 1116: sprintf(szTemp, "%p", ul); ! 1117: WinSetDlgItemText(hwndDlg, DID_WPFNWP, (PSZ)szTemp); ! 1118: ! 1119: ul = (ULONG)WinQueryWindowULong(hwnd, QWL_HMQ); ! 1120: sprintf(szTemp, "0x%04x", (SHORT)ul); ! 1121: WinSetDlgItemText(hwndDlg, DID_WHMQ, (PSZ)szTemp); ! 1122: ! 1123: } ! 1124: } ! 1125: ! 1126: ! 1127: ! 1128: /**************************** Public Function ******************************\ ! 1129: * void ProcHookThread() ! 1130: * ! 1131: * Effects: This function will wait for the hook to have messages, when it ! 1132: * does, it will Set a memory semaphore, Post a WM_SEM1 message to the other ! 1133: * thread, and wait for the other thread has processed all of the messages. ! 1134: * ! 1135: * Return value: none ! 1136: \***************************************************************************/ ! 1137: ! 1138: void FAR ProcHookThread() ! 1139: { ! 1140: /* We'll look for a variation to run while the thread is active. */ ! 1141: ! 1142: while (TRUE) { ! 1143: /* ! 1144: * Wait for a message to become available. ! 1145: */ ! 1146: if (!SpyGetNextMessage(NULL, -1L)) ! 1147: break; ! 1148: ! 1149: /* ! 1150: * Now we have a message, set our semaphore, Post a WM_SEM2 ! 1151: * message to the Client window, and wait for the client to ! 1152: * clear the semaphore. ! 1153: */ ! 1154: DosSemSet((HSEM)(PULONG)&semThread); ! 1155: WinPostMsg(hwndSpy, WM_SEM2, (MPARAM)1, (MPARAM)1); ! 1156: DosSemWait((HSEM)(PULONG)&semThread, -1L); ! 1157: } ! 1158: ! 1159: DosExit(EXIT_THREAD, 0); ! 1160: } ! 1161: ! 1162: ! 1163: ! 1164: ! 1165: /**************************** Public Function ******************************\ ! 1166: * void ProcessQueueMsg(pqmsg) ! 1167: * ! 1168: * Effects: This function will process the hook, by calling the hooks ! 1169: * get message. We will than post the message to the current output ! 1170: * destinations. ! 1171: * ! 1172: * Return value: none ! 1173: \***************************************************************************/ ! 1174: ! 1175: void ProcessQueueMsg(pqmsg) ! 1176: QMSG *pqmsg; ! 1177: { ! 1178: MSGI *pmsgi; ! 1179: SHORT item; ! 1180: CHAR cSource; ! 1181: CHAR cThread; ! 1182: char szNextMessage[100]; ! 1183: char szTime[10]; ! 1184: SHORT cch; ! 1185: USHORT cchWritten; ! 1186: ! 1187: ! 1188: /* ! 1189: * Now lets Build the message to output ! 1190: */ ! 1191: if (WinIsWindow(hab, pqmsg->hwnd)) { ! 1192: if (WinIsChild(pqmsg->hwnd, hwndSpy)) ! 1193: return; /* dont want endless loops */ ! 1194: } ! 1195: ! 1196: cThread = ':'; ! 1197: if (pqmsg->time == (ULONG)-1) { ! 1198: /* Sent message */ ! 1199: szTime[0] = '\0'; ! 1200: cSource = 'S'; ! 1201: if (pqmsg->ptl.x) ! 1202: cThread = '*'; ! 1203: } else { ! 1204: cSource = 'I'; ! 1205: sprintf (szTime, "%-08lx", pqmsg->time); ! 1206: } ! 1207: ! 1208: if ((pmsgi = PmsgiFromMsg(pqmsg->msg)) == NULL) { ! 1209: /* ! 1210: * Message not in list, use default ! 1211: */ ! 1212: cch = sprintf(szNextMessage, ! 1213: "%c%cMSG:0x%04x H:%04x 1:%08lx 2:%08lx T:%s", ! 1214: cSource, cThread, (SHORT)pqmsg->msg, (SHORT)pqmsg->hwnd, ! 1215: pqmsg->mp1, pqmsg->mp2, szTime); ! 1216: } else if (pmsgi->wOptions & MSGI_MOUSE) { ! 1217: /* ! 1218: * Mouse message, decode to mouse types ! 1219: */ ! 1220: cch = sprintf(szNextMessage, ! 1221: "%c%c%-20s H:%04x X:%-4d Y:%-4d HT:%04x T:%s", ! 1222: cSource, cThread, pmsgi->szMsg, (SHORT)pqmsg->hwnd, ! 1223: SHORT1FROMMP(pqmsg->mp1), SHORT2FROMMP(pqmsg->mp1), ! 1224: SHORT1FROMMP(pqmsg->mp2), szTime); ! 1225: } else if (pmsgi->wOptions & MSGI_KEY) { ! 1226: /* ! 1227: * Key messages, output special ! 1228: */ ! 1229: cch = sprintf(szNextMessage, ! 1230: "%c%c%-20s H:%04x F:%04x R:%d S:%2x C:%04x(%c) V:%02x T:%s", ! 1231: cSource, cThread, pmsgi->szMsg, (SHORT)pqmsg->hwnd, ! 1232: SHORT1FROMMP(pqmsg->mp1), ! 1233: CHAR3FROMMP(pqmsg->mp1), CHAR4FROMMP(pqmsg->mp1), ! 1234: SHORT1FROMMP(pqmsg->mp2), SHORT1FROMMP(pqmsg->mp2), ! 1235: SHORT2FROMMP(pqmsg->mp2), szTime); ! 1236: } else { ! 1237: /* No special format */ ! 1238: cch = sprintf(szNextMessage, ! 1239: "%c%c%-20s H:%04x 1:%08lx 2:%08lx T:%s", ! 1240: cSource, cThread, pmsgi->szMsg, (SHORT)pqmsg->hwnd, ! 1241: pqmsg->mp1, pqmsg->mp2, szTime); ! 1242: } ! 1243: ! 1244: OutputString(szNextMessage, cch); ! 1245: } ! 1246: ! 1247: ! 1248: ! 1249: /**************************** Public Function ******************************\ ! 1250: * void OutputString(char szOut, SHORT cch); ! 1251: * ! 1252: * Effects: This function will output the specified string to the ! 1253: * destinations. ! 1254: * ! 1255: * Return value: none ! 1256: \***************************************************************************/ ! 1257: ! 1258: void OutputString(szOut, cch) ! 1259: char szOut[]; ! 1260: SHORT cch; ! 1261: { ! 1262: SHORT item; ! 1263: char *psz; ! 1264: USHORT cchWritten; ! 1265: ! 1266: ! 1267: ! 1268: /* Now display the new Line on the screen */ ! 1269: if (spyopt.fWindow) { ! 1270: item = (SHORT)WinSendMsg(hwndSpyList, LM_INSERTITEM, ! 1271: (MPARAM)LIT_END, (MPARAM)(PSZ)szOut); ! 1272: ! 1273: WinSendMsg(hwndSpyList, LM_SETTOPINDEX, (MPARAM)item, 0L); ! 1274: ! 1275: /* See if we have to many lines now */ ! 1276: while (item >= spyopt.cWindowLines) ! 1277: item = (SHORT)WinSendMsg(hwndSpyList, LM_DELETEITEM, ! 1278: (MPARAM)0, 0L); ! 1279: } ! 1280: ! 1281: /* now for file need cr/lf */ ! 1282: psz = szOut + cch; /* point to trailing null */ ! 1283: *psz++ = '\r'; ! 1284: *psz++ = '\n'; ! 1285: *psz = '\0'; ! 1286: ! 1287: if (spyopt.fFile) ! 1288: DosWrite(spyopt.hfileSpy, (PSZ)szOut, cch+2, ! 1289: (PUSHORT)&cchWritten); ! 1290: ! 1291: } ! 1292: ! 1293: ! 1294: /**************************** Public Function ******************************\ ! 1295: * MSGI * PmsgiFromMsg(USHORT msg) ! 1296: * ! 1297: * Effects: Locate the msg in the array of message items ! 1298: * ! 1299: * Return value: pointer to item that has the specified msg, or NULL ! 1300: \***************************************************************************/ ! 1301: MSGI *PmsgiFromMsg(msg) ! 1302: USHORT msg; ! 1303: { ! 1304: register MSGI *pmsgi = rgmsgi; /* Start at beginning */ ! 1305: register USHORT i; ! 1306: ! 1307: /* ! 1308: * Currently is a simple linear search, should be made faster ! 1309: * Probabably a binary search. ! 1310: */ ! 1311: for (i=0; i< cmsgi; i++) { ! 1312: if (pmsgi->msg == msg) ! 1313: return (pmsgi); ! 1314: if (pmsgi->msg > msg) ! 1315: return (NULL); ! 1316: pmsgi++; ! 1317: }; ! 1318: ! 1319: return (NULL); ! 1320: } ! 1321: ! 1322: ! 1323: ! 1324: ! 1325: /**************************** Public Function ******************************\ ! 1326: * MRESULT FAR PASCAL SpySaveListDlgProc(hwnd, msg, mp1, mp2) ! 1327: * ! 1328: * Effects: The Spy Windows Dialog procedure ! 1329: * ! 1330: * Return value: none ! 1331: \***************************************************************************/ ! 1332: MRESULT FAR PASCAL SpySaveListDlgProc(hwnd, msg, mp1, mp2) ! 1333: HWND hwnd; ! 1334: USHORT msg; ! 1335: MPARAM mp1; ! 1336: MPARAM mp2; ! 1337: { ! 1338: HFILE hfileOut; ! 1339: char szTemp[100]; ! 1340: char szTime[10]; ! 1341: char szDate[10]; ! 1342: SHORT cItems; ! 1343: SHORT iItem; ! 1344: USHORT cch; ! 1345: USHORT cchWritten; ! 1346: USHORT wAction; ! 1347: ULONG lTemp; ! 1348: ! 1349: switch (msg) { ! 1350: ! 1351: case WM_INITDLG: ! 1352: WinSendDlgItemMsg(hwnd, DID_APPEND, BM_SETCHECK, ! 1353: (MPARAM)spyopt.fAppend, 0L); ! 1354: /* Initialize the dialog items */ ! 1355: WinSetDlgItemText(hwnd, DID_FILENAME, spyopt.szSaveFileName); ! 1356: break; ! 1357: ! 1358: case WM_COMMAND: ! 1359: switch (SHORT1FROMMP(mp1)) { ! 1360: case DID_OK: ! 1361: /* ! 1362: * Get the file name, and try to open the file, ! 1363: * Then loop through and dump the listbox contents to the ! 1364: * file. ! 1365: */ ! 1366: spyopt.fAppend = (BOOL)WinSendDlgItemMsg(hwnd, ! 1367: DID_APPEND, BM_QUERYCHECK, 0L, 0L); ! 1368: ! 1369: WinQueryDlgItemText(hwnd, DID_FILENAME, ! 1370: sizeof(spyopt.szSaveFileName), spyopt.szSaveFileName); ! 1371: ! 1372: if (DosOpen((PSZ)spyopt.szSaveFileName, (HFILE far *)&hfileOut, ! 1373: (USHORT far *)&wAction, 0L, 0, ! 1374: spyopt.fAppend? 0x0011 : 0x0012, 0x00C1, 0L) == 0) { ! 1375: ! 1376: /* If append, get to the end of the file */ ! 1377: if (spyopt.fAppend) ! 1378: DosChgFilePtr(hfileOut, 0L, 2, (PULONG)&lTemp); ! 1379: ! 1380: /* Get count of items */ ! 1381: cItems = (SHORT)WinSendMsg(hwndSpyList, LM_QUERYITEMCOUNT, ! 1382: 0L, 0L); ! 1383: ! 1384: /* Write out a title block to the file */ ! 1385: _strdate(szDate); ! 1386: _strtime(szTime); ! 1387: DosWrite(hfileOut, ! 1388: (PSZ)"***************************************\r\n", ! 1389: 41, (PUSHORT)&cchWritten); ! 1390: cch = sprintf(szTemp, "* Spy: %-10s %-10s *\r\n", ! 1391: szDate, szTime); ! 1392: DosWrite(hfileOut, (PSZ)szTemp, cch, (PUSHORT)&cchWritten); ! 1393: ! 1394: DosWrite(hfileOut, ! 1395: (PSZ)"***************************************\r\n", ! 1396: 41, (PUSHORT)&cchWritten); ! 1397: ! 1398: ! 1399: /* Now output the list to the file */ ! 1400: for (iItem = 0; iItem < cItems; iItem++) { ! 1401: cch = (SHORT)WinSendMsg(hwndSpyList, LM_QUERYITEMTEXT, ! 1402: MPFROM2SHORT(iItem, sizeof(szTemp)), ! 1403: (MPARAM)(PSZ)szTemp); ! 1404: /* Add Newline at end of string */ ! 1405: szTemp[cch++] = '\r'; ! 1406: szTemp[cch++] = '\n'; ! 1407: szTemp[cch] = '\0'; ! 1408: DosWrite(hfileOut, (PSZ)szTemp, cch, ! 1409: (PUSHORT)&cchWritten); ! 1410: } ! 1411: DosClose(hfileOut); ! 1412: } ! 1413: ! 1414: case DID_CANCEL: ! 1415: /* Now dismiss the dialog */ ! 1416: WinDismissDlg(hwnd, SHORT1FROMMP(mp1)); ! 1417: break; ! 1418: break; ! 1419: } ! 1420: ! 1421: default: ! 1422: return(WinDefDlgProc(hwnd, msg, mp1, mp2)); ! 1423: } ! 1424: return 0L; ! 1425: } ! 1426: ! 1427: ! 1428: /**************************** Public Function ******************************\ ! 1429: * SelOrDeselWithMouse(BOOL fSelect) ! 1430: * ! 1431: * Effects: Fastway to add/or remove window from watch list ! 1432: * ! 1433: * Return value: none ! 1434: \***************************************************************************/ ! 1435: ! 1436: void SelOrDeselWithMouse(fSelect) ! 1437: BOOL fSelect; ! 1438: { ! 1439: HWND rghwnd[MAXHWNDS]; ! 1440: HWND hwndPoint; ! 1441: SHORT chwnd; ! 1442: BOOL fWinCurInList; ! 1443: SHORT i; ! 1444: ! 1445: /* First get the window of interest */ ! 1446: hwndPoint = HwndSelWinWithMouse(hwndSpy, FALSE); ! 1447: if (hwndPoint == NULL) ! 1448: return; /* No window selected */ ! 1449: fWinCurInList = SpyFWindowInList(hwndPoint); ! 1450: ! 1451: if ((fWinCurInList && fSelect) ! 1452: || (!fWinCurInList && !fSelect)) ! 1453: return; /* Alredy right state */ ! 1454: ! 1455: chwnd = SpyGetWindowList(MAXHWNDS, (HWND FAR *)rghwnd); ! 1456: ! 1457: if (fSelect) { ! 1458: /* Add window to end of list */ ! 1459: rghwnd[chwnd++] = hwndPoint; ! 1460: } else { ! 1461: /* find it in the list, and delete it out */ ! 1462: for (i=0; rghwnd[i] != hwndPoint; i++) ! 1463: ; ! 1464: ! 1465: /* Now copy rest of them down */ ! 1466: chwnd--; /* One less item */ ! 1467: for (;i < chwnd; i++ ) { ! 1468: rghwnd[i] = rghwnd[i+1]; ! 1469: } ! 1470: } ! 1471: ! 1472: /* Now call to update the list */ ! 1473: SpySetWindowList(chwnd, (HWND FAR *)rghwnd); ! 1474: } ! 1475: ! 1476: ! 1477: /**************************** Public Function ******************************\ ! 1478: * EnableOrDisableMsg(BOOL fEnable) ! 1479: * ! 1480: * Effects: Fastway to enable or disable a particular message code. The one ! 1481: * that is currently selected in the output listbox. ! 1482: * ! 1483: * Return value: none ! 1484: \***************************************************************************/ ! 1485: ! 1486: void EnableOrDisableMsg(fEnable) ! 1487: BOOL fEnable; ! 1488: { ! 1489: USHORT itemSel; ! 1490: char szTemp[100]; ! 1491: char *psz; ! 1492: MSGI *pmsgi; ! 1493: SHORT i; ! 1494: ! 1495: itemSel = (USHORT)WinSendMsg(hwndSpyList, LM_QUERYSELECTION, ! 1496: (MPARAM)LIT_FIRST, 0L); ! 1497: if (itemSel == (USHORT)LIT_NONE) ! 1498: return; /* None to process */ ! 1499: ! 1500: /* Get the message text */ ! 1501: WinSendMsg(hwndSpyList, LM_QUERYITEMTEXT, ! 1502: MPFROM2SHORT(itemSel, sizeof(szTemp)), (MPARAM)(PSZ)szTemp); ! 1503: ! 1504: /* Now lets extract the messgae string from the line */ ! 1505: psz = &szTemp[3]; ! 1506: while (*psz != ' ') ! 1507: psz++; /* locate first blank */ ! 1508: *psz = '\0'; /* Zero terminate string */ ! 1509: ! 1510: ! 1511: /* ! 1512: * Loop through all of the items in our list, until we find a ! 1513: * string that matches our string. ! 1514: */ ! 1515: pmsgi = rgmsgi; /* Point to start of list */ ! 1516: for (i = 0; i < cmsgi; i++) { ! 1517: if (strcmp(&szTemp[2], pmsgi->szMsg) == 0) { ! 1518: /* ! 1519: * Found our message, update the bit of the message, and ! 1520: * call the function to let the hook know the new results ! 1521: */ ! 1522: if (fEnable) ! 1523: pmsgi->wOptions |= MSGI_ENABLED; ! 1524: else ! 1525: pmsgi->wOptions &= ~MSGI_ENABLED; ! 1526: ! 1527: UpdateHooksMsgTable(); /* Set Spys Msg table */ ! 1528: return; ! 1529: } ! 1530: pmsgi++; ! 1531: } ! 1532: } ! 1533: ! 1534: ! 1535: ! 1536: /**************************** Public Function ******************************\ ! 1537: * DumpOneWindowInfo() ! 1538: * ! 1539: * Effects: Dump the information about one window to the current outputs ! 1540: * ! 1541: * Return value: none ! 1542: \***************************************************************************/ ! 1543: void DumpOneWindowInfo() ! 1544: { ! 1545: HWND hwndPoint; ! 1546: HWND hwndT; ! 1547: SHORT wLevel; ! 1548: ! 1549: hwndPoint = HwndSelWinWithMouse(hwndSpy, FALSE); ! 1550: if (hwndPoint == NULL) ! 1551: return; /* No window selected */ ! 1552: ! 1553: /* Now see what level the window is at */ ! 1554: wLevel = 0; ! 1555: hwndT = hwndPoint; ! 1556: while (hwndT != NULL) { ! 1557: wLevel++; ! 1558: hwndT = WinQueryWindow(hwndT, QW_PARENT, FALSE); ! 1559: }; ! 1560: ! 1561: ! 1562: DumpWindowInfo(hwndPoint, wLevel); ! 1563: } ! 1564: ! 1565: ! 1566: /**************************** Private Function ******************************\ ! 1567: * DumpAllWIndowsInfo (HWND hwnd, WORD wLevel) ! 1568: * ! 1569: * Effects: Dumps the complet window list out to the current output units. ! 1570: * ! 1571: * ! 1572: * Return value: ! 1573: \***************************************************************************/ ! 1574: void DumpAllWindowsInfo(hwnd, wLevel) ! 1575: HWND hwnd; ! 1576: SHORT wLevel; ! 1577: { ! 1578: HWND hwndT; ! 1579: SPWD *pspwdT; ! 1580: ! 1581: pspwdT = pspwd + wDumpCount; ! 1582: DumpWindowInfo(hwnd, wLevel); ! 1583: pspwdT->hwnd = hwnd; ! 1584: pspwdT->index = wDumpCount; ! 1585: ! 1586: ! 1587: /* ! 1588: * Then we recurse with all of our children ! 1589: */ ! 1590: if ((hwndT = WinQueryWindow(hwnd, QW_TOP, FALSE)) != NULL) ! 1591: DumpAllWindowsInfo(hwndT, wLevel+1); ! 1592: ! 1593: /* ! 1594: * Then go to our next sibling ! 1595: */ ! 1596: if ((hwndT = WinQueryWindow(hwnd, QW_NEXT, FALSE)) != NULL) ! 1597: DumpAllWindowsInfo(hwndT, wLevel); ! 1598: } ! 1599: ! 1600: ! 1601: ! 1602: /**************************** Private Function ******************************\ ! 1603: * DumpWindowIndex (void) ! 1604: * ! 1605: * Effects: Dump a sorted list of Hwnds and index into other list ! 1606: * This function works like sh.t ! 1607: * ! 1608: * ! 1609: * Return value: ! 1610: \***************************************************************************/ ! 1611: void DumpWindowIndex() ! 1612: { ! 1613: SHORT cch; ! 1614: char szTemp[20]; ! 1615: char szOutput[100]; ! 1616: HWND hwndT; ! 1617: SPWD *pspwdT; ! 1618: SHORT i; ! 1619: ! 1620: /* Sort the hwnds first */ ! 1621: qsort((void *)pspwd, wDumpCount, sizeof(SPWD), CompareHwnds); ! 1622: pspwdT = pspwd; ! 1623: ! 1624: strcpy (szOutput, "Index of Window Handles"); ! 1625: cch = strlen(szOutput); ! 1626: for (i=0; i< wDumpCount; i++) { ! 1627: if ((i & 3) == 0) { ! 1628: /* 4 per row */ ! 1629: OutputString(szOutput, cch); ! 1630: szOutput[0] = '\0'; ! 1631: cch = 0; ! 1632: } ! 1633: ! 1634: cch += sprintf(szTemp, "%3d-%04x ", ! 1635: pspwdT->index, (USHORT)pspwdT->hwnd); ! 1636: strcat (szOutput, szTemp); ! 1637: pspwdT++; ! 1638: } ! 1639: ! 1640: OutputString(szOutput, cch); ! 1641: ! 1642: } ! 1643: ! 1644: ! 1645: /**************************** Private Function ******************************\ ! 1646: * int CompareHwnds(SPWD *pspwd1, SPWD *pspwd2) ! 1647: * ! 1648: * Effects: Compares two window handles. ! 1649: * ! 1650: * ! 1651: * Return value: ! 1652: \***************************************************************************/ ! 1653: int cdecl CompareHwnds(pspwd1, pspwd2) ! 1654: const void *pspwd1; ! 1655: const void *pspwd2; ! 1656: { ! 1657: return (((SPWD *)pspwd1)->hwnd < ((SPWD *)pspwd2)->hwnd)? -1 : 1; ! 1658: } ! 1659: ! 1660: ! 1661: ! 1662: ! 1663: /**************************** Private Function *****************************\ ! 1664: * DumpWindowInfo(HWND hwnd, SHORT wLevel) ! 1665: * ! 1666: * Effects: Displays the information about the selected window in the dialog ! 1667: * ! 1668: * ! 1669: * Return value: ! 1670: \***************************************************************************/ ! 1671: void DumpWindowInfo(hwnd, wLevel) ! 1672: HWND hwnd; ! 1673: SHORT wLevel; ! 1674: { ! 1675: HWND hwndParent; ! 1676: HWND hwndChild; ! 1677: HWND hwndOwner; ! 1678: ! 1679: char szTemp[100]; ! 1680: SHORT cch; ! 1681: char szClass[30]; ! 1682: RECTL rcl; ! 1683: USHORT id; ! 1684: ULONG ul; ! 1685: ULONG ulStyle; ! 1686: ULONG ulPFNWP; ! 1687: ULONG ulHMQ; ! 1688: ! 1689: hwndParent = WinQueryWindow(hwnd, QW_PARENT, FALSE); ! 1690: hwndChild = WinQueryWindow(hwnd, QW_TOP, FALSE); ! 1691: hwndOwner = WinQueryWindow(hwnd, QW_OWNER, FALSE); ! 1692: id = (USHORT)WinQueryWindowUShort(hwnd, QWS_ID); ! 1693: ulHMQ = (ULONG)WinQueryWindowULong(hwnd, QWL_HMQ); ! 1694: WinQueryWindowRect(hwnd, &rcl); ! 1695: WinMapWindowPoints(hwnd, hwndParent, (PPOINTL)&rcl, 2); ! 1696: ! 1697: cch = sprintf(szTemp, ! 1698: "%d-H:%04x(%d) P:%04x C:%04x O:%04x ID:%04x MQ:%04x (%d, %d) (%d, %d)", ! 1699: ++wDumpCount, (SHORT)hwnd, wLevel, (SHORT)hwndParent, ! 1700: (SHORT)hwndChild, (SHORT)hwndOwner, id, (SHORT)ulHMQ, ! 1701: (SHORT)rcl.xLeft, (SHORT)rcl.yBottom, ! 1702: (SHORT)rcl.xRight, (SHORT)rcl.yTop); ! 1703: ! 1704: OutputString(szTemp, cch); ! 1705: ! 1706: ulStyle = (ULONG)WinQueryWindowULong(hwnd, QWL_STYLE); ! 1707: ulPFNWP = (ULONG)WinQueryWindowULong(hwnd, QWP_PFNWP); ! 1708: WinQueryClassName(hwnd, sizeof(szClass), (PSZ)szClass); ! 1709: ! 1710: cch = sprintf(szTemp, ! 1711: " St:%08lx Pf:%p Cl:%s", ! 1712: ulStyle, ulPFNWP, szClass); ! 1713: OutputString(szTemp, cch); ! 1714: } ! 1715: ! 1716: ! 1717: ! 1718: /**************************** Public Function *****************************\ ! 1719: * AboutWndProc(HWND hwnd, USHORT message, MPARAM mp1, MPARAM mp2) ! 1720: * ! 1721: * Effects: About Spy Dialog procedure ! 1722: * ! 1723: * ! 1724: * Return value: ! 1725: \***************************************************************************/ ! 1726: MRESULT FAR PASCAL AboutWndProc(hwnd, message, mp1, mp2) ! 1727: HWND hwnd; ! 1728: USHORT message; ! 1729: MPARAM mp1; ! 1730: MPARAM mp2; ! 1731: { ! 1732: switch (message) { ! 1733: case WM_COMMAND: ! 1734: WinDismissDlg(hwnd, TRUE); ! 1735: break; ! 1736: default: ! 1737: return(WinDefDlgProc(hwnd, message, mp1, mp2)); ! 1738: break; ! 1739: } ! 1740: return 0L; ! 1741: ! 1742: } /* end aboutwndproc */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.