1

Some years ago we developed an ActiveX component called CaptionX (CaptionX Home Page). It allows 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 CaptionX in the latest versions of the OS, but we cannot make it working. All searches in 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 working.

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?

10Tec
  • 11
  • 2
  • 5

2 Answers2

0

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.

TecMan
  • 2,743
  • 2
  • 30
  • 64
0

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.

  • The declaration for DwmSetWindowAttribute looks like this: 'Public Declare Function DwmSetWindowAttribute Lib "dwmapi.dll" (ByVal hWnd As Long, ByVal dwAttribute As Long, ByRef pvAttribute As Long, ByVal cbAttribute As Long) As Long' , so the 3rd parameter is passed by reference. And DWMWINDOWATTRIBUTE (not DWMNCRENDERINGPOLICY as you wrote) is in fact an integer flag. And this call works for the "disable" flag :) – 10Tec Feb 06 '12 at 08:47
  • http://msdn.microsoft.com/en-us/library/windows/desktop/aa969524%28v=vs.85%29.aspx – Dandy Cheung Feb 21 '12 at 16:11
  • Read my answer why `DwmSetWindowAttribute` can't help. – TecMan Mar 17 '16 at 08:20