1

几年前,我们开发了一个名为 CaptionX(CaptionX 主页)的 ActiveX 组件。它允许开发人员将自定义的可点击图形按钮放置到窗口标题栏中。当 Aero Glass 开启时,在除 Vista 和 Windows 7 之外的任何 Windows 中一切正常 - 绘制带有自定义图标的标题栏,就像我们使用 Windows Basic 主题一样,没有窗口边框的透明效果。

人们希望在最新版本的操作系统中使用 CaptionX,但我们无法使其正常工作。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 调用,如果需要,在哪里?

4

2 回答 2

0

您的调用可能有错误,您不应将普通的 DWMNCRP_ENABLED 值传递给 API,而应传递 DWMNCRENDERINGPOLICY 结构的 ref。

于 2012-02-04T16:01:30.133 回答
0

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

关于 Aero Basic 窗框的常见问题

相关摘录如下:

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

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

于 2016-03-17T08:19:57.813 回答