Understanding Painting Behavior Differences in Windows Vista – Desktop Composition

One new feature in Windows Vista that makes a number of visual effects possible is the Desktop Window Manager. The DWM works through composition. Rather than rendering directly to the screen, applications render to their own off-screen bitmap. The DWM then takes all of these bitmaps and composites them to render to the actual screen. Because there is always a current bitmap available, the DWM can start to use this bitmap for other things. It can render it when you mouse over the entry in the task bar. It can animate the shrinking without each individual application having to implement this. It can be rendered in Alt-Tab. It can be rendered in 3D in Windows-Tab. If the application stops responding, it can still render the last known state instead of a white screen because the bitmap is independent – it doesn’t matter if another window covers it up. (Windows will, however, “frost” it to make it clear that the window isn’t really prepared to do anything useful.)

This behavior means a couple of things for existing applications. One example: you used to be able to assume that you were rendering directly to the screen. This assumption could lead you to an implementation detail that no longer works as well on Windows Vista. For example, if you assume that not rendering a pixel is the equivalent to rendering a transparent pixel, that is no longer true. Now, the compositor could very well render that pixel as black when it composites it, and I have seen that on a few applications so far.

Here is an example of an application that simply draws a star in the client area of a dialog box. It works fine without desktop composition, but with desktop composition enabled renders with a black box around the star:

#include <windows.h>
#include “resource.h”


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) {
  DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DlgProc);

BOOL CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) {

  switch (msg) {
      return TRUE;
    case WM_PAINT:
      HDC hdc = BeginPaint(hDlg, &ps);
      RECT rc;
      GetClientRect(hDlg, &rc);
      SetMapMode(hdc, MM_ANISOTROPIC);
      SetWindowExtEx(hdc, 100, 100, NULL);
      SetViewportExtEx(hdc, rc.right, rc.bottom, NULL);
      POINT aptStar[6] = {50,2, 2,98, 98,33, 2,33, 98,98, 50,2};
      SelectObject(hdc, GetStockObject(DC_PEN));
      SetDCPenColor(hdc, RGB(0x4C, 0x4C, 0x4C));
      SelectObject(hdc, GetStockObject(DC_BRUSH));
      SetDCBrushColor(hdc, RGB(0x13, 0x70, 0xAB));
      Polygon(hdc, aptStar, 6);
      EndPaint(hDlg, &ps);
      return TRUE;
      return TRUE;
      EndDialog(hDlg, TRUE);
      return TRUE;
      return FALSE;

If you wanted to custom draw something with transparency in a composited world, you actually have to render the transparent pixels explicitly.

Of course, I am somewhat unnerved by posting code that is explicitly and intentionally wrong. However, in this particular example I really couldn’t think of a way to explain the outcome without giving you the code to actually see the results both with or without the DWM enabled. In a nutshell, you no longer want to make the assumption that you are rendering directly to the screen. If you assume that you own a particular region of the screen, and render everything in that region, you will be safe whether or not what you render goes directly to the screen or goes to an off-screen bitmap.

Comments (2)

  1. Rwin says:

    Another fun example of an application that doesn’t do this right is winamp (www.winamp.com).

    Just have a look at the rendering under the taskbar versus the rendered application on screen.

  2. portrait says:

    Is this application applicable to all browsers? If the application stops responding is there anyway for me to refresh it so I could continue working on it? What is the pixel required for this application? Most of the time, if the hardware of my PC won’t work for it; it might give me more trouble.  So far I’m using one application where I could make 3D game avatars without using too much memory of my PC.