Click here to Skip to main content
15,879,474 members
Articles / Desktop Programming / MFC
Article

CGSToolBar

,
Rate me:
Please Sign up or sign in to vote.
3.86/5 (8 votes)
20 Feb 2001CPOL 117.4K   2.6K   29   21
A flexible extension to the CToolBar class
  • Download source files - 29 Kb
  • Download demo executable - 11 Kb
  • Sample Image - CGSToolBar.gif

    Introduction

    During my current project, I found myself in possession of a number of toolbars. It's a paint program, so it started to be quite painful, having various toolbars over parts of the image, and half of the real estate is just wasted room (i.e. the caption bar ). I decided to try and write a class derived from CToolBar that was tricked into thinking it was docked when it wasn't, so it drew with a gripper and no caption bar. Simple, right?

    Well, in the end, I posted a question here, and got an answer from Masoud, who was trying to do the same thing. He found the answer, and along the way we bounced ideas off each other and ended up with a useful toolbar class that we thought was worth sharing. Please direct all compliments to me, any bugs are his fault ( only kidding Masoud ;0)

    To use CGSToolBar, just include the header file in your CMainFrame header, and replace toolbar resources with CGSToolBar. For the auto menus, you also need to create three resource ID's, namely ID_MENU_GRADIENT, ID_MENU_CAPTION, and ID_MENU_BUTTONS. More on those later.

    The header file for CGSToolBar lists the following extra functions:

    // Function to dock bars next to one another (used typically on startup)
    void DockBarNextTo(CControlBar* pDockedBar, UINT nDockBarID = 0); 
    
    // Self Explanatory
    bool IsBarVisible() { return ((this->GetStyle() & WS_VISIBLE) !=0); }; 
    
    // Three functions to change the contents of a button
    // First one takes a pointer to a bitmap and a 0 based position 
    void OnChangeButton(CBitmap * pButton, int Position); 
    // Second used a resource ID, position, and transparent colour. 
    // Transparency does not work with gradient, this is the fault of the gradient code 
    void OnChangeButton(int BitmapID, int Position,COLORREF Transp = RGB(255,0,255)); 
    // Last one changes to a solid colour ( remember this was for a paint program ;0) 
    void OnChangeButton(COLORREF colour, int Position);
    
    // Sets a button to have a drop down arrow next to it. 
    // See code for further instructions on how to use this, or the MSDN 
    void SetDropdown(int Position); 
    
    // Push buttn mode means the last button pushed stays 'down', useful for example 
    // if toolbar selects different 'modes' 
    // First function sets global behaviour 
    void SetPushButton (bool push); 
    // Second allows you to specific individual buttons to group together this way. 
    void SetPushButton (bool push, int nPos); 
    
    // The core function - this turns the caption bar off and on 
    // When it is off, the floated toolbar has a gripper and resizes slightly to allow dragging 
    void SetShowCaption (bool caption); 
    
    // This just calls SetWindowText, but I put it in just in case anyone didn't realise that is how to do it 
    
    void SetCaption (CString caption); 
    
    // Sets the colours for the gradient 
    void SetBackground(COLORREF col1, COLORREF col2) { m_RGB1 = col1; m_RGB2 = col2; }; 
    
    // The gradient is drawn in OnEraseBackground - a solid colour or bitmap could just as easily be used. 
    void SetUseGradient(bool grad) { m_bUseGradient = grad; }; 
    // This allows you to pass in a menu to be shown as a context menu 
    void SetMenu(int ID) { m_iMenuID = ID; }; 
    // These four turn on the extra menu items available, to allow the user to turn on and off pushbuttons, the caption bar and the gradient fill 
    void SetMenuAll(bool menu); 
    void SetMenuPushbutton (bool bPush); 
    void SetMenuCaption (bool bCaption); void SetMenuGradient (bool bGradient); 
    
    // Fairly obvious stuff 
    bool GetShowCaption() { return m_bShowCaption; }; 
    bool GetUseGradient() { return m_bUseGradient; }; 
    bool GetPushbutton() { return m_bPushButton; };

    There are a few items of particular interest.

    The OnChangeButton method which uses a resource also displays the bitmap transparently. It does this by generating a 1 bit alpha mask, that is, a bitmap that is white where it should draw, and black where it should not. There are other, more generic examples of how to do colour keyed transparency using this method in the appropriate section of CodeProject. Windows has a

    TransparentBlt
    function, but it is not supported in Windows 95, so you're better not to use it.

    The SetMenu allows you to pass in the ID of any menu and it will be used as a context menu, BUT by using the other SetMenu methods listed, you can also get

    CGSToolBar
    to give you these extra options to your menu. For exmaple, I pass in a menu that lists all my toolbars, so I get MSDev type behaviour where a right click lets me turn toolbars off and on, but at the top I let my users choose if they want caption bars or not.

    SetDropDown allows you to set up a button to display a menu when you push the arrow provided, but there is work to be done in CMainFrame to make this happen. Basically you need to catch TBN_DROPDOWN in OnNotify, and then figure out which toolbar was pressed and show/handle the appropriate menu. If you only have one toolbar you can override OnDropDown directly. You can get a menu to return the selection value to you by passing TPM_RETURNCMD to

    TrackPopupMenu
    and grabbing the returning DWORD, which you can then switch. There are other tutorials here on how to do this, and it's not the focus of this article to reiterate them. This behaviour is not shown in the demo project.

    Probably the trickiest thing we had to do was get the toolbar outline the correct size when drawing. It turns out that although MSDN is silent on the issue, this is done by an object in the toolbar of type CDockContext, called m_pDockContext. It keeps track of four LPRECT structures, and we update them by firing a timer when we push the left mouse button. We need to change it both when it is not docked, and when it is docked, so that it always appears the correct size. When I say always, I have not found a way to change this rect initially, as I could not override the class successfully and replace the object in CGSToolBar with one of our own, and the RECT's are set in the BeginDragging method. The end result is you get an incorrect rect drawn when you click, but it's correct as you move, and snaps to the outline you were dragging when finished.

    License

    This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


    Written By
    Software Developer (Senior)
    Australia Australia
    Programming computers ( self taught ) since about 1984 when I bought my first Apple ][. Was working on a GUI library to interface Win32 to Python, and writing graphics filters in my spare time, and then building n-tiered apps using asp, atl and asp.net in my job at Dytech. After 4 years there, I've started working from home, at first for Code Project and now for a vet telemedicine company. I owned part of a company that sells client education software in the vet market, but we sold that and I worked for the owners for five years before leaving to get away from the travel, and spend more time with my family. I now work for a company here in Hobart, doing all sorts of Microsoft based stuff in C++ and C#, with a lot of T-SQL in the mix.

    Written By
    Technical Lead Samimi Information Technology
    United Arab Emirates United Arab Emirates
    My company provides services in the fields of:

    LAN/WAN Networking
    Data Management and Security
    Data Recovery
    ERP/CRM Solutions
    IT Infrastructure Solutions
    Software/Hardware Sales/Service

    Comments and Discussions

     
    GeneralMy vote of 5 Pin
    Manoj Kumar Choubey20-Feb-12 19:45
    professionalManoj Kumar Choubey20-Feb-12 19:45 
    Nice
    GeneralMy vote of 1 Pin
    jesjsi23-Feb-10 0:24
    jesjsi23-Feb-10 0:24 
    GeneralMy vote of 1 Pin
    jessssi23-Feb-10 0:23
    jessssi23-Feb-10 0:23 
    GeneralMy vote of 1 Pin
    jessssii23-Feb-10 0:23
    jessssii23-Feb-10 0:23 
    GeneralMy vote of 1 Pin
    jessiiiii23-Feb-10 0:22
    jessiiiii23-Feb-10 0:22 
    GeneralMy vote of 1 Pin
    jess3123-Feb-10 0:22
    jess3123-Feb-10 0:22 
    GeneralMy vote of 1 Pin
    jess223-Feb-10 0:22
    jess223-Feb-10 0:22 
    GeneralMy vote of 1 Pin
    jessi123-Feb-10 0:21
    jessi123-Feb-10 0:21 
    GeneralMy vote of 1 Pin
    jessca23-Feb-10 0:13
    jessca23-Feb-10 0:13 
    GeneralMy vote of 1 Pin
    arvinder_aneja29-Jan-10 23:48
    arvinder_aneja29-Jan-10 23:48 
    GeneralRe: My vote of 1 Pin
    Media2r5-Feb-10 0:17
    Media2r5-Feb-10 0:17 
    QuestionProblem with sample Pin
    me8-Aug-06 23:26
    me8-Aug-06 23:26 
    GeneralHandle to the MENU of drop down button Pin
    Alex Evans16-Nov-04 13:25
    Alex Evans16-Nov-04 13:25 
    QuestionUse in Dialog? Pin
    nikoladsp13-Apr-04 3:26
    nikoladsp13-Apr-04 3:26 
    GeneralBackground Image Pin
    2-Jun-02 15:22
    suss2-Jun-02 15:22 
    GeneralVery good ..but Pin
    17-Sep-01 11:32
    suss17-Sep-01 11:32 
    GeneralRe: Very good ..but Pin
    Christian Graus17-Sep-01 12:25
    protectorChristian Graus17-Sep-01 12:25 
    GeneralRe: Very good ..but Pin
    Paresh Chitte20-Feb-08 18:02
    Paresh Chitte20-Feb-08 18:02 
    GeneralRe: Very good ..but Pin
    Paresh Chitte31-Mar-08 22:33
    Paresh Chitte31-Mar-08 22:33 
    Generalnice one Pin
    l a u r e n21-Feb-01 6:30
    l a u r e n21-Feb-01 6:30 
    GeneralRe: nice one Pin
    27-Feb-01 23:40
    suss27-Feb-01 23:40 

    General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

    Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.