我正在开发一个完全自定义的窗口控件并处理它的最大化,我已经覆盖了 WindowProc 函数并自己处理 WM_GETMINMAXINFO 消息。
我填充 MINMAXINFO 结构并将其发送到窗口句柄,然后就完成了。
它适用于我的主显示器,但在我的第二台显示器上,窗口太大..
我不明白的是,我在第二台显示器上最大化时发送的 MINMAXINFO 结构具有正确的尺寸信息(1920x1080),但是一旦最大化,窗口的尺寸就会以 2160x1100 结束。
有人知道发生了什么吗?
非常感谢。
@Karnalta - 不久前我正在做类似的事情。看看我的一篇旧博文。我在上面链接的可下载示例中考虑了任务栏和任务栏的自动隐藏。我的两台显示器尺寸相同,所以它似乎对我来说很完美,但请试一试。以下是您可能最感兴趣的两种方法。
private static void WmGetMinMaxInfo(IntPtr hwnd, IntPtr lParam)
{
MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO));
IntPtr monitorContainingApplication = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
if (monitorContainingApplication != System.IntPtr.Zero)
{
MONITORINFO monitorInfo = new MONITORINFO();
GetMonitorInfo(monitorContainingApplication, 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.ptMaxTrackSize.x = mmi.ptMaxSize.x; //maximum drag X size for the window
mmi.ptMaxTrackSize.y = mmi.ptMaxSize.y; //maximum drag Y size for the window
mmi.ptMinTrackSize.x = 800; //minimum drag X size for the window
mmi.ptMinTrackSize.y = 600; //minimum drag Y size for the window
mmi = AdjustWorkingAreaForAutoHide(monitorContainingApplication, mmi); //need to adjust sizing if taskbar is set to autohide
}
Marshal.StructureToPtr(mmi, lParam, true);
}
private static MINMAXINFO AdjustWorkingAreaForAutoHide(IntPtr monitorContainingApplication, MINMAXINFO mmi)
{
IntPtr hwnd = FindWindow("Shell_TrayWnd", null);
if (hwnd == null) return mmi;
IntPtr monitorWithTaskbarOnIt = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
if (!monitorContainingApplication.Equals(monitorWithTaskbarOnIt)) return mmi;
APPBARDATA abd = new APPBARDATA();
abd.cbSize = Marshal.SizeOf(abd);
abd.hWnd = hwnd;
SHAppBarMessage((int)ABMsg.ABM_GETTASKBARPOS, ref abd);
int uEdge = GetEdge(abd.rc);
bool autoHide = System.Convert.ToBoolean(SHAppBarMessage((int)ABMsg.ABM_GETSTATE, ref abd));
if (!autoHide) return mmi;
switch (uEdge)
{
case (int)ABEdge.ABE_LEFT:
mmi.ptMaxPosition.x += 2;
mmi.ptMaxTrackSize.x -= 2;
mmi.ptMaxSize.x -= 2;
break;
case (int)ABEdge.ABE_RIGHT:
mmi.ptMaxSize.x -= 2;
mmi.ptMaxTrackSize.x -= 2;
break;
case (int)ABEdge.ABE_TOP:
mmi.ptMaxPosition.y += 2;
mmi.ptMaxTrackSize.y -= 2;
mmi.ptMaxSize.y -= 2;
break;
case (int)ABEdge.ABE_BOTTOM:
mmi.ptMaxSize.y -= 2;
mmi.ptMaxTrackSize.y -= 2;
break;
default:
return mmi;
}
return mmi;
}
与其使用 win32 事件,不如让 WPF 自己最大化窗口(使用WindowState = System.Windows.WindowState.Maximized;)并修改您的窗口内容模板以适合您想要的大小可能会更容易。
例如,也许您可以将窗口内容封装在 Grid 中,并为此 Grid 设置边距。最后,然后将窗口的背景属性(如果有)移动到网格中,并为窗口背景设置透明颜色。
听起来您正在根据第二台显示器的尺寸提供尺寸。WM_GETMINMAXINFO的文档指出宽度/高度是根据主监视器的大小表示的,即使窗口将以不同的分辨率显示在不同的监视器中。