/// <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); }