SetWindowsHookEx-WM_LBUTTONDOWN两次触发WH_MOUSE回调

时间:2019-07-17 17:52:08

标签: excel vsto hook mouse setwindowshookex

在VSTO Excel加载项中,当单击交叉表中的特定坐标时,我需要在工作表的交叉表中呈现内容(并在再次单击相同坐标时再次删除内容)。

因此,我正在使用通过SetWindowsHookEx注册的MouseProc回调函数:

    _hMouseHook = WinApi.SetWindowsHookEx(WinApi.WH_MOUSE, _mouseHookProcedure,
                  WinApi.GetModuleHandle(module.ModuleName), (int)WinApi.GetCurrentThreadId());

不幸的是,似乎Excel的行为异常,并分别触发了两次WM_LBUTTONDOWN和WM_LBUTTONUP消息(可能还触发了其他消息)。

MouseProc回调的外观如下:

    private int MouseHookProcedure(int nCode, Int32 wParam, IntPtr lParam)
    {
      if (nCode == WinApi.HC_ACTION)
      {
        var mouseHookStruct = (MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseHookStruct));
        WinApi.WindowMessage message = (WinApi.WindowMessage)wParam;

        if (message == WinApi.WindowMessage.WM_LBUTTONDOWN)
        {
          Debug.WriteLine($"WH_MOUSE_Hook: WM_LBUTTONDOWN - nCode:{nCode} WParam:{wParam} LParam:{lParam} X:{mouseHookStruct.pt.X}  Y:{mouseHookStruct.pt.Y} " +
                          $"Handle:{(IntPtr)mouseHookStruct.hwnd}  Message:{message} HitTestCode:{mouseHookStruct.wHitTestCode} ExtraInfo:{mouseHookStruct.dwExtraInfo}");
        }
        else if (message == WinApi.WindowMessage.WM_LBUTTONUP)
        {
          Debug.WriteLine($"WH_MOUSE_Hook: WM_LBUTTONUP - nCode:{nCode} WParam:{wParam} LParam:{lParam} X:{mouseHookStruct.pt.X}  Y:{mouseHookStruct.pt.Y} " +
                          $"Handle:{(IntPtr)mouseHookStruct.hwnd}  Message:{message} HitTestCode:{mouseHookStruct.wHitTestCode} ExtraInfo:{mouseHookStruct.dwExtraInfo}");
        }
      }

      try
      {
        // event not handled, call next Hook to process / delegate event
        return WinApi.CallNextHookEx(_hMouseHook, nCode, wParam, lParam);
      }
      catch
      {
        return 0;
      }
    }

我还知道某些Excel安装上的行为可能有所不同,因此WM_LBUTTONDOWN消息有时仅发送一次。不幸的是,我不知道Excel行为变化的原因。

在使用Subclassing而不是钩子时,它可以很好地工作,但是不幸的是,这是没有选择的,因为Subclassing引起了与也使用它的其他加载项的兼容性问题。

我创建了一个小型VSTO测试插件,通过将事件记录到控制台来演示该问题:

  

WH_MOUSE_Hook:WM_LBUTTONDOWN-nCode:0 WParam:513 LParam:55637568 ...   WH_MOUSE_Hook:WM_LBUTTONDOWN-nCode:0 WParam:513 LParam:55637568 ...   子类:WM_LBUTTONDOWN-WParam:1 LParam:17957938消息:513 ...   WH_MOUSE_Hook:WM_LBUTTONUP-nCode:0 WParam:514 LParam:55633504 ...   WH_MOUSE_Hook:WM_LBUTTONUP-nCode:0 WParam:514 LParam:55633504 ...

我的代码有什么问题可以解释这种现象吗?还是有人已经面临这个问题并想出了一个好的/替代解决方案来解决这个问题?

可在此处找到测试加载项源代码:OneDrive Link

0 个答案:

没有答案
相关问题