Click here to Skip to main content
Click here to Skip to main content
Go to top

A Toolbar in the middle of elsewhere

, 19 Mar 2003
Rate this:
Please Sign up or sign in to vote.
This article explains how to place a toolbar right in the middle of a dialog or a form.

Sample Image - ArbTB.jpg

Introduction

Imagine you have a dialog, where you can enter text and other data related to the text. While the text should be formatted, the normal data entries should not. So you place a toolbar into your dialog, that has all the formatting buttons you need and find out, that it will dock only at the edges of your dialog. But I (the customer) wants this thing, where it belongs to: right over the format-able text entry.

To achieve the customer's need, there is a little more involved than just placing a button row in the middle of a form.

Creating the toolbar

Step one

Create a toolbar as usual and add a CToolBar member to your dialog, giving it any name that suits you. For a formatting toolbar a name like m_wndFormatBar sounds great.

Create a static control at that spot, where you want the toolbar to reside. Give this frame an ID (i.e. IDC_STC_TOOLBARFRAME). Make it slightly bigger then the tools, so you can see the space that becomes occupied by the toolbar. Within class wizard assign a member to this control. Make sure it is assigned to CStatic and not CString. Name it whatever you want (like m_Stc_ToolbarFrame).

Step two

Now comes the hard part. In the OnInitDialog method of your dialog, place following code. You may omit the comments.

// Positioning of toolbar
CSize sizeToolbar;
CRect mrect;
mrect.SetRectEmpty();
// attach command routing to dialog window
m_wndFormatBar.Create(this); 
m_wndFormatBar.LoadToolBar(IDR_TOOLBAR_FORMAT);
m_wndFormatBar.SetBarStyle(CBRS_ALIGN_TOP | CBRS_TOOLTIPS | CBRS_FLYBY);
m_wndFormatBar.ShowWindow(SW_SHOW);
// Calculate size of toolbar and adjust size of static control to fit size
sizeToolbar = m_wndFormatBar.CalcFixedLayout(false,true);
m_Stc_ToolbarFrame.GetWindowPlacement(&wpl);
wpl.rcNormalPosition.bottom = wpl.rcNormalPosition.top  + 
                                        sizeToolbar.cy + 4;
wpl.rcNormalPosition.right  = wpl.rcNormalPosition.left + 
                                        sizeToolbar.cx + 4;
// Position static control and toolbar
m_Stc_ToolbarFrame.SetWindowPlacement(&wpl);
m_wndFormatBar.SetWindowPlacement(&wpl);
// Adjust buttons into static control
m_Stc_ToolbarFrame.RepositionBars(AFX_IDW_CONTROLBAR_FIRST, 
    AFX_IDW_CONTROLBAR_LAST, 0);
m_Stc_ToolbarFrame.ShowWindow(SW_HIDE);

How this works

m_wndFormatBar.Create(this) tells the toolbar, to which window the commands are to be sent. Loading the images, setting the bar styles and displaying the toolbar is quite obvious. Then you calculate the size of the toolbar, and adjust the size of the static control accordingly with some margin.

After having done heavy numerical considerations we place the static control and put the toolbar in its lap. m_Stc_ToolbarFrame.RepositionBars tells the toolbar, which window it shall snuggle up to. Then make the static control disappear.

Omitting lines or doing the calculations wrong will be sentenced with weird optical results and strange behavior of your application. Check it out.

While the command routing is very simple, the visual updating of these commands is a little bit tricky.

Step three

Add the UpdateCommandUI handlers to your dialog and edit the methods as you would, in every Frame/View application. Do not care, when they do not seem to work. Actually they can't.

Step four

Add the line:

#include "afxpriv.h"

at the top of the dialog's cpp file, or put it inside stdafx.h. In your dialog's header file put the line:

afx_msg LRESULT OnKickIdle(WPARAM, LPARAM);

inside the message map. The best place is a line between the //}}AFX_MSG line and the DECLARE_MESSAGE_MAP() line. If there is no line, then make one by pressing return. In your dialog's cpp file look for the word END_MESSAGE_MAP(). Before that line, enter ON_MESSAGE(WM_KICKIDLE, OnKickIdle). If you forgot to include afxpriv.h the compiler will tell you, that it does not know anything about WM_KICKIDLE. (By the way, does this message mean that someone is idly kicking?)

