【问题标题】:WPF WIN32 hwndhost WM_MOUSEMOVE WM_MOUSEHOVERWPF WIN32 hwndhost WM_MOUSEMOVE WM_MOUSEHOVER
【发布时间】:2010-11-11 03:30:54
【问题描述】:

我有一个 WPF 应用程序,其用户控件包含 HwndHost。 HwndHost 的创建方式如下:

  hwndHost = CreateWindowEx(0, "static", "",
                            WS_CHILD | WS_VISIBLE,
                            0, 0,
                            hostHeight, hostWidth,
                            hwndParent.Handle,
                            (IntPtr)HOST_ID,
                            IntPtr.Zero,
                            0);

  hwndControl = CreateWindowEx(0, "Static", "",
                                WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN
                                  ,
                                0, 0,
                                hostHeight, hostWidth,
                                hwndHost,
                                (IntPtr)PICTUREBOX_ID,
                                IntPtr.Zero,
                                0);

然后我使用 HwndSourceHook 连接到消息泵,大量消息通过。

除了我想要的 WM_MOUSEMOVE、WM_MOUSEHOVER、WM_LBUTTONDOWN 和 WM_LBUTTONUP

此外,在主窗口或控件上的 WPF 代码中不会触发 OnMouseLeftButtonDown 事件,我认为是因为 Windows 正在捕获它并将其丢弃。

有人知道我怎样才能让这些通过,无论是否使用 WIN32 窗口消息?

【问题讨论】:

  • 更新:OnMouseLeftButtonUp 在 WPF 中触发,但不是 OnMouseLeftButtonDown。丢失了 plot.com?

标签: wpf winapi controls host


【解决方案1】:

您需要处理 WM_NCHITTEST。在您这样做之前,它不会向您发送鼠标消息。

// C++/CLI implementation of HwndHost.WndProc().
virtual IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, bool% handled) override
{
    switch (msg)
    {
        case WM_NCHITTEST:
        {
            handled = true;
        return IntPtr(HTCLIENT);
        }
    }

    return IntPtr::Zero;
}

【讨论】:

    【解决方案2】:

    WPF 中的 Border 元素似乎阻止了 OnMouseLeftButtonDown 被抛出。在找到更好的解决方案之前,我的临时解决方案是将 WPF 边框更改为 WPF 按钮,然后触发所有鼠标事件。

    对于大多数人来说并不理想,但因为我使用它在上面渲染 3D 并不重要。

    【讨论】:

      【解决方案3】:

      您为什么不注册一个 WndClass 并将消息传递到您自己的 WndProc 而不是挂钩消息泵?我怀疑你会得到更好的结果。

      【讨论】:

      • 我正在连接 WndProc,我认为这会给我发送的每条消息。你知道我可以用 WPF 注册一个 WndClass 吗?
      • 我不确定您做错了什么,但可能是您在 WndProc 链中的位置不正确?我对 WPF 不够熟悉,无法说出你会怎么做,但如果你可以调用 CreateWindowEx(),我不明白为什么你不能调用 RegisterClass()。
      • 好的,谢谢,我去看看。我怀疑还有其他干扰,比如我将 Hwnd 传递给的 Ogre3D 引擎,因此它可以渲染到我的窗口。
      • 您应该能够使用 Spy++ 查看窗口链以及消息消失的位置。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多