Introduction
This
article
shows a
simple way
to
add
buttons to a
toolbar
and set the
image,
tooltip and
status bar
text
dynamically.
Strategy
Override
CToolBar::OnNotify
to set
dynamic
tooltips and
CMainFrame::GetMessageString
to provide
dynamic
status text.
Create a
bitmap and
draw the
buttons onto
it. Use the
SetBitmap
toolbar
method to
assign the
bitmap to
the
toolbar
control.
Insert and
set the
button
information
with the
SetButtons
and
SetButtonInfo
methods.
Then create
the
MFC
Application
Project and
add a
CMyDynamicToolBar
CToolBar
derived
class:
-
File ->
New ->
New
project.
Create a
new
DynamicToolBar
Visual
C++,
MFC
application.
-
In
the
class
view,
right
click
the
DynamicToolBar
project.
Add->Add
Class...
Select
an
MFC
class
on
the
right
pane
and
click
Open.
-
Select
CToolBar
from the
Base
class
drop-down
list.
Type
CMyDynamicToolBar
into the
Class
Name
edit
box.
-
Click
Finish.
We need to
store the
tooltip and
status
texts. For
this
example,
we will use
the same
text vector
array. Add
the
following
code to the
MyDynamicToolBar.h
file:
Collapse
Copy
Code
#pragma once
typedef std::vector <CString> V_CString;
-
Right
click
the
CMyDynamicToolBar
class in
Class
view ->
Add->
Add
Variable...
-
From the
Access
drop
down
list,
select
private
.
-
Into the
Variable
Type
edit
box,
type
V_CString
and into
the
Variable
Name
edit
box,
type
m_asToolTips
.
-
Into the
Comment
edit
box,
type
Variable
for
storing
tool tip
text
.
Now we will
override the
CToolBar::OnNotify
event for
responding
to the
TTN_NEEDTEXT
message of
the tool
bar.
-
Right
click
the
CMyDynamicToolBar
class in
Class
view ->
Properties.
-
On
Properties,
click
the
Override
button.
-
Scroll
down to
the
OnNotify
event
and
click on
the cell
right
next to
it.
-
Select
<Add>
OnNotify
from the
drop-down
list.
-
Press
Ctrl+Shift+Enter
to
change
to full
screen
view.
-
Replace
CMyDynamicToolBar::OnNotify
with:
Collapse
Copy
Code
BOOL CMyDynamicToolBar::OnNotify(WPARAM wParam,
LPARAM lParam, LRESULT* pResult)
{
LPNMHDR pNMHDR = ((LPNMHDR)lParam);
TOOLTIPTEXTW *pTTT=(TOOLTIPTEXTW *)pNMHDR;
UINT t = TTN_NEEDTEXTW;
if(pNMHDR->code == t)
{
UINT nID=pNMHDR->idFrom;
if(!(pTTT->uFlags & TTF_IDISHWND))
{
if ((nID >= ID_MYTOOLBAR_BUTTON1) ||
(nID <= ID_MYTOOLBAR_BUTTONLAST))
{
USES_CONVERSION;
UINT btn1 = ID_MYTOOLBAR_BUTTON1;
pTTT->lpszText = T2W(m_aCString[nID - btn1]);
pTTT->hinst = NULL;
return TRUE;
}
}
}
return CToolBar::OnNotify(wParam, lParam, pResult);
}
Press
Ctrl+Shift+Enter
to change
back from
full screen
view. Add
the
following to
the end of
the
stdafx.h
file:
Collapse
Copy
Code
#define ID_MYTOOLBAR_BUTTON1 WM_USER + 1
#define ID_MYTOOLBAR_BUTTONLAST WM_USER + 100
Now we will
add some
methods for
setting and
retrieving
the
tooltips.
For
simplicity's
sake, we
will assume
that all
insertions
are
consecutive,
in the same
order for
button IDs.
-
Right
click
the
CMyDynamicToolBar
class in
Class
view ->
Add ->
Add
Function...
-
Set the
Return
type to
void
and set
the
Function
name to
InsertToolTip
.
-
Also set
the
parameter
type to
CString
and the
parameter
name to
sToolTip
.
-
Next,
click
the Add
button.
-
Set the
comment
to
Inserts
tooltip
text
consecutively
.
-
Click
Finish.
-
Edit
CMyDynamicToolBar::InsertToolTip
into
this:
Collapse
Copy
Code
void CMyDynamicToolBar::InsertToolTip(CString sToolTip)
{
m_asToolTips.push_back(sToolTip);
}
Repeat the
above steps
to create
the
following
CMyDynamicToolBar::GetToolTip
function.
Collapse
Copy
Code
CString CMyDynamicToolBar::GetToolTip(UINT nID)
{
UINT btn1 = ID_MYTOOLBAR_BUTTON1;
return m_asToolTips[nID - btn1];
}
Now modify
CMyDynamicToolBar::~CMyDynamicToolBar()
to clear the
ToolTips
arrays on
destruction.
Collapse
Copy
Code
CMyDynamicToolBar::~CMyDynamicToolBar()
{
m_asToolTips.clear();
}
Now add code
for handling
the creation
of
CMyDynamicToolBar
on the main
frame
window:
-
Right
click
CMainFrame
class.
-> Add
Variable...
-
Type
CMyDynamicToolBar
into the
Variable
Type
edit
box.
-
Type
m_wndMyToolBar
into the
Variable
Name
edit
box.
-
Click
Finish.
-
Double
click
CMainFrame::OnCreate(LPCREATESTRUCT
lpCreateStruct)
Then add the
following
code:
Collapse
Copy
Code
if (!m_wndMyToolBar.CreateEx(this,
TBSTYLE_FLAT , WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC))
{
TRACE0("Failed to create dynamic toolbar\n");
return -1; }
CDC *dc = this->GetDC();
CDC dcMem;
dcMem.CreateCompatibleDC(dc);
HBITMAP hbitmap = CreateCompatibleBitmap(dc->m_hDC, 50*16, 16);
CBitmap *bmp = CBitmap::FromHandle(hbitmap);
CBitmap* pOldBitmap = dcMem.SelectObject( bmp );
CRect rect(0, 0, 5*16, 16);
FillRect(dcMem.m_hDC, &rect, (HBRUSH) (COLOR_WINDOW));
dcMem.SetMapMode(MM_TEXT);
CString tmp = "Button ";
for (int i=0;i < 5;i++)
{
HICON icon = LoadIcon(NULL,MAKEINTRESOURCE(32512+i));
dcMem.DrawIcon( i*16, 0, icon );
char buffer[2];
m_wndMyToolBar.InsertToolTip( tmp + itoa(i,buffer,10));
}
dcMem.SelectObject(pOldBitmap);
dcMem.DeleteDC();
pOldBitmap->DeleteObject();
m_wndMyToolBar.SetBitmap(hbitmap);
m_wndMyToolBar.SetButtons(NULL,i);
for(int j=0; j < i; j++)
{
m_wndMyToolBar.SetButtonInfo(j, ID_MYTOOLBAR_BUTTON1 + j,
TBBS_BUTTON | TBBS_AUTOSIZE, j);
}
So far, we
have the
toolbar
created and
it shows
tooltip
text, but we
also want to
have the
same text on
the status
bar. We
therefore
need to
override the
CMainFrame::GetMessageString
method that
is
responsible
for
providing
status bar
text
according to
control IDs:
-
Right
click
the
CMainFrame
class in
Class
view ->
Properties.
-
On
Properties,
click
the
Override
button.
-
Scroll
down to
the
GetMessageString
method.
-
Click on
the cell
right
next to
it and
select
<Add>
GetMessageString
from the
drop
down
list.
-
Replace
MainFrame::GetMessageString
with:
Collapse
Copy
Code
void CMainFrame::GetMessageString(UINT nID, CString& rMessage) const
{
if ((nID >= ID_MYTOOLBAR_BUTTON1) && (nID <= ID_MYTOOLBAR_BUTTONLAST))
rMessage = (const_cast <CMyDynamicToolBar*> (&m_wndMyToolBar))
->GetToolTip(nID);
else
CMDIFrameWnd::GetMessageString(nID, rMessage);
return;
}
Build and
run the
application.
(F7) (F5)
Points of
interest
MSDN
documents
state that
we need to
process the
TBN_GETINFOTIP
message for
specifying
the tooltip
text. A
simpler way
to get
tooltip
texts is to
set the
TBSTYLE_LIST
style and
the
TBSTYLE_EX_MIXEDBUTTONS
toolbar
extended
style. For
buttons that
do not have
the
BTNS_SHOWTEXT
style, the
toolbar
control will
automatically
display the
button text
as a
tooltip.
This works
for Version
5.81 of
Common
Controls.