From: rofische@iiic.ethz.ch (Roman Fischer)
Subject: Solved: Sample code for a input hook
Originator: rofische@c13
Organization: Dept. Informatik, Swiss Federal Institute of Technology (ETH)
Date: Fri, 31 Jul 1992 09:41:17 GMT

XFEEL   a sample program for a input hook
=========================================

I finished this version of XFEEL yesterday. It is in no way perfect
or correct, but it shows how to install a input hook. So it may be
a help for those who are currently writting hook-procedures.

The only documentation available to me was the OS/2 Programer's
Reference from Microsoft (for OS/2 1.1 !). Hooks are discussed in
chapter 28 in Vol. 1. If you read chapter 28 carefully, you can find
the following inconsitency:
Input hooks are defined (28.3.1) with three parameters, but in the
example (28.5.2) only two parameters are specified. This wouldn't be
to bad if C-calling conventions were used, but since all exported
procedures use PASCAL-callings, specifying the wrong number of para-
meters will crash the program !
And also, the documentation says nothing about the fact that the
program, that installes the hook, MUST have a message loop !

Well, after solving the above problems i noticed that the hook
procedure can't access global variables (neither in the installing
program nor in the dll). That's why i used a named piece of sharemem
to store some data.

The idea for XFEEL was of course to aktivate a window by just moving
the mouse over it (a la X-Windows). Right now there is one known
problem: you can't drag anything around while XFEEL is active !

Since this code is just the start, all kinds of ideas, bugs, hints
and comments are welcome. Just let me know...

bye                   Roman


Some remarks on the code:

I'm develloping my OS/2 Programms with TopSpeed C 3.01 from JPI, so you'll
have to write your own make-files (i love jpi-project-managment.. :-)  ).


/*-------------------------------------------------------------------------*/
/*                                                                         */
/*   XFEEL.C    : Compile this Module to XFEEL.EXE                         */
/*                                                                         */
/*   Version    : V1.00                                                    */
/*                                                                         */
/*   Date       : 31.07.92                                                 */
/*                                                                         */
/*   Copyright  : rf for Animal                                            */
/*                                                                         */
/*-------------------------------------------------------------------------*/

#define INCL_DOSPROCESS
#define INCL_WINHOOKS
#define INCL_WINBUTTONS
#define INCL_WINFRAMEMGR
#define INCL_DOSSEMAPHORES
#define INCL_DOSMEMMGR
#define INCL_DOSMODULEMGR
#include <os2pm.h>

/*--------------------------------------------------------------------------*/
MRESULT EXPENTRY myproc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
    {
    return (WinDefWindowProc (hwnd, msg, mp1, mp2));
    }

/*--------------------------------------------------------------------------*/
unsigned long GetAddr(HMODULE *handle, char *filename, char *command)
    {
    char            errorname[6];
    unsigned long   adr;

    if (DosLoadModule (errorname, 5, filename, handle))
        return (0L);

    if (DosGetProcAddr (*handle, command, &adr))
        return (0L);

    return (adr);
    }

/*--------------------------------------------------------------------------*/
void main ()
    {
    HAB         hab;
    HMQ         hmq;
    QMSG        qmsg;
    HMODULE     mhand;
    ULONG       adr;
    SEL         sel;
    HWND        hwnd, hwndclient;
    ULONG       ff = FCF_TASKLIST;

    hab = WinInitialize (0);
    hmq = WinCreateMsgQueue (hab, 0);

    WinRegisterClass (hab, "XFEELCLASS", myproc, 0L, 0);
    hwnd = WinCreateStdWindow (HWND_DESKTOP, 0, &ff, "XFEELCLASS",
                    NULL, 0L, NULL, 0, &hwndclient);


    if (DosAllocShrSeg (sizeof (HWND), "\\SHAREMEM\\XFEEL.DAT", &sel))
        {
        WinMessageBox (HWND_DESKTOP, HWND_DESKTOP,
                 "Could not allocate Memory. Program aborted !",
                 NULL, 0, MB_OK|MB_ICONEXCLAMATION);
        return;
        }

    adr = GetAddr (&mhand, "XFEEL", "XFUNC");
    if (!WinSetHook (hab, (HMQ)NULL, HK_INPUT, (PFN)adr, mhand))
        {
        WinMessageBox (HWND_DESKTOP, HWND_DESKTOP,
                 "Could not Install Hook. Program aborted !",
                 NULL, 0, MB_OK|MB_ICONEXCLAMATION);
        return;
        }

    while (WinGetMsg (hab, &qmsg, NULL, 0, 0))
        WinDispatchMsg (hab, &qmsg);


    WinReleaseHook (hab, (HMQ)NULL, HK_INPUT, (PFN)adr, mhand);
    DosFreeModule (mhand);

    WinDestroyWindow (hwnd);
    WinDestroyMsgQueue (hmq);
    WinTerminate (hab);
    }

/*-------------------------------------------------------------------------*/
/*                                                                         */
/*   XFEEL2.C   : Compile this Module to XFEEL.DLL and place it in the     */
/*                LIBPATH.                                                 */
/*                                                                         */
/*   Version    : V1.00                                                    */
/*                                                                         */
/*   Date       : 31.07.92                                                 */
/*                                                                         */
/*   Copyright  : rf for Animal                                            */
/*                                                                         */
/*-------------------------------------------------------------------------*/

#define INCL_DOSPROCESS
#define INCL_WININPUT
#define INCL_WINFRAMEMGR
#define INCL_DOSMEMMGR

#include <os2pm.h>
#include <stdio.h>

BOOL PASCAL XFUNC (HAB hab, PQMSG qmsg, USHORT msgf)
    {
    SEL         sel;
    HWND        *hwndoldp;

    if (qmsg->msg != WM_MOUSEMOVE)      /* Intercept only Mouse-Moves */
        return (FALSE);

    if (DosGetShrSeg ("\\SHAREMEM\\XFEEL.DAT", &sel))
       return (FALSE);

    hwndoldp = (HWND *)MK_FP (sel, 0);
    if (qmsg->hwnd != *hwndoldp)
       {
       WinSetFocus (HWND_DESKTOP, qmsg->hwnd);
       *hwndoldp = qmsg->hwnd;
       }
    DosFreeSeg (sel);

    return (FALSE);
    }


have fun...                        Roman
-- 
----------------------------------------------
INTERNET: rofische@iiic.ethz.ch
----------------------------------------------
Newsgroups: comp.os.os2.programmer