Add the body of the OnKickIdle routine to your dialog class and call herein the CommandUpdateUI handlers. How? Have a look.

LRESULT CArbitraryToolbarDlg::OnKickIdle(WPARAM, LPARAM)
{ 
    CCmdUI cmdUI;
    cmdUI.m_nID = ID_FORMAT_BOLD; // The Command ID
    // Tell the dialog to call the UpdateCommandUI-routine
    cmdUI.DoUpdate(this, FALSE);
    cmdUI.m_nID = ID_FORMAT_DURCHSTRICH;
    cmdUI.DoUpdate(this, FALSE);
    cmdUI.m_nID = ID_FORMAT_KURSIV;
    cmdUI.DoUpdate(this, FALSE);
    cmdUI.m_nID = ID_FORMAT_UNTERSTRICH;
    cmdUI.DoUpdate(this, FALSE);
    cmdUI.m_nID = ID_EDIT_CUT;
    cmdUI.DoUpdate(this, FALSE);
    cmdUI.m_nID = ID_EDIT_COPY;
    cmdUI.DoUpdate(this, FALSE);
    cmdUI.m_nID = ID_EDIT_PASTE;
    cmdUI.DoUpdate(this, FALSE);
    return TRUE;
}

Step five...

Add the command handlers and test it. Drink a cup of coffee.

During this whole process you should compare your source code with mine. What you may adapt to your needs, what may not be altered I can't tell. This is taught only by experience, your experience.

The sample supplied has only the first seven buttons working. This is by design! After all, it is a sample not a full blown application.

The routines for squeezing the RichEditCtrl will be coming soon with its own class. So stay tuned.

After having read so long, may I ask you a favour? My little brother has been sent to war in the middle east now, would you please pray for him, so he will return safe and sound? Thank you.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

G. Steudtel
Software Developer (Senior)
Germany Germany
No Biography provided

Comments and Discussions

 
QuestionModeless dialogs seems do not receive WM_KICKIDLE PinmemberHvalaMne15-Apr-06 3:01 
AnswerThe problem resolved PinmemberHvalaMne16-Apr-06 15:16 
GeneralShort Summary of Improvements PinmemberHachiihcaH24-Feb-06 11:34 
GeneralFlat Toolbars Pinmembernaveed12-Oct-04 12:48 
GeneralThe app is cpu-consuming. Pinmemberarchon_cn2-Mar-04 15:52 
GeneralRe: The app is cpu-consuming. Pinmemberfgleich13-Jul-04 17:56 
GeneralA big improvement!!! PinmemberNice Life8-Dec-03 1:47 
GeneralRe: A big improvement!!! PinmemberG. Steudtel8-Dec-03 3:03 
GeneralRe: A big improvement!!! PinmemberNice Life8-Dec-03 3:10 
QuestionModeless Dialog ? Pinsusspredagabi4-Nov-03 0:14 
Hello,
I have this small problem:
I tested the implementation for a modal dialog. Works fine.
Then I tried to use it with the same dialog but modeless.
So, what happens is that bitmaps in toolbar are not re-drawn,
if I close and then re-open the dialog.
Do you have any suggestion ?
Thank you very much

Gabriel Preda
 

 
Gabriel Preda
GeneralPopup Wnds PinmemberOllie much15-Sep-03 5:28 
GeneralDebug Error. PinmemberFabricem4-Aug-03 1:01 
GeneralTooltips not working PinmemberFabricem12-Jun-03 23:23 
GeneralRe: Tooltips not working PinmemberG. Steudtel17-Jun-03 3:35 
GeneralRe: Tooltips not working PinsussAnonymous17-Jun-03 22:09 
GeneralRe: Tooltips not working Pinmemberchu_3009720-Jun-05 12:09 
GeneralAbout OnKickIdle PinmemberErnest Laurentin21-Mar-03 9:23 
GeneralRe: About OnKickIdle PinmemberG. Steudtel24-Mar-03 0:31 
GeneralRe: About OnKickIdle PinmemberPeter Hendrix21-May-03 23:27 
GeneralLooks good but... PinmemberDaniel Kamisnki20-Mar-03 15:51 
GeneralRe: Looks good but... PinmemberG. Steudtel21-Mar-03 5:28 

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

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

| Advertise | Privacy | Mobile
Web02 | 2.8.140916.1 | Last Updated 20 Mar 2003
Article Copyright 2003 by G. Steudtel
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid