Improve company productivity with a Business Account.Sign Up

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1899
  • 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.
0
Mournblade
Asked:
Mournblade
1 Solution
 
cdesignerCommented:
you can paint frame and caption by self.
need sample for CDialog ?
0
 
ShabeerCommented:
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.
0
 
JunHaanCommented:
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 :)
0
 
GregMMCommented:
http://www.codeguru.com/dialog/custom_dialog_caption.shtml
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.
0
 
JunHaanCommented:
Mournblade,
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
public:
   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 )
{
   //{{AFX_DATA_INIT(CYourDlg)
   //}}AFX_DATA_INIT
   //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
   DrawCapButton();
}

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


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;
   GetButtonRect(rect);
   GetWindowRect(rectWnd);
   rect.OffsetRect( -rectWnd.left, -rectWnd.top );
   
   //Draw
   pDC->StretchBlt( rect.left, rect.top, rect.Width(),
                    rect.Height(). &memDC, 0, 0, 16, 16, SRCCOPY );
   
   //Clean up
   memDC.DeleteDC();
   ReleaseDC( pDC );
}

void CWinsysDlg::GetButtonRect(CRect& rect)
{
      GetWindowRect(&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(CYourDlg)
afx_msg void OnNcLButtonDown( UINT nHitTest, CPoint point ); //Add this
//}}AFX_MSG
DECLARE_MESSAGE_MAP()

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

BEGIN_MESSAGE_MAP(CYourDlg, CDialog)
      //{{AFX_MSG_MAP(CYourDlg)
      ON_WM_NCLBUTTONDOWN()
      //}}AFX_MSG_MAP
END_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;
                  DrawCapButton();
            }
      }
      CDialog::OnNcLButtonDown( nHitTest, point);
}
   
//End of Code

Phew! Finished! :)
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone 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