Link to home
Start Free TrialLog in
Avatar of janus042597
janus042597

asked on

Unable to install a Task-specific Hook in Windows 95 (WH_GETMESSAGE)

HI

I have a peculiar problem with WINDOWS 95.  I am trying to subclass the window procedure of an application launched by my process.  Let us assume for example that I am trying to subclass NotePad's WndProc after it is launched by my application using CreateProcess or whatever.

Ideally according to Jeffrey Richter, if a WH_GETMESSAGE hook is installed using SetWindowsHookEx on the application whose message queue you want to monitor, any message dispatched to notepads window will be routed through
my own subclass procedure.  This is exactly what I did.  But it seems if I install a task-specific filter as oppposed to a system-wide filter, the control NEVER comes inside the Hook filter function.  Consequently the subclassing I try to do inside the filter function never gets executed.
Now if I install a system-wide filter (by giving NULL in the last parameter of SetWindowsHookEx) the control comes into the Hook filter function alright, but SetWindowLong (which I use to subclass notepad) perpetually returns ZERO.  According to the documentation given for SetWindowLong in
VC++ 5.0, you must never try to subclass a window not CREATED by your process.  But Richter says if a hook is installed, the DLL that containing your subclass procedure gets mapped into the address space of NotePad, so that my subclass procedure will be called within the context of Notepad.  But try as I might, this is not happening.  Even if I try to subclass immediately after SetWindowsHookEx (instead of inside the hook function), SetWindowLong returns ZERO.

Richter says only this method will work in Windows 95.  The other methods like manipulating Registry or using CreateRemoteThread are specific to Windows NT.  

PLEASE COULD ANYBODY HELP ME OUT ON THIS !!!!!!

Dilip
SRA Systems Ltd
INDIA
Avatar of faster
faster

Can you show us your code?
ASKER CERTIFIED SOLUTION
Avatar of vinniew
vinniew

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of janus042597

ASKER

Hello Mr. Faster

Here is the piece of code u asked for......
I wrote this code in a Regular DLL using Shared MFC.

MODULE NAME: RegDll.dll
------------------------

Exported Functions:  MyOwnSubclass, GetMsgProc, SetTheHook
All the variables with starting letter 'g' are global variables.

LRESULT WINAPI GetMsgProc(int nCode, WPARAM wParam, LPARAM                                    lParam)
{
      static BOOL bSubclassed = FALSE;
      MSG* pMsg = (MSG *) lParam;

      if (!bSubclassed && (nCode == HC_ACTION) && (pMsg->hwnd =                                       gNpad)
                  && (pMsg->message == WM_NULL))
      {
            gOrigWndProc = SubclassWindow(gNpad,                                                   MyOwnSubclass);
            //  gOrigWndProc is perennially ZERO
            bSubclassed = TRUE;
      }

      return (CallNextHook(gHook, nCode, wParam, lParam));
}

LRESULT WINAPI MyOwnSubclass(HWND hWnd, UINT uMsg, WPARAM wParam,
                              LPARAM lParam)
{
      // Control never comes here as Notepad seldom gets         //    subclassed.
      switch (uMsg)
      {
      case WM_DESTROY:
            AfxMessageBox("Got destroy message from Notepad!!!");
            break;
      default:
            break;
      }
      return (CallWindowProc(gOrigWndProc, hWnd, uMsg, wParam,                                              lParam));
}

// I call this function from an EXE (in InitInstance) to set the // hook ...
BOOL SetTheHook()
{
      WinExec("c:\\windows\\notepad.exe", SW_SHOWNORMAL);
      gNpad = FindWindow("NotePad", NULL);
      if (gNpad == NULL)
            return FALSE;

      gHook = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc,
                         GetModuleHandle("regdll.dll"),
                         GetWindowThreadProcessId(gNpad,                                                           NULL));
      //  This hook gets installed properly ........

      PostMessage(gNpad, WM_NULL, 0, 0);
      //  I am forcing control into the HOOK Filter Function         //   ......
      //  But this msg never reaches NotePads window .......

      return TRUE;
}

That's all there is to it..  But this apparently does not work.  If I change the last parameter of SetWindowsHookEx to NULL, the control comes into GetMsgProc; but nevertheless the macro SubclassWindow always returns ZERO.  Incidentally SetWindowLong has been implemented through a macro defined in "windowsx.h" ............

Dilip
SRA Systems Ltd
India
What's so special that you have to take over control of Notepad, by the way?  Do you need it to print?  My point is, why not create a file and open it using 'start notepad myfile'?

Have you tried using createProcess instead of WinExec?  You get just a little more control that way.