更改最大化窗口的样式

时间:2018-02-18 18:58:06

标签: winapi

我想要一个窗口,其行为与普通的重叠窗口相同,只是在最大化时没有加盖条(为客户区域腾出更多空间)。 我可以从窗口样式中删除WS_CAPTION|WS_SYSMENU。 但是,我无法找到合适的窗口位置和尺寸:

通过扩展边框宽度的工作区矩形来最大化普通窗口。这使得边界成为"挂起"外。当我删除WS_CAPTION时,边框不同(在我的情况下为3对4像素),所以我必须以某种方式重新定位窗口。

我尝试过:

  • 首先更改样式,然后最大化:这不会最大化到工作区域,而是全屏显示。看起来这是窗口管理器的一个功能,它依赖于WS_CAPTION样式。除此之外,边界是"悬挂"正确。

  • 首先最大化,然后改变风格,位置和大小:

    • 我找不到API来获得最大化的尺寸和位置。但是,最近的显示器的工作区对我来说很好。
    • 我无法通过适当的"悬挂边框"找到扩展窗口rect的API。 AdjustWindowRectEx几乎就在那里,但是非客户区域与边框不同(显然它还包括标题和菜单)。我也尝试使用GetSystemMetrics值自己做数学运算,但似乎太难以预测了。边框可以是SM_CXSIZEFRAME,或SM_CXSIZEFRAME + SM_CXPADDEDBORDERSM_CXFIXEDFRAME,也许这取决于操作系统版本,主题等等。

是否有可能在一个健全的官员"方法是什么?
我在下面给出了自己的答案,但它太过黑了。

2 个答案:

答案 0 :(得分:1)

您已经删除了标题。如果您不想显示边框,也请删除边框。准备好以后恢复边界。找到桌面矩形,并将窗口放入该矩形。全屏窗口可以有WS_OVERLAPPEDWS_POPUP标记,没有标题且没有边框。例如:

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);
    }
}

答案 1 :(得分:0)

这是我经过多次尝试后得到的结果。

  • 边界问题已解决。正如其他人所建议的那样,我删除边框和标题。因此无需计算它。也没有必要计算带边框的标题窗口的边框,因为这是由窗口管理器特殊设置的。

  • 为了获得并保持正确的大小,我使用MonitorFromWindow和GetMonitorInfo。位置和大小与样式更改(双向)以及WM_SIZE处理程序一起应用。观察WM_SIZE允许从外部最小化恢复事件以及TaskBar更改等中恢复。

  • 由于未知原因,使用Win +箭头键移动不起作用。仅当窗口处于最大化状态且没有标题时才会出现此问题。使用此解决方法:

    • 在WM_WINDOWPOSCHANGING中设置WS_CAPTION样式。这允许窗口正确移动。之后,WM_SIZE处理程序再次应用正确的样式/位置/大小。
    • 失败的方法:使用恢复的窗口而不是最大化。在这种情况下,restore-move-maximize-restore生命周期中出现了太多错误(恢复或最大化会导致错误的监视器)。