打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
MFC之在对话框创建菜单、工具栏、状态栏
userphoto

2022.09.22 云南

关注

希望对读者提供参考价值,也方便自己以后查阅。

首先用MFC向导创建对话框资源class CAddSourceDlg,然后在对话框类中声明需要创建的资源:

[cpp] view plain copy print?
  1. private:  
  2.     CMenu m_menu;                //菜单  
  3.     CToolBar m_toolbar;          //工具栏  
  4.     CStatusBar m_statusbar;      //状态栏  
  5.     CProgressCtrl m_progress;    //进度条  
  1. private:
  2. CMenu m_menu; //菜单
  3. CToolBar m_toolbar; //工具栏
  4. CStatusBar m_statusbar; //状态栏
  5. CProgressCtrl m_progress; //进度条

在资源窗口编辑菜单资源,如下:


接下来在成员函数OnInitDialog中将菜单资源添加到对话框。对菜单项的索引有两种方式,一种是通过位置索引,另一种是通过资源ID索引,

第一个参数的值取决于第二个参数,这在上一篇博文中有提到。

[cpp] view plain copy print?
  1. //创建菜单  
  2. m_menu.LoadMenu(IDR_MENU1);  
  3. SetMenu(&m_menu);  
  4. //设置标记菜单  
  5. GetMenu()->GetSubMenu(0)->CheckMenuItem(2, MF_CHECKED|MF_BYPOSITION);  
  6. GetMenu()->GetSubMenu(0)->CheckMenuItem(ID_DISP_STATUSBAR, MF_CHECKED|MF_BYCOMMAND);  
  1. //创建菜单
  2. m_menu.LoadMenu(IDR_MENU1);
  3. SetMenu(&m_menu);
  4. //设置标记菜单
  5. GetMenu()->GetSubMenu(0)->CheckMenuItem(2, MF_CHECKED|MF_BYPOSITION);
  6. GetMenu()->GetSubMenu(0)->CheckMenuItem(ID_DISP_STATUSBAR, MF_CHECKED|MF_BYCOMMAND);
菜单创建好了,添加前两个菜单项的响应函数如下:
[cpp] view plain copy print?
  1. void CAddSourceDlg::OnPrintT()   
  2. {  
  3.     // TODO: Add your command handler code here  
  4.     MessageBox("print T");  
  5. }  
  6.   
  7. void CAddSourceDlg::OnPrintI()   
  8. {  
  9.     // TODO: Add your command handler code here  
  10.     MessageBox("print I");  
  11. }  
  1. void CAddSourceDlg::OnPrintT()
  2. {
  3. // TODO: Add your command handler code here
  4. MessageBox("print T");
  5. }
  6. void CAddSourceDlg::OnPrintI()
  7. {
  8. // TODO: Add your command handler code here
  9. MessageBox("print I");
  10. }

然后在资源窗口编辑工具栏资源。由于工具栏相当于菜单的快捷方式,所以工具栏的按钮ID必须和关联菜

单项的ID一致,共用同一个响应函数。这里讲将工具栏按钮T和按钮I的ID分别设置成菜单项“打印“T””和打印“I”的ID。


然后在成员函数OnInitDialog中将工具栏资源添加到对话框。

[cpp] view plain copy print?
  1.       //创建工具栏  
  2. m_toolbar.CreateEx(this);                     //创建空白工具栏  
  3. m_toolbar.LoadToolBar(IDR_TOOLBAR1);          //加载工具栏资源  
  4. CRect rect;   
  5. GetClientRect(&rect);                         //计算客户区大小  
  6. m_toolbar.MoveWindow(0,0,rect.Width(), 25);   //必须设置工具栏显示位置  
  1. //创建工具栏
  2. m_toolbar.CreateEx(this); //创建空白工具栏
  3. m_toolbar.LoadToolBar(IDR_TOOLBAR1); //加载工具栏资源
  4. CRect rect;
  5. GetClientRect(&rect); //计算客户区大小
  6. m_toolbar.MoveWindow(0,0,rect.Width(), 25); //必须设置工具栏显示位置

运行程序,发现点击工具栏按钮和点击对应菜单项都会调用相同的响应函数,证明创建的工具栏没有问题。

由于在创建状态栏时需要设置各元素的ID,所以现在头文件resource.h中定义好然后在成员函数OnInitDialog中将状态栏资源添加到对话框。其中状态栏第一个元素用来显示系统时间,第二个元素用来指示鼠标位置,第三个元素用来表示进度条。

