internal static Visual GetElementFromPoint(IntPtr hwnd, Visual root, Point pointScreen) { HwndSource hwndSource = HwndSource.CriticalFromHwnd(hwnd); if (hwndSource == null) { return(null); } Point pointClient = PointUtil.ScreenToClient(pointScreen, hwndSource); Point pointRoot = PointUtil.ClientToRoot(pointClient, hwndSource); PointHitTestResult result = VisualTreeUtils.AsNearestPointHitTestResult(VisualTreeHelper.HitTest(root, pointRoot)); Visual visual = (result != null) ? result.VisualHit : null; return(visual); }
internal override Point GetPosition(IInputElement relativeTo) { VerifyAccess(); // Validate that relativeTo is either a UIElement or a ContentElement if (relativeTo != null && !InputElement.IsValid(relativeTo)) { throw new InvalidOperationException(); } PresentationSource relativePresentationSource = null; if (relativeTo != null) { DependencyObject dependencyObject = relativeTo as DependencyObject; DependencyObject containingVisual = InputElement.GetContainingVisual(dependencyObject); if (containingVisual != null) { relativePresentationSource = PresentationSource.CriticalFromVisual(containingVisual); } } else { if (_inputSource != null) { relativePresentationSource = _inputSource.Value; } } // Verify that we have a valid PresentationSource with a valid RootVisual // - if we don't we won't be able to invoke ClientToRoot or TranslatePoint and // we will just return 0,0 if (relativePresentationSource == null || relativePresentationSource.RootVisual == null) { return(new Point(0, 0)); } Point curPoint = new Point(_pointerData.Info.ptPixelLocationRaw.X, _pointerData.Info.ptPixelLocationRaw.Y); Point ptClient = PointUtil.ScreenToClient(curPoint, relativePresentationSource); Point ptRoot = PointUtil.ClientToRoot(ptClient, relativePresentationSource); Point ptRelative = InputElement.TranslatePoint(ptRoot, relativePresentationSource.RootVisual, (DependencyObject)relativeTo); return(ptRelative); }
internal static Point TranslatePoint(Point pt, DependencyObject from, DependencyObject to, out bool translated) { translated = false; Point ptTranslated = pt; // Get the containing and root visuals we are coming from. DependencyObject vFromAsDO = InputElement.GetContainingVisual(from); Visual rootFrom = InputElement.GetRootVisual(from) as Visual; Visual vFrom = vFromAsDO as Visual; if (vFromAsDO != null && vFrom == null) { // must be a Visual3D - get it's 2D visual parent vFrom = VisualTreeHelper.GetContainingVisual2D(vFromAsDO); } if (vFrom != null && rootFrom != null) { GeneralTransform gUp; Matrix mUp; bool isUpSimple = false; isUpSimple = vFrom.TrySimpleTransformToAncestor(rootFrom, false, /* do not apply inverse */ out gUp, out mUp); if (isUpSimple) { ptTranslated = mUp.Transform(ptTranslated); } else if (gUp.TryTransform(ptTranslated, out ptTranslated) == false) { // Error. Out parameter has been set false. return(new Point()); } // If no element was specified to translate to, we leave the coordinates // translated to the root. if (to != null) { // Get the containing and root visuals we are going to. DependencyObject vTo = InputElement.GetContainingVisual(to); Visual rootTo = InputElement.GetRootVisual(to) as Visual; if (vTo != null && rootTo != null) { // If both are under the same root visual, we can easily translate the point // between them by translating up to the root, and then back down. // // However, if both are under different roots, we can only translate // between them if we know how to relate the two root visuals. Currently // we only know how to do that if both roots are sourced in HwndSources. if (rootFrom != rootTo) { HwndSource sourceFrom = PresentationSource.CriticalFromVisual(rootFrom) as HwndSource; HwndSource sourceTo = PresentationSource.CriticalFromVisual(rootTo) as HwndSource; if (sourceFrom != null && sourceFrom.CriticalHandle != IntPtr.Zero && sourceFrom.CompositionTarget != null && sourceTo != null && sourceTo.CriticalHandle != IntPtr.Zero && sourceTo.CompositionTarget != null) { // Translate the point into client coordinates. ptTranslated = PointUtil.RootToClient(ptTranslated, sourceFrom); // Translate the point into screen coordinates. Point ptScreen = PointUtil.ClientToScreen(ptTranslated, sourceFrom); // Translate the point back the the client coordinates of the To window. ptTranslated = PointUtil.ScreenToClient(ptScreen, sourceTo); // Translate the point back to the root element. ptTranslated = PointUtil.ClientToRoot(ptTranslated, sourceTo); } else { // Error. Out parameter has been set false. return(new Point()); } } // Translate the point from the root to the visual. GeneralTransform gDown; Matrix mDown; Visual vToAsVisual = vTo as Visual; if (vToAsVisual == null) { // must be a Visual3D vToAsVisual = VisualTreeHelper.GetContainingVisual2D(vTo); } bool isDownSimple = vToAsVisual.TrySimpleTransformToAncestor(rootTo, true, /* apply inverse */ out gDown, out mDown); if (isDownSimple) { ptTranslated = mDown.Transform(ptTranslated); } else if (gDown != null) { if (gDown.TryTransform(ptTranslated, out ptTranslated) == false) { // Error. Out parameter has been set false. return(new Point()); } } else { // Error. Out parameter has been set false. return(new Point()); } } else { // Error. Out parameter has been set false. return(new Point()); } } } else { // Error. Out parameter has been set false. return(new Point()); } translated = true; return(ptTranslated); }