File:  [OS/2 SDKs] / os232sdk / toolkt20 / c / samples / spy / spy.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Thu Aug 9 12:26:30 2018 UTC (7 years, 9 months ago) by root
Branches: msft, MAIN
CVS tags: os2sdk-1990, HEAD
Microsoft OS/2 SDK 2.0 05-30-1990

/****************************** Module Header ******************************\
* Module Name:  spy.c - Spy application
*
* Created: Microsoft, IBM Corporation 1990
*
*	DISCLAIMER OF WARRANTIES.  The following [enclosed] code is 
*	sample code created by Microsoft Corporation and/or IBM 
*	Corporation. This sample code is not part of any standard 
*	Microsoft or IBM product and is provided to you solely for 
*	the purpose of assisting you in the development of your 
*	applications.  The code is provided "AS IS", without 
*	warranty of any kind.  Neither Microsoft nor IBM shall be 
*	liable for any damages arising out of your use of the sample 
*	code, even if they have been advised of the possibility of 
*	such damages.
*
\***************************************************************************/

#define INCL_WIN
#define INCL_WINSYS
#define INCL_DOSPROCESS
#define INCL_DOSSEMAPHORES
#define INCL_DOSMODULEMGR
#define INCL_DOSRESOURCES
#define INCL_HELP
#include <os2.h>
#include <stdio.h>
#include <string.h>
#include "spy.h"
#include "spyhk32.h"
#include "help.h"
#include <time.h>
#include <stdlib.h>


/************* GLOBAL VARIABLES         */

/************************** IN SPY.H *********************************** */
HAB         hab;
HMQ         hmqSpy;
HWND        hwndSpy;
HWND        hwndSpyFrame;
HWND        hwndSpyList = NULL;
HWND        hwndWindowLB;
HWND        hwndMessageLB;
HWND        hwndHelpInstance = NULL;
HHEAP       hHeap;
SHORT       cxBorder;
SHORT       cyBorder;
ULONG       uVersion;
BOOL        fV11 = TRUE;                // Are we version 1.1?

HPOINTER    hptrArrow;
HPOINTER    hptrSelWin;
HPOINTER    hptrIcon11 = NULL;          /* 1.1 Spy Icon */

BOOL        fDebug = FALSE;
USHORT      iCurItemFocus;              /* Index to item that has the focus */
BOOL        fSpyActive = MIA_CHECKED;   /* Any non-zero is true */
BOOL        fTrackingListBox = FALSE;   /* Tracking windows active ? */
BOOL        fAllFrames = 0;             /* Are we processing all frames ? */
BOOL        fAllWindows = 0;            /* Are we processing all windows ? */


HWND        hwndWinDlgDisp = NULL;      /* hwnds info in Window Dialog */

SHORT       wDumpCount = 0;             /* Count of which window is being dumped */
SPWD        *pspwd = NULL;
/*********************************************************************** */

/* Define memory semaphore to have second thread sleep on */
HEV         hevThread;                 /* Event semaphore to wait on */
UCHAR       rgMsgData[MAXMSGBYTES];     /* Max bytes to extract per message */


char szSpyClass[] = "Spy";
char szTitle[] = "32-bit spy sample";

/************* PROCEDURE DECLARATIONS   */



void    ProcHookThread(void);    /* will process the hook messages */

void    ProcessQueueMsg(QMSGSPY *);
void    UpdateMsgBoxCurMsgText(HWND);
void    InitializeOptions(int, char **);    /* initialize Spy initial state */
void    InitializeMenus(void);
void    InitializeHelp(void);
void    DebugBreak(void);

PSZ     DumpParam(PSZ prgData, SHORT cb, BOOL fValidData,
                UCHAR bMPType);

/* Define some variables needed for help processing */