[cpp] view plain copy print?
  1. //创建状态栏  
  2. //创建定时器,由于重载了基类消息响应函数,因此第三个参数可以为NULL  
  3. SetTimer(ID_TIMER, 1000, NULL);  
  4. static UINT indicators[] =    //指定状态栏上三个元素的ID  
  5. {  
  6.     IDS_TIME,  
  7.     IDS_PROGRESS,  
  8.     IDS_MOUSE  
  9. };  
  10.   
  11.        m_statusbar.Create(this);           //创建空白状态栏  
  12. //设置状态栏上元素的ID及元素数量  
  13.        m_statusbar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT));  
  14. //设置状态栏3个元素的宽度  
  15.        m_statusbar.SetPaneInfo(0, IDS_TIME, SBPS_NORMAL, rect.Width()/3);  
  16.        m_statusbar.SetPaneInfo(1, IDS_MOUSE, SBPS_NORMAL, 80);  
  17. m_statusbar.SetPaneInfo(2, IDS_PROGRESS, SBPS_STRETCH, 100);  
  18. //必须重新设置和调整状态栏大小,否则无法显示  
  19. RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0);  
  1. //创建状态栏
  2. //创建定时器,由于重载了基类消息响应函数,因此第三个参数可以为NULL
  3. SetTimer(ID_TIMER, 1000, NULL);
  4. static UINT indicators[] = //指定状态栏上三个元素的ID
  5. {
  6. IDS_TIME,
  7. IDS_PROGRESS,
  8. IDS_MOUSE
  9. };
  10. m_statusbar.Create(this); //创建空白状态栏
  11. //设置状态栏上元素的ID及元素数量
  12. m_statusbar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT));
  13. //设置状态栏3个元素的宽度
  14. m_statusbar.SetPaneInfo(0, IDS_TIME, SBPS_NORMAL, rect.Width()/3);
  15. m_statusbar.SetPaneInfo(1, IDS_MOUSE, SBPS_NORMAL, 80);
  16. m_statusbar.SetPaneInfo(2, IDS_PROGRESS, SBPS_STRETCH, 100);
  17. //必须重新设置和调整状态栏大小,否则无法显示
  18. RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0);

因为显示系统时间要不断刷新,所一上面创建了一个时间间隔为1秒触发事件的定时器,响应函数为基类的虚函数。这里可以重写虚函数,定义我们自己的虚函数。每隔1秒钟,重新获取系统时钟,并显示在对应状态栏上。

[cpp] view plain copy print?
  1. void CAddSourceDlg::OnTimer(UINT nIDEvent)   
  2. {  
  3.     // TODO: Add your message handler code here and/or call default  
  4.     CString strTime;  
  5.     CTime time = CTime::GetCurrentTime();  
  6.     strTime.Format("%d:%d:%d", time.GetHour(),time.GetMinute(),time.GetSecond());  
  7.     //确定字符串长度  
  8. //  CClientDC dc(this);  
  9. //  CSize sz = dc.GetTextExtent(strTime);  
  10. //  m_statusbar.SetPaneInfo(0, IDS_TIME, SBPS_NORMAL, sz.cx);  
  11.     m_statusbar.SetPaneText(0, strTime);  
  12.       
  13.     //每过1s,进度条自动增长  
  14.     //m_progress.StepIt();  
  15.     CDialog::OnTimer(nIDEvent);  
  16. }  
  1. void CAddSourceDlg::OnTimer(UINT nIDEvent)
  2. {
  3. // TODO: Add your message handler code here and/or call default
  4. CString strTime;
  5. CTime time = CTime::GetCurrentTime();
  6. strTime.Format("%d:%d:%d", time.GetHour(),time.GetMinute(),time.GetSecond());
  7. //确定字符串长度
  8. // CClientDC dc(this);
  9. // CSize sz = dc.GetTextExtent(strTime);
  10. // m_statusbar.SetPaneInfo(0, IDS_TIME, SBPS_NORMAL, sz.cx);
  11. m_statusbar.SetPaneText(0, strTime);
  12. //每过1s,进度条自动增长
  13. //m_progress.StepIt();
  14. CDialog::OnTimer(nIDEvent);
  15. }
因为要在状态栏上显示鼠标位置,这里在对话框类中定义一个鼠标移动的消息响应函数
[cpp] view plain copy print?
  1. void CAddSourceDlg::OnMouseMove(UINT nFlags, CPoint point)   
  2. {  
  3.     // TODO: Add your message handler code here and/or call default  
  4.     CString strPoint;  
  5.     strPoint.Format("%d,%d", point.x,point.y);  
  6.     m_statusbar.SetPaneText(1, strPoint);  
  7.     CDialog::OnMouseMove(nFlags, point);  
  8. }  
  1. void CAddSourceDlg::OnMouseMove(UINT nFlags, CPoint point)
  2. {
  3. // TODO: Add your message handler code here and/or call default
  4. CString strPoint;
  5. strPoint.Format("%d,%d", point.x,point.y);
  6. m_statusbar.SetPaneText(1, strPoint);
  7. CDialog::OnMouseMove(nFlags, point);
  8. }
