/// <summary> /// Return the point to sync the window to. The point is in the coordinate /// space of the image, which is the same as the client coordinate space /// of the hosted window. This function returns null if the input should /// not be synchronized for this redirected window. /// </summary> /// <returns></returns> private POINT?GetInputSyncPoint(int xScreen, int yScreen) { POINT?ptClient = null; HwndSource currentHwndSource = CurrentHwndSource; if (currentHwndSource != null) { var dpiScaleToWpfScale = CurrentHwndSource.CompositionTarget.TransformToDevice; // New! HWND hwndCapture = NativeMethods.GetCapture(); if (hwndCapture != HWND.NULL) { // The mouse is captured, so only sync input if the mouse is // captured to a hosted window within us. HWND root = NativeMethods.GetAncestor(hwndCapture, GA.ROOT); if (_redirectedWindow.Handle == root) { // The HWND with capture is within us. // Transform the screen coordinates into the local coordinates. Point pt = new Point(xScreen, yScreen); pt = currentHwndSource.TransformScreenToClient(pt); pt = currentHwndSource.TransformClientToRoot(pt); pt = currentHwndSource.RootVisual.TransformToDescendant(this).Transform(pt); pt = dpiScaleToWpfScale.Transform(pt); // New! ptClient = new POINT { x = (int)Math.Round(pt.X), y = (int)Math.Round(pt.Y) }; } } else { // The mouse is not captured, so only sync input if the mouse // is over our element. // Convert the mouse coordinates to the client coordinates of the // HwndSource. Point pt = new Point(xScreen, yScreen); pt = currentHwndSource.TransformScreenToClient(pt); pt = currentHwndSource.TransformClientToRoot(pt); RedirectedHwndHost hit = ((UIElement)currentHwndSource.RootVisual).InputHitTest(pt) as RedirectedHwndHost; if (hit == this) { // Transform into the coordinate space of the // RedirectedHwndHost element. var xfrm = currentHwndSource.RootVisual.TransformToDescendant(hit); pt = xfrm.Transform(pt); pt = dpiScaleToWpfScale.Transform(pt); // New! ptClient = new POINT { x = (int)Math.Round(pt.X), y = (int)Math.Round(pt.Y) }; } } } return(ptClient); }
public static Point TransformElementToElement(this UIElement @this, Point pt, UIElement target) { // Find the HwndSource for this element and use it to transform // the point up into screen coordinates. HwndSource hwndSource = (HwndSource)PresentationSource.FromVisual(@this); pt = hwndSource.TransformDescendantToClient(pt, @this); pt = hwndSource.TransformClientToScreen(pt); // Find the HwndSource for the target element and use it to // transform the rectangle from screen coordinates down to the // target elemnent. HwndSource targetHwndSource = (HwndSource)PresentationSource.FromVisual(target); pt = targetHwndSource.TransformScreenToClient(pt); pt = targetHwndSource.TransformClientToDescendant(pt, target); return(pt); }