static extern bool GetMonitorInfo(IntPtr hMonitor, MONITORINFO lpmi);
/// <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) { // Get the point position to determine what screen we are on POINT lMousePosition; GetCursorPos(out lMousePosition); // Get the primary monitor at cursor position 0,0 var lPrimaryScreen = MonitorFromPoint(new POINT(0, 0), MonitorOptions.MONITOR_DEFAULTTOPRIMARY); // Try and get the primary screen information var lPrimaryScreenInfo = new MONITORINFO(); if (GetMonitorInfo(lPrimaryScreen, lPrimaryScreenInfo) == false) { return; } // Now get the current screen var lCurrentScreen = MonitorFromPoint(lMousePosition, MonitorOptions.MONITOR_DEFAULTTONEAREST); // If this has changed from the last one, update the transform if (lCurrentScreen != mLastScreen || mTransformToDevice == default(Matrix)) { GetTransform(); } // Store last know screen mLastScreen = lCurrentScreen; // Get min/max structure to fill with information var lMmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO)); // If it is the primary screen, use the rcWork variable 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; } // Otherwise it's the rcMonitor values 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; } // Set min size var minSize = mTransformToDevice.Transform(new Point(mWindow.MinWidth, mWindow.MinHeight)); lMmi.ptMinTrackSize.X = (int)minSize.X; lMmi.ptMinTrackSize.Y = (int)minSize.Y; // Store new size mScreenSize = new Rect(lMmi.ptMaxPosition.X, lMmi.ptMaxPosition.Y, lMmi.ptMaxSize.X, lMmi.ptMaxSize.Y); // Now we have the max size, allow the host to tweak as needed Marshal.StructureToPtr(lMmi, lParam, true); }