Annotation of pmsdk/samples/spy/spy.c, revision 1.1

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 */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.