/**************************** Public Function ******************************\
* int cdecl main (argc, argv)
*
* Effects: Spy Main function
*
* Return value:
\***************************************************************************/
int main(argc, argv)
int argc;
char **argv;
{
    ULONG   flCreateFlags;
    QMSG    qmsg;
    RECTL   rcl;
    TID     tid;


    // Make sure the Spy Hook DLL is initialized
    SpyInitializeHook();

    hab = WinInitialize(0);
    uVersion = WinQueryVersion(hab);
    if ((LOBYTE(LOUSHORT(uVersion)) > 10) ||
            (HIBYTE(LOUSHORT(uVersion)) > 10))
        fV11 = FALSE;

    hmqSpy = WinCreateMsgQueue(hab, 0);

    if (!WinRegisterClass((HAB)NULL, szSpyClass, (PFNWP)SpyWndProc,
            CS_SYNCPAINT, 0)) {
        WinAlarm(HWND_DESKTOP, WA_ERROR);
        return(0);
    }

    /*
     * We need to process the options, before we create a heap, or we
     * will blow away our options
     */
    InitializeOptions(argc, argv);    /* initialize Spy initial state */

    /*
     * Create a heap for the program
     */
    hHeap = WinCreateHeap(0, 0, 0, 0, 0, 0);

    hptrArrow = WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, TRUE);
    cxBorder = (SHORT)WinQuerySysValue(HWND_DESKTOP, SV_CXBORDER);
    cyBorder = (SHORT)WinQuerySysValue(HWND_DESKTOP, SV_CYBORDER);

    hptrSelWin = WinQuerySysPointer(HWND_DESKTOP, SPTR_MOVE, TRUE);

    SpyInstallHook(hab, hmqSpy, spyopt.bHooks);
    SpySetAllWindowOpt (fAllWindows);
    SpySetAllFrameOpt (fAllFrames);

    flCreateFlags = FCF_TITLEBAR | FCF_SYSMENU | FCF_SIZEBORDER
        | FCF_MINMAX | FCF_SHELLPOSITION | FCF_TASKLIST | FCF_MENU
        | FCF_ACCELTABLE | FCF_ICON;

    // See if we get here
    hwndSpyFrame = WinCreateStdWindow(HWND_DESKTOP,
            WS_VISIBLE,
            (PULONG)&flCreateFlags,
            (PSZ)szSpyClass, (PSZ)szTitle,
            WS_VISIBLE,
            (HMODULE)NULL, IDR_SPY,
            (PHWND)&hwndSpy);

    WinQueryWindowRect(hwndSpy, &rcl);
    hwndSpyList = WinCreateWindow (hwndSpy, WC_LISTBOX, "",
            fV11 ? (WS_VISIBLE | LS_NOADJUSTPOS) :
                   (WS_VISIBLE | LS_NOADJUSTPOS | LS_HORZSCROLL),
            -cxBorder, -cyBorder,
            (SHORT)(rcl.xRight - rcl.xLeft) + 2 * cxBorder,
            (SHORT)(rcl.yTop - rcl.yBottom) + 2 * cyBorder,
            hwndSpy, HWND_TOP, DID_SPYLIST, NULL, NULL);

    /*
     * Read the os2.ini information if it exists, and set the menu items
     * to correspond to the initial state read from OS2.ini
     */
    InitializeMenus();
    InitializeHelp();

    /*
     * Set the focus to the list box.  Note: Only call WinSetFocus if
     * our frame is the active window.  As we may have been started in
     * the background.  If this is the case, we want to set the frames
     * focus save to the listbox, such that it will be the active window
     * when our frame is activated
     */
    if (WinQueryWindow(HWND_DESKTOP, QW_TOP, FALSE) == hwndSpyFrame)
        WinSetFocus(HWND_DESKTOP, hwndSpyList);
    else
        WinSetWindowULong(hwndSpyFrame, QWL_HWNDFOCUSSAVE,
            (ULONG)hwndSpyList);



    /* Start the thread that will process the messages from the hook */
    DosCreateEventSem(NULL, &hevThread, 0L, FALSE);
    DosCreateThread((PTID)&tid, ProcHookThread, 0L, 0L, 4096L);

    UpdateHooksMsgTable();      /* Set Spys Msg table */
    SpyHookOnOrOff (TRUE);      /* Turn the hook on */


   /*
    * Now process all of the messages
    */
    while (WinGetMsg(NULL, (PQMSG)&qmsg, NULL, 0, 0)) {
        WinDispatchMsg(NULL, (PQMSG)&qmsg);
    }

    SpyReleaseHook (TRUE);      /* Release input hook */

    WinDestroyWindow(hwndSpyFrame);
    SpyTerminateHook ();

    WinDestroyPointer(hptrArrow);
    WinDestroyPointer(hptrSelWin);
    if (hptrIcon11 != NULL)
        WinDestroyPointer (hptrIcon11);

    if (hwndHelpInstance != NULL)
       WinDestroyHelpInstance(hwndHelpInstance);


    WinDestroyMsgQueue(hmqSpy);
    WinTerminate(hab);

    /* If the spy output file is open, close it now */
    if (spyopt.hfileSpy != NULL)
        DosClose(spyopt.hfileSpy);


    DosExit(EXIT_PROCESS, 0);
}




/**************************** Public Function ******************************\
* InitializeOptions(argc, argv)
*
* Effects: Initialize spy, first from the default options, second from
*          OS2.INI file, and override from command switches.
*
* Return value:
\***************************************************************************/
VOID InitializeOptions(argc, argv)
int argc;
char **argv;
{
    ULONG    cch;


    /*
     * If the OS2.INI information exists, initialize our options to
     * the stored values
     */
    if (PrfQueryProfileSize (HINI_USER, "Spy", "Options", &cch) == 0) {
        cch = sizeof(SPYOPT);

        PrfQueryProfileData(HINI_USER, "Spy", "Options", (PSZ)&spyopt,
                &cch);
        PrfQueryProfileString(HINI_USER, "Spy", "FileName", "spy.out",
                (PSZ)spystr.szFileName, sizeof(spystr.szFileName));
        PrfQueryProfileString(HINI_USER, "Spy", "SaveFileName", "spy.lis",
                (PSZ)spystr.szSaveFileName, sizeof(spystr.szSaveFileName));
    }

    /*
     * Then check for command line overrides
     */
    while  (argc > 1) {
        argv++; /* get beyond the program name */

        /* Test for debug flag */
        if (!strcmpi(*argv, "/d") ) {
            fDebug = TRUE;
            DebugBreak();
        }

        /* Test for send message hook flag */
        if (!strcmpi(*argv, "+s"))
            spyopt.bHooks |= SPYH_SENDMSG;
        if (!strcmpi(*argv, "-s"))
            spyopt.bHooks &= ~SPYH_SENDMSG;

        /* Test for input hook flag */
        if (!strcmpi(*argv, "+i"))
            spyopt.bHooks |= SPYH_INPUT;
        if (!strcmpi(*argv, "-i"))
            spyopt.bHooks &= ~SPYH_INPUT;

        argc--;
    }
}



