VC/MFC 工具栏设计-CToolBar使用

时间:2021-08-11 00:19:14


工具栏中包含了一组用于执行命令的按钮,每个按钮都用一个图标来表示。当单击某个按钮时,会产生一个相应的消息,对这个消息的处理就是按钮的功能实现。将菜单中常用的功能放置在工具栏中,这样可以方便用户操作,省去了在级联菜单中一层层查找菜单项的麻烦。

6.2.1 工具栏类CToolBar

在MFC类库中,CToolBar类封装了工具栏的基本功能,CToolBar类的主要方法如下。

(1)Create方法:该方法用于创建工具栏窗口。语法如下:

BOOL Create( CWnd* pParentWnd, DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBRS_TOP, UINT

nID = AFX_IDW_TOOLBAR );

参数说明

pParentWnd:标识父窗口。

dwStyle:标识工具栏风格。可选值如下:

CBRS_TOP:工具栏位于框架窗口的顶部。

CBRS_BOTTOM:工具栏位于框架窗口的底部。

CBRS_NOALIGN:当父窗口重新调整尺寸时不重新定位工具栏。

CBRS_TOOLTIPS:工具栏显示工具提示。

CBRS_SIZE_DYNAMIC:工具栏是动态的。

CBRS_SIZE_FIXED:工具栏是固定的。

CBRS_FLOATING:工具栏是浮动的。

CBRS_FLYBY:状态栏显示按钮的信息。

CBRS_HIDE_INPLACE:工具栏不显示。

nID:标识工具栏ID。

(2)CreateEx方法:该方法与Create方法类似,用于创建工具栏窗口,只是该方法支持扩展风格。语法如下:

BOOL CreateEx(CWnd* pParentWnd, DWORD dwCtrlStyle = TBSTYLE_FLAT, DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBRS_ALIGN_TOP, CRect rcBorders = CRect(0, 0, 0, 0), UINT nID = AFX_IDW_TOOLBAR);

参数说明

pParentWnd:标识父窗口。

dwCtrlStyle:标识工具栏扩展风格。

dwStyle:标识工具栏风格。

rcBorders:标识工具栏边框的宽度。

nID:标识工具栏ID。

(3)SetSizes方法:该方法用于设置按钮和位图的大小。语法如下:

void SetSizes( SIZE sizeButton, SIZE sizeImage );

参数说明

sizeButton:标识按钮的大小。

sizeImage:标识位图的大小。

(4)SetHeight方法:该方法用于设置工具栏的高度。语法如下:

void SetHeight( int cyHeight );

参数说明

cyHeight:以像素为单位标识工具栏的高度。

(5)LoadToolBar方法:该方法用于加载工具栏资源。语法如下:

BOOL LoadToolBar( LPCTSTR lpszResourceName );

BOOL LoadToolBar( UINT nIDResource );

参数说明

lpszResourceName:标识资源名称。

nIDResource:标识资源ID。

返回值:如果函数执行成功,返回值是非零,否则为零。

(6)LoadBitmap方法:该方法用于加载一个位图资源,位图中包含了每个工具栏按钮的图像。语法如下:

BOOL LoadBitmap( LPCTSTR lpszResourceName );

BOOL LoadBitmap( UINT nIDResource );

参数说明

lpszResourceName:标识资源名称。

nIDResource:标识资源ID。

返回值:执行成功,返回值是非零,否则为零。

(7)SetBitmap方法:该方法用于设置工具栏按钮位图。语法如下:

BOOL SetBitmap( HBITMAP hbmImageWell );

参数说明

hbmImageWell:工具栏位图资源按钮。

(8)SetButtons方法:该方法用于向工具栏中添加按钮,并设置按钮的ID和图像索引。语法如下:

BOOL SetButtons( const UINT* lpIDArray, int nIDCount );

参数说明

lpIDArray:标识一个无符号整型数组,其中包含了按钮ID,如果数组中的某个元素值为ID_SEPARATOR,对应的按钮将是一个分隔条。

nIDCount:标识数组中的元素数量。

(9)CommandToIndex方法:该方法根据工具栏按钮ID返回按钮索引。语法如下:

int CommandToIndex( UINT nIDFind );

参数说明

nIDFind:标识按钮ID。

返回值:返回按钮ID对应的按钮索引,如果按钮ID没有对应的按钮,返回值为-1。

(10)GetItemID方法:该方法根据按钮索引返回按钮ID。语法如下:

UINT GetItemID( int nIndex ) const;

参数说明

nIndex:标识按钮索引。

返回值:返回按钮的ID,如果nIndex标识的按钮是一个分隔条,返回值是ID_SEPARATOR。

(11)GetItemRect方法:该方法根据按钮索引获取工具栏按钮的显示区域。语法如下:

virtual void GetItemRect( int nIndex, LPRECT lpRect );

参数说明

nIndex:标识按钮ID。

lpRect:用于接收按钮区域。

(12)GetButtonStyle方法:该方法用于获得按钮的风格。语法如下:

UINT GetButtonStyle( int nIndex ) const;

参数如下

nIndex:工具栏中按钮的索引,最小为0,从左到右依次增大。

(13)SetButtonStyle方法:该方法用于设置某个按钮的风格。语法如下:

void SetButtonStyle( int nIndex, UINT nStyle );

参数说明

nIndex:标识按钮索引。

nStyle:标识按钮风格。可选值如下。

TBBS_BUTTON:标准按钮。

TBBS_SEPARATOR:分隔线。

TBBS_CHECKBOX:复选风格。

TBBS_GROUP:按钮组。

TBBS_CHECKGROUP:复选按钮组。

(14)GetButtonInfo方法:该方法用于获取按钮信息。语法如下:

void GetButtonInfo( int nIndex, UINT& nID, UINT& nStyle, int& iImage ) const;

参数说明

nIndex:标识按钮索引。

nID:用于接收返回的按钮ID。

nStyle:接收按钮风格。

iImage:用于接收按钮的图像索引。

(15)SetButtonInfo方法:该方法用于设置按钮的信息。语法如下:

void SetButtonInfo( int nIndex, UINT nID, UINT nStyle, int iImage );

参数说明

nIndex:要设置信息的按钮索引。

nID:要设置按钮的ID。

nStyle:要设置按钮的风格。

iImage:要设置的位图资源索引。

(16)GetButtonText方法:该方法用于获取工具栏按钮文本。语法如下:

CString GetButtonText( int nIndex ) const;

void GetButtonText( int nIndex, CString& rString ) const;

参数说明

nIndex:标识按钮索引。

rString:用于接收按钮文本。

(17)SetButtonText方法:该方法用于设置按钮文本。语法如下:

BOOL SetButtonText( int nIndex, LPCTSTR lpszText );

参数说明

nIndex:标识按钮ID。

lpszText:标识按钮文本。

(18)GetToolBarCtrl方法:该方法用于访问底层的工具栏按钮通用控件。语法如下:

CToolBarCtrl& GetToolBarCtrl( ) const;

6.2.2 工具栏资源设计

在开发文档视图结构的应用程序时,系统会自动创建工具栏。但是如果开发基于对话框的应用程序,就需要用户自己创建工具栏了。在创建基于对话框的应用程序时,默认情况下,是不会创建工具栏资源的。如果用户想要设计工具栏,可以通过工作区的ResourceView来创建工具栏资源。

(1)在工作区的ResourceView中鼠标右键单击某个节点,在弹出的快捷菜单中选择“Insert”菜单项,打开“Insert Resource”对话框,如图6.19所示。

图6.19 “Insert Resource”对话框

(2)选择“Toolbar”选项,单击“New”按钮创建工具栏资源,如图6.20所示。

(3)在工具栏资源中绘制工具栏按钮。当用户在按钮上绘制图像后,工具栏窗口会自动创建一个新的工具栏按钮,如图6.21所示。

