Custom Draw Window Title

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.
sccheungAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

galkinCommented:
You must handle several non client messages and perform your custom non client painting after processing default painting.
These messages are WM_NCPAINT, WM_NCACTIVATE and WM_SYSCOMMAND.
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.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
sccheungAuthor Commented:
I've tried to override OnNcPaint and OnNcActivate. But there is no change!
I declare them:

// Generated message map functions
protected:
      //{{AFX_MSG(CMainFrame)
      afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
      afx_msg void OnNcPaint();
      afx_msg BOOL OnNcActivate(BOOL bActive);
      //}}AFX_MSG
      DECLARE_MESSAGE_MAP()

and then write the code:

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

BOOL CMainFrame::OnNcActivate(BOOL bActive)
{
      CWindowDC dc(this);
      CRect WinRect = CRect::CRect();
      GetWindowRect(WinRect);
      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.
0
galkinCommented:
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()).
0
Cloud Class® Course: Microsoft Office 2010

This course will introduce you to the interfaces and features of Microsoft Office 2010 Word, Excel, PowerPoint, Outlook, and Access. You will learn about the features that are shared between all products in the Office suite, as well as the new features that are product specific.

sccheungAuthor Commented:
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.
0
sccheungAuthor Commented:
What can I do now?
0
galkinCommented:
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
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) and END_MESSAGE_MAP()

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

3.
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
    CFrameWnd::OnNcPaint();

      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.SetBkColor(GetSysColor(0x000000));
         dc.SetTextColor(0xFF0000);
         dc.SetBkMode(TRANSPARENT);
         dc.FillSolidRect(&rc1, 0x000000);
       dc.DrawText((LPSTR)"Left Justified Caption", -1,
               (LPRECT)&rc1, DT_LEFT );
        
}

BOOL CMainFrame::OnNcActivate(BOOL bActivate)
{
if(!bActivate)
 {
   CFrameWnd::OnNcActivate(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

0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.