/// <summary> /// Adjusts a POINT to compensate for Win32 RTL conversion logic /// </summary> /// <remarks> /// MITIGATION: AVALON_RTL_AND_WIN32RTL /// /// When a window is marked with the WS_EX_LAYOUTRTL style, Win32 /// mirrors the coordinates during the various translation APIs. /// /// Avalon also sets up mirroring transforms so that we properly /// mirror the output since we render to DirectX, not a GDI DC. /// /// Unfortunately, this means that our coordinates are already mirrored /// by Win32, and Avalon mirrors them again. To work around this /// problem, we un-mirror the coordinates from Win32 before hit-testing /// in Avalon. /// </remarks> /// <param name="pt"> /// The POINT to be adjusted /// </param> /// <param name="handleRef"> /// A HandleRef to the hwnd containing the point to be adjusted /// </param> /// <returns> /// The adjusted point /// </returns> internal static NativeMethods.POINT AdjustForRightToLeft(NativeMethods.POINT pt, HandleRef handleRef) { int windowStyle = SafeNativeMethods.GetWindowStyle(handleRef, true); if ((windowStyle & NativeMethods.WS_EX_LAYOUTRTL) == NativeMethods.WS_EX_LAYOUTRTL) { NativeMethods.RECT rcClient = new NativeMethods.RECT(); SafeNativeMethods.GetClientRect(handleRef, ref rcClient); pt.x = rcClient.right - pt.x; } return(pt); }
internal static Point ScreenToClient(Point ptScreen, PresentationSource presentationSource) { // For now we only know how to use HwndSource. HwndSource inputSource = presentationSource as HwndSource; if (inputSource == null) { return(ptScreen); } HandleRef handleRef; new UIPermission(UIPermissionWindow.AllWindows).Assert(); // BlessedAssert: try { handleRef = new HandleRef(inputSource, inputSource.Handle); } finally { UIPermission.RevertAssert(); } // Convert the point from screen coordinates back to client coordinates. NativeMethods.POINT ptClient = new NativeMethods.POINT((int)ptScreen.X, (int)ptScreen.Y); SafeNativeMethods.ScreenToClient(handleRef, ptClient); // MITIGATION: WIN32_AND_AVALON_RTL // // When a window is marked with the WS_EX_LAYOUTRTL style, Win32 // mirrors the coordinates during the various translation APIs. // // Avalon also sets up mirroring transforms so that we properly // mirror the output since we render to DirectX, not a GDI DC. // // Unfortunately, this means that our coordinates are already mirrored // by Win32, and Avalon mirrors them again. To work around this // problem, we un-mirror the coordinates from Win32 before hit-testing // in Avalon. // int windowStyle = SafeNativeMethods.GetWindowStyle(handleRef, true); if ((windowStyle & NativeMethods.WS_EX_LAYOUTRTL) == NativeMethods.WS_EX_LAYOUTRTL) { NativeMethods.RECT rcClient = new NativeMethods.RECT(); SafeNativeMethods.GetClientRect(handleRef, ref rcClient); ptClient.x = rcClient.right - ptClient.x; } return(new Point(ptClient.x, ptClient.y)); }
/// <summary> /// Adjusts a RECT to compensate for Win32 RTL conversion logic /// </summary> /// <remarks> /// MITIGATION: AVALON_RTL_AND_WIN32RTL /// /// When a window is marked with the WS_EX_LAYOUTRTL style, Win32 /// mirrors the coordinates during the various translation APIs. /// /// Avalon also sets up mirroring transforms so that we properly /// mirror the output since we render to DirectX, not a GDI DC. /// /// Unfortunately, this means that our coordinates are already mirrored /// by Win32, and Avalon mirrors them again. To work around this /// problem, we un-mirror the coordinates from Win32 before hit-testing /// in Avalon. /// </remarks> /// <param name="rc"> /// The RECT to be adjusted /// </param> /// <param name="handleRef"> /// </param> /// <returns> /// The adjusted rectangle /// </returns> internal static NativeMethods.RECT AdjustForRightToLeft(NativeMethods.RECT rc, HandleRef handleRef) { int windowStyle = SafeNativeMethods.GetWindowStyle(handleRef, true); if ((windowStyle & NativeMethods.WS_EX_LAYOUTRTL) == NativeMethods.WS_EX_LAYOUTRTL) { NativeMethods.RECT rcClient = new NativeMethods.RECT(); SafeNativeMethods.GetClientRect(handleRef, ref rcClient); int width = rc.right - rc.left; // preserve width rc.right = rcClient.right - rc.left; // set right of rect to be as far from right of window as left of rect was from left of window rc.left = rc.right - width; // restore width by adjusting left and preserving right } return(rc); }