图6.20 工具栏窗口 图6.21 绘制工具栏按钮

说明:如果要为工具栏按钮添加分隔线,可以选中要加入分隔线位置的按钮,将这个按钮向右拖动一点距离,就会在两个按钮之间留下一点空隙,运行程序后,这点空隙就会显示成分隔线了。

(4)如果用户想要删除工具栏资源中的某个按钮,可以先选中该按钮,然后按住鼠标左键,将其拖出工具栏。

(5)在设计完工具栏按钮后,需要为工具栏按钮设置命令ID,如果不指定ID,系统会为每个工具栏按钮设置一个默认的ID。双击工具栏按钮或者选中工具栏按钮后按<Enter>键打开“Toolbar Button Properties”窗口,通过“Toolbar Button Properties”窗口可以设置工具栏按钮命令ID、大小和提示,如图6.22所示。

图6.22 “Toolbar Button Properties”窗口

说明:如果为一个工具栏按钮设置了大小,那么所有的工具栏按钮的大小都会改变为当前设置的大小。

6.2.3 工具栏的命令处理

同菜单一样,每一个工具栏按钮都有一个命令ID,通过命令ID,可以编写命令消息处理函数。当单击工具栏按钮时,会执行消息处理函数。下面介绍如何编写消息处理函数。

(1)打开类向导,选择“Message Maps”选项卡,在“Class name”列表框选择创建了工具栏的对话框类,在“Object Ids”列表中选择工具栏按钮ID,在“Messages”列表中选择“COMMAND”项,如图6.23所示。

图6.23 类向导

(2)单击“Add Function…”按钮,弹出“Add Member Function”对话框,并给出默认时的命令处理函数名,如图6.24所示。

图6.24 “Add Member Function”对话框

(3)单击“OK”按钮,就添加了工具栏按钮的命令处理函数。

6.2.4 动态创建工具栏

工具栏的创建大体有3种方法。第1种方法是先设计一个位图,其中包含了工具栏中的所有按钮图像,每个按钮图像具有相同的大小,然后调用LoadBitmap方法加载位图,最后调用SetButtons方法添加按钮,设置按钮ID和图像索引;第2种方法是定义一个图像列表CImageList对象,向该对象中添加图像,然后将图像列表关联到工具栏中;第3种方法是创建一个工具栏资源,然后调用LoadToolBar方法加载工具栏资源。下面分别介绍这3种方法的应用。

1.第1种方法

(1)创建一个基于对话框的应用程序。

(2)向对话框中添加一个按钮控件,并向工程中导入一个位图,如图6.25所示。

图6.25 工具栏位图

(3)在主窗口头文件中声明一个CToolBar类对象m_ToolBar,代码如下:

CToolBar m_ToolBar;

(4)处理“创建”按钮的单击事件,加载位图,创建工具栏,代码如下:

void CDynamicTool1Dlg::OnButton1()

{

UINT array[11];

for(int i=0;i<10;i++)

{

if(i= =3 || i= =7)

array[i] = ID_SEPARATOR; //第4、第8个按钮为分隔条

else

array[i] = i+1001;

}

m_ToolBar.Create(this);

m_ToolBar.SetButtons(array,11);

m_ToolBar.LoadBitmap(IDB_BITMAP1); //加载位图

m_ToolBar.SetSizes(CSize(40,40),CSize(32,32)); //设置按钮和按钮位图大小

RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0); //显示工具栏

}

程序运行结果如图6.26所示。

图6.26 动态创建工具栏1

2.第2种方法

(1)创建一个基于对话框应用程序。

(2)向对话框中添加一个按钮控件,并向工程中导入9个图标。

(3)在主窗口头文件中声明一个CToolBar类对象m_ToolBar和一个图像列表对象m_ImageList,代码如下:

CToolBar m_ToolBar;

CImageList m_ImageList;

(4)处理“创建”按钮的单击事件,加载图标,关联图像列表,创建工具栏,代码如下:

void CDynamicTool2Dlg::OnButton1()

{

//创建图像列表

m_ImageList.Create(32,32,ILC_COLOR24|ILC_MASK,1,1);

//向图像列表中添加图标

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON1));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON2));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON3));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON4));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON5));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON6));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON7));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON8));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON9));

UINT array[11];

for(int i=0;i<10;i++)

{

if(i= =3 || i= =7)

array[i] = ID_SEPARATOR; //第4、第8个按钮为分隔条

else

array[i] = i+1001;

}

m_ToolBar.Create(this);

m_ToolBar.SetButtons(array,11);

//关联图像列表

m_ToolBar.GetToolBarCtrl().SetImageList(&m_ImageList);

m_ToolBar.SetSizes(CSize(40,40),CSize(32,32)); //设置按钮和图标的大小

RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0);

}

程序运行结果如图6.27所示。

图6.27 动态创建工具栏2

3.第3种方法

(1)创建一个基于对话框的应用程序。

(2)向对话框中添加一个按钮控件,并创建一个工具栏资源,如图6.28所示。

图6.28 工具栏资源

(3)在主窗口头文件中声明一个CToolBar类对象m_ToolBar,代码如下:

CToolBar m_ToolBar;

(4)处理“创建”按钮的单击事件,创建工具栏,加载工具栏资源,代码如下:

void CDynamicTool3Dlg::OnButton1()

{

//创建工具栏

m_ToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP

| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_SIZE_DYNAMIC | CBRS_BORDER_TOP );

m_ToolBar.LoadToolBar(IDR_TOOLBAR1); //加载工具栏资源

//设置图像和按钮的大小

m_ToolBar.GetToolBarCtrl().SetBitmapSize(CSize(16,16));

m_ToolBar.GetToolBarCtrl().SetButtonSize(CSize(22,22));

RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0);

}

程序运行结果如图6.29所示。

图6.29 动态创建工具栏3

6.2.5 工具栏按钮的热点效果

将工具栏设置成具有热点效果可以美化程序界面。

实现步骤如下。

(1)创建一个基于对话框的应用程序。

(2)向对话框中添加一个按钮控件,并向程序中导入16个图标。

(3)在主窗口头文件中声明一个CToolBar类对象m_ToolBar和两个图像列表对象m_ImageList、m_HotImageList,代码如下:

CToolBar m_ToolBar;

CImageList m_ImageList;

CImageList m_HotImageList;

其中,m_ImageList是工具栏按钮的图像列表对象,m_HotImageList是工具栏按钮的热点图像列表对象。

(4)在OnInitDialog函数中加载图标,关联图像列表,创建工具栏,代码如下:

BOOL CHotToolDlg::OnInitDialog()

{

……

// TODO: Add extra initialization here

m_ImageList.Create(32,32,ILC_COLOR24|ILC_MASK,1,1); //创建图像列表

m_HotImageList.Create(32,32,ILC_COLOR24|ILC_MASK,1,1); //创建热点图像列表

//向图像列表中添加图标

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON1));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON2));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON3));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON4));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON5));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON6));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON7));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON8));

m_HotImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON9));

m_HotImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON10));

m_HotImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON11));

m_HotImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON12));

m_HotImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON13));

m_HotImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON14));

m_HotImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON15));

m_HotImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON16));

UINT array[10];

for(int i=0;i<9;i++)

{

if(i= =3 || i= =7)

array[i] = ID_SEPARATOR; //第4、第8个按钮为分隔条

else

array[i] = i+1001;

}

m_ToolBar.CreateEx(this,TBSTYLE_FLAT); //创建工具栏窗口

m_ToolBar.SetButtons(array,10);

m_ToolBar.SetButtonText(0,"新建");

m_ToolBar.SetButtonText(1,"打开");

m_ToolBar.SetButtonText(2,"保存");

m_ToolBar.SetButtonText(4,"剪切");

