希望对读者提供参考价值,也方便自己以后查阅。
首先用MFC向导创建对话框资源class CAddSourceDlg,然后在对话框类中声明需要创建的资源:
- private:
- CMenu m_menu; //菜单
- CToolBar m_toolbar; //工具栏
- CStatusBar m_statusbar; //状态栏
- CProgressCtrl m_progress; //进度条
在资源窗口编辑菜单资源,如下:
第一个参数的值取决于第二个参数,这在上一篇博文中有提到。
- //创建菜单
- m_menu.LoadMenu(IDR_MENU1);
- SetMenu(&m_menu);
- //设置标记菜单
- GetMenu()->GetSubMenu(0)->CheckMenuItem(2, MF_CHECKED|MF_BYPOSITION);
- GetMenu()->GetSubMenu(0)->CheckMenuItem(ID_DISP_STATUSBAR, MF_CHECKED|MF_BYCOMMAND);
菜单创建好了,添加前两个菜单项的响应函数如下:
- void CAddSourceDlg::OnPrintT()
- {
- // TODO: Add your command handler code here
- MessageBox("print T");
- }
- void CAddSourceDlg::OnPrintI()
- {
- // TODO: Add your command handler code here
- MessageBox("print I");
- }
然后在资源窗口编辑工具栏资源。由于工具栏相当于菜单的快捷方式,所以工具栏的按钮ID必须和关联菜
单项的ID一致,共用同一个响应函数。这里讲将工具栏按钮T和按钮I的ID分别设置成菜单项“打印“T””和打印“I”的ID。
然后在成员函数OnInitDialog中将工具栏资源添加到对话框。
- //创建工具栏
- m_toolbar.CreateEx(this); //创建空白工具栏
- m_toolbar.LoadToolBar(IDR_TOOLBAR1); //加载工具栏资源
- CRect rect;
- GetClientRect(&rect); //计算客户区大小
- m_toolbar.MoveWindow(0,0,rect.Width(), 25); //必须设置工具栏显示位置
运行程序,发现点击工具栏按钮和点击对应菜单项都会调用相同的响应函数,证明创建的工具栏没有问题。
由于在创建状态栏时需要设置各元素的ID,所以现在头文件resource.h中定义好然后在成员函数OnInitDialog中将状态栏资源添加到对话框。其中状态栏第一个元素用来显示系统时间,第二个元素用来指示鼠标位置,第三个元素用来表示进度条。
- //创建状态栏
- //创建定时器,由于重载了基类消息响应函数,因此第三个参数可以为NULL
- SetTimer(ID_TIMER, 1000, NULL);
- static UINT indicators[] = //指定状态栏上三个元素的ID
- {
- IDS_TIME,
- IDS_PROGRESS,
- IDS_MOUSE
- };
- m_statusbar.Create(this); //创建空白状态栏
- //设置状态栏上元素的ID及元素数量
- m_statusbar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT));
- //设置状态栏3个元素的宽度
- m_statusbar.SetPaneInfo(0, IDS_TIME, SBPS_NORMAL, rect.Width()/3);
- m_statusbar.SetPaneInfo(1, IDS_MOUSE, SBPS_NORMAL, 80);
- m_statusbar.SetPaneInfo(2, IDS_PROGRESS, SBPS_STRETCH, 100);
- //必须重新设置和调整状态栏大小,否则无法显示
- RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0);
因为显示系统时间要不断刷新,所一上面创建了一个时间间隔为1秒触发事件的定时器,响应函数为基类的虚函数。这里可以重写虚函数,定义我们自己的虚函数。每隔1秒钟,重新获取系统时钟,并显示在对应状态栏上。
- void CAddSourceDlg::OnTimer(UINT nIDEvent)
- {
- // TODO: Add your message handler code here and/or call default
- CString strTime;
- CTime time = CTime::GetCurrentTime();
- strTime.Format("%d:%d:%d", time.GetHour(),time.GetMinute(),time.GetSecond());
- //确定字符串长度
- // CClientDC dc(this);
- // CSize sz = dc.GetTextExtent(strTime);
- // m_statusbar.SetPaneInfo(0, IDS_TIME, SBPS_NORMAL, sz.cx);
- m_statusbar.SetPaneText(0, strTime);
- //每过1s,进度条自动增长
- //m_progress.StepIt();
- CDialog::OnTimer(nIDEvent);
- }
因为要在状态栏上显示鼠标位置,这里在对话框类中定义一个鼠标移动的消息响应函数
- void CAddSourceDlg::OnMouseMove(UINT nFlags, CPoint point)
- {
- // TODO: Add your message handler code here and/or call default
- CString strPoint;
- strPoint.Format("%d,%d", point.x,point.y);
- m_statusbar.SetPaneText(1, strPoint);
- CDialog::OnMouseMove(nFlags, point);
- }
然后成员函数OnInitDialog中创建进度条资源
- //创建进度条
- CRect rectPro;
- m_statusbar.GetItemRect(2, &rectPro); //获取状态栏元素2的区间大小
- //注意此处进度条的父窗口设置为状态栏
- m_progress.Create(WS_CHILD|WS_VISIBLE, rectPro, &m_statusbar, ID_PROGRESS);
- //设置初始位置
- m_progress.SetPos(50);
- //设置步长
- m_progress.SetStep(5);
也可以在定时响应函数中递增进度。最后还要实现菜单项控制工具栏和状态栏的显示、隐藏,添加其余两个菜单项的消息响应函数如下:
- void CAddSourceDlg::OnDispToolbar()
- {
- // TODO: Add your command handler code here
- if (m_toolbar.IsVisible())
- { //如果工具栏处于可见状态,则隐藏,并将菜单的标记撤除
- m_toolbar.ShowWindow(SW_HIDE);
- GetMenu()->GetSubMenu(0)->CheckMenuItem(2, MF_UNCHECKED|MF_BYPOSITION);
- }
- else
- {
- //如果工具栏处于不可见状态,则消失,并添加菜单标记
- m_toolbar.ShowWindow(SW_SHOW);
- GetMenu()->GetSubMenu(0)->CheckMenuItem(2, MF_CHECKED|MF_BYPOSITION);
- }
- }
- void CAddSourceDlg::OnDispStatusbar()
- {
- // TODO: Add your command handler code here
- if (m_statusbar.IsVisible())
- {
- m_statusbar.ShowWindow(SW_HIDE);
- GetMenu()->GetSubMenu(0)->CheckMenuItem(ID_DISP_STATUSBAR, MF_UNCHECKED|MF_BYCOMMAND);
- }
- else
- {
- m_statusbar.ShowWindow(SW_SHOW);
- GetMenu()->GetSubMenu(0)->CheckMenuItem(ID_DISP_STATUSBAR, MF_CHECKED|MF_BYCOMMAND);
- }
- }
运行程序,显示正常,虽然简陋,但是方法还算易懂。联系客服