Winapi 更改最大化窗口的样式
我想要一个窗口,它的行为与正常的重叠窗口相同,除了它在最大化时没有capton栏(以便为客户端区域腾出更多空间)。 我可以从窗口样式中删除Winapi 更改最大化窗口的样式,winapi,Winapi,我想要一个窗口,它的行为与正常的重叠窗口相同,除了它在最大化时没有capton栏(以便为客户端区域腾出更多空间)。 我可以从窗口样式中删除WS_CAPTION | WS_SYSMENU。 但是,我无法找到正确的窗口位置和大小: 通过使用边框宽度扩展工作区矩形,可以最大化普通窗口。这使得边界“悬挂”在外面。当我删除WS\u CAPTION时,边框是不同的(在我的例子中是3对4像素),因此我必须以某种方式重新定位窗口 我所尝试的: 首先更改样式,然后最大化:这不会最大化工作区域,而是全屏显示。看起
WS_CAPTION | WS_SYSMENU
。
但是,我无法找到正确的窗口位置和大小:
通过使用边框宽度扩展工作区矩形,可以最大化普通窗口。这使得边界“悬挂”在外面。当我删除WS\u CAPTION
时,边框是不同的(在我的例子中是3对4像素),因此我必须以某种方式重新定位窗口
我所尝试的:
- 首先更改样式,然后最大化:这不会最大化工作区域,而是全屏显示。看起来这是窗口管理器的一项功能,它依赖于
样式。除此之外,边界是“悬挂”正确的WS\u CAPTION
- 首先最大化,然后更改样式、位置和大小:
- 我找不到API来获得最大的大小和位置。然而,最近的监视器的工作区域在我看来很好
- 我找不到用适当的“悬挂边框”来扩展window rect的API
几乎就在那里,但是非客户端区域与边框不同(显然它还包括标题和菜单)。我还尝试自己使用AdjustWindowRectEx
值进行计算,但这似乎太不可预测了。边框可以是GetSystemMetrics
,或者SM\u CXSIZEFRAME
+SM\u CXSIZEFRAME
,或者SM\u CXPADDEDBORDER
,这可能取决于操作系统版本、主题以及其他内容SM\u CXFIXEDFRAME
我把我自己的答案放在下面,但它太粗糙了。您已经删除了标题。如果不想显示边框,请同时删除边框。准备稍后恢复边界。找到桌面矩形,并将窗口定位到该矩形中。全屏窗口可以有
WS_重叠
或WS_弹出
标志,不带标题和边框。例如:
void switch_view()
{
RECT rc;
SystemParametersInfo(SPI_GETWORKAREA, 0, &rc, 0);
DWORD style = GetWindowLongPtr(hwnd, GWL_STYLE);
if(style & WS_CAPTION)
{
SetWindowLongPtr(hwnd, GWL_STYLE, WS_OVERLAPPED);
SetWindowLongPtr(hwnd, GWL_EXSTYLE, 0);
SetWindowPos(hwnd, NULL, 0, 0, rc.right, rc.bottom,
SWP_SHOWWINDOW | SWP_FRAMECHANGED);
}
else
{
SetWindowLongPtr(hwnd, GWL_STYLE, WS_OVERLAPPEDWINDOW);
SetWindowPos(hwnd, NULL, 0, 0, 0, 0,
SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
}
}
这是我多次尝试后得到的
- 边界问题解决了。正如其他人所建议的,我删除了带有标题的边框。因此无需计算。也不需要为带有边框的标题窗口计算边框,因为这是窗口管理器的特殊情况
- 为了获得并保持正确的大小,我使用MonitorFromWindow和GetMonitorInfo。位置和大小与样式更改(两种方式)一起应用,也在WM_大小处理程序中应用。观察WM_大小可以从外部恢复最小化还原事件,以及任务栏更改等
- 由于未知原因,使用Win+箭头键移动不起作用。此问题仅在窗口处于最大化状态且没有标题时存在。使用此解决方法:
- 在WM_WindowPos中,更改设置WS_标题样式。这允许窗口正确移动。之后,WM_大小处理程序再次应用正确的样式/位置/大小
- 失败的方法:使用还原的窗口,而不是最大化。在这种情况下,在恢复移动最大化恢复生命周期中出错太多(恢复或最大化转到错误的监视器)