/**************************** Public Function ******************************\
* InitializeMenus()
*
* Effects: Initialize the menus from the initialized defaults.
*
* Return value:
\***************************************************************************/
VOID InitializeMenus()
{
    HWND        hwndMenu;
    USHORT      wAction;

    /*
     * Now we need to update the menu items to the final
     * state
     */
    hwndMenu = WinWindowFromID(hwndSpyFrame, FID_MENU);

    WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(CMD_INPUTHOOK, TRUE),
            MPFROM2SHORT(MIA_CHECKED,
             (spyopt.bHooks & SPYH_INPUT) ? MIA_CHECKED : 0));
    WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(CMD_SENDMSGHOOK, TRUE),
             MPFROM2SHORT(MIA_CHECKED,
             (spyopt.bHooks & SPYH_SENDMSG) ? MIA_CHECKED : 0));

    WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(CMD_SENDEXTEND, TRUE),
            MPFROM2SHORT(MIA_CHECKED,
             spyopt.fSendExtend ? MIA_CHECKED : 0));

    WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(CMD_OUTSCREEN, TRUE),
            MPFROM2SHORT(MIA_CHECKED, spyopt.fWindow ? MIA_CHECKED : 0));

    WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(CMD_OUTTERM, TRUE),
            MPFROM2SHORT(MIA_CHECKED, spyopt.fDebugOutput ? MIA_CHECKED : 0));

    WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(CMD_OUTFILE, TRUE),
            MPFROM2SHORT(MIA_CHECKED, spyopt.fFile ? MIA_CHECKED : 0));

    WinSendMsg(hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(CMD_ALPHASORT, TRUE),
            MPFROM2SHORT(MIA_CHECKED,
                    spyopt.fAlphaSortMsgList ? MIA_CHECKED : 0));

    /*
     * If the options specify output to file, open the file now
     */
    if (spyopt.fFile) {
        if (DosOpen((PSZ)spystr.szFileName, &spyopt.hfileSpy,
                (ULONG  *)&wAction, 0L, 0,
                0x0012, 0x00C1, 0L) != 0)
            spyopt.hfileSpy = NULL; /* Failed on open */
    }
}



/**************************** Public Function ******************************\
* InitializeHelp
*
* Effects: Initialize the help subsubsystem.
*
*
* Return value:
\***************************************************************************/
VOID InitializeHelp()
{

    /*
     * Now initialize Help - First we need to verify that the the help
     * DLL is avaialable, if not, we will not do help processing.
     */
    HELPINIT hi;
    char    szTitle[256];   /* Assume the title is not more than 256 chars */
    HWND    hwndMenu;
    SHORT   sMenuIndex;

    /* Now try to create the help instance */
    hi.hmodHelpTableModule =
    hi.hmodAccelActionBarModule = (HMODULE)NULL;
    hi.pszTutorialName = (PSZ)NULL;
    hi.pszHelpLibraryName = "spy32.hlp";
    hi.idAccelTable =
    hi.idActionBar = 0;
    hi.cb = sizeof(HELPINIT);
    hi.usShowPanelId = CMIC_HIDE_PANEL_ID;
    hi.phtHelpTable = (PHELPTABLE)MAKEULONG(IDR_SPY, 0xffff);

    WinQueryWindowText(hwndSpyFrame, sizeof(szTitle), szTitle);
    hi.pszHelpWindowTitle = szTitle;

    hwndHelpInstance = WinCreateHelpInstance(hab, &hi);
    if (hwndHelpInstance != NULL) {
        if(!WinAssociateHelpInstance(hwndHelpInstance, hwndSpyFrame) ) {
            WinDestroyHelpInstance(hwndHelpInstance);
            hwndHelpInstance = (HWND)NULL;
        }
    }

    if (hwndHelpInstance == NULL) {
        /* Help was not initialized, so gray out help items */
        hwndMenu = WinWindowFromID(hwndSpyFrame, FID_MENU);
        for (sMenuIndex = CMD_HOWHELP; sMenuIndex <= CMD_HELPINDEX;
                sMenuIndex++) {
            WinSendMsg(hwndMenu, MM_SETITEMATTR,
                    MPFROM2SHORT(sMenuIndex, TRUE),
                    MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED));
        }
    }
}



