Solved

Windows global Hooks

Posted on 2001-08-10
3
1,491 Views
Last Modified: 2013-12-03
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
Comment
Question by:vorlon
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
3 Comments
 
LVL 5

Accepted Solution

by:
robpitt earned 100 total points
ID: 6373295
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
 
LVL 20

Expert Comment

by:Madshi
ID: 6373560
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
 
LVL 2

Author Comment

by:vorlon
ID: 6374174
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

PeopleSoft Has Never Been Easier

PeopleSoft Adoption Made Smooth & Simple!

On-The-Job Training Is made Intuitive & Easy With WalkMe's On-Screen Guidance Tool.  Claim Your Free WalkMe Account Now

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

This article shows how to make a Windows 7 gadget that accepts files dropped from the Windows Explorer.  It also illustrates how to give your gadget a non-rectangular shape and how to add some nifty visual effects to text displayed in a your gadget.…
What my article will show is if you ever had to do processing to a listbox without being able to just select all the items in it. My software Visual Studio 2008 crystal report v11 My issue was I wanted to add crystal report to a form and show…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
I've attached the XLSM Excel spreadsheet I used in the video and also text files containing the macros used below. https://filedb.experts-exchange.com/incoming/2017/03_w12/1151775/Permutations.txt https://filedb.experts-exchange.com/incoming/201…

733 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question