Custom Draw Window Title

Posted on 1997-12-06
Medium Priority
Last Modified: 2008-02-01
As the title described, I wanted to draw the window title by myself. Just like Microsoft Word 7.0 and Norton AntiVirus. Their window title change from black to my title color from the left to the right.

If possible, also tell me how to draw the menu bar by my self.
Question by:sccheung
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3

Accepted Solution

galkin earned 150 total points
ID: 1175023
You must handle several non client messages and perform your custom non client painting after processing default painting.
To get device contaext call GetWindowDC() or, if you are programming in VC++ create instance of CWindowDC class
CWindowDC dc(this). Remember when wrting code for WM_NCPAINT you must first call default non client painting implementation to draw other parts of non client area like window borders etc. If you are programming in VC++ call Default() function to do this and then create instance of CWindowDC.

Author Comment

ID: 1175024
I've tried to override OnNcPaint and OnNcActivate. But there is no change!
I declare them:

// Generated message map functions
      afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
      afx_msg void OnNcPaint();
      afx_msg BOOL OnNcActivate(BOOL bActive);

and then write the code:

void CMainFrame::OnNcPaint()
      CWindowDC dc(this);
      CRect WinRect = CRect::CRect();
      dc.FillRect(WinRect, CBrush::FromHandle((HBRUSH)GetStockObject(BLACK_BRUSH)));

BOOL CMainFrame::OnNcActivate(BOOL bActive)
      CWindowDC dc(this);
      CRect WinRect = CRect::CRect();
      dc.FillRect(WinRect, CBrush::FromHandle((HBRUSH)GetStockObject(BLACK_BRUSH)));
      return true;

But the window frame doesn't turn black. Have I wrote anything wrong or I should handle more messages? If possible, please give me some sample code.

Expert Comment

ID: 1175025
I am sorry I guess(I am sorry if I am mistaken) you didn't add message macros to cpp file. Since you code seems correct. Set breakpoint in OnNcPaint and check whether debugger stops at it.
And also instead of Default function in this case call base class message handlers(CFrameWnd::OnNcPaint(), CFrameWnd::OnNcActivate()).
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!


Author Comment

ID: 1175026
I've tried to set a breakpoint in OnNcPaint. It doesn't stop. My code isn't executed at all. The window just continue painting with the default painting function.

Author Comment

ID: 1175027
What can I do now?

Expert Comment

ID: 1175028
Do the following:
1.Add afx_msg OnNcPaint() and afx_msg OnNcActivate(BOOL bActivate) message handlers to your frame class declaration.

2.Add ON_WM_NCPAINT() and ON_WM_NCACTIVATE() macros between

I guess you didn't add these macros so you failed in catching these messages

Add these messages handler implementations like

void CMainFrame::OnNcPaint()
      // Let Windows do what it usually does. Let the window
       // caption
       // be empty to avoid any Windows-initiated caption bar
       // drawing

      CWindowDC dc(this);

      CRect rc2, rc1;
    GetWindowRect(&rc2 );

      int x, y;
    // Compute the caption bar's origin. This window has a system box
    // a minimize box, a maximize box, and has a resizeable frame
       x = GetSystemMetrics( SM_CXSIZE ) +
           GetSystemMetrics( SM_CXBORDER ) +
           GetSystemMetrics( SM_CXFRAME );
       y = GetSystemMetrics( SM_CYFRAME );
         rc1.left = x;
       rc1.top = y;

    // 2*x gives twice the bitmap+border+frame size. Since there are
    // only two bitmaps, two borders, and one frame at the end of the
    // caption bar, subtract a frame to account for this.
       rc1.right = rc2.right - rc2.left - 2*x -
                   GetSystemMetrics( SM_CXFRAME );
       rc1.bottom = GetSystemMetrics( SM_CYSIZE );
    // Render the caption. Use the active caption color as the text
    // background.
         dc.FillSolidRect(&rc1, 0x000000);
       dc.DrawText((LPSTR)"Left Justified Caption", -1,
               (LPRECT)&rc1, DT_LEFT );

BOOL CMainFrame::OnNcActivate(BOOL bActivate)
      // Add code here to draw caption when window is inactive.
         return TRUE;

// Fall through if wParam == TRUE, i.e., window is active.    

This code is not perfect, for instance there is filickering while drawing caption etc. but you can perform your custom painting.

I also refere you to Microsoft knowlege base article Q99046


Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
Suggested Courses

719 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question