2

注意:我正在尝试解决鼠标问题,而不是已经解决的键盘问题

所以我正在创建一个 Visual Studio 2015 扩展,在选项页面上工作。

我正在使用 WPF,所以我使用 ElementHost 来托管 UserControl。起初它没有收到键盘事件,所以我在以下位置实现了解决方案:

WPF TextBox 在窗口窗体中的 ElementHost 中不接受输入

解决方案的快速运行:

A) 在 UserControl 的 Loaded 事件中,我这样做:

var s = HwndSource.FromVisual(this) as HwndSource;
s?.AddHook(ChildHwndSourceHook);

B)在 ChildHwndSourceHook() 中,我执行以下操作:

static IntPtr ChildHwndSourceHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
    if (msg == WM_GETDLGCODE)
    {
        handled = true;
        return new IntPtr(DLGC_WANTCHARS | DLGC_WANTARROWS | DLGC_HASSETSEL | DLGC_WANTTAB);
    }
    return IntPtr.Zero;
}

但是,现在鼠标悬停事件似乎被忽略了,因为光标在文本框或网格拆分器上移动时不会改变,甚至在我创建的新 Windows 上也不会改变。 但是,偶尔,鼠标事件确实有效,并且会继续有效,直到我移动到另一个页面或关闭对话框。这是最奇怪的部分。

我已经尝试了所有方法并整天搜索谷歌,但我并没有更接近理解为什么点击工作正常,但鼠标悬停事件似乎没有被注册。

我确实尝试过删除消息处理程序,然后打开一个窗口,但似乎一旦添加了处理程序,删除它就不会解决任何问题。

有谁知道我怎样才能让鼠标悬停在我的控件上工作?非常感谢!

4

1 回答 1

1

我发现使用创建者 Viasfora 使用的方法取得了成功。您可以在此处查看 GitHub 存储库中的代码。特别是,查看 TextObfuscationDialog 及其托管方式。我相信 VS 扩展文档可能有问题,因为我遇到了同样的问题。

编辑:

我创建了一个示例项目来展示这个方法确实有效(我现在在我自己的两个扩展中使用它)。希望这个工作代码可以让您更容易在自己的项目中实现它。

您可以在此处从我的 OneDrive下载源代码。

WPF 选项页面

UIElementDialogPage MSDN 上的说:

在运行 IsDialogMessage 样式消息循环的本机对话框内提供 Windows Presentation Foundation (WPF) 内容的无缝托管。此类启用进入和退出 WPF 子窗口句柄 (HWND) 的选项卡,并启用 WPF 子 HWND 内的键盘导航。

因此,虽然 an ElementHostwill 在 normal/WinForms 的消息循环中无法正常运行DialogPage,但UIElementDialogPagewill. 有许多具有UIElement*或类似前缀的类 - 它们有助于将 VS 的旧代码从 Windows 窗体迁移到 WPF。

于 2015-10-09T05:09:14.133 回答