m_ToolBar.SetButtonText(5,"复制");

m_ToolBar.SetButtonText(6,"粘贴");

m_ToolBar.SetButtonText(8,"打印");

m_ToolBar.SetButtonText(9,"帮助");

//关联图像列表

m_ToolBar.GetToolBarCtrl().SetImageList(&m_ImageList);

//关联热点图像列表

m_ToolBar.GetToolBarCtrl().SetHotImageList(&m_HotImageList);

m_ToolBar.SetSizes(CSize(40,40),CSize(32,32)); //设置按钮和图标的大小

RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0); //显示工具栏

return TRUE;

}

在创建具有热点效果的工具栏时,需要使用CreateEx创建工具栏窗口,只有创建的工具栏窗口具有TBSTYLE_FLAT属性时,工具栏按钮才具有热点效果。然后要使用工具栏控制类的SetHotImageList方法关联热点图像列表。

程序运行结果如图6.30所示。

图6.30 工具栏按钮的热点效果

6.2.6 具有提示功能的工具栏

系统中的工具栏是没有文本显示的,为了使用户能清楚地知道每个工具栏按钮的用途,除了形象的图像外,还应该具有提示功能,下面就来看一下工具栏的提示功能是如何实现的。

(1)创建一个基于对话框的应用程序。

(2)向对话框中添加一个按钮控件,并向工程中导入一个位图,如图6.31所示。

(3)在主窗口头文件中声明一个CToolBar类对象m_ToolBar,并声明一个CString的变量str来保存工具栏按钮文本,代码如下:

CToolBar m_ToolBar;

CString str;

(4)在OnInitDialog函数中加载位图,创建工具栏,代码如下:

BOOL CToolTipDlg::OnInitDialog()

{

……

UINT array[10];

for(int i=0;i<10;i++)

{

if(i= =3 || i= =7)

array[i] = ID_SEPARATOR; //第4、第8个按钮为分隔条

else

array[i] = i+1001;

}

m_ToolBar.Create(this);

m_ToolBar.SetButtons(array,10);

m_ToolBar.SetButtonText(0,"新建");

m_ToolBar.SetButtonText(1,"打开");

m_ToolBar.SetButtonText(2,"保存");

m_ToolBar.SetButtonText(4,"剪切");

m_ToolBar.SetButtonText(5,"复制");

m_ToolBar.SetButtonText(6,"粘贴");

m_ToolBar.SetButtonText(8,"打印");

m_ToolBar.SetButtonText(9,"帮助");

m_ToolBar.LoadBitmap(IDB_BITMAP1); //加载位图

m_ToolBar.SetSizes(CSize(36,36),CSize(16,16)); //设置按钮和按钮位图大小

m_ToolBar.EnableToolTips(TRUE);

RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0); //显示工具栏

return TRUE;

}

EnableToolTips方法用于激活工具栏的提示功能。

(5)在主窗口的消息映射部分添加ON_NOTIFY_EX映射宏,代码如下:

ON_NOTIFY_EX( TTN_NEEDTEXT, 0, OnToolTipNotify)

(6)在主窗口的头文件中添加对OnToolTipNotify函数的声明,代码如下:

afx_msg BOOL OnToolTipNotify( UINT id, NMHDR * pNMHDR, LRESULT * pResult );

(7)添加消息处理函数OnToolTipNotify的实现部分,代码如下:

BOOL CToolTipDlg::OnToolTipNotify(UINT id, NMHDR *pNMHDR, LRESULT *pResult)

{

TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pNMHDR;

UINT nID =pNMHDR->idFrom; //获取工具栏按钮ID

if(nID)

{

nID = m_ToolBar.CommandToIndex(nID); //根据ID获取按钮索引

if(nID != -1)

{

m_ToolBar.GetButtonText(nID,str); //获取工具栏文本

pTTT->lpszText = str.GetBuffer(str.GetLength()); //设置提示信息文本

pTTT->hinst = AfxGetResourceHandle();

return(TRUE);

}

}

return(FALSE);

}

OnToolTipNotify是处理TTN_NEEDTEXT消息的函数,其中参数id是发送消息的控件ID;参数pNMHDR是一个NMHDR结构指针,该结构记录了发送消息的控件ID、句柄等信息;参数pResult表示结果代码指针,TTN_NEEDTEXT消息可以忽略该参数。

程序运行结果如图6.32所示。

图6.32 具有提示功能的工具栏

6.2.7 带下拉按钮的工具栏

在工具栏按钮的旁边添加一个呈倒三角形的下拉按钮可以扩展工具栏按钮的选择功能。下拉按钮在按下后会弹出一个下拉菜单,下拉菜单中的选项就是对按钮增强的功能。下面来介绍一下如何为工具栏添加下拉按钮。

(1)创建一个基于单文档的应用程序。

(2)新建一个菜单资源,如图6.33所示。

(3)修改工具栏资源,为工具栏添加一个修改字体按钮,如图6.34所示。

图6.33 菜单资源 图6.34 工具栏资源

(4)在框架头文件中修改工具栏风格,使“A”按钮具有下拉按钮,代码如下:

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

if (CFrameWnd::OnCreate(lpCreateStruct) = = -1)

return -1;

if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP

| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||

!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))

{

TRACE0("Failed to create toolbarn");

return -1;

}

if (!m_wndStatusBar.Create(this) ||

!m_wndStatusBar.SetIndicators(indicators,

sizeof(indicators)/sizeof(UINT)))

{

TRACE0("Failed to create status barn");

return -1;

}

m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);

EnableDocking(CBRS_ALIGN_ANY);

DockControlBar(&m_wndToolBar);

m_wndToolBar.GetToolBarCtrl().SetExtendedStyle(TBSTYLE_EX_DRAWDDARROWS);

DWORD dwStyle=m_wndToolBar.GetButtonStyle(m_wndToolBar.CommandToIndex(ID_FONT));

dwStyle|=TBSTYLE_DROPDOWN;

m_wndToolBar.SetButtonStyle(m_wndToolBar.CommandToIndex(ID_FONT),dwStyle);

return 0;

}

SetExtendedStyle是CToolBarCtrl类的方法,该方法用于设置工具栏控件的扩展风格,语法如下:

DWORD SetExtendedStyle( DWORD dwExStyle ) const;

参数说明

dwExStyle:系统定义的工具栏控件风格,取值TBSTYLE_EX_DRAWDDARROWS,可以为某一个按钮添加下拉按钮。

(5)在框架源文件消息映射宏中添加如下代码:

ON_NOTIFY(TBN_DROPDOWN, AFX_IDW_TOOLBAR, OnToolbarDropDown)

(6)在框架的头文件中添加消息响应函数的声明,代码如下:

afx_msg void OnToolbarDropDown(NMTOOLBAR* pnmh, LRESULT* plRes);

(7)OnToolbarDropDown函数的实现代码如下:

void CMainFrame::OnToolbarDropDown(NMTOOLBAR* pnmtb, LRESULT *plr)

{

CWnd *pWnd;

UINT nID;

switch (pnmtb->iItem)

{

case ID_FONT:

pWnd = &m_wndToolBar;

nID = IDR_MENU1;

break;

default:

return;

}

//加载相应的显示菜单

CMenu menu;

menu.LoadMenu(nID);

CMenu* pPopup = menu.GetSubMenu(0);

ASSERT(pPopup);

CRect rc;

pWnd->SendMessage(TB_GETRECT, pnmtb->iItem, (LPARAM)&rc);

pWnd->ClientToScreen(&rc);

pPopup->TrackPopupMenu( TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_VERTICAL,

rc.left, rc.bottom, this, &rc);

}

CWnd类的ClientToScreen方法用于将客户坐标转换成屏幕坐标,TrackPopupMenu方法用于弹出菜单。

