• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1515
  • Last Modified:

Windows global Hooks

Hi all,

Need help with Windows Hooks...

I'm trying to insert a global Mouse Hook into the system chain. But it's not working working according to plan. It almost looks like it's active only on my current application.

I have the main application that inserts the hook by calling SetWindowsHookEx. The hook procedure itself resides in a DLL. Right now I have the hook procedure simply intercept the WM_MOUSEMOVE message globaly accross all applications. When a message is intercepted, I display the window handle (hwnd) and x/y positions of the mouse associated with the message on my main application (exe) by simply calling the DrawText function within my WM_PAINT. The problem is that the message is only being displayed when the hook intercepts WM_MOUSEMOVE messages for my application ONLY instead of all of the windows on the system.

Here's what I have:
In my main application (.exe) I have:

//global declarations
typedef void (*MYPROC) (LPTSTR msg);
MYPROC  ProcAdd;
HOOKPROC ProcHook;
HINSTANCE hdll;
char szStartMsg[1024];



//in my WM_CREATE message
//ProcAdd - getMyMsg is called to get a string from the DLL
//ProcHook - myMouseHook is the MouseProc hook function
hdll=LoadLibrary((LPCTSTR)szAppDll);//load the library
if (hdll!=NULL){
    (ProcAdd) = ((MYPROC)  GetProcAddress(hdll,(LPCSTR)"getMyMsg"));
    (ProcHook)= ((HOOKPROC)GetProcAddress(hdll,(LPCSTR)"myMouseHook"));

//install the hook GLOBALLY
hhook = SetWindowsHookEx(WH_MOUSE,ProcHook,hdll,0);
}



//in my WM_PAINT message
//call getMyMsg to get a string from the dll and place it in msg
(ProcAdd)(msg);
hdc = BeginPaint (hwnd, &ps) ;
GetClientRect (hwnd, &rect) ;
sprintf(szStartMsg,"%s",msg);
DrawText (hdc, szStartMsg, -1, &rect,DT_SINGLELINE) ;
EndPaint (hwnd, &ps) ;




Then, in my DLL the ProcAdd (getMymsg) function is defined as:
extern "C" void getMyMsg(LPTSTR msg){    
     sprintf(msg,szHook);
}//end getMyInt


And, my MouseProc hook function (myMouseHook) is defined as:
extern "C" LRESULT CALLBACK myMouseHook(int nCode, WPARAM wParam, LPARAM lParam){
   MOUSEHOOKSTRUCT *PMOUSEHOOKSTRUCT;


   if (nCode < 0){ // do not process the message
      return CallNextHookEx(hhook, nCode, wParam, lParam);

   }else if (nCode==HC_ACTION){
      PMOUSEHOOKSTRUCT=(MOUSEHOOKSTRUCT *)lParam;

      //capture the WM_MOUSEMOVE          
      if (wParam==WM_MOUSEMOVE){
         memset(szHook,0,1024);

         //place the hwnd, x and y data in the szHook variable
         sprintf(szHook,"hwnd=[%u], x=[%i],y=[%i]",
             PMOUSEHOOKSTRUCT->hwnd,
             PMOUSEHOOKSTRUCT->pt.x,
             PMOUSEHOOKSTRUCT->pt.y);
      }//end if wParam
   }//end if (nCode)
     
   return CallNextHookEx(hhook, nCode, wParam, lParam);
}//end myMouseHook


szHook is being written to in the hook function.
Then szHook is returned to the calling app through a call to getMyMsg.
Therefore, each time the application receives a WM_PAINT message, it should
display the current mouse position and window handle of the window in which
the mouse resides over...

In the main app, I have a 1 second timer enabled to force a WM_PAINT and
therefore repaint the window...


Like I said above, the application does display the mouse position and
window handle every second as long as I move the mouse over my main application. As
soon as I move the mouse over another application, my app doesn't display the message
even though it's being repainted.

If you need additional info, e-mail me at santos@traxxinc.net or just post a message here.

Any help would be appreciated...

Thanks
Vorlon
0
vorlon
Asked:
vorlon
1 Solution
 
robpittCommented:
There are numerous samples of using SetWindowsHookEx with a dll. I suggest searching msdn.microsoft.com for "SetWindowsHookEx DLL" and reading some of the documents found.

Here is a sample of my own which deals with WH_CBT though you could adapt it to any hook type:
http://website.lineone.net/~codebox/focuslog.zip


The key point is that the hHook value returned by SetWindowsHook() needs to be propagated to all other instances of the hook DLL as loaded by other processes. The easiest way to do this is via a shared data segment. Any other data that needs to be accesible to all instances of the DLL must also be shared between DLL instances.

Rob
0
 
MadshiCommented:
Rob is absolutely right (of course). Just a little additional explanation:

When doing global hooks, your dll is not only loaded into your own process, but a copy of your dll is loaded into each and every GUI processes system wide (that is the reason why the callback function has to be in a dll). But the global variables of the dll are only correctly initialized in the copy of the dll, which is loaded into your own application. Furthermore you're only calling the "getMyMsg" function of the copy of the dll, that is loaded in your own application. All the other dlls have their own "szHook" buffers.

The solution is to put at least the szHook and the hHook variable into a shared segment, so that they are shared between all loaded copies of your dll. Please don't ask me about how the syntax for shared segments is in C++ (I'm a Delphi programmer), but I guess, you'll find enough examples with it on the net...

Regards, Madshi.
0
 
vorlonAuthor Commented:
Thanks guys...

It totally escaped me what Madshi said:
"When doing global hooks, your dll is not only loaded into your own process, but a copy of your dll is
loaded into each and every GUI processes system wide (that is the reason why the callback function has
to be in a dll). "

Once I shared the memory (easy), it all worked...


Since Rob was the first one to suggest a shared memory correction, you get the points...


Thanks both of you...
Vorlon
0

Featured Post

[Webinar] Cloud and Mobile-First Strategy

Maybe you’ve fully adopted the cloud since the beginning. Or maybe you started with on-prem resources but are pursuing a “cloud and mobile first” strategy. Getting to that end state has its challenges. Discover how to build out a 100% cloud and mobile IT strategy in this webinar.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now