MFC对话框如何使用工具栏并修改工具栏的背景颜色与自绘对话框统一

时间:2023-01-20 23:08:07

    源码下载:http://download.csdn.net/detail/panshiqu/6031859

    最终效果图

MFC对话框如何使用工具栏并修改工具栏的背景颜色与自绘对话框统一

    不嫌丢人的说:这个问题困扰我多天,主要是也没有努力的去解决它,把希望都寄托在网友身上,遗憾的是直到我找到解决办法,我仍没有从众高手中拿到解决方法,我的问题曾在CSDN的论坛中提问过,稍后我会以这篇博文结那个帖子(http://bbs.csdn.net/topics/390565617)。

    我要写的是一个浏览器小程序,用自绘无边框的对话框为基础,有点在乎界面好坏,所以几个快捷导航按钮本来也想自绘,后来发现如果这样做,肯定好看了,但是随之带来的也是很多判断(鼠标当前处在那个按钮上,那个按钮点击了,按钮图标肯定要三态的),不得已就放弃另求他法。想到工具栏,后来简单一搜对话框上可以使用工具栏,当然肯定要自己写消息映射(这不是本文重点,后面会附代码简说)

    下面我重写程序重现问题(先把这个文章熟悉了,重点是他关于横线的解释:http://hi.baidu.com/wpzhao/item/ceb9d2d336bd69ba32db908e    然后看他提到这个网址的12楼:http://bbs.csdn.net/topics/120021346) 有了这些我就可以这样写代码,而且效果很好,就差消息映射和响应

	if (!m_wndToolBar.Create(this, WS_CHILD |  WS_VISIBLE | CBRS_ALIGN_TOP | CCS_NODIVIDER) || 
!m_wndToolBar.LoadToolBar(IDR_TOOLBAR))
{
TRACE0("未能创建工具栏\n");
return -1; // 未能创建
}

m_wndToolBar.MoveWindow(CRect(CPoint(1, 25), CSize(612, 45)));

上面的IDR_TOOLBAR是用 资源视图 插入的,但是程序要求界面就是要好看,那就用现成的图标来创建工具栏上的按钮,把百度,谷歌网站的 ICO 图标文件下下来,资源视图中插入,然后这样写代码

	if (!m_wndToolBar.Create(this, WS_CHILD |  WS_VISIBLE | CBRS_ALIGN_TOP | CCS_NODIVIDER) || 
!m_wndToolBar.LoadToolBar(IDR_TOOLBAR))
{
TRACE0("未能创建工具栏\n");
return -1; // 未能创建
}

CImageList img;

// 设置工具栏按钮最小宽度(只关心宽度)
m_wndToolBar.GetToolBarCtrl().SetButtonWidth(120, 160);

img.Create(18, 18, ILC_COLOR32|ILC_MASK, 2, 2);
img.Add(AfxGetApp()->LoadIcon(IDI_ICON_BAIDU));
img.Add(AfxGetApp()->LoadIcon(IDI_ICON_360));
img.Add(AfxGetApp()->LoadIcon(IDI_ICON_SOGOU));
img.Add(AfxGetApp()->LoadIcon(IDI_ICON_SOSO));
img.Add(AfxGetApp()->LoadIcon(IDI_ICON_GOOGLE));

m_wndToolBar.GetToolBarCtrl().SetHotImageList(&img);
img.Detach();

img.Create(16, 16, ILC_COLOR32|ILC_MASK, 2, 2);
img.Add(AfxGetApp()->LoadIcon(IDI_ICON_BAIDU));
img.Add(AfxGetApp()->LoadIcon(IDI_ICON_360));
img.Add(AfxGetApp()->LoadIcon(IDI_ICON_SOGOU));
img.Add(AfxGetApp()->LoadIcon(IDI_ICON_SOSO));
img.Add(AfxGetApp()->LoadIcon(IDI_ICON_GOOGLE));

m_wndToolBar.GetToolBarCtrl().SetImageList(&img);
img.Detach();

// 五个按钮为每个按钮设置消息和文字
m_wndToolBar.SetButtons(NULL, 5);

m_wndToolBar.SetButtonInfo(0, ID_TOOLBAR_BAIDU, TBSTYLE_BUTTON, 0);
m_wndToolBar.SetButtonText(0, _T("百度一下"));

m_wndToolBar.SetButtonInfo(1, ID_TOOLBAR_360, TBSTYLE_BUTTON, 1);
m_wndToolBar.SetButtonText(1, _T("奇虎搜索"));

m_wndToolBar.SetButtonInfo(2, ID_TOOLBAR_SOGOU, TBSTYLE_BUTTON, 2);
m_wndToolBar.SetButtonText(2, _T("狗狗搜索"));

m_wndToolBar.SetButtonInfo(3, ID_TOOLBAR_SOSO, TBSTYLE_BUTTON, 3);
m_wndToolBar.SetButtonText(3, _T("腾讯搜搜"));

m_wndToolBar.SetButtonInfo(4, ID_TOOLBAR_GOOGLE, TBSTYLE_BUTTON, 4);
m_wndToolBar.SetButtonText(4, _T("谷歌搜索"));

//m_wndToolBar.SetButtonInfo(5, 1234, TBBS_SEPARATOR, 0);

CRect rectToolBar;
m_wndToolBar.GetItemRect(0, &rectToolBar);

// 关乎文字的位置
m_wndToolBar.SetSizes(rectToolBar.Size(), CSize(85,1));

m_wndToolBar.MoveWindow(CRect(CPoint(1, 25), CSize(612, 45)));

用ICO文件做图标,是方法之一,你看用的是CImageList,当然还可以用 冷暖 BMP 图片裁剪了,这个微软都有示例代码,在  MFC  中 internet 中 MFCIE示例,那个是一个单文档应用程序,写的本身就是一个浏览器,它会对你帮助很大。

这样以来,如果程序对话框界面没有做改动的话,工具栏就是已经和对话框融为一体了,已经小完美了,但是我现在的对话框是有界面的,现在添加 OnEraseBkgnd 函数画背景

	// 设置对话框默认背景颜色
CRect rectClient;
GetClientRect(rectClient);
pDC->FillSolidRect(rectClient, RGB(205,205,0));
return TRUE;

这时会发现,工具栏的背景差异就出来了,这个时候冷静的想想,工具栏也是窗口(某位大哥说的话)也给他画个背景,这是要自己写类,继承CToolBar, 然后响应 OnEraseBkgnd 函数。 这个函数也照着上面的写,执行一下看效果,噫???,没有改变呀?博主骗人?别忘记把原来 m_wndToolBar 的类型重新定义为 你写的新类哦,这样再一看就可以了。


尾语:在研究的过程中,我也考虑到了CReBar,一是多增加了一个东西感觉不好,二是截至到发这篇文章前,我始终没有发现怎么去掉那两条灰线,CReBar设置背景的话还是很方便的,网上有很多有关文章,大家不妨深入了解下

尾语:还有一个问题,写示例程序的时候没有遇到,这里也说一下,可能是我原来程序用的东西太多了,暂时没有去找问题出在那里,对话框画背景的代码放到 OnPaint 函数中的话,工具栏下右方向有类似阴影的区域没有画上,相比OnEaserBkgnd是会被执行多次的,这就是用它不会出现那片残留区域的原因吧,更何况在OnEraseBkgnd中画,会有更小的闪烁,何乐而不为...(如果你想重现这个问题的话,就只画工具栏的背景,就会发现工具栏左下,右上有缺角,就知道我所言非虚,如果没有猜错,就是我原来程序有其他控件,一开始对话框绘制背景后,要会我的那个控件的时候,还是要调用 OnEraseBkgnd 然后有争议的那片地方就让这次调用给擦掉了)

二次编辑:第二个尾语说的有问题,关于那片类似阴影的区域没有画上背景,想了解更多请看我下一篇博文:http://blog.csdn.net/panshiqu/article/details/10536469