(8)在视图头文件中声明一个CFont类型变量Font,并在构造函数中初始化变量Font。重载OnDraw函数,设置视图中的显示文本。

(9)通过类向导为新创建的菜单和工具栏按钮添加消息处理函数,代码如下:

void CDropToolBarView::OnFont()

{

OnMenu100();

}

void CDropToolBarView::OnMenu200()

{

Font.CreatePointFont(240,"宋体");

Invalidate();

}

void CDropToolBarView::OnMenu150()

{

Font.CreatePointFont(180,"宋体");

Invalidate();

}

void CDropToolBarView::OnMenu100()

{

Font.CreatePointFont(120,"宋体");

Invalidate();

}

void CDropToolBarView::OnMenu50()

{

Font.CreatePointFont(60,"宋体");

Invalidate();

}

程序运行结果如图6.35所示。

图6.35 带下拉按钮的工具栏

6.2.8 工具栏控制类CToolBarCtrl

CToolBarCtrl类提供了Windows通用工具栏控制功能,是一个矩形子窗口,包含一个或多个按钮,这些按钮可以显示位图图像、字符文本或两者都有。

CToolBarCtrl类的主要方法如表6.1所示。

表6.1 CToolBarCtrl类主要方法表

方 

描 

Create

创建工具栏并将它与一个CToolBarCtrl类对象连接

IsButtonEnabled

指示工具栏中的指定按钮是否有效

IsButtonChecked

指示工具栏中的指定按钮是否被选中

IsButtonPressed

指示工具栏中的指定按钮是否被按下

IsButtonHidden

指示工具栏中的指定按钮是否隐藏

IsButtonIndeterminate

指示工具栏中的指定按钮的状态是否不可用[g1]

SetState

设置工具栏中的指定按钮的状态

GetState

获取工具栏中的指定按钮的状态

GetButton

获取工具栏中的指定按钮

GetButtonCount

获取工具栏按钮的数目

GetItemRect

获取工具栏按钮的边界矩形

GetRect

获取一个指定工具栏按钮的边界矩形

SetButtonStructSize

指定TBBUTTON结构的大小

GetButtonSize

获取当前工具栏按钮的大小

SetButtonSize

设置当前工具栏按钮的大小

SetBitmapSize

设置工具栏按钮的图像大小

续表

方 

描 

GetToolTips

获取与此工具栏相关联的工具栏提示的句柄

SetToolTips

将工具栏提示与工具栏进行关联

SetOwner

设置接收工具栏通知消息的按钮

SetRows

设置工具栏按钮的行数

GetRows

获取工具栏按钮的行数

SetCmdID

设置当按钮被按下时要发送到主窗口的命令ID

GetBitmapFlags

获取与工具栏位图相关联的标志

GetDisabledImageList

获取工具栏用来显示无效按钮的图像列表

GetHotImageList

获取工具栏用来显示热点按钮的图像列表

GetImageList

获取工具栏默认时的图像列表

GetStyle

获取工具栏当前的风格

GetMaxTextRows

获取工具栏按钮的显示文本的最大行数

IsButtonHighlighted

检查工具栏按钮的加亮状态

SetButtonWidth

设置工具栏按钮宽度的最大值和最小值

SetDisabledImageList

设置工具栏用来显示无效按钮的图像列表

SetHotImageList

设置工具栏用来显示热点按钮的图像列表

SetImageList

设置工具栏默认时的图像列表

GetDropTarget

设置工具栏的IDropTarget接口

SetIndent

设置工具栏中第一个按钮的缩进

SetMaxTextRows

设置工具栏按钮的显示文本的最大行数

SetStyle

设置工具栏当前的风格

GetAnchorHighlight

获取工具栏的加亮设置

SetAnchorHighlight

对工具栏进行加亮设置

GetHotItem

获取工具栏热点项索引

SetHotItem

设置工具栏热点项索引

GetInsertMark

获取工具栏的当前插入标记

SetInsertMark

设置工具栏的当前插入标记

GetMaxSize

获取工具栏可视按钮和分隔条的总大小

InsertMarkHitTest

获取工具栏中指定点的插入信息

GetExtendedStyle

获取工具栏的扩展风格

SetExtendedStyle

设置工具栏的扩展风格

GetInsertMarkColor

获取工具栏插入标记的颜色

SetInsertMarkColor

设置工具栏插入标记的颜色

MapAccelerator

将一个加速键映射到一个工具栏按钮

MoveButton

将一个工具栏按钮从一个索引移动到另一个索引

HitTest

确定一个点位于工具栏的具体位置

EnableButton

设置工具栏按钮是否有效

CheckButton

是否选中工具栏中的指定按钮

PressButton

是否按下工具栏中的指定按钮

GetButtonInfo

获取工具栏指定按钮的信息

续表

方 

描 

SetButtonInfo

设置工具栏指定按钮的信息

SetDrawTextFlags

设置Win32中DrawText功能标志

HideButton

隐藏或显示工具栏中的指定按钮

Indeterminate

设置工具栏中指定按钮是否灰色状态

AddBitmap

将位图图像添加到工具栏可用的图像列表中

AddButtons

将按钮添加到工具栏中

InsertButton

在工具栏中插入按钮

DeleteButton

从工具栏中删除按钮

CommandToIndex

获取与指定命令ID相关联的索引

RestoreState

恢复工具栏状态

MarkButton

设置工具栏的高亮显示状态

LoadImages

将位图装载到工具栏的图像列表中

SaveState

保存工具栏状态

Customize

显示CustomizeToolBar对话框

AddString

将作为资源ID传递的一个字符串添加到工具栏的内部字符串列表中

AddStrings

将多个字符串添加到工具栏的内部字符串列表中

AutoSize

调整工具栏的大小

下面使用CToolBarCtrl类创建一个工具栏。

步骤如下。

(1)创建一个基于对话框的应用程序。

(2)向对话框中添加一个按钮控件,并向工程中导入8个图标。

(3)在主窗口头文件中声明一个CToolBarCtrl类对象m_ToolBar和一个图像列表对象m_ImageList,代码如下:

CToolBarCtrl m_ToolBar;

CImageList m_ImageList;

(4)在工作区窗口中选择ResourceView,展开String Table节点,双击abc String Table节点,打开字符串编辑器,在字符串编辑器中设置工具栏按钮的显示文本,如图6.36所示。

图6.36 字符串编辑器

(5)在OnInitDialog函数中加载图标,关联图像列表,创建工具栏,代码如下:

BOOL CToolCtrlDlg::OnInitDialog()

{

……

TBBUTTON button[10];

CString string;

TCHAR * pString;

int num;

//创建一个图像列表

m_ImageList.Create(32,32,ILC_COLOR32|ILC_MASK,0,0);

//向图像列表中添加图标

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON1));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON2));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON3));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON4));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON5));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON6));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON6));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON7));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON8));

m_ToolBar.Create(WS_CHILD|WS_VISIBLE,CRect(0,0,0,0),this,1100);

m_ToolBar.SetImageList(&m_ImageList);

for(int i=0;i<10;i++)

{

button[i].dwData = 0;

button[i].fsState = TBSTATE_ENABLED;

if(i= =3 ||i= =7)

button[i].fsStyle = TBSTYLE_SEP;

else

button[i].fsStyle = TBSTYLE_BUTTON;

button[i].iBitmap = i;

string.LoadString(i + IDS_STRING1);//装载字符串资源

//为每一个字符串再加一个'',用于向工具栏里加字符串

num = string.GetLength() + 1;

pString = string.GetBufferSetLength(num);

//返回刚加的字符串的编号

button[i].iString = m_ToolBar.AddStrings(pString);

string.ReleaseBuffer();

}

m_ToolBar.AddButtons(10,button);

m_ToolBar.AutoSize();

m_ToolBar.SetStyle(TBSTYLE_FLAT|CCS_TOP);

return TRUE;

}


