|
|
1.1 root 1: /****************************** Module Header ******************************\
2: * Module Name: spy.c - Spy application
3: *
4: * Created: Microsoft, IBM Corporation 1990
5: *
6: * DISCLAIMER OF WARRANTIES. The following [enclosed] code is
7: * sample code created by Microsoft Corporation and/or IBM
8: * Corporation. This sample code is not part of any standard
9: * Microsoft or IBM product and is provided to you solely for
10: * the purpose of assisting you in the development of your
11: * applications. The code is provided "AS IS", without
12: * warranty of any kind. Neither Microsoft nor IBM shall be
13: * liable for any damages arising out of your use of the sample
14: * code, even if they have been advised of the possibility of
15: * such damages.
16: *
17: \***************************************************************************/
18:
19: #define INCL_WIN
20: #define INCL_WINSYS
21: #define INCL_DOSPROCESS
22: #define INCL_DOSSEMAPHORES
23: #define INCL_DOSMODULEMGR
24: #define INCL_DOSRESOURCES
25: #define INCL_HELP
26: #include <os2.h>
27: #include <stdio.h>
28: #include <string.h>
29: #include "spy.h"
30: #include "spyhk32.h"
31: #include "help.h"
32: #include <time.h>
33: #include <stdlib.h>
34:
35:
36: /************* GLOBAL VARIABLES */
37:
38: /************************** IN SPY.H *********************************** */
39: HAB hab;
40: HMQ hmqSpy;
41: HWND hwndSpy;
42: HWND hwndSpyFrame;
43: HWND hwndSpyList = NULL;
44: HWND hwndWindowLB;
45: HWND hwndMessageLB;
46: HWND hwndHelpInstance = NULL;
47: HHEAP hHeap;
48: SHORT cxBorder;
49: SHORT cyBorder;
50: ULONG uVersion;
51: BOOL fV11 = TRUE; // Are we version 1.1?
52:
53: HPOINTER hptrArrow;
54: HPOINTER hptrSelWin;
55: HPOINTER hptrIcon11 = NULL; /* 1.1 Spy Icon */
56:
57: BOOL fDebug = FALSE;
58: USHORT iCurItemFocus; /* Index to item that has the focus */
59: BOOL fSpyActive = MIA_CHECKED; /* Any non-zero is true */
60: BOOL fTrackingListBox = FALSE; /* Tracking windows active ? */
61: BOOL fAllFrames = 0; /* Are we processing all frames ? */
62: BOOL fAllWindows = 0; /* Are we processing all windows ? */
63:
64:
65: HWND hwndWinDlgDisp = NULL; /* hwnds info in Window Dialog */
66:
67: SHORT wDumpCount = 0; /* Count of which window is being dumped */
68: SPWD *pspwd = NULL;
69: /*********************************************************************** */
70:
71: /* Define memory semaphore to have second thread sleep on */
72: HEV hevThread; /* Event semaphore to wait on */
73: UCHAR rgMsgData[MAXMSGBYTES]; /* Max bytes to extract per message */
74:
75:
76: char szSpyClass[] = "Spy";
77: char szTitle[] = "32-bit spy sample";
78:
79: /************* PROCEDURE DECLARATIONS */
80:
81:
82:
83: void ProcHookThread(void); /* will process the hook messages */
84:
85: void ProcessQueueMsg(QMSGSPY *);
86: void UpdateMsgBoxCurMsgText(HWND);
87: void InitializeOptions(int, char **); /* initialize Spy initial state */
88: void InitializeMenus(void);
89: void InitializeHelp(void);
90: void DebugBreak(void);
91:
92: PSZ DumpParam(PSZ prgData, SHORT cb, BOOL fValidData,
93: UCHAR bMPType);
94:
95: /* Define some variables needed for help processing */
96:
97:
98: /**************************** Public Function ******************************\
99: * int cdecl main (argc, argv)
100: *
101: * Effects: Spy Main function
102: *
103: * Return value:
104: \***************************************************************************/
105: int main(argc, argv)
106: int argc;
107: char **argv;
108: {
109: ULONG flCreateFlags;
110: QMSG qmsg;
111: RECTL rcl;
112: TID tid;
113:
114:
115: // Make sure the Spy Hook DLL is initialized
116: SpyInitializeHook();
117:
118: hab = WinInitialize(0);
119: uVersion = WinQueryVersion(hab);
120: if ((LOBYTE(LOUSHORT(uVersion)) > 10) ||
121: (HIBYTE(LOUSHORT(uVersion)) > 10))
122: fV11 = FALSE;
123:
124: hmqSpy = WinCreateMsgQueue(hab, 0);
125:
126: if (!WinRegisterClass((HAB)NULL, szSpyClass, (PFNWP)SpyWndProc,
127: CS_SYNCPAINT, 0)) {
128: WinAlarm(HWND_DESKTOP, WA_ERROR);
129: return(0);
130: }
131:
132: /*
133: * We need to process the options, before we create a heap, or we
134: * will blow away our options
135: */
136: InitializeOptions(argc, argv); /* initialize Spy initial state */
137:
138: /*
139: * Create a heap for the program
140: */
141: hHeap = WinCreateHeap(0, 0, 0, 0, 0, 0);
142:
143: hptrArrow = WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, TRUE);
144: cxBorder = (SHORT)WinQuerySysValue(HWND_DESKTOP, SV_CXBORDER);
145: cyBorder = (SHORT)WinQuerySysValue(HWND_DESKTOP, SV_CYBORDER);
146:
147: hptrSelWin = WinQuerySysPointer(HWND_DESKTOP, SPTR_MOVE, TRUE);
148:
149: SpyInstallHook(hab, hmqSpy, spyopt.bHooks);
150: SpySetAllWindowOpt (fAllWindows);
151: SpySetAllFrameOpt (fAllFrames);
152:
153: flCreateFlags = FCF_TITLEBAR | FCF_SYSMENU | FCF_SIZEBORDER
154: | FCF_MINMAX | FCF_SHELLPOSITION | FCF_TASKLIST | FCF_MENU
155: | FCF_ACCELTABLE | FCF_ICON;
156:
157: // See if we get here
158: hwndSpyFrame = WinCreateStdWindow(HWND_DESKTOP,
159: WS_VISIBLE,
160: (PULONG)&flCreateFlags,
161: (PSZ)szSpyClass, (PSZ)szTitle,
162: WS_VISIBLE,
163: (HMODULE)NULL, IDR_SPY,
164: (PHWND)&hwndSpy);
165:
166: WinQueryWindowRect(hwndSpy, &rcl);
167: hwndSpyList = WinCreateWindow (hwndSpy, WC_LISTBOX, "",
168: fV11 ? (WS_VISIBLE | LS_NOADJUSTPOS) :
169: (WS_VISIBLE | LS_NOADJUSTPOS | LS_HORZSCROLL),
170: -cxBorder, -cyBorder,
171: (SHORT)(rcl.xRight - rcl.xLeft) + 2 * cxBorder,
172: (SHORT)(rcl.yTop - rcl.yBottom) + 2 * cyBorder,
173: hwndSpy, HWND_TOP, DID_SPYLIST, NULL, NULL);
174:
175: /*
176: * Read the os2.ini information if it exists, and set the menu items
177: * to correspond to the initial state read from OS2.ini
178: */
179: InitializeMenus();
180: InitializeHelp();
181:
182: /*
183: * Set the focus to the list box. Note: Only call WinSetFocus if
184: * our frame is the active window. As we may have been started in
185: * the background. If this is the case, we want to set the frames
186: * focus save to the listbox, such that it will be the active window
187: * when our frame is activated
188: */
189: if (WinQueryWindow(HWND_DESKTOP, QW_TOP, FALSE) == hwndSpyFrame)
190: WinSetFocus(HWND_DESKTOP, hwndSpyList);
191: else
192: WinSetWindowULong(hwndSpyFrame, QWL_HWNDFOCUSSAVE,
193: (ULONG)hwndSpyList);
194:
195:
196:
197: /* Start the thread that will process the messages from the hook */
198: DosCreateEventSem(NULL, &hevThread, 0L, FALSE);
199: DosCreateThread((PTID)&tid, ProcHookThread, 0L, 0L, 4096L);
200:
201: UpdateHooksMsgTable(); /* Set Spys Msg table */
202: SpyHookOnOrOff (TRUE); /* Turn the hook on */
203:
204:
205: /*
206: * Now process all of the messages
207: */
208: while (WinGetMsg(NULL, (PQMSG)&qmsg, NULL, 0, 0)) {
209: WinDispatchMsg(NULL, (PQMSG)&qmsg);
210: }
211:
212: SpyReleaseHook (TRUE); /* Release input hook */
213:
214: WinDestroyWindow(hwndSpyFrame);
215: SpyTerminateHook ();
216:
217: WinDestroyPointer(hptrArrow);
218: WinDestroyPointer(hptrSelWin);
219: if (hptrIcon11 != NULL)
220: WinDestroyPointer (hptrIcon11);
221:
222: if (hwndHelpInstance != NULL)
223: WinDestroyHelpInstance(hwndHelpInstance);
224:
225:
226: WinDestroyMsgQueue(hmqSpy);
227: WinTerminate(hab);
228:
229: /* If the spy output file is open, close it now */
230: if (spyopt.hfileSpy != NULL)
231: DosClose(spyopt.hfileSpy);
232:
233:
234: DosExit(EXIT_PROCESS, 0);
235: }
236:
237:
238:
239:
240: /**************************** Public Function ******************************\
241: * InitializeOptions(argc, argv)
242: *
243: * Effects: Initialize spy, first from the default options, second from
244: * OS2.INI file, and override from command switches.
245: *
246: * Return value:
247: \***************************************************************************/
248: VOID InitializeOptions(argc, argv)
249: int argc;
250: char **argv;
251: {
252: ULONG cch;
253:
254:
255: /*
256: * If the OS2.INI information exists, initialize our options to
257: * the stored values
258: */
259: if (PrfQueryProfileSize (HINI_USER, "Spy", "Options", &cch) == 0) {
260: cch = sizeof(SPYOPT);
261:
262: PrfQueryProfileData(HINI_USER, "Spy", "Options", (PSZ)&spyopt,
263: &cch);
264: PrfQueryProfileString(HINI_USER, "Spy", "FileName", "spy.out",
265: (PSZ)spystr.szFileName, sizeof(spystr.szFileName));
266: PrfQueryProfileString(HINI_USER, "Spy", "SaveFileName", "spy.lis",
267: (PSZ)spystr.szSaveFileName, sizeof(spystr.szSaveFileName));
268: }
269:
270: /*
271: * Then check for command line overrides
272: */
273: while (argc > 1) {
274: argv++; /* get beyond the program name */
275:
276: /* Test for debug flag */
277: if (!strcmpi(*argv, "/d") ) {
278: fDebug = TRUE;
279: DebugBreak();
280: }
281:
282: /* Test for send message hook flag */
283: if (!strcmpi(*argv, "+s"))
284: spyopt.bHooks |= SPYH_SENDMSG;
285: if (!strcmpi(*argv, "-s"))
286: spyopt.bHooks &= ~SPYH_SENDMSG;
287:
288: /* Test for input hook flag */
289: if (!strcmpi(*argv, "+i"))
290: spyopt.bHooks |= SPYH_INPUT;
291: if (!strcmpi(*argv, "-i"))
292: spyopt.bHooks &= ~SPYH_INPUT;
293:
294: argc--;
295: }
296: }
297:
298:
299:
300: /**************************** Public Function ******************************\
301: * InitializeMenus()
302: *
303: * Effects: Initialize the menus from the initialized defaults.
304: *
305: * Return value:
306: \***************************************************************************/
307: VOID InitializeMenus()
308: {
309: HWND hwndMenu;
310: USHORT wAction;
311:
312: /*
313: * Now we need to update the menu items to the final
314: * state
315: */
316: hwndMenu = WinWindowFromID(hwndSpyFrame, FID_MENU);
317:
318: WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(CMD_INPUTHOOK, TRUE),
319: MPFROM2SHORT(MIA_CHECKED,
320: (spyopt.bHooks & SPYH_INPUT) ? MIA_CHECKED : 0));
321: WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(CMD_SENDMSGHOOK, TRUE),
322: MPFROM2SHORT(MIA_CHECKED,
323: (spyopt.bHooks & SPYH_SENDMSG) ? MIA_CHECKED : 0));
324:
325: WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(CMD_SENDEXTEND, TRUE),
326: MPFROM2SHORT(MIA_CHECKED,
327: spyopt.fSendExtend ? MIA_CHECKED : 0));
328:
329: WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(CMD_OUTSCREEN, TRUE),
330: MPFROM2SHORT(MIA_CHECKED, spyopt.fWindow ? MIA_CHECKED : 0));
331:
332: WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(CMD_OUTTERM, TRUE),
333: MPFROM2SHORT(MIA_CHECKED, spyopt.fDebugOutput ? MIA_CHECKED : 0));
334:
335: WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(CMD_OUTFILE, TRUE),
336: MPFROM2SHORT(MIA_CHECKED, spyopt.fFile ? MIA_CHECKED : 0));
337:
338: WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(CMD_ALPHASORT, TRUE),
339: MPFROM2SHORT(MIA_CHECKED,
340: spyopt.fAlphaSortMsgList ? MIA_CHECKED : 0));
341:
342: /*
343: * If the options specify output to file, open the file now
344: */
345: if (spyopt.fFile) {
346: if (DosOpen((PSZ)spystr.szFileName, &spyopt.hfileSpy,
347: (ULONG *)&wAction, 0L, 0,
348: 0x0012, 0x00C1, 0L) != 0)
349: spyopt.hfileSpy = NULL; /* Failed on open */
350: }
351: }
352:
353:
354:
355: /**************************** Public Function ******************************\
356: * InitializeHelp
357: *
358: * Effects: Initialize the help subsubsystem.
359: *
360: *
361: * Return value:
362: \***************************************************************************/
363: VOID InitializeHelp()
364: {
365:
366: /*
367: * Now initialize Help - First we need to verify that the the help
368: * DLL is avaialable, if not, we will not do help processing.
369: */
370: HELPINIT hi;
371: char szTitle[256]; /* Assume the title is not more than 256 chars */
372: HWND hwndMenu;
373: SHORT sMenuIndex;
374:
375: /* Now try to create the help instance */
376: hi.hmodHelpTableModule =
377: hi.hmodAccelActionBarModule = (HMODULE)NULL;
378: hi.pszTutorialName = (PSZ)NULL;
379: hi.pszHelpLibraryName = "spy32.hlp";
380: hi.idAccelTable =
381: hi.idActionBar = 0;
382: hi.cb = sizeof(HELPINIT);
383: hi.usShowPanelId = CMIC_HIDE_PANEL_ID;
384: hi.phtHelpTable = (PHELPTABLE)MAKEULONG(IDR_SPY, 0xffff);
385:
386: WinQueryWindowText(hwndSpyFrame, sizeof(szTitle), szTitle);
387: hi.pszHelpWindowTitle = szTitle;
388:
389: hwndHelpInstance = WinCreateHelpInstance(hab, &hi);
390: if (hwndHelpInstance != NULL) {
391: if(!WinAssociateHelpInstance(hwndHelpInstance, hwndSpyFrame) ) {
392: WinDestroyHelpInstance(hwndHelpInstance);
393: hwndHelpInstance = (HWND)NULL;
394: }
395: }
396:
397: if (hwndHelpInstance == NULL) {
398: /* Help was not initialized, so gray out help items */
399: hwndMenu = WinWindowFromID(hwndSpyFrame, FID_MENU);
400: for (sMenuIndex = CMD_HOWHELP; sMenuIndex <= CMD_HELPINDEX;
401: sMenuIndex++) {
402: WinSendMsg(hwndMenu, MM_SETITEMATTR,
403: MPFROM2SHORT(sMenuIndex, TRUE),
404: MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED));
405: }
406: }
407: }
408:
409:
410:
411: /**************************** Public Function ******************************\
412: * MRESULT EXPENTRY SpyWndProc(hwnd, msg, mp1, mp2)
413: *
414: * Effects: Spy Client window procedure
415: *
416: *
417: * Return value:
418: \***************************************************************************/
419: MRESULT EXPENTRY SpyWndProc(hwnd, msg, mp1, mp2)
420: HWND hwnd;
421: USHORT msg;
422: MPARAM mp1;
423: MPARAM mp2;
424: {
425: QMSGSPY qmsgspy;
426: VOID SpyPaint();
427: SHORT cBytes;
428: ULONG ulAction;
429:
430: switch (msg) {
431: case WM_CREATE:
432: /* Set up this global first thing in case we need it elsewhere */
433: hwndSpy = hwnd;
434: break;
435:
436: case WM_SEM2:
437: /*
438: * Other thread told use there are some messages out there. Loop
439: * through and process all of the pending messages, and output
440: * the listbox position at the end. Also make sure to flush
441: * the file buffer before we go back to sleep.
442: */
443: while (SpyGetNextMessage(&qmsgspy, rgMsgData, sizeof(rgMsgData), 0L)) {
444: ProcessQueueMsg(&qmsgspy);
445: }
446:
447: if (spyopt.fFile)
448: DosBufReset(spyopt.hfileSpy);
449:
450: DosPostEventSem(hevThread);
451:
452: break;
453:
454: case WM_COMMAND:
455: switch (SHORT1FROMMP(mp1)) {
456: case CMD_ACTIVE:
457:
458: /*
459: * THe active menu item was selected, we will toggle the
460: * the selection by setting active to 0 or MIA_CHECKED.
461: * Call the hook, and then update the checkmark on the menu
462: */
463: fSpyActive ^= MIA_CHECKED; /* Toggle on or off */
464: SpyHookOnOrOff (fSpyActive);
465: WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
466: MM_SETITEMATTR, MPFROM2SHORT(CMD_ACTIVE, TRUE),
467: MPFROM2SHORT(MIA_CHECKED, fSpyActive));
468:
469: break;
470: case CMD_ABOUT:
471: WinDlgBox(HWND_DESKTOP, hwnd, (PFNWP)AboutWndProc, NULL,
472: IDD_About1Dlg, (PCH)NULL);
473: break;
474:
475: case CMD_EXIT:
476: WinPostMsg(NULL, WM_QUIT, 0L, 0L);
477: break;
478:
479: case CMD_CLRWIN:
480: /*
481: * Delete all items in the list. Simply do this
482: * By deleting the first item, until the count goes to
483: * zero
484: */
485: WinSendMsg(hwndSpyList, LM_DELETEALL, 0L, 0L);
486: break;
487:
488: case CMD_SAVEWIN:
489: SpyHookOnOrOff (FALSE);
490: WinDlgBox(HWND_DESKTOP, hwndSpyFrame,
491: (PFNWP)SpySaveListDlgProc, (HMODULE)NULL,
492: IDD_SaveListDlg, (PCH)NULL);
493: SpyHookOnOrOff (fSpyActive);
494: break;
495:
496: /*
497: * This command saves out the current options to OS2.ini
498: */
499: case CMD_SAVEOPT:
500: PrfWriteProfileData(HINI_USER, "Spy", "Options", (PSZ)&spyopt,
501: sizeof(SPYOPT));
502: PrfWriteProfileString(HINI_USER, "Spy", "FileName",
503: (PSZ)spystr.szFileName);
504: PrfWriteProfileString(HINI_USER, "Spy", "SaveFileName",
505: (PSZ)spystr.szSaveFileName);
506:
507: break;
508:
509: case CMD_WINDOWS:
510: SpyHookOnOrOff (FALSE);
511: hwndWindowLB = NULL;
512: iCurItemFocus = (USHORT)-1;
513: WinDlgBox(HWND_DESKTOP, hwndSpyFrame,
514: (PFNWP)SpyWindowsDlgProc, (HMODULE)NULL,
515: IDD_WindowsDlg, (PCH)NULL);
516:
517: SpyHookOnOrOff (fSpyActive);
518: break;
519:
520: case CMD_QUEUES:
521: SpyHookOnOrOff (FALSE);
522: hwndWindowLB = NULL;
523: iCurItemFocus = (USHORT)-1;
524: WinDlgBox(HWND_DESKTOP, hwndSpyFrame,
525: (PFNWP)SpyQueuesDlgProc, (HMODULE)NULL,
526: IDD_MsgQueueDlg, (PCH)NULL);
527:
528: SpyHookOnOrOff (fSpyActive);
529: break;
530:
531: case CMD_WNMSSEL:
532: case CMD_WNMSDSL:
533: SpyHookOnOrOff (FALSE);
534: SelOrDeselWithMouse(SHORT1FROMMP(mp1) == CMD_WNMSSEL);
535: SpyHookOnOrOff (fSpyActive);
536: break;
537:
538: case CMD_ALLWNDWS:
539:
540: /*
541: * The user selected the ALLFRAMES, toggle the state, and
542: * update the menu and the hook state.
543: */
544: fAllWindows ^= MIA_CHECKED; /* Toggle on or off */
545: SpySetAllWindowOpt (fAllWindows);
546: WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
547: MM_SETITEMATTR, MPFROM2SHORT(CMD_ALLWNDWS, TRUE),
548: MPFROM2SHORT(MIA_CHECKED, fAllWindows));
549: break;
550:
551: case CMD_ALLFRAMES:
552:
553: /*
554: * The user selected the ALLFRAMES, toggle the state, and
555: * update the menu and the hook state.
556: */
557: fAllFrames ^= MIA_CHECKED; /* Toggle on or off */
558: SpySetAllFrameOpt (fAllFrames);
559: WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
560: MM_SETITEMATTR, MPFROM2SHORT(CMD_ALLFRAMES, TRUE),
561: MPFROM2SHORT(MIA_CHECKED, fAllFrames));
562: break;
563:
564: case CMD_WNDPWIN:
565: wDumpCount = 0;
566: DumpOneWindowInfo();
567: break;
568: case CMD_WNDPALL:
569: wDumpCount = 0;
570: pspwd = (SPWD *)WinAllocMem(hHeap, sizeof(SPWD)* MAXSPYDUMP);
571: cBytes = DumpAllWindowsInfo(HWND_DESKTOP, 0);
572: cBytes += DumpAllWindowsInfo(HWND_OBJECT, -10);
573: DumpWindowIndex(cBytes);
574: WinFreeMem(hHeap, (char *)pspwd, sizeof(SPWD)* MAXSPYDUMP);
575: break;
576: case CMD_DACCEL:
577: DumpFrameAcclTable();
578: break;
579:
580: case CMD_MESSAGES:
581: SpyHookOnOrOff (FALSE);
582: WinDlgBox(HWND_DESKTOP, hwndSpyFrame,
583: (PFNWP)SpyMsgDlgProc, (HMODULE)NULL,
584: IDD_MessagesDlg, (PCH)NULL);
585: SpyHookOnOrOff (fSpyActive);
586: break;
587:
588: case CMD_ALPHASORT:
589: spyopt.fAlphaSortMsgList ^= TRUE;
590:
591: WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
592: MM_SETITEMATTR, MPFROM2SHORT(CMD_ALPHASORT, TRUE),
593: MPFROM2SHORT(MIA_CHECKED,
594: spyopt.fAlphaSortMsgList ? MIA_CHECKED : 0));
595: break;
596:
597: case CMD_SENDMSG:
598: WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
599: MM_SETITEMATTR, MPFROM2SHORT(CMD_SENDMSG, TRUE),
600: MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED));
601: WinLoadDlg(HWND_DESKTOP, hwndSpyFrame,
602: (PFNWP)SendMsgDlgProc, (HMODULE)NULL,
603: IDD_SendMsgDlg, (PCH)NULL);
604: break;
605:
606: /*
607: * The command in this section are defined in the Hooks Menu.
608: * All of these items toggle selections on or off. The first two
609: * Items must be registered with the input hook. The last two simply
610: * retrict how much information is displayed for send messages
611: */
612:
613: case CMD_INPUTHOOK:
614: spyopt.bHooks ^= SPYH_INPUT;
615: WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
616: MM_SETITEMATTR, MPFROM2SHORT(CMD_INPUTHOOK, TRUE),
617: MPFROM2SHORT(MIA_CHECKED,
618: (spyopt.bHooks & SPYH_INPUT) ? MIA_CHECKED : 0));
619: SpyReleaseHook (FALSE); /* Dont clear queue */
620: SpyInstallHook(hab, hmqSpy, spyopt.bHooks);
621: break;
622:
623: case CMD_SENDMSGHOOK:
624: spyopt.bHooks ^= SPYH_SENDMSG;
625: WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
626: MM_SETITEMATTR, MPFROM2SHORT(CMD_SENDMSGHOOK, TRUE),
627: MPFROM2SHORT(MIA_CHECKED,
628: (spyopt.bHooks & SPYH_SENDMSG) ? MIA_CHECKED : 0));
629: SpyReleaseHook (FALSE); /* Dont clear queue */
630: SpyInstallHook(hab, hmqSpy, spyopt.bHooks);
631: break;
632:
633: case CMD_SENDEXTEND:
634: spyopt.fSendExtend ^= 1; /* Toggle on or off */
635: WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
636: MM_SETITEMATTR, MPFROM2SHORT(CMD_SENDEXTEND, TRUE),
637: MPFROM2SHORT(MIA_CHECKED,
638: spyopt.fSendExtend ? MIA_CHECKED : 0));
639: break;
640:
641: /*
642: * The commands in this section are defined in the Outputs Menu.
643: * The first 3 items simply toggle outputs on or off, where the
644: * last item allows the user to change all of the output options.
645: */
646: case CMD_OUTSCREEN:
647: spyopt.fWindow ^= 1; /* Toggle on or off */
648: WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
649: MM_SETITEMATTR, MPFROM2SHORT(CMD_OUTSCREEN, TRUE),
650: MPFROM2SHORT(MIA_CHECKED, spyopt.fWindow ? MIA_CHECKED : 0));
651: break;
652:
653: case CMD_OUTTERM:
654: spyopt.fDebugOutput ^= 1; /* Toggle on or off */
655: WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
656: MM_SETITEMATTR, MPFROM2SHORT(CMD_OUTTERM, TRUE),
657: MPFROM2SHORT(MIA_CHECKED, spyopt.fDebugOutput ? MIA_CHECKED : 0));
658: break;
659:
660: case CMD_OUTFILE:
661: spyopt.fFile ^= 1; /* Toggle on or off */
662: WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
663: MM_SETITEMATTR, MPFROM2SHORT(CMD_OUTFILE, TRUE),
664: MPFROM2SHORT(MIA_CHECKED, spyopt.fFile ? MIA_CHECKED : 0));
665: /*
666: * Open or close the output file
667: */
668: if (spyopt.fFile) {
669: if (spyopt.hfileSpy == NULL)
670: if (DosOpen((PSZ)spystr.szFileName, &spyopt.hfileSpy,
671: &ulAction, 0L, 0,
672: 0x0012, 0x00C1, 0L) != 0)
673: spyopt.hfileSpy = NULL; /* Failed on open */
674: } else {
675: if (spyopt.hfileSpy != NULL) {
676: /* file open, not outputing, close it now */
677: DosClose (spyopt.hfileSpy);
678: spyopt.hfileSpy = NULL;
679: }
680: }
681: break;
682:
683: case CMD_OUTPUTS:
684: SpyHookOnOrOff (FALSE);
685: WinDlgBox(HWND_DESKTOP, hwndSpyFrame,
686: (PFNWP)SpyOutputsDlgProc, (HMODULE)NULL,
687: IDD_OutputsDlg, (PCH)NULL);
688: SpyHookOnOrOff (fSpyActive);
689: break;
690:
691: case CMD_MGDABLE:
692: case CMD_MGEABLE:
693: EnableOrDisableMsg(SHORT1FROMMP(mp1) == CMD_MGEABLE);
694: break;
695: /*
696: * Help Menu items, send message to help manager
697: */
698: case CMD_HOWHELP:
699: if (hwndHelpInstance != NULL)
700: WinSendMsg(hwndHelpInstance, HM_DISPLAY_HELP,
701: (MPARAM)NULL, (MPARAM)NULL);
702: break;
703:
704: /* Extended help option was chosen from pull-down */
705: case CMD_HELPEXTENDED:
706: if (hwndHelpInstance != NULL)
707: WinSendMsg(hwndHelpInstance, HM_EXT_HELP,
708: (MPARAM) 0, (MPARAM) 0 );
709: break;
710:
711: /* Keys help option was chosen from pull-down */
712:
713: case CMD_HELPKEYS:
714: if (hwndHelpInstance != NULL)
715: WinSendMsg(hwndHelpInstance, HM_KEYS_HELP,
716: (MPARAM) 0, (MPARAM) 0 );
717: break;
718:
719: /* Index option was chosen from pull-down */
720:
721: case CMD_HELPINDEX:
722: if (hwndHelpInstance != NULL)
723: WinSendMsg(hwndHelpInstance, HM_HELP_INDEX,
724: (MPARAM) 0, (MPARAM) 0 );
725: break;
726: }
727:
728: break;
729: case HM_HELPSUBITEM_NOT_FOUND:
730: if (hwndHelpInstance != NULL)
731: (void)WinSendMsg(hwndHelpInstance, HM_EXT_HELP,
732: (MPARAM)NULL, (MPARAM)NULL);
733: break;
734: case HM_QUERY_KEYS_HELP:
735: return (MRESULT)HLP_KEYS;
736:
737: case WM_SIZE:
738: /* We need to resize the listbox, if it exists */
739: if (hwndSpyList != NULL) {
740: WinSetWindowPos(hwndSpyList, HWND_TOP, -cxBorder, -cyBorder,
741: SHORT1FROMMP(mp2) + 2 * cxBorder,
742: SHORT2FROMMP(mp2) + 2 * cyBorder, SWP_MOVE | SWP_SIZE);
743: }
744:
745: /* Now fall through to process the message */
746: default:
747: return(WinDefWindowProc(hwnd, msg, mp1, mp2));
748: break;
749: }
750: return(0L);
751: }
752:
753:
754:
755:
756: /***************************** Private Function ****************************\
757: * USHORT UConvertStringToNum(psz)
758: *
759: * Effects:
760: * Converts the passed string to a number 0xffff if not number
761: *
762: * History:
763: * 27-September-1988 KurtE
764: \***************************************************************************/
765: USHORT UConvertStringToNum(psz)
766: register char *psz;
767: {
768: register USHORT uNum;
769: /*
770: * This aint to fancy yet, but if the first few chars are
771: * 0x, we assume the user typed in a HEX number, else if 0-9,
772: * we assume decimal, else we use the string, also for windows if the
773: * user left the 0000:0000 we ignore the high end and assume it is
774: * hex.
775: */
776:
777: /* First see if digit in first position */
778: if ((*psz >= '0') && (*psz <= '9')) {
779: /* Assume numbers now */
780: if ((*psz == '0') && (*(psz+1) == 'x')) {
781:
782: /* We are in hex mode */
783: psz += 2;
784: uNum = 0;
785: for (;;) {
786: if ((*psz >= '0') && (*psz <= '9'))
787: uNum = uNum * 16 + (USHORT)(*psz - '0');
788: else if ((*psz >= 'a') && (*psz <= 'f'))
789: uNum = uNum * 16 + (USHORT)(*psz - 'a');
790: else if ((*psz >= 'F') && (*psz <= 'F'))
791: uNum = uNum * 16 + (USHORT)(*psz - 'A');
792: else
793: break;
794: psz++;
795: }
796:
797: } else {
798: /* Decimal mode */
799: uNum = (USHORT)(*psz++ - '0');
800: while ((*psz >= '0') && (*psz <= '9')) {
801: uNum = uNum * 10 + (USHORT)(*psz++ - '0');
802: }
803: }
804:
805: return (uNum);
806:
807: } else if (psz=strchr(psz,':')) {
808: // boy this is sh.t, it should be combined above!!!
809: /* We are in hex mode */
810: psz++;
811: uNum = 0;
812: for (;;) {
813: if ((*psz >= '0') && (*psz <= '9'))
814: uNum = uNum * 16 + (USHORT)(*psz - '0');
815: else if ((*psz >= 'a') && (*psz <= 'f'))
816: uNum = uNum * 16 + (USHORT)(*psz - 'a');
817: else if ((*psz >= 'F') && (*psz <= 'F'))
818: uNum = uNum * 16 + (USHORT)(*psz - 'A');
819: else
820: break;
821: psz++;
822: }
823:
824: } else
825: /* Not num, return 0xffff */
826: return (0xffff);
827: }
828:
829:
830:
831:
832:
833: /**************************** Public Function ******************************\
834: * void ProcHookThread()
835: *
836: * Effects: This function will wait for the hook to have messages, when it
837: * does, it will Set a memory semaphore, Post a WM_SEM1 message to the other
838: * thread, and wait for the other thread has processed all of the messages.
839: *
840: * Return value: none
841: \***************************************************************************/
842:
843: void ProcHookThread()
844: {
845: ULONG ulPostCt;
846: /* We'll look for a variation to run while the thread is active. */
847: if (fDebug)
848: DebugBreak();
849:
850: while (TRUE) {
851: /*
852: * Wait for a message to become available.
853: */
854: if (!SpyGetNextMessage(NULL, NULL, 0, -1L))
855: break;
856:
857: /*
858: * Now we have a message, set our semaphore, Post a WM_SEM2
859: * message to the Client window, and wait for the client to
860: * clear the semaphore.
861: */
862: DosResetEventSem(hevThread, &ulPostCt);
863: WinPostMsg(hwndSpy, WM_SEM2, (MPARAM)1, (MPARAM)1);
864: DosWaitEventSem(hevThread, -1L);
865: }
866:
867: DosExit(EXIT_THREAD, 0);
868: }
869:
870:
871:
872:
873: /**************************** Public Function ******************************\
874: * void ProcessQueueMsg(pqmsg)
875: *
876: * Effects: This function will process the hook, by calling the hooks
877: * get message. We will than post the message to the current output
878: * destinations.
879: *
880: * Return value: none
881: \***************************************************************************/
882:
883: void ProcessQueueMsg(pqmsgspy)
884: QMSGSPY *pqmsgspy;
885: {
886: MSGI *pmsgi;
887: CHAR cSource;
888: CHAR cThread;
889: char szNextMessage[100];
890: char szTime[12];
891: SHORT cch;
892: CHAR bAscii;
893: PSZ prgData;
894:
895:
896:
897: /*
898: * Now lets Build the message to output
899: */
900: if (WinIsWindow(hab, pqmsgspy->qmsg.hwnd)) {
901: if (WinIsChild(pqmsgspy->qmsg.hwnd, hwndSpy))
902: return; /* dont want endless loops */
903: }
904:
905: cThread = ':';
906: if (pqmsgspy->qmsg.time == (ULONG)-1) {
907: /* Sent message */
908: szTime[0] = '\0';
909: cSource = 'S';
910: if (pqmsgspy->fs)
911: cThread = '*';
912: } else {
913: cSource = 'I';
914: if (pqmsgspy->fs != PM_REMOVE)
915: cThread = '-'; /* Show different for non-remove */
916:
917: sprintf (szTime, "%-08lx", pqmsgspy->qmsg.time);
918: }
919:
920: if ((pmsgi = PmsgiFromMsg(pqmsgspy->qmsg.msg)) == NULL) {
921: /*
922: * Message not in list, use default
923: */
924: cch = sprintf(szNextMessage,
925: "%c%cMSG:0x%04x H:%p 1:%08lx 2:%08lx T:%s",
926: cSource, cThread, (SHORT)pqmsgspy->qmsg.msg, pqmsgspy->qmsg.hwnd,
927: pqmsgspy->qmsg.mp1, pqmsgspy->qmsg.mp2, szTime);
928: } else if (pmsgi->wOptions & MSGI_MOUSE) {
929: /*
930: * Mouse message, decode to mouse types
931: */
932: cch = sprintf(szNextMessage,
933: "%c%c%-20s H:%p X:%-4d Y:%-4d HT:%04x T:%s",
934: cSource, cThread, pmsgi->szMsg, pqmsgspy->qmsg.hwnd,
935: SHORT1FROMMP(pqmsgspy->qmsg.mp1), SHORT2FROMMP(pqmsgspy->qmsg.mp1),
936: SHORT1FROMMP(pqmsgspy->qmsg.mp2), szTime);
937: } else if (pmsgi->wOptions & MSGI_KEY) {
938: /*
939: * Key messages, output special
940: */
941: bAscii = (CHAR)SHORT1FROMMP(pqmsgspy->qmsg.mp2);
942: if ((bAscii < ' ') || (bAscii > '~'))
943: bAscii = ' ';
944:
945: cch = sprintf(szNextMessage,
946: "%c%c%-20s H:%p F:%04x R:%d S:%2x C:%04x(%c) V:%02x T:%s",
947: cSource, cThread, pmsgi->szMsg, pqmsgspy->qmsg.hwnd,
948: SHORT1FROMMP(pqmsgspy->qmsg.mp1),
949: CHAR3FROMMP(pqmsgspy->qmsg.mp1), CHAR4FROMMP(pqmsgspy->qmsg.mp1),
950: SHORT1FROMMP(pqmsgspy->qmsg.mp2), bAscii,
951: SHORT2FROMMP(pqmsgspy->qmsg.mp2), szTime);
952: } else {
953: /* No special format */
954: cch = sprintf(szNextMessage,
955: "%c%c%-20s H:%p 1:%08lx 2:%08lx T:%s",
956: cSource, cThread, pmsgi->szMsg, pqmsgspy->qmsg.hwnd,
957: pqmsgspy->qmsg.mp1, pqmsgspy->qmsg.mp2, szTime);
958: }
959:
960: OutputString(szNextMessage, cch);
961:
962: /*
963: * Now dump out any additional information associated with the
964: * message. The processing depends of the type of message on
965: * how we are going to process the data.
966: */
967: if (spyopt.fSendExtend) {
968: prgData = DumpParam((PSZ)rgMsgData, pqmsgspy->cbDataMP1,
969: pqmsgspy->fMP1Valid, pqmsgspy->bMPType);
970:
971: DumpParam(prgData, pqmsgspy->cbDataMP2, pqmsgspy->fMP1Valid,
972: (UCHAR)((pqmsgspy->bMPType) >> 3));
973: }
974:
975: }
976:
977:
978:
979:
980: /**************************** Public Function ******************************\
981: * PSZ DumpParam(PSZ prgData, MPARAM mp, SHORT cb, BOOL fValid, UCHAR bMPType)
982: *
983: * Dump the additional information that was captured for the message.
984: * using the currently defined types.
985: *
986: * Return value: PSZ - Pointer to next available byte after process DATA
987: \***************************************************************************/
988: PSZ DumpParam(prgData, cb, fValidData, bMPType)
989: PSZ prgData;
990: SHORT cb;
991: BOOL fValidData;
992: UCHAR bMPType;
993: {
994: char szNextMessage[100];
995: SHORT cch;
996:
997:
998: if (fValidData) {
999: /* Process by type */
1000: switch (bMPType & 0x07) {
1001: case MPT_SWP:
1002: cch = sprintf(szNextMessage,
1003: " SWP: fs:%p cx:%d cy:%d y:%d x:%d HB:%p H:%p",
1004: ((PSWP)prgData)->fl, ((PSWP)prgData)->cy, ((PSWP)prgData)->cx,
1005: ((PSWP)prgData)->y, ((PSWP)prgData)->x,
1006: ((PSWP)prgData)->hwndInsertBehind,
1007: ((PSWP)prgData)->hwnd);
1008:
1009: break;
1010:
1011: case MPT_RECTL:
1012: cch = sprintf(szNextMessage,
1013: " RECTL: xLeft:%d yBottom:%d xRight:%d yTop:%d",
1014: ((PRECTL)prgData)->xLeft, ((PRECTL)prgData)->yBottom,
1015: ((PRECTL)prgData)->xRight, ((PRECTL)prgData)->yTop);
1016: break;
1017:
1018: case MPT_QMSG:
1019: cch = sprintf(szNextMessage,
1020: " QMSG: H:%p M:%04x M1:%08lx M2:%08lx T:%08lx (%d, %d)",
1021: ((PQMSG)prgData)->hwnd, ((PQMSG)prgData)->msg,
1022: ((PQMSG)prgData)->mp1,((PQMSG)prgData)->mp2,
1023: ((PQMSG)prgData)->time,
1024: ((PQMSG)prgData)->ptl.x, ((PQMSG)prgData)->ptl.y);
1025: break;
1026:
1027: default:
1028: goto NoData;
1029: }
1030:
1031: OutputString(szNextMessage, cch);
1032: }
1033: NoData:
1034: return (prgData + cb);
1035: }
1036:
1037:
1038:
1039:
1040: /**************************** Public Function ******************************\
1041: * void OutputString(char szOut, SHORT cch);
1042: *
1043: * Effects: This function will output the specified string to the
1044: * destinations.
1045: *
1046: * Return value: none
1047: \***************************************************************************/
1048:
1049: void OutputString(szOut, cch)
1050: char szOut[];
1051: SHORT cch;
1052: {
1053: SHORT item;
1054: char *psz;
1055: ULONG cchWritten;
1056:
1057: /* This is a private entry point in the PMWIN dll that places */
1058: /* strings into the window. */
1059: SHORT _far16 _pascal _loadds DebugOutput( char _far16 * );
1060:
1061: /* Now display the new Line on the screen */
1062: if (spyopt.fWindow) {
1063: item = (SHORT)WinSendMsg(hwndSpyList, LM_INSERTITEM,
1064: (MPARAM)LIT_END, (MPARAM)(PSZ)szOut);
1065:
1066: WinSendMsg(hwndSpyList, LM_SETTOPINDEX, (MPARAM)item, 0L);
1067:
1068: /* See if we have to many lines now */
1069: while (item >= spyopt.cWindowLines)
1070: item = (SHORT)WinSendMsg(hwndSpyList, LM_DELETEITEM,
1071: (MPARAM)0, 0L);
1072: }
1073:
1074: /* now for file or debug terminal need cr/lf */
1075: psz = szOut + cch; /* point to trailing null */
1076: *psz++ = '\r';
1077: *psz++ = '\n';
1078: *psz = '\0';
1079:
1080: if (spyopt.fDebugOutput)
1081: DebugOutput((char _far16*)szOut);
1082:
1083: if (spyopt.fFile)
1084: DosWrite(spyopt.hfileSpy, (PSZ)szOut, cch+2,
1085: &cchWritten);
1086:
1087: }
1088:
1089:
1090: /**************************** Public Function ******************************\
1091: * MSGI * PmsgiFromMsg(USHORT msg)
1092: *
1093: * Effects: Locate the msg in the array of message items
1094: *
1095: * Return value: pointer to item that has the specified msg, or NULL
1096: \***************************************************************************/
1097: MSGI *PmsgiFromMsg(msg)
1098: USHORT msg;
1099: {
1100: register MSGI *pmsgi = rgmsgi; /* Start at beginning */
1101: register USHORT i;
1102:
1103: /*
1104: * Currently is a simple linear search, should be made faster
1105: * Probabably a binary search.
1106: */
1107: for (i=0; i< cmsgi; i++) {
1108: if (pmsgi->msg == msg)
1109: return (pmsgi);
1110: if (pmsgi->msg > msg)
1111: return (NULL);
1112: pmsgi++;
1113: };
1114:
1115: return (NULL);
1116: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.