public static void WmGetMinMaxInfo(IntPtr hwnd, IntPtr lParam) { MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO)); int MONITOR_DEFAULTTONEAREST = 0x00000002; IntPtr monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); if (monitor != IntPtr.Zero) { MONITORINFO monitorInfo = new MONITORINFO(); GetMonitorInfo(monitor, monitorInfo); RECT rcWorkArea = monitorInfo.rcWork; RECT rcMonitorArea = monitorInfo.rcMonitor; mmi.ptMaxPosition.x = Math.Abs(rcWorkArea.left - rcMonitorArea.left); mmi.ptMaxPosition.y = Math.Abs(rcWorkArea.top - rcMonitorArea.top); mmi.ptMaxSize.x = Math.Abs(rcWorkArea.right - rcWorkArea.left); mmi.ptMaxSize.y = Math.Abs(rcWorkArea.bottom - rcWorkArea.top); } Marshal.StructureToPtr(mmi, lParam, true); }
public static void WmGetMinMaxInfo(System.IntPtr hwnd, System.IntPtr lParam) { MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO)); // Adjust the maximized size and position to fit the work area of the correct monitor System.IntPtr monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); if (monitor != System.IntPtr.Zero) { MonitorInfoEx monitorInfo = new MonitorInfoEx(); monitorInfo.cbSize = Marshal.SizeOf(monitorInfo); GetMonitorInfo(new HandleRef(hwnd, monitor), monitorInfo); Rect rcWorkArea = monitorInfo.rcWork; Rect rcMonitorArea = monitorInfo.rcMonitor; mmi.ptMaxPosition.x = Math.Abs(rcWorkArea.Left - rcMonitorArea.Left); mmi.ptMaxPosition.y = Math.Abs(rcWorkArea.Top - rcMonitorArea.Top); mmi.ptMaxSize.x = Math.Abs(rcWorkArea.Right - rcWorkArea.Left); mmi.ptMaxSize.y = Math.Abs(rcWorkArea.Bottom - rcWorkArea.Top); } Marshal.StructureToPtr(mmi, lParam, true); }
/// <summary> /// Get the min/max window size for this window /// Correctly accounting for the taskbar size and position /// </summary> /// <param name="hwnd"></param> /// <param name="lParam"></param> private void WmGetMinMaxInfo(System.IntPtr hwnd, System.IntPtr lParam) { POINT lMousePosition; GetCursorPos(out lMousePosition); IntPtr lPrimaryScreen = MonitorFromPoint(new POINT(0, 0), MonitorOptions.MONITOR_DEFAULTTOPRIMARY); MONITORINFO lPrimaryScreenInfo = new MONITORINFO(); if (GetMonitorInfo(lPrimaryScreen, lPrimaryScreenInfo) == false) { return; } IntPtr lCurrentScreen = MonitorFromPoint(lMousePosition, MonitorOptions.MONITOR_DEFAULTTONEAREST); MINMAXINFO lMmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO)); if (lPrimaryScreen.Equals(lCurrentScreen) == true) { lMmi.ptMaxPosition.X = lPrimaryScreenInfo.rcWork.Left; lMmi.ptMaxPosition.Y = lPrimaryScreenInfo.rcWork.Top; lMmi.ptMaxSize.X = lPrimaryScreenInfo.rcWork.Right - lPrimaryScreenInfo.rcWork.Left; lMmi.ptMaxSize.Y = lPrimaryScreenInfo.rcWork.Bottom - lPrimaryScreenInfo.rcWork.Top; } else { lMmi.ptMaxPosition.X = lPrimaryScreenInfo.rcMonitor.Left; lMmi.ptMaxPosition.Y = lPrimaryScreenInfo.rcMonitor.Top; lMmi.ptMaxSize.X = lPrimaryScreenInfo.rcMonitor.Right - lPrimaryScreenInfo.rcMonitor.Left; lMmi.ptMaxSize.Y = lPrimaryScreenInfo.rcMonitor.Bottom - lPrimaryScreenInfo.rcMonitor.Top; } // Now we have the max size, allow the host to tweak as needed Marshal.StructureToPtr(lMmi, lParam, true); }
private static IntPtr WindowHookProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { CustomChrome window = GetWindow(hWnd) as CustomChrome; switch (msg) { // Toggle the DropShadowEffect when window is snapped or maximized case WM_SIZE: { int resizing = (int)wParam; if (resizing == SIZE_RESTORED) { MonitorArea monitorArea = GetMonitorArea(hWnd); if (monitorArea != null) { // LOWORD int width = ((int)lParam & 0x0000ffff); // HIWORD int height = (int)((int)lParam & 0xffff0000) >> 16; // Detect if window was snapped to screen side of current monitor // or if spanning width on multiple monitors (to avoid unsnapping) if (height == monitorArea.Work.Height || width >= SystemParameters.VirtualScreenWidth) { window.IsSnapped = true; UpdateResizeBorder(window, monitorArea, window.Left, window.Left + width); } else { window.IsSnapped = false; ShowDropShadow(window); EnableResizeBorder(window); } } } else if (resizing == SIZE_MAXIMIZED) { // Required when maximized from dragging window DisableResizeBorder(window); } } break; // To handle proper resizing of the custom window case WM_GETMINMAXINFO: { MonitorArea monitorArea = GetMonitorArea(hWnd); if (monitorArea != null) { MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO)); mmi.ptMaxPosition.x = monitorArea.Offset.x; mmi.ptMaxPosition.y = monitorArea.Offset.y; mmi.ptMaxSize.x = monitorArea.Work.Width; mmi.ptMaxSize.y = monitorArea.Work.Height; // To support minimum window size mmi.ptMinTrackSize.x = (int)window.MinWidth; mmi.ptMinTrackSize.y = (int)window.MinHeight; Marshal.StructureToPtr(mmi, lParam, true); handled = true; } } break; // To activate/deactivate border resize handles from window position case WM_WINDOWPOSCHANGED: { WINDOWPOS windowPos = (WINDOWPOS)Marshal.PtrToStructure(lParam, typeof(WINDOWPOS)); // When window is snapped and position changes if ((windowPos.flags & SWP_NOMOVE) != SWP_NOMOVE) { if (window.IsSnapped) { MonitorArea monitorArea = GetMonitorArea(hWnd); if (monitorArea != null) { UpdateResizeBorder(window, monitorArea, windowPos.x, windowPos.x + windowPos.cx); } } } } break; } return(IntPtr.Zero); }