我想检索鼠标位置并阻止正常系统鼠标而不诉诸原始输入。理论上这是可能的,但似乎当我用低级鼠标钩子阻塞(返回 1)时,鼠标的坐标也不再有效。每次移动到新位置都会导致额外的鼠标位置(由系统生成)回到原始位置。返回 0 或调用 SetCursorPos() 使其工作,但这正是我不想要的。任何有关获得正确鼠标位置同时阻止鼠标的提示/提示都值得赞赏!
DLL 代码(ml.dll):
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <windows.h>
#include <windowsx.h>
#ifndef LLMHF_INJECTED
#define LLMHF_INJECTED 1
#endif
static void * self ;
static void * hook ;
__declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
{
if(DLL_PROCESS_ATTACH == reason)
{
self = instance ;
DisableThreadLibraryCalls(instance);
}
return TRUE;
}
static LRESULT CALLBACK hook_mouse(int code, WPARAM wParam, LPARAM lParam)
{
MSLLHOOKSTRUCT * msl = (MSLLHOOKSTRUCT *)lParam;
if(code < 0)
{
return CallNextHookEx(NULL, code, wParam, lParam);
}
switch(wParam)
{
case WM_MOUSEMOVE :
case WM_LBUTTONDOWN :
case WM_RBUTTONDOWN :
case WM_MBUTTONDOWN :
case WM_LBUTTONUP :
case WM_RBUTTONUP :
case WM_MBUTTONUP :
default : break;
}
printf("%3d,%3d (marker : 0x%08x) : W:%u L:%u\n", msl -> pt.x, msl -> pt.y, msl -> dwExtraInfo, wParam, lParam);
CallNextHookEx(NULL, code, wParam, lParam);
return 1;
}
__declspec(dllexport) void mouse_hook_low_start(int marker)
{
if(NULL == (hook = SetWindowsHookEx(WH_MOUSE_LL, hook_mouse, self, 0)))
{
assert(0);
}
}
__declspec(dllexport) void mouse_hook_low_stop(void)
{
if(FALSE == UnhookWindowsHookEx(hook))
{
assert(0);
}
}
test.exe 代码
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <windows.h>
static DWORD pid;
enum {
TRIGGER = WM_APP + 1024,
} ;
static DWORD WINAPI hook(LPVOID param)
{
int done = 0;
void * dll = LoadLibrary("ml.dll");
assert(dll);
void (*start)(void) = (void (*)(void))GetProcAddress(dll, "mouse_hook_low_start");
void (*stop)(void) = (void (*)(void))GetProcAddress(dll, "mouse_hook_low_stop");
assert(start);
assert(stop);
start();
while(0 == done)
{
MSG msg;
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if(TRIGGER == msg.message)
{
done = 1;
break ;
}
DispatchMessage(&msg);
}
Sleep(5);
}
stop();
}
void start_hook(void)
{
void * thread;
if(NULL == (thread = CreateThread(NULL, 0, hook, NULL, 0, &pid)))
{
assert(0);
}
}
void stop_hook(void)
{
if(0 == PostThreadMessage(pid, TRIGGER, 0, 0))
{
assert(0);
}
}
int main(void)
{
setbuf(stdout, NULL);
setbuf(stderr, NULL);
SetCursorPos(100,100);
start_hook();
getchar();
stop_hook();
return 0;
}