出自: http://lmx18.blog.163.com/blog/static/434936792013727102116830/

工具栏中包含了一组用于执行命令的按钮,每个按钮都用一个图标来表示。当单击某个按钮时,会产生一个相应的消息,对这个消息的处理就是按钮的功能实现。将菜单中常用的功能放置在工具栏中,这样可以方便用户操作,省去了在级联菜单中一层层查找菜单项的麻烦。

6.2.1 工具栏类CToolBar

在MFC类库中,CToolBar类封装了工具栏的基本功能,CToolBar类的主要方法如下。

(1)Create方法:该方法用于创建工具栏窗口。语法如下:

BOOL Create( CWnd* pParentWnd, DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBRS_TOP, UINT

nID = AFX_IDW_TOOLBAR );

参数说明

pParentWnd:标识父窗口。

dwStyle:标识工具栏风格。可选值如下:

CBRS_TOP:工具栏位于框架窗口的顶部。

CBRS_BOTTOM:工具栏位于框架窗口的底部。

CBRS_NOALIGN:当父窗口重新调整尺寸时不重新定位工具栏。

CBRS_TOOLTIPS:工具栏显示工具提示。

CBRS_SIZE_DYNAMIC:工具栏是动态的。

CBRS_SIZE_FIXED:工具栏是固定的。

CBRS_FLOATING:工具栏是浮动的。

CBRS_FLYBY:状态栏显示按钮的信息。

CBRS_HIDE_INPLACE:工具栏不显示。

nID:标识工具栏ID。

(2)CreateEx方法:该方法与Create方法类似,用于创建工具栏窗口,只是该方法支持扩展风格。语法如下:

BOOL CreateEx(CWnd* pParentWnd, DWORD dwCtrlStyle = TBSTYLE_FLAT, DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBRS_ALIGN_TOP, CRect rcBorders = CRect(0, 0, 0, 0), UINT nID = AFX_IDW_TOOLBAR);

参数说明

pParentWnd:标识父窗口。

dwCtrlStyle:标识工具栏扩展风格。

dwStyle:标识工具栏风格。

rcBorders:标识工具栏边框的宽度。

nID:标识工具栏ID。

(3)SetSizes方法:该方法用于设置按钮和位图的大小。语法如下:

void SetSizes( SIZE sizeButton, SIZE sizeImage );

参数说明

sizeButton:标识按钮的大小。

sizeImage:标识位图的大小。

(4)SetHeight方法:该方法用于设置工具栏的高度。语法如下:

void SetHeight( int cyHeight );

参数说明

cyHeight:以像素为单位标识工具栏的高度。

(5)LoadToolBar方法:该方法用于加载工具栏资源。语法如下:

BOOL LoadToolBar( LPCTSTR lpszResourceName );

BOOL LoadToolBar( UINT nIDResource );

参数说明

lpszResourceName:标识资源名称。

nIDResource:标识资源ID。

返回值:如果函数执行成功,返回值是非零,否则为零。

(6)LoadBitmap方法:该方法用于加载一个位图资源,位图中包含了每个工具栏按钮的图像。语法如下:

BOOL LoadBitmap( LPCTSTR lpszResourceName );

BOOL LoadBitmap( UINT nIDResource );

参数说明

lpszResourceName:标识资源名称。

nIDResource:标识资源ID。

返回值:执行成功,返回值是非零,否则为零。

(7)SetBitmap方法:该方法用于设置工具栏按钮位图。语法如下:

BOOL SetBitmap( HBITMAP hbmImageWell );

参数说明

hbmImageWell:工具栏位图资源按钮。

(8)SetButtons方法:该方法用于向工具栏中添加按钮,并设置按钮的ID和图像索引。语法如下:

BOOL SetButtons( const UINT* lpIDArray, int nIDCount );

参数说明

lpIDArray:标识一个无符号整型数组,其中包含了按钮ID,如果数组中的某个元素值为ID_SEPARATOR,对应的按钮将是一个分隔条。

nIDCount:标识数组中的元素数量。

(9)CommandToIndex方法:该方法根据工具栏按钮ID返回按钮索引。语法如下:

int CommandToIndex( UINT nIDFind );

参数说明

nIDFind:标识按钮ID。

返回值:返回按钮ID对应的按钮索引,如果按钮ID没有对应的按钮,返回值为-1。

(10)GetItemID方法:该方法根据按钮索引返回按钮ID。语法如下:

UINT GetItemID( int nIndex ) const;

参数说明

nIndex:标识按钮索引。

返回值:返回按钮的ID,如果nIndex标识的按钮是一个分隔条,返回值是ID_SEPARATOR。

(11)GetItemRect方法:该方法根据按钮索引获取工具栏按钮的显示区域。语法如下:

virtual void GetItemRect( int nIndex, LPRECT lpRect );

参数说明

nIndex:标识按钮ID。

lpRect:用于接收按钮区域。

(12)GetButtonStyle方法:该方法用于获得按钮的风格。语法如下:

UINT GetButtonStyle( int nIndex ) const;

参数如下

nIndex:工具栏中按钮的索引,最小为0,从左到右依次增大。

(13)SetButtonStyle方法:该方法用于设置某个按钮的风格。语法如下:

void SetButtonStyle( int nIndex, UINT nStyle );

参数说明

nIndex:标识按钮索引。

nStyle:标识按钮风格。可选值如下。

TBBS_BUTTON:标准按钮。

TBBS_SEPARATOR:分隔线。

TBBS_CHECKBOX:复选风格。

TBBS_GROUP:按钮组。

TBBS_CHECKGROUP:复选按钮组。

(14)GetButtonInfo方法:该方法用于获取按钮信息。语法如下:

void GetButtonInfo( int nIndex, UINT& nID, UINT& nStyle, int& iImage ) const;

参数说明

nIndex:标识按钮索引。

nID:用于接收返回的按钮ID。

nStyle:接收按钮风格。

iImage:用于接收按钮的图像索引。

(15)SetButtonInfo方法:该方法用于设置按钮的信息。语法如下:

void SetButtonInfo( int nIndex, UINT nID, UINT nStyle, int iImage );

参数说明

nIndex:要设置信息的按钮索引。

nID:要设置按钮的ID。

nStyle:要设置按钮的风格。

iImage:要设置的位图资源索引。

(16)GetButtonText方法:该方法用于获取工具栏按钮文本。语法如下:

CString GetButtonText( int nIndex ) const;

void GetButtonText( int nIndex, CString& rString ) const;

参数说明

nIndex:标识按钮索引。

rString:用于接收按钮文本。

(17)SetButtonText方法:该方法用于设置按钮文本。语法如下:

BOOL SetButtonText( int nIndex, LPCTSTR lpszText );

参数说明

nIndex:标识按钮ID。

lpszText:标识按钮文本。

(18)GetToolBarCtrl方法:该方法用于访问底层的工具栏按钮通用控件。语法如下:

CToolBarCtrl& GetToolBarCtrl( ) const;

6.2.2 工具栏资源设计

在开发文档视图结构的应用程序时,系统会自动创建工具栏。但是如果开发基于对话框的应用程序,就需要用户自己创建工具栏了。在创建基于对话框的应用程序时,默认情况下,是不会创建工具栏资源的。如果用户想要设计工具栏,可以通过工作区的ResourceView来创建工具栏资源。

(1)在工作区的ResourceView中鼠标右键单击某个节点,在弹出的快捷菜单中选择“Insert”菜单项,打开“Insert Resource”对话框,如图6.19所示。

图6.19 “Insert Resource”对话框

(2)选择“Toolbar”选项,单击“New”按钮创建工具栏资源,如图6.20所示。

(3)在工具栏资源中绘制工具栏按钮。当用户在按钮上绘制图像后,工具栏窗口会自动创建一个新的工具栏按钮,如图6.21所示。