/**************************** Public Function ******************************\
* MRESULT EXPENTRY SpyWndProc(hwnd, msg, mp1, mp2)
*
* Effects: Spy Client window procedure
*
*
* Return value:
\***************************************************************************/
MRESULT EXPENTRY SpyWndProc(hwnd, msg, mp1, mp2)
HWND hwnd;
USHORT msg;
MPARAM mp1;
MPARAM mp2;
{
    QMSGSPY qmsgspy;
    VOID    SpyPaint();
    SHORT   cBytes;
    ULONG   ulAction;

    switch (msg) {
    case WM_CREATE:
        /* Set up this global first thing in case we need it elsewhere */
        hwndSpy = hwnd;
        break;

    case WM_SEM2:
        /*
         * Other thread told use there are some messages out there.  Loop
         * through and process all of the pending messages, and output
         * the listbox position at the end.  Also make sure to flush
         * the file buffer before we go back to sleep.
         */
        while (SpyGetNextMessage(&qmsgspy, rgMsgData, sizeof(rgMsgData), 0L)) {
            ProcessQueueMsg(&qmsgspy);
        }

        if (spyopt.fFile)
            DosBufReset(spyopt.hfileSpy);

        DosPostEventSem(hevThread);

        break;

    case WM_COMMAND:
        switch (SHORT1FROMMP(mp1)) {
        case CMD_ACTIVE:

            /*
             * THe active menu item was selected, we will toggle the
             * the selection by setting active to 0 or MIA_CHECKED.
             * Call the hook, and then update the checkmark on the menu
             */
            fSpyActive ^= MIA_CHECKED;  /* Toggle on or off */
            SpyHookOnOrOff (fSpyActive);
            WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
                MM_SETITEMATTR, MPFROM2SHORT(CMD_ACTIVE, TRUE),
                MPFROM2SHORT(MIA_CHECKED, fSpyActive));

            break;
        case CMD_ABOUT:
            WinDlgBox(HWND_DESKTOP, hwnd, (PFNWP)AboutWndProc, NULL,
                    IDD_About1Dlg, (PCH)NULL);
            break;

        case CMD_EXIT:
            WinPostMsg(NULL, WM_QUIT, 0L, 0L);
            break;

        case CMD_CLRWIN:
            /*
             * Delete all items in the list.  Simply do this
             * By deleting the first item, until the count goes to
             * zero
             */
            WinSendMsg(hwndSpyList, LM_DELETEALL, 0L, 0L);
            break;

        case CMD_SAVEWIN:
            SpyHookOnOrOff (FALSE);
            WinDlgBox(HWND_DESKTOP, hwndSpyFrame,
                (PFNWP)SpySaveListDlgProc, (HMODULE)NULL,
                IDD_SaveListDlg, (PCH)NULL);
            SpyHookOnOrOff (fSpyActive);
            break;

        /*
         * This command saves out the current options to OS2.ini
         */
        case CMD_SAVEOPT:
            PrfWriteProfileData(HINI_USER, "Spy", "Options", (PSZ)&spyopt,
                    sizeof(SPYOPT));
            PrfWriteProfileString(HINI_USER, "Spy", "FileName",
                    (PSZ)spystr.szFileName);
            PrfWriteProfileString(HINI_USER, "Spy", "SaveFileName",
                    (PSZ)spystr.szSaveFileName);

            break;

        case CMD_WINDOWS:
            SpyHookOnOrOff (FALSE);
            hwndWindowLB = NULL;
            iCurItemFocus = (USHORT)-1;
            WinDlgBox(HWND_DESKTOP, hwndSpyFrame,
                (PFNWP)SpyWindowsDlgProc, (HMODULE)NULL,
                IDD_WindowsDlg, (PCH)NULL);

            SpyHookOnOrOff (fSpyActive);
            break;

        case CMD_QUEUES:
            SpyHookOnOrOff (FALSE);
            hwndWindowLB = NULL;
            iCurItemFocus = (USHORT)-1;
            WinDlgBox(HWND_DESKTOP, hwndSpyFrame,
                (PFNWP)SpyQueuesDlgProc, (HMODULE)NULL,
                IDD_MsgQueueDlg, (PCH)NULL);

            SpyHookOnOrOff (fSpyActive);
            break;

        case CMD_WNMSSEL:
        case CMD_WNMSDSL:
            SpyHookOnOrOff (FALSE);
            SelOrDeselWithMouse(SHORT1FROMMP(mp1) == CMD_WNMSSEL);
            SpyHookOnOrOff (fSpyActive);
            break;

        case CMD_ALLWNDWS:

            /*
             * The user selected the ALLFRAMES, toggle the state, and
             * update the menu and the hook state.
             */
            fAllWindows ^= MIA_CHECKED;  /* Toggle on or off */
            SpySetAllWindowOpt (fAllWindows);
            WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
                MM_SETITEMATTR, MPFROM2SHORT(CMD_ALLWNDWS, TRUE),
                MPFROM2SHORT(MIA_CHECKED, fAllWindows));
            break;

        case CMD_ALLFRAMES:

            /*
             * The user selected the ALLFRAMES, toggle the state, and
             * update the menu and the hook state.
             */
            fAllFrames ^= MIA_CHECKED;  /* Toggle on or off */
            SpySetAllFrameOpt (fAllFrames);
            WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
                MM_SETITEMATTR, MPFROM2SHORT(CMD_ALLFRAMES, TRUE),
                MPFROM2SHORT(MIA_CHECKED, fAllFrames));
            break;

        case CMD_WNDPWIN:
            wDumpCount = 0;
            DumpOneWindowInfo();
            break;
        case CMD_WNDPALL:
            wDumpCount = 0;
            pspwd = (SPWD *)WinAllocMem(hHeap, sizeof(SPWD)* MAXSPYDUMP);
            cBytes = DumpAllWindowsInfo(HWND_DESKTOP, 0);
            cBytes += DumpAllWindowsInfo(HWND_OBJECT, -10);
            DumpWindowIndex(cBytes);
            WinFreeMem(hHeap, (char *)pspwd, sizeof(SPWD)* MAXSPYDUMP);
            break;
        case CMD_DACCEL:
            DumpFrameAcclTable();
            break;

        case CMD_MESSAGES:
            SpyHookOnOrOff (FALSE);
            WinDlgBox(HWND_DESKTOP, hwndSpyFrame,
                (PFNWP)SpyMsgDlgProc, (HMODULE)NULL,
                IDD_MessagesDlg, (PCH)NULL);
            SpyHookOnOrOff (fSpyActive);
            break;

        case CMD_ALPHASORT:
            spyopt.fAlphaSortMsgList ^= TRUE;

            WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
                    MM_SETITEMATTR, MPFROM2SHORT(CMD_ALPHASORT, TRUE),
                    MPFROM2SHORT(MIA_CHECKED,
                            spyopt.fAlphaSortMsgList ? MIA_CHECKED : 0));
            break;

        case CMD_SENDMSG:
            WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
                MM_SETITEMATTR, MPFROM2SHORT(CMD_SENDMSG, TRUE),
                MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED));
            WinLoadDlg(HWND_DESKTOP, hwndSpyFrame,
                (PFNWP)SendMsgDlgProc, (HMODULE)NULL,
                IDD_SendMsgDlg, (PCH)NULL);
            break;

        /*
         * The command in this section are defined in the Hooks Menu.
         * All of these items toggle selections on or off.  The first two
         * Items must be registered with the input hook.  The last two simply
         * retrict how much information is displayed for send messages
         */

        case CMD_INPUTHOOK:
            spyopt.bHooks ^= SPYH_INPUT;
            WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
                MM_SETITEMATTR, MPFROM2SHORT(CMD_INPUTHOOK, TRUE),
                MPFROM2SHORT(MIA_CHECKED,
                     (spyopt.bHooks & SPYH_INPUT) ? MIA_CHECKED : 0));
                SpyReleaseHook (FALSE);     /* Dont clear queue */
                SpyInstallHook(hab, hmqSpy, spyopt.bHooks);
            break;

        case CMD_SENDMSGHOOK:
            spyopt.bHooks ^= SPYH_SENDMSG;
            WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
                MM_SETITEMATTR, MPFROM2SHORT(CMD_SENDMSGHOOK, TRUE),
                MPFROM2SHORT(MIA_CHECKED,
                     (spyopt.bHooks & SPYH_SENDMSG) ? MIA_CHECKED : 0));
                SpyReleaseHook (FALSE);     /* Dont clear queue */
                SpyInstallHook(hab, hmqSpy, spyopt.bHooks);
            break;

        case CMD_SENDEXTEND:
            spyopt.fSendExtend ^= 1;  /* Toggle on or off */
            WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
                MM_SETITEMATTR, MPFROM2SHORT(CMD_SENDEXTEND, TRUE),
                MPFROM2SHORT(MIA_CHECKED,
                     spyopt.fSendExtend ? MIA_CHECKED : 0));
            break;

        /*
         * The commands in this section are defined in the Outputs Menu.
         * The first 3 items simply toggle outputs on or off, where the
         * last item allows the user to change all of the output options.
         */
        case CMD_OUTSCREEN:
            spyopt.fWindow ^= 1;  /* Toggle on or off */
            WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
                MM_SETITEMATTR, MPFROM2SHORT(CMD_OUTSCREEN, TRUE),
                MPFROM2SHORT(MIA_CHECKED, spyopt.fWindow ? MIA_CHECKED : 0));
            break;

        case CMD_OUTTERM:
            spyopt.fDebugOutput ^= 1;  /* Toggle on or off */
            WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
                MM_SETITEMATTR, MPFROM2SHORT(CMD_OUTTERM, TRUE),
                MPFROM2SHORT(MIA_CHECKED, spyopt.fDebugOutput ? MIA_CHECKED : 0));
            break;

        case CMD_OUTFILE:
            spyopt.fFile ^= 1;  /* Toggle on or off */
            WinSendMsg(WinWindowFromID(hwndSpyFrame, FID_MENU),
                MM_SETITEMATTR, MPFROM2SHORT(CMD_OUTFILE, TRUE),
                MPFROM2SHORT(MIA_CHECKED, spyopt.fFile ? MIA_CHECKED : 0));
            /*
             * Open or close the output file
             */
            if (spyopt.fFile) {
                 if (spyopt.hfileSpy == NULL)
                    if (DosOpen((PSZ)spystr.szFileName, &spyopt.hfileSpy,
                            &ulAction, 0L, 0,
                            0x0012, 0x00C1, 0L) != 0)
                        spyopt.hfileSpy = NULL; /* Failed on open */
            } else {
                if (spyopt.hfileSpy != NULL) {
                    /* file open, not outputing, close it now */
                    DosClose (spyopt.hfileSpy);
                    spyopt.hfileSpy = NULL;
                }
            }
            break;

        case CMD_OUTPUTS:
            SpyHookOnOrOff (FALSE);
            WinDlgBox(HWND_DESKTOP, hwndSpyFrame,
                (PFNWP)SpyOutputsDlgProc, (HMODULE)NULL,
                IDD_OutputsDlg, (PCH)NULL);
            SpyHookOnOrOff (fSpyActive);
            break;

        case CMD_MGDABLE:
        case CMD_MGEABLE:
            EnableOrDisableMsg(SHORT1FROMMP(mp1) == CMD_MGEABLE);
            break;
        /*
         * Help Menu items, send message to help manager
         */
        case CMD_HOWHELP:
        if (hwndHelpInstance != NULL)
             WinSendMsg(hwndHelpInstance, HM_DISPLAY_HELP,
                        (MPARAM)NULL, (MPARAM)NULL);
           break;

        /* Extended help option was chosen from pull-down */
        case CMD_HELPEXTENDED:
           if (hwndHelpInstance != NULL)
             WinSendMsg(hwndHelpInstance, HM_EXT_HELP,
             (MPARAM) 0, (MPARAM) 0 );
           break;

        /* Keys help option was chosen from pull-down */

        case CMD_HELPKEYS:
           if (hwndHelpInstance != NULL)
             WinSendMsg(hwndHelpInstance, HM_KEYS_HELP,
               (MPARAM) 0, (MPARAM) 0 );
           break;

        /* Index option was chosen from pull-down */

        case CMD_HELPINDEX:
           if (hwndHelpInstance != NULL)
             WinSendMsg(hwndHelpInstance, HM_HELP_INDEX,
               (MPARAM) 0, (MPARAM) 0 );
           break;
        }

        break;
    case HM_HELPSUBITEM_NOT_FOUND:
        if (hwndHelpInstance != NULL)
            (void)WinSendMsg(hwndHelpInstance, HM_EXT_HELP,
                                        (MPARAM)NULL, (MPARAM)NULL);
        break;
    case HM_QUERY_KEYS_HELP:
        return (MRESULT)HLP_KEYS;

    case WM_SIZE:
        /* We need to resize the listbox, if it exists */
        if (hwndSpyList != NULL) {
            WinSetWindowPos(hwndSpyList, HWND_TOP, -cxBorder, -cyBorder,
                SHORT1FROMMP(mp2) + 2 * cxBorder,
                SHORT2FROMMP(mp2) + 2 * cyBorder, SWP_MOVE | SWP_SIZE);
        }

        /* Now fall through to process the message */
    default:
        return(WinDefWindowProc(hwnd, msg, mp1, mp2));
        break;
    }
    return(0L);
}




/***************************** Private Function ****************************\
* USHORT UConvertStringToNum(psz)
*
* Effects:
*   Converts the passed string to a number 0xffff if not number
*
* History:
*   27-September-1988 KurtE
\***************************************************************************/
USHORT  UConvertStringToNum(psz)
register char   *psz;
{
    register USHORT uNum;
    /*
     * This aint to fancy yet, but if the first few chars are
     * 0x, we assume the user typed in a HEX number, else if 0-9,
     * we assume decimal, else we use the string, also for windows if the
     * user left the 0000:0000 we ignore the high end and assume it is
     * hex.
     */

    /* First see if digit in first position */
    if ((*psz >= '0') && (*psz <= '9')) {
        /* Assume numbers now */
        if ((*psz == '0') && (*(psz+1) == 'x')) {

            /* We are in hex mode */
            psz += 2;
            uNum = 0;
            for (;;) {
                if ((*psz >= '0') && (*psz <= '9'))
                    uNum = uNum * 16 + (USHORT)(*psz - '0');
                else if ((*psz >= 'a') && (*psz <= 'f'))
                    uNum = uNum * 16 + (USHORT)(*psz - 'a');
                else if ((*psz >= 'F') && (*psz <= 'F'))
                    uNum = uNum * 16 + (USHORT)(*psz - 'A');
                else
                    break;
                psz++;
            }

        } else {
            /* Decimal mode */
            uNum = (USHORT)(*psz++ - '0');
            while ((*psz >= '0') && (*psz <= '9')) {
                uNum = uNum * 10 + (USHORT)(*psz++ - '0');
            }
        }

        return (uNum);

    } else if (psz=strchr(psz,':')) {
        // boy this is sh.t, it should be combined above!!!
            /* We are in hex mode */
            psz++;
            uNum = 0;
            for (;;) {
                if ((*psz >= '0') && (*psz <= '9'))
                    uNum = uNum * 16 + (USHORT)(*psz - '0');
                else if ((*psz >= 'a') && (*psz <= 'f'))
                    uNum = uNum * 16 + (USHORT)(*psz - 'a');
                else if ((*psz >= 'F') && (*psz <= 'F'))
                    uNum = uNum * 16 + (USHORT)(*psz - 'A');
                else
                    break;
                psz++;
            }

    } else
        /* Not num, return 0xffff */
        return (0xffff);
}





