How to handle Win + Shift + LEft / Right on Win7 with custom WM_GETMINMAXINFO logic?
I have a custom windows implementation in a WPF application that intercepts WM_GETMINMAXINFO like this:
private void MaximiseWithTaskbar(System.IntPtr hwnd, System.IntPtr lParam)
{
MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO));
System.IntPtr monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
if (monitor != System.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);
mmi.ptMinTrackSize.x = Convert.ToInt16(this.MinWidth * (desktopDpiX / 96));
mmi.ptMinTrackSize.y = Convert.ToInt16(this.MinHeight * (desktopDpiY / 96));
}
Marshal.StructureToPtr(mmi, lParam, true);
}
Everything works and it allows me to maximize the borderless window without having to sit in the taskbar, which is great, but really doesn't like moving between monitors with the new Win7 keyboard shortcuts.
Whenever the app is moved using Win + Shift + Left / Right, the WM_GETMINMAXINFO message is received as you would expect, but MonitorFromWindow (hwnd, MONITOR_DEFAULTTONEAREST) returns the monitor, the app has just been moved FROM, not the monitor it moves TO so if the monitors have different resolutions, the window ends up in the wrong size.
I'm not sure if there is anything else I can call other than MonitorFromWindow, or if there is a "moving monitors" message that I can hook up to WM_GETMINMAXINFO. I am guessing there is a way to do this because "normal" windows are working fine.
a source to share
According to the MSDN page the WM_GETMINMAXINFO is sent:
"when the size or position of the window is about to change"
which explains why your call to MonitorFromWindow returns the previous monitor.
How about using the WM_WINDOWPOSCHANGED message ? It is sent after every window move. You can get the HWND from the WINDOWPOS structure and use it in the MonitorFromWindow call to get the monitor. When the next WM_GETMINMAXINFO is sent, you can use it just like you do now.
a source to share