【问题标题】:Change style of maximized window更改最大化窗口的样式
【发布时间】:2018-02-18 18:58:06
【问题描述】:

我想要一个行为与普通重叠窗口相同的窗口,除了它在最大化时没有 capton bar(为客户区腾出更多空间)。 我可以从窗口样式中删除WS_CAPTION|WS_SYSMENU。 但是,我找不到正确获取窗口位置和大小的方法:

通过扩展具有边框宽度的工作区域矩形来最大化普通窗口。这使得边界“挂”在外面。当我删除 WS_CAPTION 时,边框是不同的(在我的例子中是 3 对 4 像素),所以我必须以某种方式重新定位窗口。

我尝试过的:

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

  • 先最大化,再改变样式、位置和大小:

    • 我找不到获取最大化大小和位置的 API。但是,最近的显示器的工作区对我来说看起来不错。
    • 我找不到用适当的“悬挂边框”扩展窗口矩形的 API。 AdjustWindowRectEx 几乎就在那里,但是非客户区与边框不同(显然它还包括标题和菜单)。我也尝试使用GetSystemMetrics 值自己进行数学运算,但它似乎太不可预测了。边框可能是SM_CXSIZEFRAME,或SM_CXSIZEFRAME+SM_CXPADDEDBORDER,或SM_CXFIXEDFRAME,这可能取决于操作系统版本、主题等。

是否有可能以稳健的“官方”方式做到这一点?
我把我自己的答案放在下面,但它太黑了。

【问题讨论】:

  • 我认为您实际上并不想这样做。最大化窗口的行为与全屏窗口不同,试图使它们相同是非常痛苦的 - 有很多潜在的用户混淆 - 自 Windows 95 发布以来 - 没有人成功。浏览器、媒体播放器和游戏都具有与最大化不同的全屏模式。当然,您需要自己的 UI 才能进入和离开全屏模式 - 但您要做的就是剥离所有 chrome 并调整窗口大小以完全适合全屏显示。
  • 所以我不应该保留窗口边框?这让事情变得简单多了。
  • 是的。 shell 可以理解这种全屏窗口——如果窗口的大小正好填满显示屏,shell 会在它是活动窗口时自动隐藏任务栏。
  • Raymond Chen 在他的博客上详细解释了这一点:blogs.msdn.microsoft.com/oldnewthing/20100412-00/?p=14353
  • 我看到了 oldnewthing 文章和所有的 cmets。

标签: winapi


【解决方案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);
    }
}

【讨论】:

    【解决方案2】:

    这是我多次尝试后得到的。

    • 解决了边框问题。正如其他人所建议的,我将边框与标题一起删除。因此无需计算。带边框的标题窗口也不需要计算边框,因为这是窗口管理器的特殊情况。

    • 为了获得并保持正确的大小,我使用 MonitorFromWindow 和 GetMonitorInfo。位置和大小与样式更改(两种方式)以及 WM_SIZE 处理程序一起应用。观看 WM_SIZE 可以从外部最小化还原事件以及任务栏更改等中恢复。

    • 由于未知原因,使用 Win+箭头键无法移动。此问题仅在窗口处于最大化状态且没有标题时存在。使用此解决方法:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-14
      • 1970-01-01
      • 1970-01-01
      • 2015-07-21
      相关资源
      最近更新 更多