/**************************** Public Function ******************************\
* void ProcHookThread()
*
* Effects: This function will wait for the hook to have messages,  when it
*   does, it will Set a memory semaphore, Post a WM_SEM1 message to the other
*   thread, and wait for the other thread has processed all of the messages.
*
* Return value: none
\***************************************************************************/

void ProcHookThread()
{
    ULONG ulPostCt;
    /* We'll look for a variation to run while the thread is active. */
    if (fDebug)
        DebugBreak();

    while (TRUE) {
        /*
         * Wait for a message to become available.
         */
        if (!SpyGetNextMessage(NULL, NULL, 0, -1L))
            break;

        /*
         * Now we have a message, set our semaphore, Post a WM_SEM2
         * message to the Client window, and wait for the client to
         * clear the semaphore.
         */
        DosResetEventSem(hevThread, &ulPostCt);
        WinPostMsg(hwndSpy, WM_SEM2, (MPARAM)1, (MPARAM)1);
        DosWaitEventSem(hevThread, -1L);
    }

    DosExit(EXIT_THREAD, 0);
}




/**************************** Public Function ******************************\
* void ProcessQueueMsg(pqmsg)
*
* Effects: This function will process the hook, by calling the hooks
*   get message.  We will than post the message to the current output
*   destinations.
*
* Return value: none
\***************************************************************************/

