Example #1
0
        public static void CenterWindowToScreen(IntPtr hwnd, bool useWorkArea = true)
        {
            try
            {
                IntPtr handle = MonitorFromWindow(GetDesktopWindow(), MONITOR.DEFAULTTONEAREST);

                MONITORINFOEXW monInfo = new MONITORINFOEXW(null);
                monInfo.cbSize = (uint)Marshal.SizeOf(monInfo);

                GetMonitorInfoW(handle, ref monInfo);
                var screenRect = useWorkArea ? monInfo.rcWork : monInfo.rcMonitor;
                var midX       = (monInfo.rcMonitor.right - monInfo.rcMonitor.left) / 2;
                var midY       = (monInfo.rcMonitor.bottom - monInfo.rcMonitor.top) / 2;
                var size       = GetWindowSize(hwnd);
                var left       = midX - (size.Width / 2);
                var top        = midY - (size.Height / 2);

                SetWindowPos(
                    hwnd,
                    IntPtr.Zero,
                    left,
                    top,
                    -1,
                    -1,
                    SWP.NOACTIVATE | SWP.NOSIZE | SWP.NOZORDER);
            }
            catch { }
            {
            }
        }
Example #2
0
        public int GetDisplayRefreshRate()
        {
            // Get a monitor handle ("HMONITOR") for the window.
            //    If the window is straddling more than one monitor, Windows will pick the "best" one.
            IntPtr hmonitor = MonitorFromWindow(_hwnd, MONITOR_DEFAULTTONEAREST);

            if (hmonitor == IntPtr.Zero)
            {
                return(0);
            }

            // Get more information about the monitor.
            MONITORINFOEXW monitorInfo = new MONITORINFOEXW
            {
                cbSize = (uint)Marshal.SizeOf <MONITORINFOEXW>()
            };

            bool bResult = GetMonitorInfoW(hmonitor, ref monitorInfo);

            if (!bResult)
            {
                return(0);
            }

            // Get display settings from Windows API
            bResult = EnumDisplaySettingsW(monitorInfo.szDevice, ENUM_CURRENT_SETTINGS, out DEVMODEW devMode);
            if (!bResult)
            {
                return(0);
            }

            return((int)devMode.dmDisplayFrequency);
        }
Example #3
0
        private unsafe bool HandleMinMaxSizes(IntPtr lParam)
        {
            bool isHandled = false;

            MINMAXINFO *mmi = (MINMAXINFO *)lParam;

            if (!_options.MinimumSize.IsEmpty)
            {
                mmi->ptMinTrackSize.X = _options.MinimumSize.Width;
                mmi->ptMinTrackSize.Y = _options.MinimumSize.Height;
                isHandled             = true;
            }

            if (!_options.MaximumSize.IsEmpty)
            {
                mmi->ptMaxTrackSize.X = _options.MaximumSize.Width;
                mmi->ptMaxTrackSize.Y = _options.MaximumSize.Height;
                isHandled             = true;
            }

            // https://stackoverflow.com/questions/39816031/maximize-window-maintaining-taskbar-limits
            if (_options.WindowFrameless && _options.WindowState == WindowState.Maximize)
            {
                IntPtr handle = MonitorFromWindow(GetDesktopWindow(), MONITOR.DEFAULTTONEAREST);

                MONITORINFOEXW monInfo = new MONITORINFOEXW(null);
                monInfo.cbSize = (uint)Marshal.SizeOf(monInfo);

                var captionHeight = GetSystemMetrics(SystemMetric.SM_CYCAPTION);

                GetMonitorInfoW(handle, ref monInfo);
                var workArea    = monInfo.rcWork;
                var monitorArea = monInfo.rcMonitor;
                mmi->ptMaxPosition.X = Math.Abs(workArea.left - monitorArea.left) - captionHeight / 2;
                mmi->ptMaxPosition.Y = Math.Abs(workArea.top - monitorArea.top);
                mmi->ptMaxSize.X     = Math.Abs(workArea.right - workArea.left) + captionHeight;
                mmi->ptMaxSize.Y     = Math.Abs(workArea.bottom - workArea.top) + captionHeight;

                isHandled = true;
            }

            return(isHandled);
        }
Example #4
0
        private string GetTextForTextBlock()
        {
            // 1. Get the window handle ("HWND" in Win32 parlance)
            WindowInteropHelper helper = new WindowInteropHelper(this);
            IntPtr hwnd = helper.Handle;

            // 2. Get a monitor handle ("HMONITOR") for the window.
            //    If the window is straddling more than one monitor, Windows will pick the "best" one.
            IntPtr hmonitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);

            if (hmonitor == IntPtr.Zero)
            {
                return("MonitorFromWindow returned NULL ☹");
            }

            // 3. Get more information about the monitor.
            MONITORINFOEXW monitorInfo = new MONITORINFOEXW();

            monitorInfo.cbSize = (uint)Marshal.SizeOf <MONITORINFOEXW>();

            bool bResult = GetMonitorInfoW(hmonitor, ref monitorInfo);

            if (!bResult)
            {
                return("GetMonitorInfoW returned FALSE ☹");
            }

            // 4. Get the current display settings for that monitor, which includes the resolution and refresh rate.
            DEVMODEW devMode = new DEVMODEW();

            devMode.dmSize = (ushort)Marshal.SizeOf <DEVMODEW>();

            bResult = EnumDisplaySettingsW(monitorInfo.szDevice, ENUM_CURRENT_SETTINGS, out devMode);
            if (!bResult)
            {
                return("EnumDisplaySettingsW returned FALSE ☹");
            }

            // Done!
            return(string.Format("{0} x {1} @ {2}hz", devMode.dmPelsWidth, devMode.dmPelsHeight, devMode.dmDisplayFrequency));
        }
