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