Click here to Skip to main content
15,867,704 members
Articles / Desktop Programming / MFC
Article

A Toolbar in the middle of elsewhere

Rate me:
Please Sign up or sign in to vote.
4.83/5 (20 votes)
19 Mar 20033 min read 130.5K   2.3K   57   21
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


Written By
Software Developer (Senior)
Germany Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionModeless dialogs seems do not receive WM_KICKIDLE Pin
HvalaMne15-Apr-06 3:01
HvalaMne15-Apr-06 3:01 
AnswerThe problem resolved Pin
HvalaMne16-Apr-06 15:16
HvalaMne16-Apr-06 15:16 
GeneralShort Summary of Improvements Pin
HachiihcaH24-Feb-06 11:34
HachiihcaH24-Feb-06 11:34 
GeneralFlat Toolbars Pin
naveed12-Oct-04 12:48
naveed12-Oct-04 12:48 
GeneralThe app is cpu-consuming. Pin
K. Spinoza2-Mar-04 15:52
K. Spinoza2-Mar-04 15:52 
GeneralRe: The app is cpu-consuming. Pin
fgleich13-Jul-04 17:56
fgleich13-Jul-04 17:56 
GeneralA big improvement!!! Pin
Joe Sonderegger8-Dec-03 1:47
Joe Sonderegger8-Dec-03 1:47 
GeneralRe: A big improvement!!! Pin
G. Steudtel8-Dec-03 3:03
G. Steudtel8-Dec-03 3:03 
GeneralRe: A big improvement!!! Pin
Joe Sonderegger8-Dec-03 3:10
Joe Sonderegger8-Dec-03 3:10 
QuestionModeless Dialog ? Pin
predagabi4-Nov-03 0:14
predagabi4-Nov-03 0:14 
GeneralPopup Wnds Pin
Ollie much15-Sep-03 5:28
Ollie much15-Sep-03 5:28 
GeneralDebug Error. Pin
Fabricem4-Aug-03 1:01
Fabricem4-Aug-03 1:01 
GeneralTooltips not working Pin
Fabricem12-Jun-03 23:23
Fabricem12-Jun-03 23:23 
GeneralRe: Tooltips not working Pin
G. Steudtel17-Jun-03 3:35
G. Steudtel17-Jun-03 3:35 
GeneralRe: Tooltips not working Pin
Anonymous17-Jun-03 22:09
Anonymous17-Jun-03 22:09 
GeneralRe: Tooltips not working Pin
chu_3009720-Jun-05 12:09
chu_3009720-Jun-05 12:09 
GeneralAbout OnKickIdle Pin
Ernest Laurentin21-Mar-03 9:23
Ernest Laurentin21-Mar-03 9:23 
GeneralRe: About OnKickIdle Pin
G. Steudtel24-Mar-03 0:31
G. Steudtel24-Mar-03 0:31 
GeneralRe: About OnKickIdle Pin
PeterHarrie21-May-03 23:27
PeterHarrie21-May-03 23:27 
GeneralLooks good but... Pin
Daniel Kamisnki20-Mar-03 15:51
Daniel Kamisnki20-Mar-03 15:51 
GeneralRe: Looks good but... Pin
G. Steudtel21-Mar-03 5:28
G. Steudtel21-Mar-03 5:28 

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.