Example #5
0
        private (MONITORINFO mi, string device) GetMonitorInfoEx(IntPtr hMonitor)
        {
            unsafe
            {
                MONITORINFOEXW miEx = default;
                MONITORINFO *  pmi  = (MONITORINFO *)&miEx;
                (*pmi).cbSize = (uint)sizeof(MONITORINFOEXW);
                if (!NativeMethods.GetMonitorInfo(new(hMonitor), pmi))
                {
                    try
                    {
                        throw new Win32Exception().WithMessage($"Could not read the monitor information for HMONITOR={hMonitor:X8}!");
                    }
                    catch (Win32Exception e) when(e.IsInvalidMonitorHandleException() || !IsMonitorValid(hMonitor))
                    {
                        throw new InvalidDisplayReferenceException(hMonitor, e);
                    }
                }

                char *pszDevice = (char *)&miEx.szDevice;
                return(*pmi, new string(pszDevice));
            }
        }
Example #6
0
        public static Rectangle FullScreenBounds(Rectangle configuredBounds)
        {
            try
            {
                IntPtr handle = MonitorFromWindow(GetDesktopWindow(), MONITOR.DEFAULTTOPRIMARY);

                MONITORINFOEXW monInfo = new MONITORINFOEXW(null);

                GetMonitorInfoW(handle, ref monInfo);
                RECT rect = monInfo.rcMonitor;

                if (rect.Width <= 0 || rect.Height <= 0)
                {
                    return(configuredBounds);
                }

                return(rect);
            }
            catch { }
            {
            }

            return(configuredBounds);
        }
Example #7
0
 private static extern bool GetMonitorInfoW(
     IntPtr hMonitor,
     ref MONITORINFOEXW lpmi);
Example #8
0
 public static extern BOOL GetMonitorInfoW(IntPtr hMonitor, ref MONITORINFOEXW lpmi);
Example #9
0
 public static partial BOOL GetMonitorInfoW(IntPtr hMonitor, ref MONITORINFOEXW lpmi);
Example #10
0
        public void HandleNCCalcsize(IntPtr wParam, IntPtr lParam)
        {
            // lParam is an [in, out] that can be either a RECT* (wParam == FALSE) or an NCCALCSIZE_PARAMS*.
            // Since the first field of NCCALCSIZE_PARAMS is a RECT and is the only field we care about
            // we can unconditionally treat it as a RECT.

            /* DefWindowProc must be called in both the maximized and non-maximized
             * cases, otherwise tile/cascade windows won't work */

            var nonclient = (RECT)Marshal.PtrToStructure(lParam, typeof(RECT));

            DefWindowProcW(_framelessInfo.Handle, WM.NCCALCSIZE, wParam, lParam);
            var client = (RECT)Marshal.PtrToStructure(lParam, typeof(RECT));

            if (IsMaximized(_framelessInfo.Handle))
            {
                WINDOWINFO wi = new WINDOWINFO(null);
                GetWindowInfo(_framelessInfo.Handle, ref wi);

                /* Maximized windows always have a non-client border that hangs over
                 * the edge of the screen, so the size proposed by WM_NCCALCSIZE is
                 * fine. Just adjust the top border to remove the window title. */
                var rect = new RECT();
                rect.left   = client.left;
                rect.top    = (int)(nonclient.top + wi.cyWindowBorders);
                rect.right  = client.right;
                rect.bottom = client.bottom;

                IntPtr         mon = MonitorFromWindow(_framelessInfo.Handle, MONITOR.DEFAULTTOPRIMARY);
                MONITORINFOEXW mi  = new MONITORINFOEXW(null);
                GetMonitorInfoW(mon, ref mi);

                /* If the client rectangle is the same as the monitor's rectangle,
                 * the shell assumes that the window has gone fullscreen, so it removes
                 * the topmost attribute from any auto-hide appbars, making them
                 * inaccessible. To avoid this, reduce the size of the client area by
                 * one pixel on a certain edge. The edge is chosen based on which side
                 * of the monitor is likely to contain an auto-hide appbar, so the
                 * missing client area is covered by it. */
                if (rect.AreEqual(mi.rcMonitor))
                {
                    if (HasAutohideAppbar(ABE_BOTTOM, mi.rcMonitor))
                    {
                        rect.bottom--;
                    }

                    else if (HasAutohideAppbar(ABE_LEFT, mi.rcMonitor))
                    {
                        rect.left++;
                    }

                    else if (HasAutohideAppbar(ABE_TOP, mi.rcMonitor))
                    {
                        rect.top++;
                    }

                    else if (HasAutohideAppbar(ABE_RIGHT, mi.rcMonitor))
                    {
                        rect.right--;
                    }
                }

                Marshal.StructureToPtr(rect, lParam, false);
            }
            else
            {
                /* For the non-maximized case, set the output RECT to what it was
                 * before WM_NCCALCSIZE modified it. This will make the client size the
                 * same as the non-client size. */
                Marshal.StructureToPtr(nonclient, lParam, false);
            }
        }