图6.20 工具栏窗口 图6.21 绘制工具栏按钮

说明:如果要为工具栏按钮添加分隔线,可以选中要加入分隔线位置的按钮,将这个按钮向右拖动一点距离,就会在两个按钮之间留下一点空隙,运行程序后,这点空隙就会显示成分隔线了。

(4)如果用户想要删除工具栏资源中的某个按钮,可以先选中该按钮,然后按住鼠标左键,将其拖出工具栏。

(5)在设计完工具栏按钮后,需要为工具栏按钮设置命令ID,如果不指定ID,系统会为每个工具栏按钮设置一个默认的ID。双击工具栏按钮或者选中工具栏按钮后按<Enter>键打开“Toolbar Button Properties”窗口,通过“Toolbar Button Properties”窗口可以设置工具栏按钮命令ID、大小和提示,如图6.22所示。

图6.22 “Toolbar Button Properties”窗口

说明:如果为一个工具栏按钮设置了大小,那么所有的工具栏按钮的大小都会改变为当前设置的大小。

6.2.3 工具栏的命令处理

同菜单一样,每一个工具栏按钮都有一个命令ID,通过命令ID,可以编写命令消息处理函数。当单击工具栏按钮时,会执行消息处理函数。下面介绍如何编写消息处理函数。

(1)打开类向导,选择“Message Maps”选项卡,在“Class name”列表框选择创建了工具栏的对话框类,在“Object Ids”列表中选择工具栏按钮ID,在“Messages”列表中选择“COMMAND”项,如图6.23所示。

图6.23 类向导

(2)单击“Add Function…”按钮,弹出“Add Member Function”对话框,并给出默认时的命令处理函数名,如图6.24所示。

图6.24 “Add Member Function”对话框

(3)单击“OK”按钮,就添加了工具栏按钮的命令处理函数。

6.2.4 动态创建工具栏

工具栏的创建大体有3种方法。第1种方法是先设计一个位图,其中包含了工具栏中的所有按钮图像,每个按钮图像具有相同的大小,然后调用LoadBitmap方法加载位图,最后调用SetButtons方法添加按钮,设置按钮ID和图像索引;第2种方法是定义一个图像列表CImageList对象,向该对象中添加图像,然后将图像列表关联到工具栏中;第3种方法是创建一个工具栏资源,然后调用LoadToolBar方法加载工具栏资源。下面分别介绍这3种方法的应用。

1.第1种方法

(1)创建一个基于对话框的应用程序。

(2)向对话框中添加一个按钮控件,并向工程中导入一个位图,如图6.25所示。

图6.25 工具栏位图

(3)在主窗口头文件中声明一个CToolBar类对象m_ToolBar,代码如下:

CToolBar m_ToolBar;

(4)处理“创建”按钮的单击事件,加载位图,创建工具栏,代码如下:

void CDynamicTool1Dlg::OnButton1()

{

UINT array[11];

for(int i=0;i<10;i++)

{

if(i= =3 || i= =7)

array[i] = ID_SEPARATOR; //第4、第8个按钮为分隔条

else

array[i] = i+1001;

}

m_ToolBar.Create(this);

m_ToolBar.SetButtons(array,11);

m_ToolBar.LoadBitmap(IDB_BITMAP1); //加载位图

m_ToolBar.SetSizes(CSize(40,40),CSize(32,32)); //设置按钮和按钮位图大小

RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0); //显示工具栏

}

程序运行结果如图6.26所示。

图6.26 动态创建工具栏1

2.第2种方法

(1)创建一个基于对话框应用程序。

(2)向对话框中添加一个按钮控件,并向工程中导入9个图标。

(3)在主窗口头文件中声明一个CToolBar类对象m_ToolBar和一个图像列表对象m_ImageList,代码如下:

CToolBar m_ToolBar;

CImageList m_ImageList;

(4)处理“创建”按钮的单击事件,加载图标,关联图像列表,创建工具栏,代码如下:

void CDynamicTool2Dlg::OnButton1()

{

//创建图像列表

m_ImageList.Create(32,32,ILC_COLOR24|ILC_MASK,1,1);

//向图像列表中添加图标

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON1));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON2));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON3));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON4));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON5));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON6));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON7));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON8));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON9));

UINT array[11];

for(int i=0;i<10;i++)

{

if(i= =3 || i= =7)

array[i] = ID_SEPARATOR; //第4、第8个按钮为分隔条

else

array[i] = i+1001;

}

m_ToolBar.Create(this);

m_ToolBar.SetButtons(array,11);

//关联图像列表

m_ToolBar.GetToolBarCtrl().SetImageList(&m_ImageList);

m_ToolBar.SetSizes(CSize(40,40),CSize(32,32)); //设置按钮和图标的大小

RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0);

}

程序运行结果如图6.27所示。

图6.27 动态创建工具栏2

3.第3种方法

(1)创建一个基于对话框的应用程序。

(2)向对话框中添加一个按钮控件,并创建一个工具栏资源,如图6.28所示。

图6.28 工具栏资源

(3)在主窗口头文件中声明一个CToolBar类对象m_ToolBar,代码如下:

CToolBar m_ToolBar;

(4)处理“创建”按钮的单击事件,创建工具栏,加载工具栏资源,代码如下:

void CDynamicTool3Dlg::OnButton1()

{

//创建工具栏

m_ToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP

| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_SIZE_DYNAMIC | CBRS_BORDER_TOP );

m_ToolBar.LoadToolBar(IDR_TOOLBAR1); //加载工具栏资源

//设置图像和按钮的大小

m_ToolBar.GetToolBarCtrl().SetBitmapSize(CSize(16,16));

m_ToolBar.GetToolBarCtrl().SetButtonSize(CSize(22,22));

RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0);

}

程序运行结果如图6.29所示。

图6.29 动态创建工具栏3

6.2.5 工具栏按钮的热点效果

将工具栏设置成具有热点效果可以美化程序界面。

实现步骤如下。

(1)创建一个基于对话框的应用程序。

(2)向对话框中添加一个按钮控件,并向程序中导入16个图标。

(3)在主窗口头文件中声明一个CToolBar类对象m_ToolBar和两个图像列表对象m_ImageList、m_HotImageList,代码如下:

CToolBar m_ToolBar;

CImageList m_ImageList;

CImageList m_HotImageList;

其中,m_ImageList是工具栏按钮的图像列表对象,m_HotImageList是工具栏按钮的热点图像列表对象。

(4)在OnInitDialog函数中加载图标,关联图像列表,创建工具栏,代码如下:

BOOL CHotToolDlg::OnInitDialog()

{

……

// TODO: Add extra initialization here

m_ImageList.Create(32,32,ILC_COLOR24|ILC_MASK,1,1); //创建图像列表

m_HotImageList.Create(32,32,ILC_COLOR24|ILC_MASK,1,1); //创建热点图像列表

//向图像列表中添加图标

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON1));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON2));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON3));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON4));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON5));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON6));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON7));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON8));

m_HotImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON9));

m_HotImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON10));

m_HotImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON11));

m_HotImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON12));

m_HotImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON13));

m_HotImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON14));

m_HotImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON15));

m_HotImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON16));

UINT array[10];

for(int i=0;i<9;i++)

{

if(i= =3 || i= =7)

array[i] = ID_SEPARATOR; //第4、第8个按钮为分隔条

else

array[i] = i+1001;

}

m_ToolBar.CreateEx(this,TBSTYLE_FLAT); //创建工具栏窗口

m_ToolBar.SetButtons(array,10);

m_ToolBar.SetButtonText(0,"新建");

m_ToolBar.SetButtonText(1,"打开");

m_ToolBar.SetButtonText(2,"保存");

m_ToolBar.SetButtonText(4,"剪切");

