【发布时间】:2014-02-10 11:41:27
【问题描述】:
我有一个需要嵌入到 WPF 应用程序中的 Win32 (OpenGL) 控件。它必须响应并传播鼠标和键盘事件。
我创建了一个 HwndHost 派生实例来托管本机窗口,并覆盖了此类中的 WndProc 函数。为了向 WPF 传播 win32 消息,我处理特定的鼠标消息并将它们映射到 WPF 事件,然后使用静态 InputManager 类来引发它们。
问题是,当我去处理它们时,鼠标坐标搞砸了。
这是我用来引发事件的代码示例:
IntPtr MyHwndHost::WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, bool% handled)
{
switch (msg)
{
case WM_LBUTTONDOWN:
{
MouseButtonEventArgs^ eventArgs = gcnew MouseButtonEventArgs(
Mouse::PrimaryDevice,
Environment::TickCount,
MouseButton::Left);
eventArgs->RoutedEvent = UIElement::PreviewMouseDownEvent;
eventArgs->Source = this;
// Raise the WPF event from the specified WPF event source.
InputManager::Current->ProcessInput(eventArgs);
eventArgs->RoutedEvent = UIElement::MouseDownEvent;
InputManager::Current->ProcessInput(eventArgs);
CommandManager::InvalidateRequerySuggested();
handled = true;
return IntPtr::Zero;
}
break;
}
return HwndHost::WndProc(hwnd, msg, wParam, lParam, handled);
}
当我的 WPF 事件处理程序被触发并尝试检索鼠标坐标(例如 e.GetPosition((IInputElement) sender))时,我收到了错误的值(无论原始事件在我的控制范围内发生的位置,它们始终是相同的值)。
我得到的值似乎与承载应用程序的 WPF 窗口的屏幕位置有关,因为它们会随着窗口位置的变化而变化,但它们也不对应于应用程序窗口的实际位置。
我认为这可能与 WPF InputManager 的内部状态有关,并且当我的事件被引发时,私有字段 MouseDevice._inputSource 是 null,但我的实验.net 反射没有产生任何结果。
我真的不知道还能尝试什么。键盘支持开箱即用,只是鼠标位置支持我无法正常工作。
【问题讨论】:
-
在转发之前,我看不到您在哪里将鼠标坐标(如果有记忆在 LPARAM 中编码)分配给 eventArgs。查看 MouseButtonEventArgs 的定义,我看不到将鼠标坐标注入其中的方法。
-
如果将消息转发到父窗口并让 WPF 担心将其转换为 WPF 事件,它是否有效?
-
@arx - 不幸的是它没有。
-
@user1793036 - 你是对的,没有办法注入鼠标坐标。 WPF 在内部类中自行确定它们。