Visual Studio 扩展鼠标按钮事件不工作

Visual Studio Extension Mouse Button events not working

我有一个带有(异步)工具 window 的 Visual Studio 扩展。工具 window 有一个 UserControl,控件有一个 Image,我使用 WriteableBitmap 作为来源。基本上,我正在尝试在工具 window.

上使用图形 API (Vulkan)

基本上,我的扩展看起来类似于 Visual Studio 的 3d 模型编辑器。

我的问题是,当我单击工具 window 时,会调用 none 鼠标事件处理程序,如 MouseLeftButtonDownPreprocessMouseLeftButtonDown。我已经尝试将鼠标事件处理程序添加到 UserControlImage 甚至 HwndHost,但我没有成功。

我知道 IMouseProcessor 或其他变体,但在我看来,它们用于文本编辑器,而不仅仅是工具 window 窗格或用户控件。

HwndHostWndProc方法似乎也没有接收到任何鼠标事件。简单地 "cheesing" 它通过替换父 Hwnd 的 WndProc 似乎工作,但我不想创建一个扩展来控制整个 Visual Studio。

== 编辑 ==

public partial class MyControl : UserControl {
    public MyControl () {
        InitializeComponents ();
        MouseLeftButtonDown += MyLeftButtonDown;
    }
    ...
    private void MyLeftButtonDown (object sender, MouseButtonEventArgs e) {
        // This code never gets executed.
    }
}

这些也没有。

<UserControl ...
             IsHitTestVisible="True"
             MouseLeftButtonDown="MyLeftButtonDown ">
    <Image x:Name="View" ... />
    <!--- nor this --->
    <!--- <Image x:Name="View" MouseLeftButtonDown="MyLeftButtonDown " /> --->
</UserControl>

这也不行。

public partial class MyControl : UserControl {
    public MyControl () {
        InitializeComponents ();
        // View is an object of Image class.
        View.MouseLeftButtonDown += MyLeftButtonDown;
    }
    ...
    private void MyLeftButtonDown (object sender, MouseButtonEventArgs e) {
        // This code never gets executed.
    }
}
// C++/CLI
IntPtr MyHost::WndProc (IntPtr hWndPtr, int uMsg, IntPtr wParamPtr, IntPtr lParamPtr, bool % handled)
{
    auto hWnd = (HWND) hWndPtr.ToPointer ();
    auto wParam = (WPARAM) wParamPtr.ToPointer ();
    auto lParam = (LPARAM) lParamPtr.ToPointer ();

    switch (uMsg)
    {
        case WM_LBUTTONDOWN: // This doesn't get called.
            break;
        ...
        default:
            handled = false;
            return IntPtr (DefWindowProc (hWnd, uMsg, wParam, lParam));
    }
    ...
    handled = true;
    return IntPtr (0);
}

我还没有想出如何用 ImageUserControl 处理鼠标输入,但我想出了 HwndHost

显然,如果您的 HwndHost 没有回复 WM_NCHITTEST,那么您的 HwndHost 将永远不会收到任何鼠标事件,例如 WM_LBUTTONDOWN

// C++/CLI
IntPtr MyHost::WndProc (IntPtr hWndPtr, int uMsg, IntPtr wParamPtr, IntPtr lParamPtr, bool % handled)
{
    auto hWnd = (HWND) hWndPtr.ToPointer ();
    auto wParam = (WPARAM) wParamPtr.ToPointer ();
    auto lParam = (LPARAM) lParamPtr.ToPointer ();

    switch (uMsg)
    {
        case WM_NCHITTEST: // This message.
            SetFocus (hWnd);
            handled = true;
            return IntPtr (HTCLIENT);
        case WM_LBUTTONDOWN: // This works now.
            break;
        ...
        default:
            handled = false;
            return IntPtr (DefWindowProc (hWnd, uMsg, wParam, lParam));
    }
    ...
    handled = true;
    return IntPtr (0);
}

然后,您可以放置​​一些委托或事件并调用它们以获取 WndProc 消息。