1

我现在正在玩窗户挂钩。我设置了一个全局低级鼠标钩子,我想反转鼠标移动。为此我有几个方法(我希望这是正确的,我的英语不是很好,抱歉)。第一个是修改lParam参数,用CallNextHookEx函数转发:

LRESULT CALLBACK MouseInvertProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    MSLLHOOKSTRUCT* ms = NULL;
    int dx = 0; //delta x
    int dy = 0; //delta y
    if(nCode == HC_ACTION)
    {
        if(wParam == WM_MOUSEMOVE)
        {
            ms = (MSLLHOOKSTRUCT*)lParam;
            dx = ms->pt.x - g_oldMousePos.x;
            dy = ms->pt.y - g_oldMousePos.y;
            ms->pt.x = ms->pt.x - 2 * dx;
            ms->pt.y = ms->pt.y - 2 * dy;
            GetCursorPos(&g_oldMousePos);

            return CallNextHookEx(g_MouseInvertHook,nCode,wParam, (LPARAM)ms);          
        }
        else
            return CallNextHookEx(g_MouseInvertHook, nCode, wParam, lParam);
    }
    return CallNextHookEx(g_MouseInvertHook, nCode, wParam, lParam);            
}

但这根本没有效果。有人知道为什么吗?
第二次尝试是提供修改后的鼠标坐标的输入:

LRESULT CALLBACK MouseInvertProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    MSLLHOOKSTRUCT* ms = NULL;
    int dx = 0; //delta x
    int dy = 0; //delta y
    if(nCode == HC_ACTION)
    {
        if(wParam == WM_MOUSEMOVE)
        {
            ms = (MSLLHOOKSTRUCT*)lParam;
            dx = ms->pt.x - g_oldMousePos.x;
            dy = ms->pt.y - g_oldMousePos.y;
            ms->pt.x = ms->pt.x - 2 * dx;
            ms->pt.y = ms->pt.y - 2 * dy;
            GetCursorPos(&g_oldMousePos);

            if(!g_artificialma) //g_artificialma is true when i created a artificial mouse input.
            {
                g_artificialma = true;
                mouse_event(MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE, ms->pt.x, ms->pt.y, NULL, NULL);
                return 1;                           
            }
            else
            {               
                g_artificialma = false;
                return CallNextHookEx(g_MouseInvertHook, nCode, wParam, lParam);
            }           
        }
        else
            return CallNextHookEx(g_MouseInvertHook, nCode, wParam, lParam);
    }
    return CallNextHookEx(g_MouseInvertHook, nCode, wParam, lParam);
}           

使用 g_artificialma 变量我想防止无限循环,因为当我调用 mouse_event 时会调用 hookproc。
但是这样我的鼠标就卡在了屏幕的左上角。

最后一次尝试是简单地调用 SetCursorPos 函数:

LRESULT CALLBACK MouseInvertProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    MSLLHOOKSTRUCT* ms = NULL;
    int dx = 0; //delta x
    int dy = 0; //delta y
    if(nCode == HC_ACTION)
    {
        if(wParam == WM_MOUSEMOVE)
        {
            ms = (MSLLHOOKSTRUCT*)lParam;
            dx = ms->pt.x - g_oldMousePos.x;
            dy = ms->pt.y - g_oldMousePos.y;
            ms->pt.x = ms->pt.x - 2 * dx;
            ms->pt.y = ms->pt.y - 2 * dy;
            GetCursorPos(&g_oldMousePos);

            SetCursorPos(ms->pt.x, ms->pt.y);                       
        }
        else
            return CallNextHookEx(g_MouseInvertHook, nCode, wParam, lParam);
    }
    return CallNextHookEx(g_MouseInvertHook, nCode, wParam, lParam);            
}

这工作得很好,但是在 3d 应用程序中,例如这会导致奇怪的鼠标移动
,我认为这种方式真的很难看,因为我阻止了其他应用程序安装的其他钩子。

那么你有什么建议可以以一种良好的工作和干净的方式解决这个问题(也许没有窗户挂钩)?

4

1 回答 1

0

您的“最后一次尝试”代码在我的测试中完全没有效果:

#define _WIN32_WINNT 0x0501

#include <iostream>
#include <windows.h>
using namespace std;

HHOOK g_MouseInvertHook;
POINT g_oldMousePos;
LRESULT CALLBACK MouseInvertProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    MSLLHOOKSTRUCT* ms = NULL;
    int dx = 0; //delta x
    int dy = 0; //delta y
    if(nCode == HC_ACTION)
    {
        if(wParam == WM_MOUSEMOVE)
        {
            ms = (MSLLHOOKSTRUCT*)lParam;
            dx = ms->pt.x - g_oldMousePos.x;
            dy = ms->pt.y - g_oldMousePos.y;
            ms->pt.x = ms->pt.x - 2 * dx;
            ms->pt.y = ms->pt.y - 2 * dy;
            GetCursorPos(&g_oldMousePos);

            SetCursorPos(ms->pt.x, ms->pt.y);                       
        }
        else
            return CallNextHookEx(g_MouseInvertHook, nCode, wParam, lParam);
    }
    return CallNextHookEx(g_MouseInvertHook, nCode, wParam, lParam);            
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
  GetCursorPos(&g_oldMousePos);
  g_MouseInvertHook = SetWindowsHookEx(WH_MOUSE_LL, MouseInvertProc, hInstance, 0);
  MSG msg;
  while(GetMessage(&msg, NULL, 0, 0))
  {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }
  return msg.wParam;
}

您能否举一个仅使用您的该功能的应用程序(如我的)的小示例并给出您所描述的结果?

于 2014-08-24T18:54:38.160 回答