0

我想检索鼠标位置阻止正常系统鼠标而不诉诸原始输入。理论上这是可能的,但似乎当我用低级鼠标钩子阻塞(返回 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;
}
4

0 回答 0