工具欄和列表視圖都是把自己的圖像存儲在圖像列表中。這個圖像列表實際上就是一個圖像清單。它是一個由許多小圖像組成的長條型位圖圖像。如圖一所示:
圖一
假設你有7個20x20的圖標,則在圖像清單中會將它們保存為一個140x20的位圖(7x20=140)。你可以根據需要來調整這個位圖的顏色特性;但是必須在創建圖像清單時指出要使用多少種顏色。在缺省情況下是16色。另外,當MFC加載工具欄位圖時使用的一個內部函數,AfxLoadSysColorBitmap,也假設顏色為16色。所以用MFC編程時,為了顯示256色圖像,你必須要對圖像清單進行處理。
我編寫了DEMO程序TBColor來說明如何在工具欄中顯示256色圖像,這個程序是一個極其典型的MFC程序——它有一個漂亮的工具欄。如圖二所示:
圖二
按下工具欄的每一個按鈕都彈出“關於”對話框。具體處理細節全都在CMainFrame::OnCreate函數中實現:
MainFrm.cpp //////////////////////////////////////////////////////////////// // Set tabsize = 3 in your editor. // #include "StdAfx.h" #include "MainFrm.h" #include "Resource.h" BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) ON_WM_CREATE() END_MESSAGE_MAP() static UINT indicators[] = { ID_SEPARATOR, // status line indicator ID_INDICATOR_CAPS, ID_INDICATOR_NUM, ID_INDICATOR_SCRL, }; CMainFrame::CMainFrame() { } CMainFrame::~CMainFrame() { } BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) { cs.style |= WS_CLIPCHILDREN; return CFrameWnd::PreCreateWindow(cs); } int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { VERIFY(CFrameWnd::OnCreate(lpCreateStruct)==0); //創建並加載工具欄 // VERIFY(m_wndToolBar.Create(this)); VERIFY(m_wndToolBar.LoadToolBar(IDR_MAINFRAME)); // 加載工具欄位圖 - 必須使用::LoadImage映射顏色 // 將(192,192,192) 映射到 COLOR_3DFACE. // HBITMAP hbm = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME), IMAGE_BITMAP, 0,0, // cx,cy LR_CREATEDIBSECTION | LR_LOADMAP3DCOLORS ); CBitmap bm; bm.Attach(hbm); // 創建圖像清單並設置工具欄 // 256色圖像必須使用ILC_COLOR8! // m_ilToolBar.Create(20,20, ILC_COLOR8, 4, 4); m_ilToolBar.Add(&bm,(CBitmap*)NULL); m_wndToolBar.GetToolBarCtrl().SetImageList(&m_ilToolBar); VERIFY(m_wndStatusBar.Create(this)); VERIFY(m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT))); VERIFY(m_wndView.Create(_T("Press a button, any button."), WS_VISIBLE|WS_CHILD|SS_CENTERIMAGE|SS_CENTER, CRect(0,0,0,0), this, AFX_IDW_PANE_FIRST)); return 0; }第一步一定要用::LoadImage加載工具欄位圖。這個函數是個多用途函數,它可以加載光標、圖標和位圖。加載位圖時,這個函數甚至還能將位圖中的某些顏色映射到當前的屏幕顏色。例如,DEMO程序中的工具欄位圖(圖一)使用RGB(192,192,192)為背景;如果恰好系統上有3D顏色,則LR_LOADMAP3DCOLORS標志會讓LoadImage將背景映射到系統實際的3D(GetSysColor(COLOR_3DFACE))顏色。
HBITMAP hbm = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME), IMAGE_BITMAP, 0,0, // cx, cy LR_CREATEDIBSECTION | LR_LOADMAP3DCOLORS );LoadImage返回一個位圖句柄(HBITMAP),但MFC會更喜歡與CBitmaps打交道,所以接下來就是創建一個CBitmap對象並將它與你的句柄聯系(Attach)起來。 CBitmap bm;