m_ToolBar.SetButtonText(5,"复制");

m_ToolBar.SetButtonText(6,"粘贴");

m_ToolBar.SetButtonText(8,"打印");

m_ToolBar.SetButtonText(9,"帮助");

//关联图像列表

m_ToolBar.GetToolBarCtrl().SetImageList(&m_ImageList);

//关联热点图像列表

m_ToolBar.GetToolBarCtrl().SetHotImageList(&m_HotImageList);

m_ToolBar.SetSizes(CSize(40,40),CSize(32,32)); //设置按钮和图标的大小

RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0); //显示工具栏

return TRUE;

}

在创建具有热点效果的工具栏时,需要使用CreateEx创建工具栏窗口,只有创建的工具栏窗口具有TBSTYLE_FLAT属性时,工具栏按钮才具有热点效果。然后要使用工具栏控制类的SetHotImageList方法关联热点图像列表。

程序运行结果如图6.30所示。

图6.30 工具栏按钮的热点效果

6.2.6 具有提示功能的工具栏

系统中的工具栏是没有文本显示的,为了使用户能清楚地知道每个工具栏按钮的用途,除了形象的图像外,还应该具有提示功能,下面就来看一下工具栏的提示功能是如何实现的。

(1)创建一个基于对话框的应用程序。

(2)向对话框中添加一个按钮控件,并向工程中导入一个位图,如图6.31所示。

(3)在主窗口头文件中声明一个CToolBar类对象m_ToolBar,并声明一个CString的变量str来保存工具栏按钮文本,代码如下:

CToolBar m_ToolBar;

CString str;

(4)在OnInitDialog函数中加载位图,创建工具栏,代码如下:

BOOL CToolTipDlg::OnInitDialog()

{

……

UINT array[10];

for(int i=0;i<10;i++)

{

if(i= =3 || i= =7)

array[i] = ID_SEPARATOR; //第4、第8个按钮为分隔条

else

array[i] = i+1001;

}

m_ToolBar.Create(this);

m_ToolBar.SetButtons(array,10);

m_ToolBar.SetButtonText(0,"新建");

m_ToolBar.SetButtonText(1,"打开");

m_ToolBar.SetButtonText(2,"保存");

m_ToolBar.SetButtonText(4,"剪切");

m_ToolBar.SetButtonText(5,"复制");

m_ToolBar.SetButtonText(6,"粘贴");

m_ToolBar.SetButtonText(8,"打印");

m_ToolBar.SetButtonText(9,"帮助");

m_ToolBar.LoadBitmap(IDB_BITMAP1); //加载位图

m_ToolBar.SetSizes(CSize(36,36),CSize(16,16)); //设置按钮和按钮位图大小

m_ToolBar.EnableToolTips(TRUE);

RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0); //显示工具栏

return TRUE;

}

EnableToolTips方法用于激活工具栏的提示功能。

(5)在主窗口的消息映射部分添加ON_NOTIFY_EX映射宏,代码如下:

ON_NOTIFY_EX( TTN_NEEDTEXT, 0, OnToolTipNotify)

(6)在主窗口的头文件中添加对OnToolTipNotify函数的声明,代码如下:

afx_msg BOOL OnToolTipNotify( UINT id, NMHDR * pNMHDR, LRESULT * pResult );

(7)添加消息处理函数OnToolTipNotify的实现部分,代码如下:

BOOL CToolTipDlg::OnToolTipNotify(UINT id, NMHDR *pNMHDR, LRESULT *pResult)

{

TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pNMHDR;

UINT nID =pNMHDR->idFrom; //获取工具栏按钮ID

if(nID)

{

nID = m_ToolBar.CommandToIndex(nID); //根据ID获取按钮索引

if(nID != -1)

{

m_ToolBar.GetButtonText(nID,str); //获取工具栏文本

pTTT->lpszText = str.GetBuffer(str.GetLength()); //设置提示信息文本

pTTT->hinst = AfxGetResourceHandle();

return(TRUE);

}

}

return(FALSE);

}

OnToolTipNotify是处理TTN_NEEDTEXT消息的函数,其中参数id是发送消息的控件ID;参数pNMHDR是一个NMHDR结构指针,该结构记录了发送消息的控件ID、句柄等信息;参数pResult表示结果代码指针,TTN_NEEDTEXT消息可以忽略该参数。

程序运行结果如图6.32所示。

图6.32 具有提示功能的工具栏

6.2.7 带下拉按钮的工具栏

在工具栏按钮的旁边添加一个呈倒三角形的下拉按钮可以扩展工具栏按钮的选择功能。下拉按钮在按下后会弹出一个下拉菜单,下拉菜单中的选项就是对按钮增强的功能。下面来介绍一下如何为工具栏添加下拉按钮。

(1)创建一个基于单文档的应用程序。

(2)新建一个菜单资源,如图6.33所示。

(3)修改工具栏资源,为工具栏添加一个修改字体按钮,如图6.34所示。

图6.33 菜单资源 图6.34 工具栏资源

(4)在框架头文件中修改工具栏风格,使“A”按钮具有下拉按钮,代码如下:

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

if (CFrameWnd::OnCreate(lpCreateStruct) = = -1)

return -1;

if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP

| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||

!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))

{

TRACE0("Failed to create toolbarn");

return -1;

}

if (!m_wndStatusBar.Create(this) ||

!m_wndStatusBar.SetIndicators(indicators,

sizeof(indicators)/sizeof(UINT)))

{

TRACE0("Failed to create status barn");

return -1;

}

m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);

EnableDocking(CBRS_ALIGN_ANY);

DockControlBar(&m_wndToolBar);

m_wndToolBar.GetToolBarCtrl().SetExtendedStyle(TBSTYLE_EX_DRAWDDARROWS);

DWORD dwStyle=m_wndToolBar.GetButtonStyle(m_wndToolBar.CommandToIndex(ID_FONT));

dwStyle|=TBSTYLE_DROPDOWN;

m_wndToolBar.SetButtonStyle(m_wndToolBar.CommandToIndex(ID_FONT),dwStyle);

return 0;

}

SetExtendedStyle是CToolBarCtrl类的方法,该方法用于设置工具栏控件的扩展风格,语法如下:

DWORD SetExtendedStyle( DWORD dwExStyle ) const;

参数说明

dwExStyle:系统定义的工具栏控件风格,取值TBSTYLE_EX_DRAWDDARROWS,可以为某一个按钮添加下拉按钮。

(5)在框架源文件消息映射宏中添加如下代码:

ON_NOTIFY(TBN_DROPDOWN, AFX_IDW_TOOLBAR, OnToolbarDropDown)

(6)在框架的头文件中添加消息响应函数的声明,代码如下:

afx_msg void OnToolbarDropDown(NMTOOLBAR* pnmh, LRESULT* plRes);

(7)OnToolbarDropDown函数的实现代码如下:

void CMainFrame::OnToolbarDropDown(NMTOOLBAR* pnmtb, LRESULT *plr)

{

CWnd *pWnd;

UINT nID;

switch (pnmtb->iItem)

{

case ID_FONT:

pWnd = &m_wndToolBar;

nID = IDR_MENU1;

break;

default:

return;

}

//加载相应的显示菜单

CMenu menu;

menu.LoadMenu(nID);

CMenu* pPopup = menu.GetSubMenu(0);

ASSERT(pPopup);

CRect rc;

pWnd->SendMessage(TB_GETRECT, pnmtb->iItem, (LPARAM)&rc);

pWnd->ClientToScreen(&rc);

pPopup->TrackPopupMenu( TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_VERTICAL,

rc.left, rc.bottom, this, &rc);

}

CWnd类的ClientToScreen方法用于将客户坐标转换成屏幕坐标,TrackPopupMenu方法用于弹出菜单。

(8)在视图头文件中声明一个CFont类型变量Font,并在构造函数中初始化变量Font。重载OnDraw函数,设置视图中的显示文本。

