【问题标题】:Borderless Window Using Areo Snap, Shadow, Minimize Animation, and Shake使用 Areo Snap、阴影、最小化动画和抖动的无边框窗口
【发布时间】:2013-05-21 20:39:29
【问题描述】:

我正在 Windows 上制作一个带有无边框窗口的应用程序。但是,由于窗口是无边框的,所以我没有区域阴影、捕捉、最小化动画或抖动。我环顾四周,发现没有解释如何实现这一点的网站。但是,我知道这是可能的,因为 Office 2013、Visual Studio 2012 和 Steam 都具有这些功能并且是无边界的。我专门使用 QT 和 C++,但如果你已经为另一个窗口库解决了这个问题,我也想听听你的解决方案。任何一个。我所说的区域阴影并不是指两侧的阴影,而是指所有活动的本地区域窗口应用程序的所有侧面的发光阴影。

【问题讨论】:

  • 我阅读了 DWMWA_ALLOW_NCPAINT。所以 2013 和 VS2012 的字在边界上画出来隐藏它?
  • 很多人都在寻找这个问题的答案,正如我所看到的。不久前我是他们中的一员。我尝试了已经在这篇文章中回答的实现,但由于它们不完全适合的原因。经过一段时间的谷歌搜索和修改 deimos1877 的 BodrelessWindow 示例,我最终为 Qt 找到了更轻量级的解决方案。这是一个只有 QMainWindow 的简单 Qt 项目。随意使用并根据您的需要采用它。主要优点是 - Qt 窗口和本机 WinAPI 之间没有代理类,在 Aero 关闭时没有窗口标题闪烁。 bitbucket.org/artem_bodrin/framless

标签: c++ windows qt aero borderless


【解决方案1】:

在使用 Spy++ 检查 Steam 的窗口(它的窗口样式、它如何回复窗口消息)并尝试匹配它所做的一切,并结合来自此 C# borderless window behavior 的 DWMAPI 调用后,我相信我想通了。

要隐藏窗口的边框,请在 WindowProc 中处理 WM_NCCALCSIZE 消息:

case WM_NCCALCSIZE: {
    if (window->is_borderless) {
        return 0;
    } else {
        return DefWindowProc(hwnd, msg, wparam, lparam);
    }
}

要启用阴影,您需要做的就是:

MARGINS borderless = {1,1,1,1};
DwmExtendFrameIntoClientArea(hwnd, &borderless);

要关闭它,请恢复默认边距MARGINS windowed = {0,0,0,0};。 或许也可以输入SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_ASYNCWINDOWPOS | SWP_NOSIZE | SWP_NOMOVE );,以确保框架被重绘。

但是,这似乎不适用于所有窗口样式,显然您的窗口样式不能包含标题栏。标题栏可以正常工作,添加一个似乎可以启用最小化动画。

我使用阴影的最简单的窗口样式是WS_POPUP | WS_THICKFRAME,同时我还使用了WS_POPUP | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CAPTION 的aero snap、最大化、最小化和平滑最小化动画。

似乎不需要通过DwmSetWindowAttribute 更改DWMWA_NCRENDERING_POLICYDWMWA_ALLOW_NCPAINT,默认设置似乎有效。

提醒一句:DwmExtendFrameIntoClientArea 完全符合其名称的含义,因此,如果您将带有 alpha 通道的图像直接绘制到您的客户区域(例如使用 opengl、direct3d/2d),则会看到一个小框架通过它:

所以你可能不得不在透明元素后面放置一个不透明的小部件、画笔或其他东西。

如果一切顺利,它应该是这样的:

Here is a small example project,F11 切换无边框/窗口模式,F12 打开和关闭无边框阴影。

【讨论】:

  • Steam 仍然有与 Aero 相同的阴影。它也有 Aero Snap/Shake/Stuff,但缺少最小化动画。
  • @RandomUser 我的解决方案除了最小化过渡之外的所有事情 - 使阴影工作所需的窗口样式的结果。甚至 Outlook 2013 也缺少这一点,所以我不相信它是可能的,而不像 Visual Studio 那样伪装它。 (有时您可以看到窗口框架在“客户”区域内变得可见 - 所以它们确实似乎在框架上绘制)
  • Visual Studio 的最小化动画看起来就像一个带边框的窗口。他们只是在伪装方面做得很好吗?知道我们如何去伪造它吗?
  • 看起来是这样的。不过,我认为要获得最小化动画需要付出很多努力-您不会获得航空阴影;您必须绘制 your own shadow/glow 而不是框架。此外,可能有很多特殊情况需要处理,以保持边境的欺骗不存在。说,确保 Alt+PrintScreen 仅捕获客户区域而不是框架,用于航空捕捉的窗口大小(因此由于透明边框而没有间隙)...
  • 我认为除了最小化动画之外的所有内容。
【解决方案2】:

感谢 melak47 的回答。

对于正在寻找 C++/Qt 示例的人来说,这个 GitHub profect 基于 melak47 代码完成了这项工作(感谢 deimos1877)! https://github.com/deimos1877/BorderlessWindow

请务必使用 Visual Studio 编译器 (>= 2010) 来获取所需的 DLL,它应该可以工作。 此示例包括 aerosnap 支持、无边框窗口、最小化效果、aero 阴影。

【讨论】:

  • 我想说,这是最好的答案,希望新人来这里使用这个演示。
  • 使用 Qt5.8 在第 257 行的 qwinhost.cpp 中出现编译器错误,抱怨找不到 qWinAppInst() 标识符。 qWinAppInst() 已从 Qt5.8 中的 QtCore 中删除(请参阅 here),因此您必须将其替换为 GetModuleHandle(0)
【解决方案3】:

我已经创建了一个响应为 Photoshop。

BorderlessWindowQt-Modern-Gui

【讨论】:

  • 我没有说否决票,我只是想告诉你,链接应该只是支持,因为如果链接被破坏,你的答案就没有用了
  • GPL2。我更喜欢自己实现。
  • 它运行良好,如果有人有机会改进它等等。他很受欢迎。
猜你喜欢
  • 2012-11-05
  • 2017-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-22
  • 1970-01-01
  • 2012-02-15
  • 2020-07-09
相关资源
最近更新 更多