我的目标
我想将左键单击转换为右键单击
我的方法
- 我通过 SetWindowsHookEx (user32.dll) 注册了一个低级挂钩
- 过滤鼠标左键
- 检查我是否要翻译特定的点击
- 如果我真的想
- 不要传递消息
- 通过 mouse_event 创建一个新的鼠标点击(user32.dll 也是)
问题
当我做这样描述的事情时:
private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) {
if(nCode >= 0 && MouseMessages.WM_LBUTTONDOWN == (MouseMessages)wParam && doRight) {
doRight = false;
MSLLHOOKSTRUCT hookStruct = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
mouse_event(/*right down + right up*/8 | 16, hookStruct.pt.x, hookStruct.pt.y, 0, 0);
return new IntPtr(1);
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
对 mouse_event 的调用失败并出现 PInvokeStackImbalance-Exception,我想,我应该关心一下。
DLLImports
因为通常 PInvokeStackImbalance 是由于不正确的导入签名而出现的,这里是我的:
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelMouseProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern void mouse_event(long dwFlags, long dx, long dy, long cButtons, long dwExtraInfo);
紧急情况
在这种情况下,我隔离问题的常规方法会失败 - 因为 mouse_event-call 本身有效,并且左键单击的垃圾也有效。当结构超过部分的总和时,我讨厌它......