MFC对话框中的工具栏、状态栏设计小结

时间:2022-03-26 06:50:28

对网上的资料结合自己的实践的总结,由于大部分都是网上先辈们的经验,这里只是直接将内容拿来,格式优化一下更易读而已。

对话框中建立工具栏的方法

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

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:标识工具栏风格。可选值如下:

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;

2、工具栏资源设计

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

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

(2)选择“Toolbar”选项,单击“New”按钮创建工具栏资源

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

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

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

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

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

3、工具栏的命令处理

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

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

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

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

4、动态创建工具栏

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

1.第1种方法

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

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

(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); //显示工具栏
}

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);
}

3.第3种方法

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

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

(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);
}

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、具有提示功能的工具栏

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

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

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

(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消息可以忽略该参数。

7、带下拉按钮的工具栏

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

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

(2)新建一个菜单资源。

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

(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();

}

8、工具栏控制类CToolBarCtrl

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

CToolBarCtrl类的主要方法如下表所示:

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节点,打开字符串编辑器,在字符串编辑器中设置工具栏按钮的显示文本。

(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;
}

对话框中建立状态栏的方法

状态栏(CStatusBar 类的一个窗口对象)包含几个“窗格”。每个窗格都是状态栏中可用来显示信息的矩形区域。
例如,很多应用程序在最右边的窗格显示CAPSLOCK、NUMLOCK和其他键的状态。
应用程序还经常在最左边的窗格(窗格0)显示信息文本,此窗格有时称为“消息窗格”。 例如,默认 MFC
状态栏使用消息窗格显示一个字符串,来解释当前选定的菜单项或工具栏按钮。
新建窗格
To create a status bar, follow these steps:

1.Construct the CStatusBar object.

2.Call the Create (or CreateEx) function to create the status-bar window and attach it to the CStatusBar object.

3.Call SetIndicators to associate a string ID with each indicator.

方法一:

首先要在类成员中添加变量声明:

CStatusBar m_Statusbar;

接下来进行状态栏的创建和显示,在OnInitDialog()中:

//获得系统当前时间
CTime time;
time=time.GetCurrentTime();
CString stime;
stime.Format("%s",time.Format("%y-%m-%d %H:%M:%S"));

//创建状态栏
UINT array[2]={12301,12302}; //注:这里是ID号,应保证不与resource.h中的其他ID号重复
m_Statusbar.Create(this);
m_Statusbar.SetIndicators(array,sizeof(array)/sizeof(UINT));

//显示状态栏
CRect rect;
GetWindowRect(rect);
m_Statusbar.SetPaneInfo(0,array[0],0,rect.Width()/3);
m_Statusbar.SetPaneInfo(1,array[1],0,rect.Width()/3*2);
m_Statusbar.SetPaneText(0,stime);
m_Statusbar.SetPaneText(1,"小鬼当家博客:blog.sina.com.cn/u/1628556937");
RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0);

效果图如下图所示:

MFC对话框中的工具栏、状态栏设计小结

【注】
上述的

UINT array[2]={12301,12302};

也可以使用一下方法写成更明确的方式:

/* 
1.定义窗格的命令 ID。
在“视图”菜单上单击“资源视图”。右击项目资源并单击“资源符号”。在“资源符号”对话框中,单击“新建”。
键入一个命令 ID 名称:例如,ID_INDICATOR_PAGE。为 ID 指定值,或接受“资源符号”对话框建议的值。
例如,对于 ID_INDICATOR_PAGE,接受默认值。关闭“资源符号”对话框。

2.定义窗格中要显示的默认字符串。
打开“资源视图”后,在为应用程序列出资源类型的窗口中双击“String Table”。
打开“字符串表”编辑器后,从“插入”菜单中选择“新建字符串”。
在“字符串属性”窗口中,选择窗格的命令 ID(例如:ID_INDICATOR_PAGE)并键入默认字符串值,
如“Page ”。关闭字符串编辑器。(需要一个默认字符串以避免编译器错误。)

3.在文件 MAINFRM.CPP 中定位 indicators 数组。
该数组按从左向右的顺序为状态栏的所有指示器列出了命令 ID。
在数组中的适当位置,输入窗格的命令 ID。
*/


static UINT BASED_CODE indicators[] =
{
ID_SEPARATOR, //分隔符(系统自带,可不写)
ID_INDICATOR_CAPS, //大小写指示符(系统自带,可不写)
ID_INDICATOR_NUM, //NumLoak指示符(系统自带,可不写)
ID_INDICATOR_SCRL, //Scroll指示符(系统自带,可不写)
ID_INDICATOR_PAGE, //用户自定义
};

方法二:

在对话框窗口的OnInitDialog()过程写上以下代码即可:

//设置状态栏
HWND hDlg=GetSafeHwnd();
HWND hStatusWindow=CreateStatusWindow(WS_CHILD|WS_VISIBLE|WS_BORDER,
TEXT("就绪"),//显示在状态栏上的信息
hDlg, //父窗口句柄
IDS_STATUS); //预定义的资源ID,相当于状态栏的ID号:GetDlgItem(IDS_STATUS)

int pint[4]={100,200,350,-1};//状态栏第一个方格右边界离窗口客户区左边界的距离为100
//第二个方格右边界离窗口客户区左边界的距离为200
//...以此类推
//-1表示该方格的右边界为为窗口客户区的右边界
::SendMessage(hStatusWindow,SB_SETPARTS,4,(LPARAM)pint);
::SendMessage(hStatusWindow,SB_SETTEXT,1,(LPARAM)TEXT("信息1"));
::SendMessage(hStatusWindow,SB_SETTEXT,2,(LPARAM)TEXT("信息2"));
::SendMessage(hStatusWindow,SB_SETTEXT,3,(LPARAM)TEXT("信息3"));

效果截图如下:

MFC对话框中的工具栏、状态栏设计小结

预定义资源ID截图,在【资源视图】里面的String Table进行添加即可:

MFC对话框中的工具栏、状态栏设计小结

参考资料

MFC工具栏设计

MFC基于对话框中添加状态栏

MFC状态栏创建和设计

给MFC对话框设置状态栏