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

这篇博客主要解决3个问题:

1、如何在对话框资源上创建菜单,用菜单项控制工具栏和状态栏的显示与隐藏;

2、如何在对话框资源上创建工具栏,并实现工具栏上按钮的响应;

3、如何在对话框资源上创建状态栏,在状态栏分别获取系统时间、鼠标位置、进度条。

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


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

private:
	CMenu m_menu;                //菜单
	CToolBar m_toolbar;          //工具栏
	CStatusBar m_statusbar;      //状态栏
	CProgressCtrl m_progress;    //进度条

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


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

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

    //创建菜单
    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);
	}
}
运行程序,显示正常,虽然简陋,但是方法还算易懂。













猜你喜欢

转载自blog.csdn.net/GK_2014/article/details/46350011
今日推荐