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



几年前,我们开发了一个名为CaptionX(CaptionX主页)的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

到我们代码中的许多地方,但它没有任何效果。如果Aero Glass效果在使用DwmSetWindowAttribute的窗口中默认使用,我们可以禁用它,但不能启用它。

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

您的调用可能有错误,您不应该将普通的DWMNCRP_ENABLED值传递到API中,而是应该传递DWMNCRNDERINGPOLICY结构的ref。

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

关于Aero Basic窗框的常见问题

相关摘录如下:

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

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

相关内容

  • 没有找到相关文章

最新更新