(9)通过类向导为新创建的菜单和工具栏按钮添加消息处理函数,代码如下:

void CDropToolBarView::OnFont()

{

OnMenu100();

}

void CDropToolBarView::OnMenu200()

{

Font.CreatePointFont(240,"宋体");

Invalidate();

}

void CDropToolBarView::OnMenu150()

{

Font.CreatePointFont(180,"宋体");

Invalidate();

}

void CDropToolBarView::OnMenu100()

{

Font.CreatePointFont(120,"宋体");

Invalidate();

}

void CDropToolBarView::OnMenu50()

{

Font.CreatePointFont(60,"宋体");

Invalidate();

}

程序运行结果如图6.35所示。

图6.35 带下拉按钮的工具栏

6.2.8 工具栏控制类CToolBarCtrl

CToolBarCtrl类提供了Windows通用工具栏控制功能,是一个矩形子窗口,包含一个或多个按钮,这些按钮可以显示位图图像、字符文本或两者都有。

CToolBarCtrl类的主要方法如表6.1所示。

表6.1 CToolBarCtrl类主要方法表

方 

描 

Create

创建工具栏并将它与一个CToolBarCtrl类对象连接

IsButtonEnabled

指示工具栏中的指定按钮是否有效

IsButtonChecked

指示工具栏中的指定按钮是否被选中

IsButtonPressed

指示工具栏中的指定按钮是否被按下

IsButtonHidden

指示工具栏中的指定按钮是否隐藏

IsButtonIndeterminate

指示工具栏中的指定按钮的状态是否不可用[g1]

SetState

设置工具栏中的指定按钮的状态

GetState

获取工具栏中的指定按钮的状态

GetButton

获取工具栏中的指定按钮

GetButtonCount

获取工具栏按钮的数目

GetItemRect

获取工具栏按钮的边界矩形

GetRect

获取一个指定工具栏按钮的边界矩形

SetButtonStructSize

指定TBBUTTON结构的大小

GetButtonSize

获取当前工具栏按钮的大小

SetButtonSize

设置当前工具栏按钮的大小

SetBitmapSize

设置工具栏按钮的图像大小

续表

方 

描 

GetToolTips

获取与此工具栏相关联的工具栏提示的句柄

SetToolTips

将工具栏提示与工具栏进行关联

SetOwner

设置接收工具栏通知消息的按钮

SetRows

设置工具栏按钮的行数

GetRows

获取工具栏按钮的行数

SetCmdID

设置当按钮被按下时要发送到主窗口的命令ID

GetBitmapFlags

获取与工具栏位图相关联的标志

GetDisabledImageList

获取工具栏用来显示无效按钮的图像列表

GetHotImageList

获取工具栏用来显示热点按钮的图像列表

GetImageList

获取工具栏默认时的图像列表

GetStyle

获取工具栏当前的风格

GetMaxTextRows

获取工具栏按钮的显示文本的最大行数

IsButtonHighlighted

检查工具栏按钮的加亮状态

SetButtonWidth

设置工具栏按钮宽度的最大值和最小值

SetDisabledImageList

设置工具栏用来显示无效按钮的图像列表

SetHotImageList

设置工具栏用来显示热点按钮的图像列表

SetImageList

设置工具栏默认时的图像列表

GetDropTarget

设置工具栏的IDropTarget接口

SetIndent

设置工具栏中第一个按钮的缩进

SetMaxTextRows

设置工具栏按钮的显示文本的最大行数

SetStyle

设置工具栏当前的风格

GetAnchorHighlight

获取工具栏的加亮设置

SetAnchorHighlight

对工具栏进行加亮设置

GetHotItem

获取工具栏热点项索引

SetHotItem

设置工具栏热点项索引

GetInsertMark

获取工具栏的当前插入标记

SetInsertMark

设置工具栏的当前插入标记

GetMaxSize

获取工具栏可视按钮和分隔条的总大小

InsertMarkHitTest

获取工具栏中指定点的插入信息

GetExtendedStyle

获取工具栏的扩展风格

SetExtendedStyle

设置工具栏的扩展风格

GetInsertMarkColor

获取工具栏插入标记的颜色

SetInsertMarkColor

设置工具栏插入标记的颜色

MapAccelerator

将一个加速键映射到一个工具栏按钮

MoveButton

将一个工具栏按钮从一个索引移动到另一个索引

HitTest

确定一个点位于工具栏的具体位置

EnableButton

设置工具栏按钮是否有效

CheckButton

是否选中工具栏中的指定按钮

PressButton

是否按下工具栏中的指定按钮

GetButtonInfo

获取工具栏指定按钮的信息

续表

方 

描 

SetButtonInfo

设置工具栏指定按钮的信息

SetDrawTextFlags

设置Win32中DrawText功能标志

HideButton

隐藏或显示工具栏中的指定按钮

Indeterminate

设置工具栏中指定按钮是否灰色状态

AddBitmap

将位图图像添加到工具栏可用的图像列表中

AddButtons

将按钮添加到工具栏中

InsertButton

在工具栏中插入按钮

DeleteButton

从工具栏中删除按钮

CommandToIndex

获取与指定命令ID相关联的索引

RestoreState

恢复工具栏状态

MarkButton

设置工具栏的高亮显示状态

LoadImages

将位图装载到工具栏的图像列表中

SaveState

保存工具栏状态

Customize

显示CustomizeToolBar对话框

AddString

将作为资源ID传递的一个字符串添加到工具栏的内部字符串列表中

AddStrings

将多个字符串添加到工具栏的内部字符串列表中

AutoSize

调整工具栏的大小

下面使用CToolBarCtrl类创建一个工具栏。

步骤如下。

(1)创建一个基于对话框的应用程序。

(2)向对话框中添加一个按钮控件,并向工程中导入8个图标。

(3)在主窗口头文件中声明一个CToolBarCtrl类对象m_ToolBar和一个图像列表对象m_ImageList,代码如下:

CToolBarCtrl m_ToolBar;

CImageList m_ImageList;

(4)在工作区窗口中选择ResourceView,展开String Table节点,双击abc String Table节点,打开字符串编辑器,在字符串编辑器中设置工具栏按钮的显示文本,如图6.36所示。

图6.36 字符串编辑器

(5)在OnInitDialog函数中加载图标,关联图像列表,创建工具栏,代码如下:

BOOL CToolCtrlDlg::OnInitDialog()

{

……

TBBUTTON button[10];

CString string;

TCHAR * pString;

int num;

//创建一个图像列表

m_ImageList.Create(32,32,ILC_COLOR32|ILC_MASK,0,0);

//向图像列表中添加图标

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON1));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON2));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON3));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON4));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON5));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON6));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON6));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON7));

m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON8));

m_ToolBar.Create(WS_CHILD|WS_VISIBLE,CRect(0,0,0,0),this,1100);

m_ToolBar.SetImageList(&m_ImageList);

for(int i=0;i<10;i++)

{

button[i].dwData = 0;

button[i].fsState = TBSTATE_ENABLED;

if(i= =3 ||i= =7)

button[i].fsStyle = TBSTYLE_SEP;

else

button[i].fsStyle = TBSTYLE_BUTTON;

button[i].iBitmap = i;

string.LoadString(i + IDS_STRING1);//装载字符串资源

//为每一个字符串再加一个'',用于向工具栏里加字符串

num = string.GetLength() + 1;

pString = string.GetBufferSetLength(num);

//返回刚加的字符串的编号

button[i].iString = m_ToolBar.AddStrings(pString);

string.ReleaseBuffer();

}

m_ToolBar.AddButtons(10,button);

m_ToolBar.AutoSize();

m_ToolBar.SetStyle(TBSTYLE_FLAT|CCS_TOP);

return TRUE;

}