private void _InitializeCaptionButtonLocation() { if (!Standard.Utility.IsOSVistaOrNewer || !Standard.NativeMethods.IsThemeActive()) { this._LegacyInitializeCaptionButtonLocation(); } else { Standard.TITLEBARINFOEX structure = new Standard.TITLEBARINFOEX { cbSize = Marshal.SizeOf(typeof(Standard.TITLEBARINFOEX)) }; IntPtr ptr = Marshal.AllocHGlobal(structure.cbSize); try { Marshal.StructureToPtr(structure, ptr, false); Standard.NativeMethods.ShowWindow(this._messageHwnd.Handle, Standard.SW.SHOW); Standard.NativeMethods.SendMessage(this._messageHwnd.Handle, Standard.WM.GETTITLEBARINFOEX, IntPtr.Zero, ptr); structure = (Standard.TITLEBARINFOEX)Marshal.PtrToStructure(ptr, typeof(Standard.TITLEBARINFOEX)); } finally { Standard.NativeMethods.ShowWindow(this._messageHwnd.Handle, Standard.SW.HIDE); Standard.Utility.SafeFreeHGlobal(ref ptr); } Standard.RECT rect = Standard.RECT.Union(structure.rgrect_CloseButton, structure.rgrect_MinimizeButton); Standard.RECT windowRect = Standard.NativeMethods.GetWindowRect(this._messageHwnd.Handle); Rect deviceRectangle = new Rect((double)((rect.Left - windowRect.Width) - windowRect.Left), (double)(rect.Top - windowRect.Top), (double)rect.Width, (double)rect.Height); Rect rect4 = Standard.DpiHelper.DeviceRectToLogical(deviceRectangle); this.WindowCaptionButtonsLocation = rect4; } }
private void _InitializeCaptionButtonLocation() { // There is a completely different way to do this on XP. if (!Utility.IsOSVistaOrNewer || !NativeMethods.IsThemeActive()) { _LegacyInitializeCaptionButtonLocation(); return; } var tbix = new TITLEBARINFOEX { cbSize = Marshal.SizeOf(typeof(TITLEBARINFOEX)) }; IntPtr lParam = Marshal.AllocHGlobal(tbix.cbSize); try { Marshal.StructureToPtr(tbix, lParam, false); // This might flash a window in the taskbar while being calculated. // WM_GETTITLEBARINFOEX doesn't work correctly unless the window is visible while processing. // use SW.SHOWNA instead SW.SHOW to avoid some brief flashing when launched the window NativeMethods.ShowWindow(_messageHwnd.Handle, SW.SHOWNA); NativeMethods.SendMessage(_messageHwnd.Handle, WM.GETTITLEBARINFOEX, IntPtr.Zero, lParam); tbix = (TITLEBARINFOEX)Marshal.PtrToStructure(lParam, typeof(TITLEBARINFOEX)); } finally { NativeMethods.ShowWindow(_messageHwnd.Handle, SW.HIDE); Utility.SafeFreeHGlobal(ref lParam); } // TITLEBARINFOEX has information relative to the screen. We need to convert the containing rect // to instead be relative to the top-right corner of the window. RECT rcAllCaptionButtons = RECT.Union(tbix.rgrect_CloseButton, tbix.rgrect_MinimizeButton); // For all known themes, the RECT for the maximize box shouldn't add anything to the union of the minimize and close boxes. Assert.AreEqual(rcAllCaptionButtons, RECT.Union(rcAllCaptionButtons, tbix.rgrect_MaximizeButton)); RECT rcWindow = NativeMethods.GetWindowRect(_messageHwnd.Handle); // Reorient the Top/Right to be relative to the top right edge of the Window. var deviceCaptionLocation = new Rect( rcAllCaptionButtons.Left - rcWindow.Width - rcWindow.Left, rcAllCaptionButtons.Top - rcWindow.Top, rcAllCaptionButtons.Width, rcAllCaptionButtons.Height); Rect logicalCaptionLocation = DpiHelper.DeviceRectToLogical(deviceCaptionLocation); WindowCaptionButtonsLocation = logicalCaptionLocation; }