Ejemplo n.º 1
0
        /// <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);
        }