程序目标:在基于对话框的MFC项目中,自制三个 Toolbar 按钮(用颜色区分,分别为红、绿、蓝);程序运行时,单击红色按钮显示一个红色的填充椭圆;再单击绿色按钮则进行清屏;最后单击蓝色按钮退出程序。
具体步骤如下:
1、利用VS2022建立一个基于对话框的MFC应用,项目名称:myToolbar,具体步骤略。项目建好后,选择对话框界面,删去“TODO:*** ”、“确定”、“取消”等。然后右键对话框->属性->文字描述:myToolbar。
2、结决方案资源管理器->右键资源文件->选择 Toobar ->新建。此时,会出现绘制位图按钮的界面,屏幕右上方有各种绘图工具,左上角有要编辑的按钮,靠近中间有放大图。我们要编辑的就是这个放大图。
如果没有出现调色板,可以右键按钮选择 "显示颜色窗口" 即可出现。接着,利用绘图工具画出第一个红色按钮(用喷枪全喷成红色),再右键画好的红色按钮,将ID改为ID_RED;此时,在画好的红色按钮右边又出现了一个灰色按钮,点击它又出现绘图界面,我们将其喷成绿色,然后ID改为ID_GREEN;照方抓药,再弄一个蓝色的,ID改为ID_BLUE。每画好一个按钮,旁边就出现一个灰色的,不想再增加按钮时就不要点它了。一旦绘制按钮多了不想要,把它用鼠标拖出扔了即可。
3、步骤2中的绘图编辑界面如果找不到了,可以通过视图 -> 其它窗口 -> 资源视图 -> 点开 Toobar -> 双击 IDR_TOOLBAR1 就可出现编辑界面。(IDR_TOOLBAR1就是我们要编辑的工具条的ID)
4、到这一步后,暂时将绘图界面关上。下面开始给程序添加一些代码,实际上大量的结构性代码都是VS自动生成的,省了我们很多事,我们就先不管它了。以下是要增加的代码,代码及含义见注释。
5、先找到 myToolbarDlg.h 文件,在public:下面声明一个工具条成员变量,代码:
CToolBar toolbar; //声明工具条成员变量
6、再找到myToolbarDlg.cpp文件,在初始化程序 CmyToolbarDlg::OnInitDialog() 中添加下列代码,位置在"TODO:"之后:
CWnd* pWnd = AfxGetApp()->GetMainWnd();toolbar.Create(pWnd); //工具栏的父窗口,直接写this也可;Create还有许多参数,这里全使用缺省值toolbar.LoadToolBar(IDR_TOOLBAR1); //加载工具条UINT arr[] = {ID_RED,ID_GREEN,ID_BLUE}; //把按钮数组化toolbar.SetButtons(arr, 3); //按钮赋给工具条RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0); //重置工具条,否则不显示
此时,如运行程序,对话框上已经出现三个按钮,只是点击没有反应。
7、再回到myToolbarDlg.h文件,在protect:下面声明三个按钮响应函数,代码:
afx_msg void OnIDRed(); //画红色边线红色填充的椭圆afx_msg void OnIDGreen(); //恢复屏幕原来颜色afx_msg void OnIDBlue(); //恢复屏幕原来颜色
因为这三个按钮是自己画的,所以使用类向导找不到(下面还有步骤也是这样),需要自己直接写上去。
8、转到myToolbarDlg.cpp文件,找到对话框类的消息处理宏BEGIN_MESSAGE_MAP(CmyToolbarDlg, CDialogEx),在其中添加三个按钮的单击消息处理宏:
ON_COMMAND(ID_RED, OnIDRed) //抛出点击红色工具按钮消息ON_COMMAND(ID_GREEN,OnIDGreen) //抛出点击绿色按钮消息ON_COMMAND(ID_BLUE, OnIDBlue) //抛出点击蓝色按钮消息
此时,单击消息与处理函数之间已经建立的映射关系,只是函数没有实现。
9、实现void CmyToolbarDlg::OnIDRed() 函数,位置在myToolbarDlg.cpp文件后边找个地方就行。全部代码如下:
//点击红色按钮的消息处理程序(绘制红色椭圆)
void CmyToolbarDlg::OnIDRed()
{CRect rect;//定义矩形类对象(格式化结构)GetClientRect(&rect);//全局函数获得客户区数据存入rectCDC* pDC = GetDC(); //定义设备上下文指针pDC->SetMapMode(MM_ANISOTROPIC);//映射模式(窗口模式确定为自定义)pDC->SetWindowExt(rect.Width(), rect.Height());//逻辑窗口尺寸pDC->SetViewportExt(rect.Width(), -rect.Height());//物理窗口尺寸,同时更改Y方向pDC->SetViewportOrg(rect.Width() / 2, rect.Height() / 2);//圆心确定rect.OffsetRect(-rect.Width() / 2, -rect.Height() / 2);//将自定义坐标系重置rectrect.DeflateRect(50, 50);//将客户区矩形内缩50(防止画图画到工具条区域)CBrush redBrush(0x0000FF);//定义红色画刷(画刷颜色为封闭图的填充色)CBrush* pOldBrush = pDC->SelectObject(&redBrush);CPen redPen(PS_SOLID, 1, 0x0000FF); //定义一个画笔:红色实线(16进制红颜色为0xbbggrr)CPen* pOldPen = pDC->SelectObject(&redPen); //将画笔选入int x = rect.Width() / 2;int y = rect.Height() / 2;pDC->Ellipse(-x, y, x, -y); //以缩小后的1/2客户区矩形高、宽为长短半径做椭圆pDC->SelectObject(pOldBrush);//恢复缺省画刷
}
10、实现void CmyToolbarDlg::OnIDGreen(),位置挨着上一个程序即可,代码如下:
//点击绿色按钮的消息处理程序(清空窗口)
void CmyToolbarDlg::OnIDGreen()
{CRect rect;//定义矩形类对象(格式化结构)GetClientRect(&rect);//全局函数获得客户区数据存入rectrect.DeflateRect(50, 50);//将客户区矩形内缩50(防止恢复颜色影响工具条区域)CDC* pDC = GetDC(); //定义设备上下文指针pDC->FillSolidRect(&rect, GetSysColor(COLOR_3DFACE));//sysBKcolor
}
11、实现void CmyToolbarDlg::OnIDBlue(),位置还是挨着上一个,代码如下:
//点击蓝色按钮的消息处理程序(退出)
void CmyToolbarDlg::OnIDBlue()
{MessageBox(L"程序即将关闭...");CDialog::OnOK(); //调用OnClose不能关闭对话框,故调用OnOK
}
12、运行效果截图:
a. 显示红色椭圆截图
b. 清屏后、退出前界面截图