>> ... but I need to call GetMouseInput from different Processes ...
Originally Posted by
MSDN
However, the WH_MOUSE_LL hook is not injected into another process. Instead, the context switches back to the process that installed the hook and it is called in its original context. Then the context switches back to the application that generated the event.
DLL or no DLL - doesn't matter - it'll work the same. Not using a DLL is a lot easier to manage. However, it may be nice to have in case you switch to hook which does need to be in a DLL.
Originally Posted by
MSDN
This hook is called in the context of the thread that installed it. The call is made by sending a message to the thread that installed the hook. Therefore, the thread that installed the hook must have a message loop.
So "lpGetMouseInput()" must implement a message loop, or your hook function will never receive any calls.
>> But which message I need to get?
You just need a "message pump" or "message loop". And it has to be in the thread that called SetWindowsHookEx().
Console App Sample:
Code:
#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <iostream>
#include <cstdio>
using namespace std;
HHOOK g_Hook;
HANDLE g_evExit;
LRESULT CALLBACK LowLevelMouseProc (int code, WPARAM wParam, LPARAM lParam)
{
if (code == HC_ACTION)
{
const char *msg;
char msg_buff[128];
switch (wParam)
{
case WM_LBUTTONDOWN: msg = "WM_LBUTTONDOWN"; break;
case WM_LBUTTONUP: msg = "WM_LBUTTONUP"; break;
case WM_MOUSEMOVE: msg = "WM_MOUSEMOVE"; break;
case WM_MOUSEWHEEL: msg = "WM_MOUSEWHEEL"; break;
case WM_MOUSEHWHEEL: msg = "WM_MOUSEHWHEEL"; break;
case WM_RBUTTONDOWN: msg = "WM_RBUTTONDOWN"; break;
case WM_RBUTTONUP: msg = "WM_RBUTTONUP"; break;
default:
sprintf(msg_buff, "Unknown msg: %u", wParam);
msg = msg_buff;
break;
}//switch
const MSLLHOOKSTRUCT *p =
reinterpret_cast<const MSLLHOOKSTRUCT*>(lParam);
cout << msg << " - [" << p->pt.x << ',' << p->pt.y << ']' << endl;
static bool left_down = false;
static bool right_down = false;
switch (wParam)
{
case WM_LBUTTONDOWN: left_down = true; break;
case WM_LBUTTONUP: left_down = false; break;
case WM_RBUTTONDOWN: right_down = true; break;
case WM_RBUTTONUP: right_down = false; break;
}//switch
if (left_down && right_down)
SetEvent(g_evExit);
}//if
return CallNextHookEx(g_Hook, code, wParam, lParam);
}//LowLevelMouseProc
int main()
{
g_evExit = CreateEvent(0, TRUE, FALSE, 0);
if (!g_evExit)
{
cerr << "CreateEvent failed, le = " << GetLastError() << endl;
return 1;
}//if
g_Hook = SetWindowsHookEx(WH_MOUSE_LL, &LowLevelMouseProc,
GetModuleHandle(0), 0);
if (!g_Hook)
{
cerr << "SetWindowsHookEx() failed, le = " << GetLastError() << endl;
return 1;
}//if
cout << "Press both left and right mouse buttons to exit..." << endl;
MSG msg;
DWORD status;
while (1)
{
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
DispatchMessage(&msg);
status = MsgWaitForMultipleObjects(1, &g_evExit, FALSE,
INFINITE, QS_ALLINPUT);
if (status == (WAIT_OBJECT_0 + 1))
{
// there are messages to process, eat em up
continue;
}//if
else
{
// assume g_evExit is signaled
break;
}//else
}//while
cout << "Exiting..." << endl;
UnhookWindowsHookEx(g_Hook);
CloseHandle(g_evExit);
return 0;
}//main
gg