0

I am trying to get global mouse position. I have a hook working that can get the mouse position, however it only has access to it inside the hook code. Trying to access the data inside main doesn't work.

The best way to explain this is with code:

LRESULT CALLBACK mouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
     PMSLLHOOKSTRUCT p = (PMSLLHOOKSTRUCT) lParam;
     position.x = p->pt.x;
     position.y = p->pt.y;
     std::cout<<position.x<<std::endl;
     return CallNextHookEx(NULL, nCode, wParam, lParam);
}

int WINAPI WinMain (HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpszArgument,int nCmdShow)
{
     HHOOK mouseHook = SetWindowsHookEx(WH_MOUSE_LL,mouseHookProc,hInstance,NULL);

     MessageBox(NULL, "Press OK to close.", "", MB_OK);
     return 0;
}

With the above code, moving the mouse will show the new position in the console window. However, if I put the std::cout<<position.x<<std::endl; inside of main, it will just say 0. position is a global variable.

Code when the output is inside of main:

LRESULT CALLBACK mouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
     PMSLLHOOKSTRUCT p = (PMSLLHOOKSTRUCT) lParam;
     position.x = p->pt.x;
     position.y = p->pt.y;

     return CallNextHookEx(NULL, nCode, wParam, lParam);
}

int WINAPI WinMain (HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpszArgument,int nCmdShow)
{
     HHOOK mouseHook = SetWindowsHookEx(WH_MOUSE_LL,mouseHookProc,hInstance,NULL);
     for(;;)
     {
         std::cout<<position.x<<std::endl;
     }
     MessageBox(NULL, "Press OK to close.", "", MB_OK);
     return 0;
}

The first chunk of code works fine, it detects the mouse position, I just don't know how to get the x,y data into my main.

BSMP
  • 4,596
  • 8
  • 33
  • 44
motsu35
  • 21
  • 2
  • 5

2 Answers2

2

re this posted code:

LRESULT CALLBACK mouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
     PMSLLHOOKSTRUCT p = (PMSLLHOOKSTRUCT) lParam;
     position.x = p->pt.x;
     position.y = p->pt.y;

     return CallNextHookEx(NULL, nCode, wParam, lParam);
}

int WINAPI WinMain (HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpszArgument,int nCmdShow)
{
     HHOOK mouseHook = SetWindowsHookEx(WH_MOUSE_LL,mouseHookProc,hInstance,NULL);
     std::cout<<position.x<<std::endl;
     MessageBox(NULL, "Press OK to close.", "", MB_OK);
     return 0;
}

Here's what the main function specifies should happen:

  • First, a call to SetWindowsHookEx (this happens once).
  • Then, outputting position (this happens once).
  • Then, displaying a MessageBox (this happens once).

That's all.

During the call to MessageBox the hook procedure is called (whenever you move your mouse), but it doesn't do anything visible, just an internal update.

Why did you expect more?


How to fix:

  • Instead of relying on the internal message loop in MessageBox, which doesn't do any output, code up your own.
  • Not to do with functionality, but just because the current code is like very dirty clothing that does serve its purpose but feels ungood to wear: replace Microsoft's WinMain monstrosity with a standard C and C++ main.
Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • i accidentally pasted the second part of the code wrong, there is an infinite loop trying to output position. i thought since the hook is running, it would constantly update position. however its not. – motsu35 Apr 12 '13 at 10:32
  • more confusion... if i change the cout / msgbox to multiple of them (msgbox, cout, msgbox,cout....msgbox,cout) then pressing ok will show the position, the next ok will show the position, and so on. however when printing inside an infinite loop my mouse is just very laggy and all i get is 0's – motsu35 Apr 12 '13 at 10:37
  • a *message loop* calls `GetMessage` repeatedly. for each message you will usually call `TranslateMessage` and `DispatchMessage`. – Cheers and hth. - Alf Apr 12 '13 at 11:21
  • "replace Microsoft's WinMain monstrosity with a standard C and C++ main." how is that productive? in visual studio this is just asking for pain unless you want to fiddle with linker settings and project settings too. whats wrong with fitting in with your target platform and following the recommendation from the platform holder? i'd call that best practice even... – jheriko Oct 30 '14 at 15:34
  • @jheriko: i understand your emotional reaction and i sympathize. rest assured, though, that as you gain more experience with the tools you will also gain more confidence in your own judgment, and less confidence in microsoft's. what now seems impossibly non-conforming to you, like ooh, we can't fiddle with the settings!, oh no!, will then only seem reasonable; those ways and settings that now seem perfect, coming from microsoft as they do, will then even just at slight glance show severe shortcomings and problems. you're not there yet. hang on, and you'll get there. – Cheers and hth. - Alf Oct 30 '14 at 15:58
1

For global hook the hook procedure mouseHookProc should be in a DLL so that it can be injected into processes. Check this: http://www.codeproject.com/Articles/1037/Hooks-and-DLLs

Abhijit-K
  • 3,569
  • 1
  • 23
  • 31
  • how would i get the mouse position from the dll? i have not worked with coding dlls before. – motsu35 Apr 12 '13 at 10:23
  • From a dll you would use `PostMessage` to post the details to the main application using handle to the main application window. Use a custom message and the application should register for that. The mouse details can be passed as `wparam` and `lparam` of `PostMessage`. Also there are several ways to get handle to window using API's. Another way would be to pass the handle when the dll is loaded. – Abhijit-K Apr 12 '13 at 11:39