BUG: The gripper bar is drawn incorrectly when an MFC application uses Windows XP Visual Styles (843490)



The information in this article applies to:

  • The Microsoft Foundation Classes (MFC), when used with:
    • Microsoft Visual C++, 32-bit Enterprise Edition 6.0, when used with:
      • the operating system: Microsoft Windows XP

SYMPTOMS

You may notice that the gripper bar on the toolbar is not drawn by using the background color of the toolbar when all the following conditions are true:
  • You are working on a computer that is running Microsoft Windows XP.
  • You are running a Single-document interface (SDI) application or a Multiple-document interface (MDI) application that was developed by using Microsoft Visual C++ 6.0 and the Microsoft Foundation Classes (MFC) libraries.
  • You are trying to implement Windows XP Visual Styles in your MFC application by adding a manifest file.
Note You do not notice this behavior if your application does not implement Windows XP Visual Styles. Also, you do not notice this behavior if you use CReBar class-derived control bars instead of CToolBar class-derived control bars.

The gripper bar is drawn with the color of the desktop or by using the background color of the application instead of the background color of the toolbar.

CAUSE

When your application uses a manifest file to implement Windows XP Visual Styles, the gripper bar on the toolbar is drawn by using the color of the desktop or by using the background color of your application.

RESOLUTION

To draw the gripper bar correctly, you must add a new class that is derived from the CToolBar class in your code, you must override different methods of the CToolBar class, and you must use the derived class member.

The following steps are an overview of what you will do in this section to resolve this problem:
  1. Sub-class the CToolBar class.
  2. Override the DrawGripper method and the DoPaint method of the base class.
  3. Handle the OnNcPaint message.
  4. Use the derived class member variable instead of the CToolBar class member variable.
To do this, follow these steps.

Note The following procedure is based on the 828548VC6 sample project that is mentioned in the "More Information" section.
  1. Start Microsoft Visual Studio 6.0.
  2. Open the 828548VC6 project in Visual Studio 6.0.
  3. In the Workspace window, click the FileView tab.
  4. Expand the Header Files folder, and then double-click the Mainfrm.h file.

    The Mainfrm.h file opens in the code editor.
  5. Add the following code before the CMainFrame class definition.
    class CMyToolBar : public CToolBar
    {
    public:
    	void DrawGripper(CDC* pDC, const CRect& rect);
    	void EraseNonClient();
    	virtual void DoPaint(CDC* pDC);
    
    protected:
    
    	//{{AFX_MSG(CMyToolBar)
    	afx_msg void OnNcPaint();
    	//}}AFX_MSG
    	
    	DECLARE_MESSAGE_MAP()
    };
  6. In the code editor, locate the following code.
    CToolBar    m_wndToolBar;
  7. Replace the code that you located in step 6 with the following code.
    CMyToolBar    m_wndToolBar;
  8. In the Workspace window, expand the Source Files folder on the FileView tab, and then double-click the Mainfrm.cpp file.
  9. Add the following code after the compiler directives at the top of the code editor.
    //////////////////////////////////////////////////////
    // CMyToolBar
    
    BEGIN_MESSAGE_MAP(CMyToolBar, CToolBar)
    	//{{AFX_MSG_MAP(CMyToolBar)
    	ON_WM_NCPAINT()
    	//}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    
    void CMyToolBar::OnNcPaint() 
    {
    	EraseNonClient();
    }
    void CMyToolBar::EraseNonClient()
    {
    
    	// Get window DC that is clipped to the non-client area.
    	CWindowDC dc(this);
    	CRect rectClient;
    	GetClientRect(rectClient);
    	CRect rectWindow;
    	GetWindowRect(rectWindow);
    	ScreenToClient(rectWindow);
    	rectClient.OffsetRect(-rectWindow.left, -rectWindow.top);
    	dc.ExcludeClipRect(rectClient);
    
    	// Draw the borders in the non-client area.
    	rectWindow.OffsetRect(-rectWindow.left, -rectWindow.top);
    	DrawBorders(&dc, rectWindow);
    
    	// Erase the parts that are not drawn.
    	dc.IntersectClipRect(rectWindow);
    	SendMessage(WM_ERASEBKGND, (WPARAM)dc.m_hDC);
    
    	// Draw the gripper in the non-client area.
    	DrawGripper(&dc, rectWindow);
    }
    
    void CMyToolBar::DoPaint(CDC* pDC)
    {
    	ASSERT_VALID(this);
    	ASSERT_VALID(pDC);
    
    	// Paint inside the client area.
    	CRect rect;
    	GetClientRect(rect);
    	DrawBorders(pDC, rect);
    	DrawGripper(pDC, rect);
    }
    
    void CMyToolBar::DrawGripper(CDC* pDC, const CRect& rect)
    {
    	pDC->FillSolidRect( &rect, ::GetSysColor(COLOR_BTNFACE)); // Fill in the background.
    	CToolBar::DrawGripper(pDC,rect);
    }
    /////////////////////////////////////////////////////////////////////////
  10. Press F7 to build your application.
  11. Press CTRL+F5 to run your application.
You do not notice the behavior that is mentioned in the "Symptoms" section.

STATUS

Microsoft has confirmed that this is a bug in the Microsoft products that are listed in the "Applies to" section.

MORE INFORMATION

Steps to reproduce the problem

To create an MFC-SDI application or an MFC-MDI application, follow these steps:
  1. Click Start, point to All Programs, and then point to Microsoft Visual Studio 6.0.
  2. Click Microsoft Visual C++ 6.0. The Microsoft Visual Studio IDE for Visual C++ opens.
  3. On the File menu, click New. The New dialog box appears.
  4. On the Projects tab, click MFC AppWizard (exe).
  5. In the Project name box, type 828548VC6.
  6. In the Location box, type C:\, and then click OK.
  7. In the MFC AppWizard - Step 1 dialog box, click either Single document or Multiple documents, and then click Finish.
  8. In the New Project Information dialog box, click OK.
  9. Implement Windows XP Visual Styles:
    1. In a text editor such as Notepad, paste the following XML code.
      <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
        <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> 
        <description>Character Map application</description> 
        <dependency> 
            <dependentAssembly> 
                <assemblyIdentity 
                    type="win32" 
                    name="Microsoft.Windows.Common-Controls" 
                    version="6.0.0.0" 
                    processorArchitecture="X86" 
                    publicKeyToken="6595b64144ccf1df" 
                    language="*" 
                /> 
            </dependentAssembly> 
        </dependency> 
        </assembly>
    2. Save the document in the Debug folder. Name the document 828548VC6.exe.manifest. The Debug folder is located in the 828548VC6 folder of your project.

      Note You must save the document in the Debug folder because the manifest file must exist in the same folder as the executable file.
  10. Press F7 to build the application.
  11. Press CTRL+F5 to run the application.
You notice the behavior that is mentioned in the "Symptoms" section.

back to the "Resolution" section

REFERENCES

For more information, visit the following Microsoft Developer Network (MSDN) Web sites:

Modification Type:MajorLast Reviewed:6/22/2004
Keywords:kbgraphic kbdraw kbRebarCtrl kbMDI kbAppWizard kbcode kbbug KB843490 kbAudDeveloper