WPF - 在屏幕外渲染的网格上模拟鼠标事件

时间:2009-12-17 15:19:56

标签: wpf events input simulation off-screen

我将具有多个元素(按钮,文本框,...)的WPF网格渲染到位图,然后将其用作Direct3D场景中3D表面的纹理。对于用户交互,我从2D鼠标光标位置创建3D射线到3D场景中,找到与gui曲面的交点。所以我知道用户点击了WPF网格的位置,但是从那里我被卡住了:

如何在WPF元素上模拟鼠标事件,而它们实际上并未在打开的窗口中显示,而是在屏幕外呈现?

最近,我正在研究UIAutomation和RaiseEvent,但这些用于将事件发送到单个元素,而不是整个可视树。手动遍历树并在光标位置查找元素将是一个选项,但我还没有找到一种方法来准确地执行此操作。 VisualTreeHelper.HitTest是一个很好的开始,但它没有找到TextBox,而是找到TextBoxView而不是ListBox,它找到了一个Border。

编辑:在HitTest的结果回调中返回HitTestResultBehavior.Continue让我遍历给定点的所有元素。我现在可以将鼠标事件发送到所有这些元素,但MouseEventArgs对象的值是真实鼠标的值。所以我必须创建一个显然不可能的自定义MouseDevice。

PointHitTestParameters p = new PointHitTestParameters(new Point(
    ((Vector2)hit).X * sourceElement.ActualWidth, 
    (1 - ((Vector2)hit).Y) * sourceElement.ActualHeight));
VisualTreeHelper.HitTest(sourceElement,
     new HitTestFilterCallback(delegate(DependencyObject o)
     {
         return HitTestFilterBehavior.Continue;
     }),
     new HitTestResultCallback(delegate(HitTestResult r)
     {
         UIElement el = r.VisualHit as UIElement;
         if (el != null)
         {
             MouseButtonEventArgs e = new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Left);
             if (leftMouseDown) e.RoutedEvent = Mouse.MouseDownEvent;
             else e.RoutedEvent = Mouse.MouseUpEvent;
             el.RaiseEvent(e);
         }
         return HitTestResultBehavior.Continue;
     }), p);

2 个答案:

答案 0 :(得分:0)

您可以通过PostMessage(..)win32方法将Windows消息(如WM_MOUSEMOVE)发送到WPF窗口的HWND。我相信这些消息将由WPF读取并执行,就像它来自用户一样。

答案 1 :(得分:0)

如果你真的很勇敢,可以试试my hack to get access to the WPF IDirect3DDevice9Ex。从那里你可以将swapshchain中的backbuffer复制到你的d3d场景。如果您使用的是9Ex(Vista D3D9),您可以利用共享资源(在设备和进程之间共享表面/纹理/等)功能来帮助提高性能。

您可能仍需要使用Windows消息进行交互性操作。