1. 程式人生 > >MFC對話方塊如何使用工具欄並修改工具欄的背景顏色與自繪對話方塊統一

MFC對話方塊如何使用工具欄並修改工具欄的背景顏色與自繪對話方塊統一

    原始碼下載:http://download.csdn.net/detail/panshiqu/6031859

    最終效果圖


    不嫌丟人的說:這個問題困擾我多天,主要是也沒有努力的去解決它,把希望都寄託在網友身上,遺憾的是直到我找到解決辦法,我仍沒有從眾高手中拿到解決方法,我的問題曾在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