void ProcessQueueMsg(pqmsgspy)
    QMSGSPY    *pqmsgspy;
{
    MSGI    *pmsgi;
    CHAR    cSource;
    CHAR    cThread;
    char    szNextMessage[100];
    char    szTime[12];
    SHORT    cch;
    CHAR    bAscii;
    PSZ     prgData;



    /*
     * Now lets Build the message to output
     */
    if (WinIsWindow(hab, pqmsgspy->qmsg.hwnd)) {
        if (WinIsChild(pqmsgspy->qmsg.hwnd, hwndSpy))
            return;     /* dont want endless loops */
    }

    cThread = ':';
    if (pqmsgspy->qmsg.time == (ULONG)-1) {
        /* Sent message */
        szTime[0] = '\0';
        cSource = 'S';
        if (pqmsgspy->fs)
            cThread = '*';
    } else {
        cSource = 'I';
        if (pqmsgspy->fs != PM_REMOVE)
            cThread = '-';  /* Show different for non-remove */

        sprintf (szTime, "%-08lx", pqmsgspy->qmsg.time);
    }

    if ((pmsgi = PmsgiFromMsg(pqmsgspy->qmsg.msg)) == NULL) {
        /*
         * Message not in list, use default
         */
        cch = sprintf(szNextMessage,
            "%c%cMSG:0x%04x            H:%p 1:%08lx 2:%08lx T:%s",
            cSource, cThread, (SHORT)pqmsgspy->qmsg.msg, pqmsgspy->qmsg.hwnd,
            pqmsgspy->qmsg.mp1, pqmsgspy->qmsg.mp2, szTime);
    } else if (pmsgi->wOptions & MSGI_MOUSE) {
        /*
         * Mouse message, decode to mouse types
         */
        cch = sprintf(szNextMessage,
            "%c%c%-20s H:%p X:%-4d Y:%-4d HT:%04x T:%s",
            cSource, cThread, pmsgi->szMsg, pqmsgspy->qmsg.hwnd,
            SHORT1FROMMP(pqmsgspy->qmsg.mp1), SHORT2FROMMP(pqmsgspy->qmsg.mp1),
            SHORT1FROMMP(pqmsgspy->qmsg.mp2), szTime);
    } else if (pmsgi->wOptions & MSGI_KEY) {
        /*
         * Key messages, output special
         */
        bAscii = (CHAR)SHORT1FROMMP(pqmsgspy->qmsg.mp2);
        if ((bAscii < ' ') || (bAscii > '~'))
            bAscii = ' ';

        cch = sprintf(szNextMessage,
            "%c%c%-20s H:%p F:%04x R:%d S:%2x C:%04x(%c) V:%02x T:%s",
            cSource, cThread, pmsgi->szMsg, pqmsgspy->qmsg.hwnd,
            SHORT1FROMMP(pqmsgspy->qmsg.mp1),
            CHAR3FROMMP(pqmsgspy->qmsg.mp1),  CHAR4FROMMP(pqmsgspy->qmsg.mp1),
            SHORT1FROMMP(pqmsgspy->qmsg.mp2), bAscii,
            SHORT2FROMMP(pqmsgspy->qmsg.mp2), szTime);
    } else {
        /* No special format */
        cch = sprintf(szNextMessage,
            "%c%c%-20s H:%p 1:%08lx 2:%08lx T:%s",
            cSource, cThread, pmsgi->szMsg, pqmsgspy->qmsg.hwnd,
            pqmsgspy->qmsg.mp1, pqmsgspy->qmsg.mp2, szTime);
    }

    OutputString(szNextMessage, cch);

    /*
     * Now dump out any additional information associated with the
     * message.  The processing depends of the type of message on
     * how we are going to process the data.
     */
    if (spyopt.fSendExtend) {
        prgData = DumpParam((PSZ)rgMsgData, pqmsgspy->cbDataMP1,
                pqmsgspy->fMP1Valid, pqmsgspy->bMPType);

        DumpParam(prgData, pqmsgspy->cbDataMP2, pqmsgspy->fMP1Valid,
                (UCHAR)((pqmsgspy->bMPType) >> 3));
    }

}




