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

时间:2012-02-02 12:17:13

标签: vb6 aero aero-glass custom-draw

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

人们希望在最新版本的操作系统中使用CaptionX,但我们无法使其正常运行。 互联网上的所有搜索都告诉我们,当我们使用带有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调用,如果是这样的话?

2 个答案:

答案 0 :(得分:0)

您的调用可能存在错误,您不应将简单的DWMNCRP_ENABLED值传递给API,而是应传递DWMNCRENDERINGPOLICY结构的引用。

答案 1 :(得分:0)

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

Frequently asked questions about the Aero Basic window frame

相关摘录如下:

  

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

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