MFC Feature pack and desktop composition issue

MFC Feature pack applicationmakes it possible to mimic the look and feel of office and outlook, however, when it comes to customization, well, one has to make a few changes to the application to get the desired result.

Problem

I came across a scenario where an MFC feature application carrying office 2007 style look-n-feel fails to repaint and resize properly when the Desktop composition feature of another application is changed on the Vista/windows 7 machine.

To give a little background on windows Desktop Manager, desktop composition feature was introduced in Windows Vista/WIN7 which fundamentally changed the way applications display pixels on the screen. When desktop composition is enabled, individual windows no longer draw directly to the screen or primary display device as they did in previous versions of Windows. Instead, their drawing is redirected to off-screen surfaces in video memory, which are then rendered into a desktop image and presented on the display.

Desktop composition is performed by the Desktop Window Manager (DWM). Through desktop composition, DWM enables visual effects on the desktop as well as various features such as glass window frames, 3-D window transition animations, Windows Flip and Windows Flip3D, and high resolution support. Details of Desktop window manager is described in this article.

msdn.microsoft.com/en-us/library/aa969538(VS.85).aspx

Cause

WM_DWMCOMPOSITIONCHANGED message is sent to all top-level windows when Desktop Window Manager (DWM) composition has been enabled or disabled. Now, this has a wired effect on the MFC applications, resulting in resize and repaint issues. The issue occurs as the global app state gets corrupted when the desktop composition of the other application is changed and the CMDIFrameWndEx class does not handle the WM_DWMCOMPOSITIONCHANGED message.

Resolution

 In order to fix the issue, we need to handle WM_DWMCOMPOSITIONCHANGED message in the CMainFrame class.

 

Below is the correct handler that fixes the issue.

 

<code Snip>

 

void CMainFrame::OnCompositionChanged()

{

    CMDIFrameWndEx::OnDWMCompositionChanged(0, 0);

    if (afxGlobalData.DwmIsCompositionEnabled())

    {

        SetWindowRgn(NULL, TRUE);

    }

 m_Impl.OnChangeVisualManager();

}

 

<Code snip>

OnChangeVisualManager() call will recalculate the main frame layout and redraw it completely, which is what needs to happen in this situation.

By adding the following handler we make sure that the desktop composition is enabled and our app works fineJ.

Thanks,

Ganesh S