Annotation of os232sdk/toolkt20/c/samples/spy/spy.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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