在自定义绘制的窗口标题中启用 Aero Glass(WM_NCPAINT、DwmSetWindowAttribute)

发布于 2025-01-01 23:14:17 字数 1103 浏览 0 评论 0 原文

几年前,我们开发了一个 ActiveX 组件,允许开发人员将自定义的可点击图形按钮放入窗口标题栏中。 当打开 Aero Glass 时,除了 Vista 和 Windows 7 之外,所有 Windows 都可以正常工作 - 带有自定义图标的标题栏的绘制方式就像我们使用 Windows Basic 主题一样,而没有窗口边框的透明效果。

人们希望在最新版本的操作系统中使用此 ActiveX,但我们无法使其发挥作用。 Internet 上的所有搜索都告诉我们,当我们使用带有 DWMWA_NCRENDERING_POLICY 属性的 DwmSetWindowAttribute API 调用在窗口标题中使用自定义绘图时,需要启用 Aero Glass,但我们尚未设法使其工作。

我们在窗口的非客户端表面上绘制的代码如下所示(抱歉 - 这是旧的 VB6:):

Friend Function WindowProc(ByVal lPrevWndProc As Long, ByVal hwnd As Long, ByVal iMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
   
   Select Case iMsg

   Case WM_NCPAINT
      DoNCPaint lPrevWndProc, wParam
      WindowProc = 0
      Exit Function

   Case WM_...
      ' Other message handlers

   End Select
   
   WindowProc = CallWindowProc(lPrevWndProc, hwnd, iMsg, wParam, lParam)
End Function

我们在代码中的许多地方添加了以下调用

DwmSetWindowAttribute m_hwnd, DWMWA_NCRENDERING_POLICY, DWMNCRP_ENABLED, 4

,但它没有任何效果。如果使用 DwmSetWindowAttribute 在窗口中默认使用 Aero Glass 效果,我们可以禁用它,但无法启用它。

我们做错了什么?我们是否需要在代码中添加更多 API 调用?如果需要,在哪里添加?

Some years ago we developed an ActiveX component allowing the developers to place custom clickable graphical buttons into the window title bar.
All works fine in any Windows except Vista and Windows 7 when Aero Glass is turned on - the title bar with our custom icons is drawn as if we used the Windows Basic theme without the transparency effect for the window borders.

People would like to use this ActiveX in the latest versions of the OS, but we cannot make it work.
All searches on the Internet tell us we need to enable Aero Glass when we use custom drawing in the window title using the DwmSetWindowAttribute API call with the DWMWA_NCRENDERING_POLICY attribute, but we have not managed to make it work.

Our code that draws on the window's non-client surface looks like this (sorry - it's the old VB6 :):

Friend Function WindowProc(ByVal lPrevWndProc As Long, ByVal hwnd As Long, ByVal iMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
   
   Select Case iMsg

   Case WM_NCPAINT
      DoNCPaint lPrevWndProc, wParam
      WindowProc = 0
      Exit Function

   Case WM_...
      ' Other message handlers

   End Select
   
   WindowProc = CallWindowProc(lPrevWndProc, hwnd, iMsg, wParam, lParam)
End Function

We added the following call

DwmSetWindowAttribute m_hwnd, DWMWA_NCRENDERING_POLICY, DWMNCRP_ENABLED, 4

to many places in our code, but it does not have any effect. We can disable the Aero Glass effect if it is used by default in a window using DwmSetWindowAttribute, but cannot enable it.

What are we doing wrong? Do we need to add more API calls to our code, and if so where?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

泼猴你往哪里跑 2025-01-08 23:14:17

您的调用可能存在错误,您不应将普通的 DWMNCRP_ENABLED 值传递到 API 中,而应传递 DWMNCRENDERINGPOLICY 结构的引用。

There may be a mistake on your calling, you should not pass a plain DWMNCRP_ENABLED value into the API, instead, you should pass a ref of a DWMNCRENDERINGPOLICY structure.

寂寞美少年 2025-01-08 23:14:17

这种旧方法在从 Vista 开始的最新版本的 Windows 中不起作用,因为新的桌面窗口管理器 (DWM) 负责绘制窗口框架。这也是在 web.archive.org 中发现的一个有趣的博客,它解释了问题的本质:

有关 Aero Basic 窗框的常见问题

相关摘录如下:

DWM 没有任何遗留问题,因为应用程序无法
在玻璃框架内绘制,因为它是由一个渲染和管理的
完全不同的过程。如果应用程序尝试执行此操作,Windows
将检测到它并完全移除玻璃框架(因此
恢复到基本框架),以便应用程序可以绘制它所需要的内容
想画画。

要在Windows Vista、7等中修改窗口标题栏,我们需要使用新的 DWM API

This old approach does not work in latest versions of Windows starting from Vista because of the new Desktop Window Manager (DWM) responsible for drawing the window frame. Here is also one interesting blog found in the web.archive.org that explains the nature of the problem:

Frequently asked questions about the Aero Basic window frame

The pertinent excerpt is the following:

The DWM doesn't have any legacy worries because applications cannot
draw inside the glass frame, since it's rendered and managed by a
totally different process. If an application tries to do it, Windows
will detect it and remove the glass frame entirely (and therefore
revert to the Basic frame), so that the application can draw what it
wants to draw.

To modify the window title bar in Windows Vista, 7 and so on, we need to use the new DWM API.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文