• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1858
  • Last Modified:

How to add buttons to title bar of CFrameWnd?

I would like to add buttons to the title bar of a CFrameWnd.  Anyone know how to do this?  If there is nothing straightforward, how can I change the client area of the frame in order to draw on the title bar?  Thanks.
1 Solution
you can paint frame and caption by self.
need sample for CDialog ?
Add the code to create button in OnNcCreate function in CMainFrame Class.
In the function check nHitTest = HTCAPTION before adding the code.
Try with this.
Mourneblade, I have a complete answer to your question, but its quite long and I was hoping you could increase the points... 50 is too little :)
This source code demonstrates how you can add buttons to dialog caption bar and also how you can paint the caption.

A lot of peoples asked me to show how they can add buttons to the caption. Of course, first the question is:
Is it possible to add buttons to the non-client area?
The answer is NO.
So what is this article about? Well, this demo shows how to add buttons to the non-client area.
I'll answer your question anyway...

To have a button in the title bar, you'd need to create a 'pseudo' button. We would have to process the mouse messages and draw the button ourselves...

First of all, since we're drawing our own button, we'd need two bitmaps... One for the button-up state amd the other for the button-down state. Give the bitmaps a dimension of 16x16(I assume you're app is a regular window, not a tool window). I'll use IDB_BUTTONUP and IDB_BUTTONDOWN for this example.

First, declare a few variables in your header file, as public :

//Start of code

class CYourDlg : public CDialog
// Construction
   CYourDlg(CWnd* pParent = NULL);      // standard constructor

   //Add these
   void DrawCapButton();
   void GetButtonRect( CRect &rect );  
   bool m_bPressed;
   CBitmap m_bitmapPressed;
   CBitmap m_bitmapUnpressed;


//End of code

In the constructor of your dialog class, load the two bitmaps :

//Start of code

CYourDlg::CYourDlg(CWnd *pParent ) : CDialog( CYourDlg::IDD, pParent )
   //Add these
   m_bPressed = FALSE;
   m_bitmapPressed.LoadBitmap( IDB_BUTTONDOWN );
   m_bitmapUnpressed.LoadBitmap( IDB_BUTTONUP );

//End of code

Then, using the ClassWizard, add the WM_NCPAINT and the WM_ACTIVATE message handlers to your class. Modify them and add the DrawCapButton and GetButtonRect functions as well :

//Start of code
void CYourDlg::OnNcPaint()
   //Add this

void CYourDlg::OnActivate( UINT nState, CWnd* pWndOther, BOOL bMinimized )
   //Add this

void CYourDlg::DrawCapButton()

   //Skip if window is not visible or minimized
   if( !IsWindowVisible() || IsIconic() ) return;
   //Get the bitmap
   CDC memDC;
   CDC* pDC = GetWindowDC();
   memDC.CreateCompatibleDC( pDC );
   memDC.SelectObject( m_bPressed ? &m_bitmapPressed : &m_bitmapUnpressed );
   //Convert button rect into non-client area coordinates
   CRect rect, rectWnd;
   rect.OffsetRect( -rectWnd.left, -rectWnd.top );
   pDC->StretchBlt( rect.left, rect.top, rect.Width(),
                    rect.Height(). &memDC, 0, 0, 16, 16, SRCCOPY );
   //Clean up
   ReleaseDC( pDC );

void CWinsysDlg::GetButtonRect(CRect& rect)

      rect.top += GetSystemMetrics(SM_CYFRAME)+1;            
      rect.bottom = rect.top + GetSystemMetrics(SM_CYSIZE)-4;      
                rect.left = rect.right - GetSystemMetrics(SM_CXFRAME) -             ( 4 * GetSystemMetrics(SM_CXSIZE))-1;
                //Replace 4 with the current number of buttons in your caption + 1

      rect.right = rect.left + GetSystemMetrics(SM_CXSIZE)-3;      

Okay, now you'd want to activate your button :

//Start of Code
//In .h file

// Generated message map functions
afx_msg void OnNcLButtonDown( UINT nHitTest, CPoint point ); //Add this

//In .cpp file
//Add to message map


void CWinsysDlg::OnNcLButtonDown(UINT nHitTest, CPoint point)
      if( nHitTest == HTCAPTION )
            //see if in button area
            CRect rect;
            GetButtonRect( rect );
            if( rect.PtInRect( point ) )
                  m_bPressed = !m_bPressed;
      CDialog::OnNcLButtonDown( nHitTest, point);
//End of Code

Phew! Finished! :)

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now