Solved

How to add buttons to title bar of CFrameWnd?

Posted on 2000-04-22
5
1,582 Views
Last Modified: 2013-11-20
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
Comment
Question by:Mournblade
5 Comments
 
LVL 9

Expert Comment

by:cdesigner
ID: 2740217
you can paint frame and caption by self.
need sample for CDialog ?
0
 

Expert Comment

by:Shabeer
ID: 2754314
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
 
LVL 2

Expert Comment

by:JunHaan
ID: 2783787
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
 

Expert Comment

by:GregMM
ID: 2802375
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
 
LVL 2

Accepted Solution

by:
JunHaan earned 50 total points
ID: 2821943
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

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

Introduction: Dynamic window placements and drawing on a form, simple usage of windows registry as a storage place for information. Continuing from the first article about sudoku.  There we have designed the application and put a lot of user int…
Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar – let’s display the timestamp there.  We need to get the timestamp from the document s…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…

705 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

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now