--- pmsdk/samples/spy/spy.c 2018/08/09 12:28:12 1.1 +++ pmsdk/samples/spy/spy.c 2018/08/09 12:28:21 1.1.1.2 @@ -1,27 +1,30 @@ -/****************************** Module Header ******************************\ -* Module Name: spy.c - Spy application -* -* Created by Microsoft Corporation, 1987 +/***************************************************************************\ +* spy.c - Spy application * +* Created by Microsoft Corporation, 1989 \***************************************************************************/ -#define INCL_PM -#define INCL_WINSYS #define INCL_DOSPROCESS -#include "os2.h" -#include "stdio.h" -#include "string.h" +#define INCL_WINDIALOGS +#define INCL_WINFRAMEMGR +#define INCL_WINHEAP +#define INCL_WININPUT +#define INCL_WINLISTBOXES +#define INCL_WINMENUS +#define INCL_WINMESSAGEMGR +#define INCL_WINPOINTERS +#define INCL_WINSHELLDATA +#define INCL_WINSYS +#define INCL_WINWINDOWMGR +#include +#include +#include +#include +#include +#include #include "spy.h" -#include "spyhook.h" -#include "time.h" -#include "stdlib.h" - - -/************* GLOBAL VARIABLES */ - -char szSpyClass[] = "Spy"; -char szTitle[] = "Spy"; +/* File Local Variables */ HAB hab; HMQ hmqSpy; HWND hwndSpy; @@ -30,77 +33,49 @@ HWND hwndSpyList = NULL; HWND hwndWindowLB; HWND hwndMessageLB; HHEAP hHeap; +SHORT cxBorder; +SHORT cyBorder; HPOINTER hptrArrow; HPOINTER hptrSelWin; USHORT iCurItemFocus; /* Index to item that has the focus */ BOOL fSpyActive = MIA_CHECKED; /* Any non-zero is true */ -BOOL fTrackingWindows = FALSE; /* Tracking windows active ? */ +BOOL fTrackingListBox = FALSE; /* Tracking windows active ? */ BOOL fAllFrames = 0; /* Are we processing all frames ? */ - fAllWindows = 0; /* Are we processing all windows ? */ +BOOL fAllWindows = 0; /* Are we processing all windows ? */ -USHORT bHooks = SPYH_INPUT | SPYH_SENDMSG; /* Default to both hooks */ HWND hwndWinDlgDisp = NULL; /* hwnds info in Window Dialog */ -/* Define memory semaphore to have second thread sleep on */ -ULONG semThread = 0L; /* Thread to wait on */ -int AboutCount = 0; - -/* - * simple structure for sorting Hwnds in dumping - */ -typedef struct _spwd { - HWND hwnd; - SHORT index; -} SPWD; - SHORT wDumpCount = 0; /* Count of which window is being dumped */ -SPWD *pspwd = NULL; -#define MAXSPYDUMP 1000 /* Max of a thousand windows */ - - +SPWD *pspwd = NULL; -/************* PROCEDURE DECLARATIONS */ -MRESULT FAR PASCAL SpyWndProc(); -MRESULT FAR PASCAL SpyMsgDlgProc(); -MRESULT FAR PASCAL SpyOutputsDlgProc(); -MRESULT FAR PASCAL SpyWindowsDlgProc(); -MRESULT FAR PASCAL SpySaveListDlgProc(); -MRESULT FAR PASCAL AboutWndProc(); +/* Define memory semaphore to have second thread sleep on */ +ULONG semThread = 0L; /* Thread to wait on */ +int AboutCount = 0; +UCHAR rgMsgData[MAXMSGBYTES]; /* Max bytes to extract per message */ -void InitWindowList(HWND, HWND, int); -void BuildWindowWatchList(HWND); -void DisplayWindowInfo(HWND, HWND); -void DumpWindowInfo(HWND, SHORT); -void DumpWindowIndex(void); -int cdecl CompareHwnds(const void *, const void *); -void DumpOneWindowInfo(void); -void DumpAllWindowsInfo(HWND, SHORT); +char szSpyClass[] = "Spy"; +char szTitle[] = ""; +/* Function Prototypes */ +int cdecl main(int, char **); void FAR ProcHookThread(void); /* will process the hook messages */ -MSGI *PmsgiFromMsg(USHORT); - -void UpdMsgsLBSels (HWND, USHORT, BOOL); -void UpdMsgTblFromLB (HWND); -void UpdateHooksMsgTable(void); -void ProcessQueueMsg(QMSG *); -HWND HwndSelWinWithMouse(HWND, BOOL); -void SelOrDeselWithMouse(BOOL); -void EnableOrDisableMsg(BOOL); -void OutputString(char [], SHORT); /* Output string to output devices */ - +void ProcessQueueMsg(QMSGSPY *); +void UpdateMsgBoxCurMsgText(HWND); +void InitializeOptions(int, char **); /* initialize Spy initial state */ +PSZ DumpParam(PSZ prgData, MPARAM mp, SHORT cb, UCHAR bMPType); +MRESULT CALLBACK SpyWndProc(HWND, USHORT, MPARAM, MPARAM); +VOID SpyPaint(VOID); -/**************************** Public Function ******************************\ +/***************************************************************************\ * int cdecl main (argc, argv) * -* Effects: Spy Main function -* -* Return value: +* Spy Main function \***************************************************************************/ int cdecl main(argc, argv) int argc; @@ -112,26 +87,18 @@ char **argv; TID tid; char *prgStack; - while (argc > 1) { - argv++; /* get beyond the program name */ - - /* Test for send message flag */ - if (!strcmp(*argv, "/s") || !strcmp(*argv, "/S")) - bHooks |= SPYH_SENDMSG; - - argc--; - } hab = WinInitialize(0); hmqSpy = WinCreateMsgQueue(hab, 0); if (!WinRegisterClass((HAB)NULL, szSpyClass, (PFNWP)SpyWndProc, - CS_SIZEREDRAW, 0)) { + CS_SYNCPAINT, 0)) { WinAlarm(HWND_DESKTOP, 0xffff); return(0); } + /* * Create a heap for the program */ @@ -140,7 +107,6 @@ char **argv; /* * Create a stack for the thread - also initialize the stack by zeroing * the first 32 bytes, and filling the remainder with a known value - * */ prgStack = WinAllocMem(hHeap, CBSTACK); if (prgStack == NULL) @@ -148,19 +114,19 @@ char **argv; memset(prgStack, '\0', 32); /* Init first 32 bytes to zero */ memset(prgStack+32,'\345', CBSTACK-32); /* Remainder to known value */ - hptrArrow = WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, TRUE); - hptrSelWin = WinQuerySysPointer(HWND_DESKTOP, SPTR_MOVE, TRUE); - + hptrArrow = WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, TRUE); + cxBorder = (SHORT)WinQuerySysValue(HWND_DESKTOP, SV_CXBORDER); + cyBorder = (SHORT)WinQuerySysValue(HWND_DESKTOP, SV_CYBORDER); + hptrSelWin = WinQuerySysPointer(HWND_DESKTOP, SPTR_MOVE, TRUE); - SpyInstallHook(hab, hmqSpy, bHooks); + SpyInstallHook(hab, hmqSpy, spyopt.bHooks); SpySetAllWindowOpt (fAllWindows); SpySetAllFrameOpt (fAllFrames); - flCreateFlags = FCF_TITLEBAR | FCF_SYSMENU | FCF_MENU | FCF_SIZEBORDER - | FCF_MINMAX; + flCreateFlags = FCF_STANDARD; hwndSpyFrame = WinCreateStdWindow(HWND_DESKTOP, - WS_VISIBLE | FS_ICON | FS_ACCELTABLE, + WS_VISIBLE, (VOID FAR *)&flCreateFlags, szSpyClass, szTitle, WS_VISIBLE, @@ -170,20 +136,43 @@ char **argv; WinQueryWindowRect(hwndSpy, &rcl); hwndSpyList = WinCreateWindow (hwndSpy, WC_LISTBOX, "", WS_VISIBLE | LS_NOADJUSTPOS, - 0, 0, (SHORT)(rcl.xRight - rcl.xLeft), - (SHORT)(rcl.yTop - rcl.yBottom), + -cxBorder, -cyBorder, + (SHORT)(rcl.xRight - rcl.xLeft) + 2 * cxBorder, + (SHORT)(rcl.yTop - rcl.yBottom) + 2 * cyBorder, hwndSpy, HWND_TOP, DID_SPYLIST, NULL, NULL); - WinSetFocus(HWND_DESKTOP, hwndSpyList); + /* + * Read the os2.ini information if it exists, and set the menu items + * to correspond to the initial state read from OS2.INI. + */ + InitializeOptions(argc, argv); /* initialize Spy initial state */ + + /* + * Set the focus to the list box. Note: Only call WinSetFocus if + * our frame is the active window. As we may have been started in + * the background. If this is the case, we want to set the frame's + * focus save to the listbox, such that it will be the active window + * when our frame is activated. + */ + if (WinQueryWindow(HWND_DESKTOP, QW_TOP, FALSE) == hwndSpyFrame) + WinSetFocus(HWND_DESKTOP, hwndSpyList); + else + WinSetWindowULong(hwndSpyFrame, QWL_HWNDFOCUSSAVE, + (ULONG)hwndSpyList); + /* Start the thread that will process the messages from the hook */ DosCreateThread(ProcHookThread, (PTID)&tid, (PBYTE)(prgStack + CBSTACK - 1)); - UpdateHooksMsgTable(); /* Set Spys Msg table */ + UpdateHooksMsgTable(); /* Set Spy's Message Table */ SpyHookOnOrOff (TRUE); /* Turn the hook on */ + + /* + * Now process all of the messages + */ while (WinGetMsg(NULL, (PQMSG)&qmsg, NULL, 0, 0)) { WinDispatchMsg(NULL, (PQMSG)&qmsg); } @@ -192,8 +181,8 @@ char **argv; WinDestroyWindow(hwndSpyFrame); - WinDestroyPointer(hptrArrow); - WinDestroyPointer(hptrSelWin); + WinDestroyPointer(hptrArrow); + WinDestroyPointer(hptrSelWin); Abort: WinDestroyMsgQueue(hmqSpy); @@ -203,29 +192,120 @@ Abort: if (spyopt.hfileSpy != NULL) DosClose(spyopt.hfileSpy); + DosExit(EXIT_PROCESS, 0); } -/**************************** Public Function ******************************\ -* MRESULT FAR PASCAL SpyWndProc(hwnd, msg, mp1, mp2) -* -* Effects: Spy Client window procedure + + +/***************************************************************************\ +* InitializeOptions(argc, argv) * +* Initialize spy, first from the default options, second from +* OS2.INI file, and override from command switches. +\***************************************************************************/ +VOID InitializeOptions(argc, argv) +int argc; +char **argv; +{ + USHORT cch; + USHORT wAction; + HWND hwndMenu; + + + /* + * If the OS2.INI information exists, initialize our options to + * the stored values. + */ + if (WinQueryProfileSize (hab, "Spy", "Options", &cch) == 0) { + cch = sizeof(SPYOPT); + + WinQueryProfileData(hab, "Spy", "Options", (PSZ)&spyopt, + &cch); + WinQueryProfileString(hab, "Spy", "FileName", "spy.out", + (PSZ)spystr.szFileName, sizeof(spystr.szFileName)); + WinQueryProfileString(hab, "Spy", "SaveFileName", "spy.lis", + (PSZ)spystr.szSaveFileName, sizeof(spystr.szSaveFileName)); + } + + /* + * Then check for command line overrides + */ + while (argc > 1) { + argv++; /* get beyond the program name */ + + /* Test for send message hook flag */ + if (!strcmpi(*argv, "+s")) + spyopt.bHooks |= SPYH_SENDMSG; + if (!strcmpi(*argv, "-s")) + spyopt.bHooks &= ~SPYH_SENDMSG; + + /* Test for input hook flag */ + if (!strcmpi(*argv, "+i")) + spyopt.bHooks |= SPYH_INPUT; + if (!strcmpi(*argv, "-i")) + spyopt.bHooks &= ~SPYH_INPUT; + + argc--; + } + + /* + * Now we need to update the menu items to the final + * state + */ + hwndMenu = WinWindowFromID(hwndSpyFrame, FID_MENU); + + WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(CMD_INPUTHOOK, TRUE), + MPFROM2SHORT(MIA_CHECKED, + (spyopt.bHooks & SPYH_INPUT) ? MIA_CHECKED : 0)); + WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(CMD_SENDMSGHOOK, TRUE), + MPFROM2SHORT(MIA_CHECKED, + (spyopt.bHooks & SPYH_SENDMSG) ? MIA_CHECKED : 0)); + + WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(CMD_SENDEXTEND, TRUE), + MPFROM2SHORT(MIA_CHECKED, + spyopt.fSendExtend ? MIA_CHECKED : 0)); + + WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(CMD_SENDSTACK, TRUE), + MPFROM2SHORT(MIA_CHECKED, + spyopt.fSendStack ? MIA_CHECKED : 0)); + WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(CMD_OUTSCREEN, TRUE), + MPFROM2SHORT(MIA_CHECKED, spyopt.fWindow ? MIA_CHECKED : 0)); + + WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(CMD_OUTFILE, TRUE), + MPFROM2SHORT(MIA_CHECKED, spyopt.fFile ? MIA_CHECKED : 0)); + + WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(CMD_ALPHASORT, TRUE), + MPFROM2SHORT(MIA_CHECKED, + spyopt.fAlphaSortMsgList ? MIA_CHECKED : 0)); + + /* + * If the options specify output to file, open the file now + */ + if (spyopt.fFile) { + if (DosOpen((PSZ)spystr.szFileName, &spyopt.hfileSpy, + (USHORT far *)&wAction, 0L, 0, + 0x0012, 0x00C1, 0L) != 0) + spyopt.hfileSpy = NULL; /* Failed on open */ + } +} + + +/***************************************************************************\ +* MRESULT CALLBACK SpyWndProc(hwnd, msg, mp1, mp2) * -* Return value: +* Spy Client window procedure \***************************************************************************/ -MRESULT FAR PASCAL SpyWndProc(hwnd, msg, mp1, mp2) +MRESULT CALLBACK SpyWndProc(hwnd, msg, mp1, mp2) HWND hwnd; USHORT msg; MPARAM mp1; MPARAM mp2; { - HPS hps; - QMSG qmsg; - RECTL rclPaint; - VOID SpyPaint(); - SHORT cItems; + QMSGSPY qmsgspy; + SHORT cBytes; + USHORT wAction; switch (msg) { case WM_CREATE: @@ -240,8 +320,8 @@ MPARAM mp2; * the listbox position at the end. Also make sure to flush * the file buffer before we go back to sleep. */ - while (SpyGetNextMessage(&qmsg, 0L)) { - ProcessQueueMsg(&qmsg); + while (SpyGetNextMessage(&qmsgspy, rgMsgData, sizeof(rgMsgData), 0L)) { + ProcessQueueMsg(&qmsgspy); } if (spyopt.fFile) @@ -268,13 +348,7 @@ MPARAM mp2; break; case CMD_ABOUT: - if (AboutCount == 4) { - AboutCount = 0; - WinDlgBox(HWND_DESKTOP, hwnd, (PFNWP)AboutWndProc, NULL, About2Dlg, (PCH)NULL); - } else { - AboutCount++; - WinDlgBox(HWND_DESKTOP, hwnd, (PFNWP)AboutWndProc, NULL, About1Dlg, (PCH)NULL); - } + WinDlgBox(HWND_DESKTOP, hwnd, (PFNWP)AboutWndProc, NULL, AboutDlg, (PCH)NULL); break; case CMD_EXIT: @@ -298,6 +372,28 @@ MPARAM mp2; SpyHookOnOrOff (fSpyActive); break; + /* + * This command saves out the current options to OS2.ini + */ + case CMD_SAVEOPT: + WinWriteProfileData(hab, "Spy", "Options", (PSZ)&spyopt, + sizeof(SPYOPT)); + WinWriteProfileString(hab, "Spy", "FileName", + (PSZ)spystr.szFileName); + WinWriteProfileString(hab, "Spy", "SaveFileName", + (PSZ)spystr.szSaveFileName); + + break; + + case CMD_LISTNEAR: + WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU), + MM_SETITEMATTR, MPFROM2SHORT(CMD_LISTNEAR, TRUE), + MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED)); + WinLoadDlg(HWND_DESKTOP, hwndSpyFrame, + (PFNWP)ListNearDlgProc, (HMODULE)NULL, + ListNearDlg, (PCH)NULL); + break; + case CMD_WINDOWS: SpyHookOnOrOff (FALSE); hwndWindowLB = NULL; @@ -309,6 +405,17 @@ MPARAM mp2; SpyHookOnOrOff (fSpyActive); break; + case CMD_QUEUES: + SpyHookOnOrOff (FALSE); + hwndWindowLB = NULL; + iCurItemFocus = (USHORT)-1; + WinDlgBox(HWND_DESKTOP, hwndSpyFrame, + (PFNWP)SpyQueuesDlgProc, (HMODULE)NULL, + MsgQueueDlg, (PCH)NULL); + + SpyHookOnOrOff (fSpyActive); + break; + case CMD_WNMSSEL: case CMD_WNMSDSL: SpyHookOnOrOff (FALSE); @@ -343,15 +450,16 @@ MPARAM mp2; break; case CMD_WNDPWIN: - wDumpCount = 0; + wDumpCount = 0; DumpOneWindowInfo(); break; + case CMD_WNDPALL: - wDumpCount = 0; + wDumpCount = 0; pspwd = (SPWD *)WinAllocMem(hHeap, sizeof(SPWD)* MAXSPYDUMP); - DumpAllWindowsInfo(HWND_DESKTOP, 0); - DumpAllWindowsInfo(HWND_OBJECT, -10); /* Make it show up */ - DumpWindowIndex(); + cBytes = DumpAllWindowsInfo(HWND_DESKTOP, 0); + cBytes += DumpAllWindowsInfo(HWND_OBJECT, -10); + DumpWindowIndex(cBytes); WinFreeMem(hHeap, (char *)pspwd, sizeof(SPWD)* MAXSPYDUMP); break; @@ -363,231 +471,81 @@ MPARAM mp2; SpyHookOnOrOff (fSpyActive); break; - case CMD_OUTPUTS: - SpyHookOnOrOff (FALSE); - WinDlgBox(HWND_DESKTOP, hwndSpyFrame, - (PFNWP)SpyOutputsDlgProc, (HMODULE)NULL, - OutputsDlg, (PCH)NULL); - SpyHookOnOrOff (fSpyActive); - break; + case CMD_ALPHASORT: + spyopt.fAlphaSortMsgList ^= TRUE; - case CMD_MGDABLE: - case CMD_MGEABLE: - EnableOrDisableMsg(SHORT1FROMMP(mp1) == CMD_MGEABLE); + WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU), + MM_SETITEMATTR, MPFROM2SHORT(CMD_ALPHASORT, TRUE), + MPFROM2SHORT(MIA_CHECKED, + spyopt.fAlphaSortMsgList ? MIA_CHECKED : 0)); break; - } - - break; - case WM_SIZE: - /* We need to resize the listbox, if it exists */ - if (hwndSpyList != NULL) { - WinSetWindowPos(hwndSpyList, HWND_TOP, 0, 0, - SHORT1FROMMP(mp2), SHORT2FROMMP(mp2), SWP_SIZE); - } - - /* Now fall through to process the message */ - default: - return(WinDefWindowProc(hwnd, msg, mp1, mp2)); - break; - } - return(0L); -} - - - -/**************************** Public Function ******************************\ -* MRESULT FAR PASCAL SpyMsgDlgProc (hwnd, msg, mp1, mp2) -* -* Effects: Message List dialog procedure -* -* -* Return value: -\***************************************************************************/ -MRESULT FAR PASCAL SpyMsgDlgProc(hwnd, msg, mp1, mp2) -HWND hwnd; -USHORT msg; -MPARAM mp1; -MPARAM mp2; -{ - SHORT i; - MSGI *pmsgi; - USHORT item; - SHORT bHooksNew; - USHORT wAction; - - switch (msg) { - - case WM_INITDLG: /* - * Initialize the list box with the list of messages that are - * defined in our message table + * The command in this section are defined in the Hooks Menu. + * All of these items toggle selections on or off. The first two + * items must be registered with the input hook. The last two simply + * retrict how much information is displayed for send messages. */ - pmsgi = rgmsgi; /* Point to start of list */ - hwndMessageLB = WinWindowFromID(hwnd, DID_OMSGLIST); - for (i = 0; i < cmsgi; i++) { - pmsgi->iListBox = item = (USHORT)WinSendMsg(hwndMessageLB, - LM_INSERTITEM, -#if 0 - (MPARAM)LIT_SORTASCENDING, -#else - (MPARAM)LIT_END, -#endif - (MPARAM)(PSZ)pmsgi->szMsg); - WinSendMsg(hwndMessageLB, LM_SETITEMHANDLE, (MPARAM)item, - (MPARAM)i); - if (pmsgi->wOptions & MSGI_ENABLED) { - WinSendMsg(hwndMessageLB, LM_SELECTITEM, (MPARAM)item, - (MPARAM)TRUE); - } - pmsgi++; - } - - /* Initialize the Hook type record */ - WinSendDlgItemMsg(hwnd, DID_OINPUT, BM_SETCHECK, - (MPARAM)(bHooks & SPYH_INPUT)?1 : 0, 0L); - - WinSendDlgItemMsg(hwnd, DID_OSENDMSG, BM_SETCHECK, - (MPARAM)(bHooks & SPYH_SENDMSG)?1 : 0, 0L); - - break; - - case WM_COMMAND: - switch (SHORT1FROMMP(mp1)) { - case DID_OK: - - /* - * Call to update the Message table select bits - */ - UpdMsgTblFromLB (hwnd); - - /* Setup new hook options */ - bHooksNew = 0; - - if ((BOOL)WinSendDlgItemMsg(hwnd, - DID_OINPUT, BM_QUERYCHECK, 0L, 0L)) - bHooksNew = SPYH_INPUT; - - if ((BOOL)WinSendDlgItemMsg(hwnd, - DID_OSENDMSG, BM_QUERYCHECK, 0L, 0L)) - bHooksNew |= SPYH_SENDMSG; - - if (bHooksNew != bHooks) { + case CMD_INPUTHOOK: + spyopt.bHooks ^= SPYH_INPUT; + WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU), + MM_SETITEMATTR, MPFROM2SHORT(CMD_INPUTHOOK, TRUE), + MPFROM2SHORT(MIA_CHECKED, + (spyopt.bHooks & SPYH_INPUT) ? MIA_CHECKED : 0)); SpyReleaseHook (FALSE); /* Dont clear queue */ - bHooks = bHooksNew; - SpyInstallHook(hab, hmqSpy, bHooks); /* Install hook again */ - } - - /* Fall through to DID_CANCEL */ - case DID_CANCEL: - /* Now dismiss the dialog */ - WinDismissDlg(hwnd, SHORT1FROMMP(mp1)); + SpyInstallHook(hab, hmqSpy, spyopt.bHooks); break; - /* - * These case simply update the listbox with which messages are - * enabled - */ - case DID_MALL: - UpdMsgsLBSels (hwnd, 0, TRUE); - break; - case DID_MNONE: - UpdMsgsLBSels (hwnd, 0, FALSE); - break; - case DID_MCON: - UpdMsgsLBSels (hwnd, MSGI_KEY, TRUE); - break; - case DID_MCOFF: - UpdMsgsLBSels (hwnd, MSGI_KEY, FALSE); - break; - case DID_MMON: - UpdMsgsLBSels (hwnd, MSGI_MOUSE, TRUE); - break; - case DID_MMOFF: - UpdMsgsLBSels (hwnd, MSGI_MOUSE, FALSE); - break; - case DID_MFON: - UpdMsgsLBSels (hwnd, MSGI_FREQ, TRUE); - break; - case DID_MFOFF: - UpdMsgsLBSels (hwnd, MSGI_FREQ, FALSE); + case CMD_SENDMSGHOOK: + spyopt.bHooks ^= SPYH_SENDMSG; + WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU), + MM_SETITEMATTR, MPFROM2SHORT(CMD_SENDMSGHOOK, TRUE), + MPFROM2SHORT(MIA_CHECKED, + (spyopt.bHooks & SPYH_SENDMSG) ? MIA_CHECKED : 0)); + SpyReleaseHook (FALSE); /* Dont clear queue */ + SpyInstallHook(hab, hmqSpy, spyopt.bHooks); break; - } - break; - - default: - return(WinDefDlgProc(hwnd, msg, mp1, mp2)); - break; - } - return 0L; -} - - -/**************************** Public Function ******************************\ -* MRESULT FAR PASCAL SpyOutputsDlgProc (hwnd, msg, mp1, mp2) -* -* Effects: Output Options dialog procedure -* -* -* Return value: -\***************************************************************************/ -MRESULT FAR PASCAL SpyOutputsDlgProc(hwnd, msg, mp1, mp2) -HWND hwnd; -USHORT msg; -MPARAM mp1; -MPARAM mp2; -{ - SHORT i; - MSGI *pmsgi; - USHORT item; - SHORT bHooksNew; - USHORT wAction; + case CMD_SENDEXTEND: + spyopt.fSendExtend ^= 1; /* Toggle on or off */ + WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU), + MM_SETITEMATTR, MPFROM2SHORT(CMD_SENDEXTEND, TRUE), + MPFROM2SHORT(MIA_CHECKED, + spyopt.fSendExtend ? MIA_CHECKED : 0)); + break; - switch (msg) { + case CMD_SENDSTACK: + spyopt.fSendStack ^= 1; /* Toggle on or off */ + WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU), + MM_SETITEMATTR, MPFROM2SHORT(CMD_SENDSTACK, TRUE), + MPFROM2SHORT(MIA_CHECKED, + spyopt.fSendStack ? MIA_CHECKED : 0)); + break; - case WM_INITDLG: /* - * Now initialize the output options in the dialog + * The commands in this section are defined in the Outputs Menu. + * The first 3 items simply toggle outputs on or off, where the + * last item allows the user to change all of the output options. */ - WinSendDlgItemMsg(hwnd, DID_WINDOW, BM_SETCHECK, - (MPARAM)spyopt.fWindow, 0L); - WinSendDlgItemMsg(hwnd, DID_FILE, BM_SETCHECK, - (MPARAM)spyopt.fFile, 0L); - - WinSetDlgItemShort(hwnd, DID_WINDOWLINES, spyopt.cWindowLines, FALSE); - WinSetDlgItemText(hwnd, DID_FILENAME, spyopt.szFileName); - - - break; - - case WM_COMMAND: - switch (SHORT1FROMMP(mp1)) { - case DID_OK: - - /* - * Now retrieve the output options from the - * dialog - */ - spyopt.fWindow = (BOOL)WinSendDlgItemMsg(hwnd, - DID_WINDOW, BM_QUERYCHECK, 0L, 0L); - spyopt.fFile = (BOOL)WinSendDlgItemMsg(hwnd, - DID_FILE, BM_QUERYCHECK, 0L, 0L); - - WinQueryDlgItemShort(hwnd, DID_WINDOWLINES, &spyopt.cWindowLines, FALSE); - WinQueryDlgItemText(hwnd, DID_FILENAME, - sizeof(spyopt.szFileName), spyopt.szFileName); + case CMD_OUTSCREEN: + spyopt.fWindow ^= 1; /* Toggle on or off */ + WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU), + MM_SETITEMATTR, MPFROM2SHORT(CMD_OUTSCREEN, TRUE), + MPFROM2SHORT(MIA_CHECKED, spyopt.fWindow ? MIA_CHECKED : 0)); + break; + case CMD_OUTFILE: + spyopt.fFile ^= 1; /* Toggle on or off */ + WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU), + MM_SETITEMATTR, MPFROM2SHORT(CMD_OUTFILE, TRUE), + MPFROM2SHORT(MIA_CHECKED, spyopt.fFile ? MIA_CHECKED : 0)); /* - * Now take care of file operations - * If a file is already active, we will continue to use it, and - * ignore the case where the user may have changed file names - * Will truncate any file. + * Open or close the output file */ if (spyopt.fFile) { if (spyopt.hfileSpy == NULL) - if (DosOpen((PSZ)spyopt.szFileName, &spyopt.hfileSpy, + if (DosOpen((PSZ)spystr.szFileName, &spyopt.hfileSpy, (USHORT far *)&wAction, 0L, 0, 0x0012, 0x00C1, 0L) != 0) spyopt.hfileSpy = NULL; /* Failed on open */ @@ -598,552 +556,110 @@ MPARAM mp2; spyopt.hfileSpy = NULL; } } - /* Fall through to DID_CANCEL */ - case DID_CANCEL: - /* Now dismiss the dialog */ - WinDismissDlg(hwnd, SHORT1FROMMP(mp1)); break; - } - break; - - default: - return(WinDefDlgProc(hwnd, msg, mp1, mp2)); - break; - } - return 0L; -} - - - -/**************************** Public Function ******************************\ -* void UpdMsgsLBSels (HWND hwndDialog, USHORT uMask, fOnOrOff); -* -* Effects: Will update the selected items in the message listbox, that is -* displayed in the options dialog -* -* Return value: none -\***************************************************************************/ -void UpdMsgsLBSels (hwndDialog, uMask, fOnOrOff) -HWND hwndDialog; -USHORT uMask; -BOOL fOnOrOff; -{ - - SHORT i; - MSGI *pmsgi; - - /* - * Loop through all of the items in our list, if the mask is 0 or - * the bit is on in the item, then update the select state in listbox - * defined in our message table - */ - pmsgi = rgmsgi; /* Point to start of list */ - for (i = 0; i < cmsgi; i++) { - if ((uMask == 0) || (pmsgi->wOptions & uMask)) { - WinSendMsg(hwndMessageLB, LM_SELECTITEM, - (MPARAM)pmsgi->iListBox, (MPARAM)fOnOrOff); - } - pmsgi++; - } -} - -/**************************** Public Function ******************************\ -* void UpdMsgsLBSels (HWND hwndDialog, USHORT uMask, fOnOrOff); -* -* Effects: Will update the selected items in the message listbox, that is -* displayed in the options dialog -* -* Return value: none -\***************************************************************************/ -void UpdMsgTblFromLB (hwndDialog) -HWND hwndDialog; -{ - - USHORT i; - register MSGI *pmsgi; - USHORT itemSel; - - /* - * Loop through all of the items in the list and update the selection - * status depending of if the item is selected in the list box or - * not. - */ - /* First simply turn off all of the bits */ - pmsgi = rgmsgi; - for (i = 0; i < cmsgi; i++) { - pmsgi->wOptions &= ~MSGI_ENABLED; - pmsgi++; - } - - /* Then turn on all of the selected items */ - itemSel = (USHORT)LIT_FIRST; - - while ((itemSel = (USHORT)WinSendMsg(hwndMessageLB, LM_QUERYSELECTION, - (MPARAM)itemSel, 0L)) != (USHORT)LIT_NONE) { - - /* The item handle contains index in our array */ - i = (USHORT)WinSendMsg(hwndMessageLB, LM_QUERYITEMHANDLE, - (MPARAM)itemSel, 0L); - - rgmsgi[i].wOptions |= MSGI_ENABLED; - } - - /* Now call function to update the hooks message list */ - UpdateHooksMsgTable(); -} -/**************************** Public Function ******************************\ -* void UpdateHooksMsgTable(void) -* -* Effects: Set the message bitmask to the hook, for interested messages. -* displayed in the options dialog -* -* Return value: none -\***************************************************************************/ -void UpdateHooksMsgTable() -{ - MSGI *pmsgi; - char rgb[MAXMSGFILTERBYTES]; - int i; - char *prgb; - unsigned char mask; - - /* - * First zero the bitmask - */ - memset(rgb,'\0', MAXMSGFILTERBYTES); - mask = 1; - prgb = rgb; - - /* - * Quick and dirty loop to set the bits - */ - pmsgi = rgmsgi; - for (i = 0; i <= MAXMSGFILTER; i++) { - /* If enabled, set bit in bit table */ - - if (pmsgi->msg == i) { - if (pmsgi->wOptions & MSGI_ENABLED) - *prgb |= mask; - - pmsgi++; - } else { - /* Hole in range, set it true */ - *prgb |= mask; - } - - - /* Setup next mask */ - mask <<= 1; - if (mask == 0) { - mask = 1; - prgb++; - } - } - /* Now call the hook function with the new mask */ - SpySetMessageList((char far *)rgb); -} - - - - -/**************************** Public Function ******************************\ -* MRESULT FAR PASCAL SpyWindowsDlgProc(hwnd, msg, mp1, mp2) -* -* Effects: The Spy Windows Dialog procedure -* -* Return value: none -\***************************************************************************/ -MRESULT FAR PASCAL SpyWindowsDlgProc(hwnd, msg, mp1, mp2) -HWND hwnd; -USHORT msg; -MPARAM mp1; -MPARAM mp2; -{ - BOOL fSelect = TRUE; - SHORT cWindows; - QMSG qmsg; - HWND hwndPoint; - HWND hwndItem; /* from handle of list item */ - USHORT iItemFocus; /* Index to item that has the focus */ - - switch (msg) { - - case WM_INITDLG: - /* Initialize the dialog items */ - hwndWindowLB = WinWindowFromID(hwnd, DID_WINDOWLIST); - InitWindowList(hwnd, HWND_DESKTOP, 0); - hwndWinDlgDisp = NULL; - fTrackingWindows = TRUE; - break; - - case WM_COMMAND: - switch (SHORT1FROMMP(mp1)) { - case DID_OK: - BuildWindowWatchList(hwnd); - case DID_CANCEL: - /* Now dismiss the dialog */ - WinDismissDlg(hwnd, SHORT1FROMMP(mp1)); - break; - case DID_WUNSELALL: - fSelect = FALSE; - case DID_WSELALL: - cWindows = (SHORT) WinSendMsg(hwndWindowLB, LM_QUERYITEMCOUNT, - 0L, 0L); - - fTrackingWindows = FALSE; - while (cWindows) { - /* Loop through all windows, selecting or unselcting all */ - WinSendMsg(hwndWindowLB, LM_SELECTITEM, (MPARAM)--cWindows, - (MPARAM)fSelect); - } - fTrackingWindows = TRUE; + case CMD_OUTPUTS: + SpyHookOnOrOff (FALSE); + WinDlgBox(HWND_DESKTOP, hwndSpyFrame, + (PFNWP)SpyOutputsDlgProc, (HMODULE)NULL, + OutputsDlg, (PCH)NULL); + SpyHookOnOrOff (fSpyActive); break; - case DID_WSELMOUSE: - /* Call function to track mouse, returns window handle */ - hwndPoint = HwndSelWinWithMouse(hwnd, TRUE); - if (hwndPoint == NULL) - break; /* No window to process */ - - /* - * Now find the window in the list, Make the item visible - * and set the item as selected. - */ - cWindows = (SHORT) WinSendMsg(hwndWindowLB, LM_QUERYITEMCOUNT, - 0L, 0L); - - while (cWindows) { - /* - * Loop through all windows until we wind the right - * one with the correct window handle - */ - hwndItem = (HWND)WinSendMsg(hwndWindowLB, LM_QUERYITEMHANDLE, - (MPARAM)--cWindows, 0L); - - if (hwndItem == hwndPoint) { - /* found the right item, move it to top */ - WinSendMsg(hwndWindowLB, LM_SETTOPINDEX, (MPARAM)cWindows, 0L); - WinSendMsg(hwndWindowLB, LM_SELECTITEM, (MPARAM)cWindows, - (MPARAM)TRUE); - break; - } - } + case CMD_MGDABLE: + case CMD_MGEABLE: + EnableOrDisableMsg(SHORT1FROMMP(mp1) == CMD_MGEABLE); break; - - } - break; - - - default: - /* - * Default is to see if the listbox has changed its focus - * item number. If it has, then we want to display the information - * about the window that the listbox cursor is over. There is no - * legal way to do this, so I am trying to extract data out of the - * extended bytes of the listbox data structure. - * DONT DO THIS !!! - */ - if (fTrackingWindows && hwndWindowLB != NULL) { - iItemFocus = WinQueryWindowUShort(hwndWindowLB, 10); - if (iItemFocus != iCurItemFocus) { - iCurItemFocus = iItemFocus; - if (iItemFocus != (USHORT)-1) { - hwndItem = (HWND)WinSendMsg(hwndWindowLB, LM_QUERYITEMHANDLE, - (MPARAM)iItemFocus, 0L); - DisplayWindowInfo(hwnd, hwndItem); - } - } } - return(WinDefDlgProc(hwnd, msg, mp1, mp2)); - } - return 0L; -} - + break; -/**************************** Private Function ******************************\ -* InitWindowList (hwndDialog, hwnd, level) -* -* Effects: Builds the list of windows displayed in the windows dialog -* -* -* Return value: -\***************************************************************************/ -void InitWindowList(hwndDialog, hwnd, level) -HWND hwndDialog; -HWND hwnd; -int level; -{ - char szTemp[30]; - char szId[20]; - HWND hwndT; - USHORT item; - USHORT id; - int i; - - /* - * We will first add this item to our list of - * items in the listbox, If the item is in our list of hwnds, - * set the item selected. To keep from getting into endless loops - * will not add spywindow client, and descendants. - */ - if (hwnd != hwndSpy) { - id = (USHORT)WinQueryWindowUShort(hwnd, QWS_ID); - sprintf(szId, "ID: %x", id); - - for (i = 0; i < cToName; i++) { - if (id == rgidtoname[i].id) { - strcpy (szId, rgidtoname[i].szIdName); - break; - } + case WM_SIZE: + /* We need to resize the listbox, if it exists */ + if (hwndSpyList != NULL) { + WinSetWindowPos(hwndSpyList, HWND_TOP, -cxBorder, -cyBorder, + SHORT1FROMMP(mp2) + 2 * cxBorder, + SHORT2FROMMP(mp2) + 2 * cyBorder, SWP_MOVE | SWP_SIZE); } - sprintf(szTemp, "0x%04x(%d) - %s", (USHORT)hwnd, level, szId); - item = (USHORT)WinSendMsg(hwndWindowLB, LM_INSERTITEM, - (MPARAM)LIT_END, (MPARAM)(PSZ)szTemp); - - /* Set the item handle to the handle of the window */ - WinSendMsg(hwndWindowLB, LM_SETITEMHANDLE, (MPARAM)item, - (MPARAM)hwnd); - - if (SpyFWindowInList(hwnd)) - WinSendMsg(hwndWindowLB, LM_SELECTITEM, (MPARAM)item, - (MPARAM)TRUE); - - /* - * Then we recurse with all of our children - */ - if ((hwndT = WinQueryWindow(hwnd, QW_TOP, FALSE)) != NULL) - InitWindowList(hwndDialog, hwndT, level+1); + /* Now fall through to process the message */ + default: + return(WinDefWindowProc(hwnd, msg, mp1, mp2)); + break; } - - /* - * Then go to our next sibling - */ - if ((hwndT = WinQueryWindow(hwnd, QW_NEXT, FALSE)) != NULL) - InitWindowList(hwndDialog, hwndT, level); + return(0L); } -/**************************** Private Function *****************************\ -* BuildWindowWatchList(hwndDialog) -* -* Effects: Updates the list of windows to be watched from the listbox -* -* -* Return value: -\***************************************************************************/ -void BuildWindowWatchList(hwndDialog) -HWND hwndDialog; -{ - - USHORT itemPrevious; - USHORT item; - HWND hwnd; - - SHORT chwnd; - HWND rghwnd[MAXHWNDS]; - - /* - * Simply loop through asking for the next selected item in the - * list. Make sure not to overrun our list. - */ - itemPrevious = (USHORT)LIT_FIRST; - chwnd = 0; - - while ((item = (USHORT)WinSendMsg(hwndWindowLB, LM_QUERYSELECTION, - (MPARAM)itemPrevious, 0L)) != (USHORT)LIT_NONE) { - /* - * Get the items handle, which has the value of the window handle - */ - hwnd = (HWND)WinSendMsg(hwndWindowLB, LM_QUERYITEMHANDLE, - (MPARAM)item, 0L); - - rghwnd[chwnd++] = hwnd; - if (chwnd >= MAXHWNDS) - break; /* Dont overflow array */ - itemPrevious = item; /* Where to cointinue the search */ - } - - SpySetWindowList (chwnd, rghwnd); -} - -/**************************** Public Function ******************************\ -* HWND HwndSelWinWithMouse(HWND hwnd, BOOL fDisplayInfo) -* -* Effects: This function is used to allow the user to select a window with -* the mouse. If fDisplayInfo is TRUE, it will update the -* information in the dialog box, about the window that the -* mouse is currently over. +/***************************************************************************\ +* USHORT UConvertStringToNum(psz) * -* Return value: none +* Converts the passed string to a number 0xffff if not number \***************************************************************************/ -HWND HwndSelWinWithMouse(hwnd, fDisplayInfo) -HWND hwnd; -BOOL fDisplayInfo; +USHORT UConvertStringToNum(psz) +register char *psz; { - - QMSG qmsg; - HWND hwndPoint; - char szClassName[50]; /* Class name of window */ - CLASSINFO classinfo; /* Information about class */ - - - /* - * First set the capture to the specified window - */ - WinSetCapture(HWND_DESKTOP, hwnd); - WinSetPointer (HWND_DESKTOP, hptrSelWin); - - /* - * Now loop through all of the messages that are sent, until - * we get our mouse 1 down message. We will also filter out - * the WM_MOVE message, else we will dispatch the messages. - */ - while (WinGetMsg(hab, &qmsg, NULL, 0, 0)) { - if (qmsg.msg == WM_MOUSEMOVE) { - if (fDisplayInfo) { - hwndPoint = WinWindowFromPoint(HWND_DESKTOP, - &qmsg.ptl, TRUE, FALSE); - DisplayWindowInfo(hwnd, hwndPoint); + register USHORT uNum; + + /* + * If the first few chars are 0x, we assume the user typed in a + * HEX number, else if 0-9, we assume decimal, else we use the string. + */ + /* First see if digit in first position */ + if ((*psz >= '0') && (*psz <= '9')) { + /* Assume numbers now */ + if ((*psz == '0') && (*(psz+1) == 'x')) { + + /* We are in hex mode */ + psz += 2; + uNum = 0; + for (;;) { + if ((*psz >= '0') && (*psz <= '9')) + uNum = uNum * 16 + (USHORT)(*psz - '0'); + else if ((*psz >= 'a') && (*psz <= 'f')) + uNum = uNum * 16 + (USHORT)(*psz - 'a'); + else if ((*psz >= 'F') && (*psz <= 'F')) + uNum = uNum * 16 + (USHORT)(*psz - 'A'); + else + break; + psz++; } - } - else if (qmsg.msg == WM_BUTTON1DOWN) - break; - else - WinDispatchMsg(hab, &qmsg); - } - - WinSetPointer (HWND_DESKTOP, hptrArrow); - WinSetCapture(HWND_DESKTOP, NULL); - - /* - * Map the point to the window, If the CTRL-Key is down, - * we will go up through the parent chain until we get to - * a frame window or desktop. Dont let hwndSpy through!!! - */ - hwndPoint = WinWindowFromPoint(HWND_DESKTOP, - &qmsg.ptl, TRUE, FALSE); - if (WinGetKeyState(HWND_DESKTOP, VK_CTRL) & 0x8000) { - /* Asked for frame window */ - for (;;) { - if (hwndPoint == NULL) - return (NULL); /* No frames available */ - /* See if frame class */ - WinQueryClassName(hwndPoint, sizeof(szClassName), - (PSZ)szClassName); - WinQueryClassInfo(hab, (PSZ)szClassName, - &classinfo); - if (classinfo.flClassStyle & CS_FRAME) - break; /* We have our frame */ - - /* Not frame, go back to parent */ - hwndPoint = WinQueryWindow(hwndPoint, QW_PARENT, FALSE); + } else { + /* Decimal mode */ + uNum = (USHORT)(*psz++ - '0'); + while ((*psz >= '0') && (*psz <= '9')) { + uNum = uNum * 10 + (USHORT)(*psz++ - '0'); + } } - } - - if (fDisplayInfo) - DisplayWindowInfo(hwnd, hwndPoint); - if (WinIsChild(hwndPoint, hwndSpy)) - return (NULL); /* Dont want to get in endless loops */ - - return (hwndPoint); + return (uNum); + } else + /* Not num, return 0xffff */ + return (0xffff); } -/**************************** Private Function *****************************\ -* DisplayWindowInfo(HWND hwndDialog, HWND hwnd) -* -* Effects: Displays the information about the selected window in the dialog -* -* -* Return value: -\***************************************************************************/ -void DisplayWindowInfo(hwndDlg, hwnd) -HWND hwndDlg; -HWND hwnd; -{ - HWND hwndT; - char szTemp[50]; - RECTL rcl; - USHORT id; - ULONG ul; - - if (hwnd != hwndWinDlgDisp) - { - hwndWinDlgDisp = hwnd; - - /* This could be table driven */ - sprintf(szTemp, "0x%04x", (SHORT)hwnd); - WinSetDlgItemText(hwndDlg, DID_WHANDLE, (PSZ)szTemp); - - WinQueryClassName(hwnd, sizeof(szTemp), (PSZ)szTemp); - WinSetDlgItemText(hwndDlg, DID_WCLASS, (PSZ)szTemp); - - hwndT = WinQueryWindow(hwnd, QW_PARENT, FALSE); - sprintf(szTemp, "0x%04x", (SHORT)hwndT); - WinSetDlgItemText(hwndDlg, DID_WPARENT, (PSZ)szTemp); - hwndT = WinQueryWindow(hwnd, QW_TOP, FALSE); - sprintf(szTemp, "0x%04x", (SHORT)hwndT); - WinSetDlgItemText(hwndDlg, DID_WCHILD, (PSZ)szTemp); - - hwndT = WinQueryWindow(hwnd, QW_OWNER, FALSE); - sprintf(szTemp, "0x%04x", (SHORT)hwndT); - WinSetDlgItemText(hwndDlg, DID_WOWNER, (PSZ)szTemp); - - WinQueryWindowRect(hwnd, &rcl); - sprintf(szTemp, "(%d, %d), (%d, %d)", (SHORT)rcl.xLeft, - (SHORT)rcl.yBottom, (SHORT)rcl.xRight, (SHORT)rcl.yTop); - WinSetDlgItemText(hwndDlg, DID_WRECT, (PSZ)szTemp); - - id = (USHORT)WinQueryWindowUShort(hwnd, QWS_ID); - sprintf(szTemp, "0x%04x", id); - WinSetDlgItemText(hwndDlg, DID_WID, (PSZ)szTemp); - - ul = (ULONG)WinQueryWindowULong(hwnd, QWL_STYLE); - sprintf(szTemp, "0x%08lx", ul); - WinSetDlgItemText(hwndDlg, DID_WSTYLE, (PSZ)szTemp); - - ul = (ULONG)WinQueryWindowULong(hwnd, QWP_PFNWP); - sprintf(szTemp, "%p", ul); - WinSetDlgItemText(hwndDlg, DID_WPFNWP, (PSZ)szTemp); - - ul = (ULONG)WinQueryWindowULong(hwnd, QWL_HMQ); - sprintf(szTemp, "0x%04x", (SHORT)ul); - WinSetDlgItemText(hwndDlg, DID_WHMQ, (PSZ)szTemp); - - } -} - - - -/**************************** Public Function ******************************\ +/***************************************************************************\ * void ProcHookThread() * -* Effects: This function will wait for the hook to have messages, when it -* does, it will Set a memory semaphore, Post a WM_SEM1 message to the other +* This function will wait for the hook to have messages, when it +* does, it will set a memory semaphore, post a WM_SEM1 message to the other * thread, and wait for the other thread has processed all of the messages. -* -* Return value: none \***************************************************************************/ void FAR ProcHookThread() { - /* We'll look for a variation to run while the thread is active. */ - while (TRUE) { /* * Wait for a message to become available. */ - if (!SpyGetNextMessage(NULL, -1L)) + if (!SpyGetNextMessage(NULL, NULL, 0, -1L)) break; /* @@ -1162,97 +678,194 @@ void FAR ProcHookThread() -/**************************** Public Function ******************************\ +/***************************************************************************\ * void ProcessQueueMsg(pqmsg) * -* Effects: This function will process the hook, by calling the hooks -* get message. We will than post the message to the current output -* destinations. -* -* Return value: none +* This function will process the hook, by calling the hooks which get +* messages. We will than post the message to the current output destinations. \***************************************************************************/ -void ProcessQueueMsg(pqmsg) - QMSG *pqmsg; +void ProcessQueueMsg(pqmsgspy) + QMSGSPY *pqmsgspy; { MSGI *pmsgi; SHORT item; CHAR cSource; CHAR cThread; char szNextMessage[100]; - char szTime[10]; - SHORT cch; - USHORT cchWritten; + char szTime[12]; + SHORT cch; + CHAR bAscii; + PSZ prgData; + /* - * Now lets Build the message to output + * Now let's build the message to output */ - if (WinIsWindow(hab, pqmsg->hwnd)) { - if (WinIsChild(pqmsg->hwnd, hwndSpy)) - return; /* dont want endless loops */ + if (WinIsWindow(hab, pqmsgspy->qmsg.hwnd)) { + if (WinIsChild(pqmsgspy->qmsg.hwnd, hwndSpy)) + return; /* don't want endless loops */ } cThread = ':'; - if (pqmsg->time == (ULONG)-1) { + if (pqmsgspy->qmsg.time == (ULONG)-1) { /* Sent message */ szTime[0] = '\0'; cSource = 'S'; - if (pqmsg->ptl.x) + if (pqmsgspy->fs) cThread = '*'; } else { cSource = 'I'; - sprintf (szTime, "%-08lx", pqmsg->time); + if (pqmsgspy->fs != PM_REMOVE) + cThread = '-'; /* Show different for non-remove */ + + sprintf (szTime, "%-08lx", pqmsgspy->qmsg.time); } - if ((pmsgi = PmsgiFromMsg(pqmsg->msg)) == NULL) { + if ((pmsgi = PmsgiFromMsg(pqmsgspy->qmsg.msg)) == NULL) { /* * Message not in list, use default */ cch = sprintf(szNextMessage, "%c%cMSG:0x%04x H:%04x 1:%08lx 2:%08lx T:%s", - cSource, cThread, (SHORT)pqmsg->msg, (SHORT)pqmsg->hwnd, - pqmsg->mp1, pqmsg->mp2, szTime); + cSource, cThread, (SHORT)pqmsgspy->qmsg.msg, (SHORT)pqmsgspy->qmsg.hwnd, + pqmsgspy->qmsg.mp1, pqmsgspy->qmsg.mp2, szTime); } else if (pmsgi->wOptions & MSGI_MOUSE) { /* * Mouse message, decode to mouse types */ cch = sprintf(szNextMessage, "%c%c%-20s H:%04x X:%-4d Y:%-4d HT:%04x T:%s", - cSource, cThread, pmsgi->szMsg, (SHORT)pqmsg->hwnd, - SHORT1FROMMP(pqmsg->mp1), SHORT2FROMMP(pqmsg->mp1), - SHORT1FROMMP(pqmsg->mp2), szTime); + cSource, cThread, pmsgi->szMsg, (SHORT)pqmsgspy->qmsg.hwnd, + SHORT1FROMMP(pqmsgspy->qmsg.mp1), SHORT2FROMMP(pqmsgspy->qmsg.mp1), + SHORT1FROMMP(pqmsgspy->qmsg.mp2), szTime); } else if (pmsgi->wOptions & MSGI_KEY) { /* * Key messages, output special */ + bAscii = (CHAR)SHORT1FROMMP(pqmsgspy->qmsg.mp2); + if ((bAscii < ' ') || (bAscii > '~')) + bAscii = ' '; + cch = sprintf(szNextMessage, "%c%c%-20s H:%04x F:%04x R:%d S:%2x C:%04x(%c) V:%02x T:%s", - cSource, cThread, pmsgi->szMsg, (SHORT)pqmsg->hwnd, - SHORT1FROMMP(pqmsg->mp1), - CHAR3FROMMP(pqmsg->mp1), CHAR4FROMMP(pqmsg->mp1), - SHORT1FROMMP(pqmsg->mp2), SHORT1FROMMP(pqmsg->mp2), - SHORT2FROMMP(pqmsg->mp2), szTime); + cSource, cThread, pmsgi->szMsg, (SHORT)pqmsgspy->qmsg.hwnd, + SHORT1FROMMP(pqmsgspy->qmsg.mp1), + CHAR3FROMMP(pqmsgspy->qmsg.mp1), CHAR4FROMMP(pqmsgspy->qmsg.mp1), + SHORT1FROMMP(pqmsgspy->qmsg.mp2), bAscii, + SHORT2FROMMP(pqmsgspy->qmsg.mp2), szTime); } else { /* No special format */ cch = sprintf(szNextMessage, "%c%c%-20s H:%04x 1:%08lx 2:%08lx T:%s", - cSource, cThread, pmsgi->szMsg, (SHORT)pqmsg->hwnd, - pqmsg->mp1, pqmsg->mp2, szTime); + cSource, cThread, pmsgi->szMsg, (SHORT)pqmsgspy->qmsg.hwnd, + pqmsgspy->qmsg.mp1, pqmsgspy->qmsg.mp2, szTime); } OutputString(szNextMessage, cch); + + /* + * Now dump out any additional information associated with the + * message. The processing depends of the type of message on + * how we are going to process the data. + */ + if (spyopt.fSendExtend) { + prgData = DumpParam((PSZ)rgMsgData, pqmsgspy->qmsg.mp1, + pqmsgspy->cbDataMP1, pqmsgspy->bMPType); + DumpParam(prgData, pqmsgspy->qmsg.mp2, pqmsgspy->cbDataMP2, + (UCHAR)((pqmsgspy->bMPType) >> 3)); + } + + /* + * If this is a send message, also display the call stack information + * of who called WinSendMsg + */ + if (spyopt.fSendStack && (pqmsgspy->qmsg.time == (ULONG)-1)) { + cch = sprintf(szNextMessage, + " PID: %-3d TID: %-2d Stack:", + pqmsgspy->pidSend, pqmsgspy->tidSend); + + /* Now loop and add the stack info */ + for (item=0; (item < MAXSTRACE) && + (pqmsgspy->pvoidStack[item] != NULL); item++) { + cch += sprintf(szTime, " %p", pqmsgspy->pvoidStack[item]); + strcat(szNextMessage, szTime); + } + + OutputString(szNextMessage, cch); + } + +} + + + + +/***************************************************************************\ +* PSZ DumpParam(PSZ prgData, MPARAM mp, SHORT cb, UCHAR bMPType) +* +* Dump the additional information that was captured for the message. +* using the currently defined types. +* +* Returns: PSZ - Pointer to next available byte after process DATA +\***************************************************************************/ +PSZ DumpParam(prgData, mp, cb, bMPType) +PSZ prgData; +MPARAM mp; +SHORT cb; +UCHAR bMPType; +{ + char szNextMessage[100]; + SHORT cch; + + + if (FGuessValidPointer((PSZ)mp, cb)) { + /* Process by type */ + switch (bMPType & 0x07) { + case MPT_SWP: + cch = sprintf(szNextMessage, + " SWP: fs:%04x cx:%d cy:%d y:%d x:%d HB:%04x H:%04x", + ((PSWP)prgData)->fs, ((PSWP)prgData)->cy, ((PSWP)prgData)->cx, + ((PSWP)prgData)->y, ((PSWP)prgData)->x, + (SHORT)((PSWP)prgData)->hwndInsertBehind, + (SHORT)((PSWP)prgData)->hwnd); + + break; + + case MPT_RECTL: + cch = sprintf(szNextMessage, + " RECTL: xLeft:%d yBottom:%d xRight:%d yTop:%d", + ((PRECTL)prgData)->xLeft, ((PRECTL)prgData)->yBottom, + ((PRECTL)prgData)->xRight, ((PRECTL)prgData)->yTop); + break; + + case MPT_QMSG: + cch = sprintf(szNextMessage, + " QMSG: H:%04x M:%04x M1:%08lx M2:%08lx T:%08lx (%d, %d)", + (SHORT)((PQMSG)prgData)->hwnd, ((PQMSG)prgData)->msg, + ((PQMSG)prgData)->mp1,((PQMSG)prgData)->mp2, + ((PQMSG)prgData)->time, + ((PQMSG)prgData)->ptl.x, ((PQMSG)prgData)->ptl.y); + break; + + default: + goto NoData; + } + + OutputString(szNextMessage, cch); + } +NoData: + return (prgData + cb); } -/**************************** Public Function ******************************\ + +/***************************************************************************\ * void OutputString(char szOut, SHORT cch); * -* Effects: This function will output the specified string to the +* This function will output the specified string to the * destinations. -* -* Return value: none \***************************************************************************/ void OutputString(szOut, cch) @@ -1265,14 +878,14 @@ SHORT cch; - /* Now display the new Line on the screen */ + /* Now display the new line on the screen */ if (spyopt.fWindow) { item = (SHORT)WinSendMsg(hwndSpyList, LM_INSERTITEM, (MPARAM)LIT_END, (MPARAM)(PSZ)szOut); WinSendMsg(hwndSpyList, LM_SETTOPINDEX, (MPARAM)item, 0L); - /* See if we have to many lines now */ + /* See if we have too many lines now */ while (item >= spyopt.cWindowLines) item = (SHORT)WinSendMsg(hwndSpyList, LM_DELETEITEM, (MPARAM)0, 0L); @@ -1291,12 +904,12 @@ SHORT cch; } -/**************************** Public Function ******************************\ +/***************************************************************************\ * MSGI * PmsgiFromMsg(USHORT msg) * -* Effects: Locate the msg in the array of message items +* Locate the msg in the array of message items * -* Return value: pointer to item that has the specified msg, or NULL +* Returns: pointer to item that has the specified msg, or NULL \***************************************************************************/ MSGI *PmsgiFromMsg(msg) USHORT msg; @@ -1306,7 +919,7 @@ USHORT msg; /* * Currently is a simple linear search, should be made faster - * Probabably a binary search. + * probably by using binary search. */ for (i=0; i< cmsgi; i++) { if (pmsgi->msg == msg) @@ -1318,425 +931,3 @@ USHORT msg; return (NULL); } - - - - -/**************************** Public Function ******************************\ -* MRESULT FAR PASCAL SpySaveListDlgProc(hwnd, msg, mp1, mp2) -* -* Effects: The Spy Windows Dialog procedure -* -* Return value: none -\***************************************************************************/ -MRESULT FAR PASCAL SpySaveListDlgProc(hwnd, msg, mp1, mp2) -HWND hwnd; -USHORT msg; -MPARAM mp1; -MPARAM mp2; -{ - HFILE hfileOut; - char szTemp[100]; - char szTime[10]; - char szDate[10]; - SHORT cItems; - SHORT iItem; - USHORT cch; - USHORT cchWritten; - USHORT wAction; - ULONG lTemp; - - switch (msg) { - - case WM_INITDLG: - WinSendDlgItemMsg(hwnd, DID_APPEND, BM_SETCHECK, - (MPARAM)spyopt.fAppend, 0L); - /* Initialize the dialog items */ - WinSetDlgItemText(hwnd, DID_FILENAME, spyopt.szSaveFileName); - break; - - case WM_COMMAND: - switch (SHORT1FROMMP(mp1)) { - case DID_OK: - /* - * Get the file name, and try to open the file, - * Then loop through and dump the listbox contents to the - * file. - */ - spyopt.fAppend = (BOOL)WinSendDlgItemMsg(hwnd, - DID_APPEND, BM_QUERYCHECK, 0L, 0L); - - WinQueryDlgItemText(hwnd, DID_FILENAME, - sizeof(spyopt.szSaveFileName), spyopt.szSaveFileName); - - if (DosOpen((PSZ)spyopt.szSaveFileName, (HFILE far *)&hfileOut, - (USHORT far *)&wAction, 0L, 0, - spyopt.fAppend? 0x0011 : 0x0012, 0x00C1, 0L) == 0) { - - /* If append, get to the end of the file */ - if (spyopt.fAppend) - DosChgFilePtr(hfileOut, 0L, 2, (PULONG)&lTemp); - - /* Get count of items */ - cItems = (SHORT)WinSendMsg(hwndSpyList, LM_QUERYITEMCOUNT, - 0L, 0L); - - /* Write out a title block to the file */ - _strdate(szDate); - _strtime(szTime); - DosWrite(hfileOut, - (PSZ)"***************************************\r\n", - 41, (PUSHORT)&cchWritten); - cch = sprintf(szTemp, "* Spy: %-10s %-10s *\r\n", - szDate, szTime); - DosWrite(hfileOut, (PSZ)szTemp, cch, (PUSHORT)&cchWritten); - - DosWrite(hfileOut, - (PSZ)"***************************************\r\n", - 41, (PUSHORT)&cchWritten); - - - /* Now output the list to the file */ - for (iItem = 0; iItem < cItems; iItem++) { - cch = (SHORT)WinSendMsg(hwndSpyList, LM_QUERYITEMTEXT, - MPFROM2SHORT(iItem, sizeof(szTemp)), - (MPARAM)(PSZ)szTemp); - /* Add Newline at end of string */ - szTemp[cch++] = '\r'; - szTemp[cch++] = '\n'; - szTemp[cch] = '\0'; - DosWrite(hfileOut, (PSZ)szTemp, cch, - (PUSHORT)&cchWritten); - } - DosClose(hfileOut); - } - - case DID_CANCEL: - /* Now dismiss the dialog */ - WinDismissDlg(hwnd, SHORT1FROMMP(mp1)); - break; - break; - } - - default: - return(WinDefDlgProc(hwnd, msg, mp1, mp2)); - } - return 0L; -} - - -/**************************** Public Function ******************************\ -* SelOrDeselWithMouse(BOOL fSelect) -* -* Effects: Fastway to add/or remove window from watch list -* -* Return value: none -\***************************************************************************/ - -void SelOrDeselWithMouse(fSelect) -BOOL fSelect; -{ - HWND rghwnd[MAXHWNDS]; - HWND hwndPoint; - SHORT chwnd; - BOOL fWinCurInList; - SHORT i; - - /* First get the window of interest */ - hwndPoint = HwndSelWinWithMouse(hwndSpy, FALSE); - if (hwndPoint == NULL) - return; /* No window selected */ - fWinCurInList = SpyFWindowInList(hwndPoint); - - if ((fWinCurInList && fSelect) - || (!fWinCurInList && !fSelect)) - return; /* Alredy right state */ - - chwnd = SpyGetWindowList(MAXHWNDS, (HWND FAR *)rghwnd); - - if (fSelect) { - /* Add window to end of list */ - rghwnd[chwnd++] = hwndPoint; - } else { - /* find it in the list, and delete it out */ - for (i=0; rghwnd[i] != hwndPoint; i++) - ; - - /* Now copy rest of them down */ - chwnd--; /* One less item */ - for (;i < chwnd; i++ ) { - rghwnd[i] = rghwnd[i+1]; - } - } - - /* Now call to update the list */ - SpySetWindowList(chwnd, (HWND FAR *)rghwnd); -} - - -/**************************** Public Function ******************************\ -* EnableOrDisableMsg(BOOL fEnable) -* -* Effects: Fastway to enable or disable a particular message code. The one -* that is currently selected in the output listbox. -* -* Return value: none -\***************************************************************************/ - -void EnableOrDisableMsg(fEnable) -BOOL fEnable; -{ - USHORT itemSel; - char szTemp[100]; - char *psz; - MSGI *pmsgi; - SHORT i; - - itemSel = (USHORT)WinSendMsg(hwndSpyList, LM_QUERYSELECTION, - (MPARAM)LIT_FIRST, 0L); - if (itemSel == (USHORT)LIT_NONE) - return; /* None to process */ - - /* Get the message text */ - WinSendMsg(hwndSpyList, LM_QUERYITEMTEXT, - MPFROM2SHORT(itemSel, sizeof(szTemp)), (MPARAM)(PSZ)szTemp); - - /* Now lets extract the messgae string from the line */ - psz = &szTemp[3]; - while (*psz != ' ') - psz++; /* locate first blank */ - *psz = '\0'; /* Zero terminate string */ - - - /* - * Loop through all of the items in our list, until we find a - * string that matches our string. - */ - pmsgi = rgmsgi; /* Point to start of list */ - for (i = 0; i < cmsgi; i++) { - if (strcmp(&szTemp[2], pmsgi->szMsg) == 0) { - /* - * Found our message, update the bit of the message, and - * call the function to let the hook know the new results - */ - if (fEnable) - pmsgi->wOptions |= MSGI_ENABLED; - else - pmsgi->wOptions &= ~MSGI_ENABLED; - - UpdateHooksMsgTable(); /* Set Spys Msg table */ - return; - } - pmsgi++; - } -} - - - -/**************************** Public Function ******************************\ -* DumpOneWindowInfo() -* -* Effects: Dump the information about one window to the current outputs -* -* Return value: none -\***************************************************************************/ -void DumpOneWindowInfo() -{ - HWND hwndPoint; - HWND hwndT; - SHORT wLevel; - - hwndPoint = HwndSelWinWithMouse(hwndSpy, FALSE); - if (hwndPoint == NULL) - return; /* No window selected */ - - /* Now see what level the window is at */ - wLevel = 0; - hwndT = hwndPoint; - while (hwndT != NULL) { - wLevel++; - hwndT = WinQueryWindow(hwndT, QW_PARENT, FALSE); - }; - - - DumpWindowInfo(hwndPoint, wLevel); -} - - -/**************************** Private Function ******************************\ -* DumpAllWIndowsInfo (HWND hwnd, WORD wLevel) -* -* Effects: Dumps the complet window list out to the current output units. -* -* -* Return value: -\***************************************************************************/ -void DumpAllWindowsInfo(hwnd, wLevel) -HWND hwnd; -SHORT wLevel; -{ - HWND hwndT; - SPWD *pspwdT; - - pspwdT = pspwd + wDumpCount; - DumpWindowInfo(hwnd, wLevel); - pspwdT->hwnd = hwnd; - pspwdT->index = wDumpCount; - - - /* - * Then we recurse with all of our children - */ - if ((hwndT = WinQueryWindow(hwnd, QW_TOP, FALSE)) != NULL) - DumpAllWindowsInfo(hwndT, wLevel+1); - - /* - * Then go to our next sibling - */ - if ((hwndT = WinQueryWindow(hwnd, QW_NEXT, FALSE)) != NULL) - DumpAllWindowsInfo(hwndT, wLevel); -} - - - -/**************************** Private Function ******************************\ -* DumpWindowIndex (void) -* -* Effects: Dump a sorted list of Hwnds and index into other list -* This function works like sh.t -* -* -* Return value: -\***************************************************************************/ -void DumpWindowIndex() -{ - SHORT cch; - char szTemp[20]; - char szOutput[100]; - HWND hwndT; - SPWD *pspwdT; - SHORT i; - - /* Sort the hwnds first */ - qsort((void *)pspwd, wDumpCount, sizeof(SPWD), CompareHwnds); - pspwdT = pspwd; - - strcpy (szOutput, "Index of Window Handles"); - cch = strlen(szOutput); - for (i=0; i< wDumpCount; i++) { - if ((i & 3) == 0) { - /* 4 per row */ - OutputString(szOutput, cch); - szOutput[0] = '\0'; - cch = 0; - } - - cch += sprintf(szTemp, "%3d-%04x ", - pspwdT->index, (USHORT)pspwdT->hwnd); - strcat (szOutput, szTemp); - pspwdT++; - } - - OutputString(szOutput, cch); - -} - - -/**************************** Private Function ******************************\ -* int CompareHwnds(SPWD *pspwd1, SPWD *pspwd2) -* -* Effects: Compares two window handles. -* -* -* Return value: -\***************************************************************************/ -int cdecl CompareHwnds(pspwd1, pspwd2) -const void *pspwd1; -const void *pspwd2; -{ - return (((SPWD *)pspwd1)->hwnd < ((SPWD *)pspwd2)->hwnd)? -1 : 1; -} - - - - -/**************************** Private Function *****************************\ -* DumpWindowInfo(HWND hwnd, SHORT wLevel) -* -* Effects: Displays the information about the selected window in the dialog -* -* -* Return value: -\***************************************************************************/ -void DumpWindowInfo(hwnd, wLevel) -HWND hwnd; -SHORT wLevel; -{ - HWND hwndParent; - HWND hwndChild; - HWND hwndOwner; - - char szTemp[100]; - SHORT cch; - char szClass[30]; - RECTL rcl; - USHORT id; - ULONG ul; - ULONG ulStyle; - ULONG ulPFNWP; - ULONG ulHMQ; - - hwndParent = WinQueryWindow(hwnd, QW_PARENT, FALSE); - hwndChild = WinQueryWindow(hwnd, QW_TOP, FALSE); - hwndOwner = WinQueryWindow(hwnd, QW_OWNER, FALSE); - id = (USHORT)WinQueryWindowUShort(hwnd, QWS_ID); - ulHMQ = (ULONG)WinQueryWindowULong(hwnd, QWL_HMQ); - WinQueryWindowRect(hwnd, &rcl); - WinMapWindowPoints(hwnd, hwndParent, (PPOINTL)&rcl, 2); - - cch = sprintf(szTemp, - "%d-H:%04x(%d) P:%04x C:%04x O:%04x ID:%04x MQ:%04x (%d, %d) (%d, %d)", - ++wDumpCount, (SHORT)hwnd, wLevel, (SHORT)hwndParent, - (SHORT)hwndChild, (SHORT)hwndOwner, id, (SHORT)ulHMQ, - (SHORT)rcl.xLeft, (SHORT)rcl.yBottom, - (SHORT)rcl.xRight, (SHORT)rcl.yTop); - - OutputString(szTemp, cch); - - ulStyle = (ULONG)WinQueryWindowULong(hwnd, QWL_STYLE); - ulPFNWP = (ULONG)WinQueryWindowULong(hwnd, QWP_PFNWP); - WinQueryClassName(hwnd, sizeof(szClass), (PSZ)szClass); - - cch = sprintf(szTemp, - " St:%08lx Pf:%p Cl:%s", - ulStyle, ulPFNWP, szClass); - OutputString(szTemp, cch); -} - - - -/**************************** Public Function *****************************\ -* AboutWndProc(HWND hwnd, USHORT message, MPARAM mp1, MPARAM mp2) -* -* Effects: About Spy Dialog procedure -* -* -* Return value: -\***************************************************************************/ -MRESULT FAR PASCAL AboutWndProc(hwnd, message, mp1, mp2) -HWND hwnd; -USHORT message; -MPARAM mp1; -MPARAM mp2; -{ - switch (message) { - case WM_COMMAND: - WinDismissDlg(hwnd, TRUE); - break; - default: - return(WinDefDlgProc(hwnd, message, mp1, mp2)); - break; - } - return 0L; - -} /* end aboutwndproc */