31

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

4

3 回答 3

42

在使用 Spy++ 检查 Steam 的窗口(它的窗口样式,它如何回复窗口消息)并尝试匹配它所做的一切,并结合来自这个C# 无边框窗口行为的 DWMAPI 调用之后,我相信我想通了。

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

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,还获得了 aero snap、最大化、最小化和我使用的平滑最小化动画WS_POPUP | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CAPTION

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

提醒一句:DwmExtendFrameIntoClientArea正如其名称所暗示的那样,因此,如果您将带有 alpha 通道的图像直接绘制到您的客户区域(例如使用 opengl、direct3d/2d),则可以通过它看到一个小框架:

在客户区显示阴影和框架的无边框窗口

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

如果一切顺利,它应该如下所示:

在此处输入图像描述

这是一个小示例项目,F11 切换无边框/窗口模式,F12 打开和关闭无边框阴影。

于 2013-07-18T03:02:20.817 回答
11

感谢 melak47 的回答。

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

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

于 2014-08-06T12:17:23.263 回答
1

我创建了一个响应为 Photoshop 的。

BorderlessWindowQt-Modern-Gui

图像真正的无边框窗口Qt

于 2018-01-15T17:20:59.307 回答