|
|
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.