/**************************** Public Function ******************************\
* PSZ DumpParam(PSZ prgData, MPARAM mp, SHORT cb, BOOL fValid, UCHAR bMPType)
*
* Dump the additional information that was captured for the message.
*   using the currently defined types.
*
* Return value: PSZ - Pointer to next available byte after process DATA
\***************************************************************************/
PSZ DumpParam(prgData, cb, fValidData, bMPType)
PSZ         prgData;
SHORT       cb;
BOOL        fValidData;
UCHAR       bMPType;
{
    char    szNextMessage[100];
    SHORT   cch;


    if (fValidData) {
        /* Process by type */
        switch (bMPType & 0x07) {
        case MPT_SWP:
            cch = sprintf(szNextMessage,
                "    SWP:               fs:%p cx:%d cy:%d y:%d x:%d HB:%p H:%p",
                ((PSWP)prgData)->fl, ((PSWP)prgData)->cy, ((PSWP)prgData)->cx,
                ((PSWP)prgData)->y, ((PSWP)prgData)->x,
                ((PSWP)prgData)->hwndInsertBehind,
                ((PSWP)prgData)->hwnd);

            break;

        case MPT_RECTL:
            cch = sprintf(szNextMessage,
                "    RECTL:             xLeft:%d yBottom:%d xRight:%d yTop:%d",
                ((PRECTL)prgData)->xLeft, ((PRECTL)prgData)->yBottom,
                ((PRECTL)prgData)->xRight, ((PRECTL)prgData)->yTop);
            break;

        case MPT_QMSG:
            cch = sprintf(szNextMessage,
                "    QMSG: H:%p       M:%04x M1:%08lx M2:%08lx T:%08lx (%d, %d)",
                ((PQMSG)prgData)->hwnd, ((PQMSG)prgData)->msg,
                ((PQMSG)prgData)->mp1,((PQMSG)prgData)->mp2,
                ((PQMSG)prgData)->time,
                ((PQMSG)prgData)->ptl.x, ((PQMSG)prgData)->ptl.y);
            break;

        default:
            goto NoData;
        }

        OutputString(szNextMessage, cch);
    }
NoData:
    return (prgData + cb);
}




/**************************** Public Function ******************************\
* void OutputString(char szOut, SHORT cch);
*
* Effects: This function will output the specified string to the
*   destinations.
*
* Return value: none
\***************************************************************************/

void OutputString(szOut, cch)
char        szOut[];
SHORT       cch;
{
    SHORT   item;
    char    *psz;
    ULONG  cchWritten;

    /* This is a private entry point in the PMWIN dll that places	*/
    /* strings into the window.						*/
    SHORT _far16 _pascal _loadds DebugOutput( char _far16 * );

    /* Now display the new Line on the screen */
    if (spyopt.fWindow) {
        item = (SHORT)WinSendMsg(hwndSpyList, LM_INSERTITEM,
            (MPARAM)LIT_END, (MPARAM)(PSZ)szOut);

        WinSendMsg(hwndSpyList, LM_SETTOPINDEX, (MPARAM)item, 0L);

        /* See if we have to many lines now */
        while (item >= spyopt.cWindowLines)
            item = (SHORT)WinSendMsg(hwndSpyList, LM_DELETEITEM,
                    (MPARAM)0, 0L);
    }

    /* now for file or debug terminal need cr/lf */
    psz = szOut + cch;    /* point to trailing null */
    *psz++ = '\r';
    *psz++ = '\n';
    *psz = '\0';

    if (spyopt.fDebugOutput)
        DebugOutput((char _far16*)szOut);

    if (spyopt.fFile)
        DosWrite(spyopt.hfileSpy, (PSZ)szOut, cch+2,
                &cchWritten);

}


/**************************** Public Function ******************************\
* MSGI  * PmsgiFromMsg(USHORT msg)
*
* Effects: Locate the msg in the array of message items
*
* Return value: pointer to item that has the specified msg, or NULL
\***************************************************************************/
MSGI *PmsgiFromMsg(msg)
USHORT msg;
{
    register MSGI   *pmsgi = rgmsgi;    /* Start at beginning */
    register USHORT i;

    /*
     * Currently is a simple linear search, should be made faster
     * Probabably a binary search.
     */
    for (i=0; i< cmsgi; i++) {
        if (pmsgi->msg == msg)
            return (pmsgi);
        if (pmsgi->msg > msg)
            return (NULL);
        pmsgi++;
    };

    return (NULL);
}

unix.superglobalmegacorp.com

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