然后成员函数OnInitDialog中创建进度条资源
[cpp] view plain copy print?
  1. //创建进度条  
  2. CRect rectPro;  
  3. m_statusbar.GetItemRect(2, &rectPro);   //获取状态栏元素2的区间大小  
  4. //注意此处进度条的父窗口设置为状态栏  
  5. m_progress.Create(WS_CHILD|WS_VISIBLE, rectPro, &m_statusbar, ID_PROGRESS);  
  6. //设置初始位置  
  7. m_progress.SetPos(50);  
  8. //设置步长  
  9. m_progress.SetStep(5);  
  1. //创建进度条
  2. CRect rectPro;
  3. m_statusbar.GetItemRect(2, &rectPro); //获取状态栏元素2的区间大小
  4. //注意此处进度条的父窗口设置为状态栏
  5. m_progress.Create(WS_CHILD|WS_VISIBLE, rectPro, &m_statusbar, ID_PROGRESS);
  6. //设置初始位置
  7. m_progress.SetPos(50);
  8. //设置步长
  9. m_progress.SetStep(5);
也可以在定时响应函数中递增进度。

最后还要实现菜单项控制工具栏和状态栏的显示、隐藏,添加其余两个菜单项的消息响应函数如下:

[cpp] view plain copy print?
  1. void CAddSourceDlg::OnDispToolbar()   
  2. {  
  3.     // TODO: Add your command handler code here  
  4.     if (m_toolbar.IsVisible())  
  5.     {   //如果工具栏处于可见状态,则隐藏,并将菜单的标记撤除  
  6.         m_toolbar.ShowWindow(SW_HIDE);  
  7.         GetMenu()->GetSubMenu(0)->CheckMenuItem(2, MF_UNCHECKED|MF_BYPOSITION);  
  8.     }  
  9.     else  
  10.     {  
  11.         //如果工具栏处于不可见状态,则消失,并添加菜单标记  
  12.         m_toolbar.ShowWindow(SW_SHOW);  
  13.         GetMenu()->GetSubMenu(0)->CheckMenuItem(2, MF_CHECKED|MF_BYPOSITION);  
  14.     }  
  15. }  
  16.   
  17. void CAddSourceDlg::OnDispStatusbar()   
  18. {  
  19.     // TODO: Add your command handler code here  
  20.     if (m_statusbar.IsVisible())  
  21.     {  
  22.         m_statusbar.ShowWindow(SW_HIDE);  
  23.         GetMenu()->GetSubMenu(0)->CheckMenuItem(ID_DISP_STATUSBAR, MF_UNCHECKED|MF_BYCOMMAND);  
  24.     }  
  25.     else  
  26.     {  
  27.         m_statusbar.ShowWindow(SW_SHOW);  
  28.         GetMenu()->GetSubMenu(0)->CheckMenuItem(ID_DISP_STATUSBAR, MF_CHECKED|MF_BYCOMMAND);  
  29.     }  
  30. }  
  1. void CAddSourceDlg::OnDispToolbar()
  2. {
  3. // TODO: Add your command handler code here
  4. if (m_toolbar.IsVisible())
  5. { //如果工具栏处于可见状态,则隐藏,并将菜单的标记撤除
  6. m_toolbar.ShowWindow(SW_HIDE);
  7. GetMenu()->GetSubMenu(0)->CheckMenuItem(2, MF_UNCHECKED|MF_BYPOSITION);
  8. }
  9. else
  10. {
  11. //如果工具栏处于不可见状态,则消失,并添加菜单标记
  12. m_toolbar.ShowWindow(SW_SHOW);
  13. GetMenu()->GetSubMenu(0)->CheckMenuItem(2, MF_CHECKED|MF_BYPOSITION);
  14. }
  15. }
  16. void CAddSourceDlg::OnDispStatusbar()
  17. {
  18. // TODO: Add your command handler code here
  19. if (m_statusbar.IsVisible())
  20. {
  21. m_statusbar.ShowWindow(SW_HIDE);
  22. GetMenu()->GetSubMenu(0)->CheckMenuItem(ID_DISP_STATUSBAR, MF_UNCHECKED|MF_BYCOMMAND);
  23. }
  24. else
  25. {
  26. m_statusbar.ShowWindow(SW_SHOW);
  27. GetMenu()->GetSubMenu(0)->CheckMenuItem(ID_DISP_STATUSBAR, MF_CHECKED|MF_BYCOMMAND);
  28. }
  29. }
运行程序,显示正常,虽然简陋,但是方法还算易懂。





本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
自定义状态栏和工具栏
在菜单中加入图标
用VB编写记事本
VB基础状态栏(StatusBar)和工具栏(ToolBar)
第八章 VB中ActiveX控件的使用
VB程序设计多文档界面、工具栏与图形设计
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服