1. 程式人生 > >從零起步CMFCToolBar用法詳解

從零起步CMFCToolBar用法詳解

CMFCToolBar是vs08sp1以後引入的新的工具欄控制元件,和Ribbon主題結合的很好,不同與CToolBar,它是從CPane派生出來的,用法跟CToolbar 有一些不同,研究了幾天,記錄在下面。

  1. 首先給出工具欄四種狀態圖示BMP檔案,這4個檔案分別為圖示按鈕的Cold、Hot、Disabled、Enabled狀態,資源是從VS的MSMoney這個Demo裡考出來的,每個按鈕大小時46*46。效果見下圖,這裡給出本站下載資源
  2. 新建一個空白SDI文件,選用Ribbon主題。找到資源工具欄-Toobar上右鍵新建一個toolbar,取名IDR_MYTOOLBAR,在右側的編輯欄裡將新建出來的工具欄第一個圖示的屬性-Height和width改為46*46,此時圖示會變大。見下圖。
    用鉛筆工具在這個圖示上隨便畫個東西,完成時,它的右側會多一個圖示,繼續畫,一直第6個圖示(此時會有第7個出來,不用畫了)。
  3. 匯入下載的四個bmp檔案到資源裡,如下圖,ID分別取好。
  4. 用類嚮導從CMFCToolBar裡派生一個新類,或者直接拷貝下面的程式碼到Mainfrm.h檔案裡
    class CMYToolBar : public CMFCToolBar
    {
    public: 
    	DECLARE_DYNCREATE(CMYToolBar)
    
    	// Construction
    public:
    	CMYToolBar();
    
    	virtual ~CMYToolBar ();
    public:
    	virtual BOOL LoadToolBar (UINT uiResID, UINT uiColdResID = 0, 
    		UINT uiMenuResID = 0, BOOL bLocked = FALSE,
    		UINT uiDisabledResID = 0, UINT uiMenuDisabledResID = 0,
    		UINT uiHotResID = 0);
    
    protected:
    	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    	DECLARE_MESSAGE_MAP()
    
    	virtual BOOL DrawButton (CDC* pDC, CMFCToolBarButton* pButton, 
    		CMFCToolBarImages* pImages, BOOL bHighlighted,
    		BOOL bDrawDisabledImages);
    
    };
    mainfrm類裡新增控制元件變數
    CMYToolBar			m_wndMyToolBar;
  5. mainfrm.cpp新增類實現程式碼
    IMPLEMENT_DYNCREATE(CMYToolBar, CMFCToolBar)
    
    CMYToolBar::CMYToolBar()
    {
    }
    
    
    CMYToolBar::~CMYToolBar()
    {
    }
    
    
    BEGIN_MESSAGE_MAP(CMYToolBar, CMFCToolBar)
    	ON_WM_CREATE()
    	
    END_MESSAGE_MAP()
    
    /////////////////////////////////////////////////////////////////////////////
    // CMSMToolBar message handlers
    
    int CMYToolBar::OnCreate(LPCREATESTRUCT lpCreateStruct) 
    {
    	if (CMFCToolBar::OnCreate(lpCreateStruct) == -1)
    		return -1;
    
    	SetPaneStyle(CBRS_GRIPPER | CBRS_BORDER_TOP | CBRS_BORDER_BOTTOM | 
    		CBRS_BORDER_LEFT | CBRS_BORDER_RIGHT| CBRS_SIZE_DYNAMIC);
    	SetBorders ();
    
    	SetGrayDisabledButtons (FALSE);
    
    	return 0;
    }
    
    
    BOOL CMYToolBar::LoadToolBar(UINT uiResID, UINT uiColdResID, UINT uiMenuResID, 
    	BOOL bLocked,
    	UINT uiDisabledResID, UINT uiMenuDisabledResID,
    	UINT uiHotResID)
    {
    	if (!CMFCToolBar::LoadToolBar (uiResID, uiColdResID, uiMenuResID, bLocked, 
    		uiDisabledResID, uiMenuDisabledResID, uiHotResID))
    	{
    		return FALSE;
    	}
    
    
    	return TRUE;
    }
    
    BOOL CMYToolBar::DrawButton(CDC* pDC, CMFCToolBarButton* pButton,
    	CMFCToolBarImages* pImages,
    	BOOL bHighlighted, BOOL bDrawDisabledImages)
    {
    	ASSERT_VALID (pDC);
    	ASSERT_VALID (pButton);
    
    
    	CMFCToolBarImages* pNewImages = pImages;
    
    	CAfxDrawState ds;
    	/*
    	if (!m_bMenuMode && (pButton->m_nStyle & (TBBS_PRESSED)) && 
    		m_PressedImages.GetCount () > 0)
    	{
    		pNewImages = &m_PressedImages;
    
    		pNewImages->SetTransparentColor (afxGlobalData.clrBtnFace);
    
    		pNewImages->PrepareDrawImage (ds, GetImageSize (), FALSE);
    	}
    	*/
    	if (!CMFCToolBar::DrawButton (pDC, pButton, pNewImages, bHighlighted, 
    		bDrawDisabledImages))
    	{
    		return FALSE;
    	}
    
    	if (pNewImages != pImages)
    	{
    		pNewImages->EndDrawImage (ds);
    	}
    
    	return TRUE;
    }
    
    
    
    
    mainfrm.cpp裡的OnCreate裡新增控制元件初始化程式碼
            UINT uiToolbarHotID  = IDB_HOTBITMAP;
    	UINT uiToolbarColdID = IDB_COLDBITMAP;
    	UINT uiToolbarDisID  = IDB_DISBITMAP;
    	UINT uiToolbarPresID = IDB_PRESBITMAP;
    	if (!m_wndMyToolBar.CreateEx (this, TBSTYLE_FLAT,
    		TBSTYLE_TOOLTIPS | CBRS_SIZE_DYNAMIC|  AFX_DEFAULT_TOOLBAR_STYLE) ||
    		!m_wndMyToolBar.LoadToolBar (IDR_MYTOOLBAR, uiToolbarColdID, 0, 
    		TRUE, uiToolbarDisID, 0, uiToolbarHotID))
    	{
    		TRACE0("Failed to create toolbar\n");
    		return -1;      // fail to create
    	}
    
    	m_wndMyToolBar.EnableDocking(CBRS_ALIGN_ANY); 
    	EnableDocking(CBRS_ALIGN_ANY);  
    	DockPane (&m_wndMyToolBar);
    	m_wndMyToolBar.SetWindowText(_T("新的CMFCToolBar控制元件!"));
  6. 編譯執行,就有結果了。
  7. 還要新增各個按鈕的事件程式碼,按鈕就可以enable了,在.h裡寫
    	afx_msg void OnViewButton1();
    	afx_msg void OnUpdateViewButton1(CCmdUI* pCmdUI);
    在.cpp裡寫
    	ON_COMMAND(ID_BUTTON32774, &CMainFrame::OnViewButton1)
    	ON_UPDATE_COMMAND_UI(ID_BUTTON32774, &CMainFrame::OnUpdateViewButton1)
    按鈕ID和程式碼放的位置就不多說了
  8. 好了,至此完畢,可以拖動,浮動工具欄了。

========================================2014.12.22=============

今天找到方法進行工具欄狀態的更新,就是按下工具欄某按鈕之後,該按鈕一直是按下的狀態,滑鼠可以移開進行其他操作。很簡單,設定一個按下狀態標誌位bBTDown,響應

ON_UPDATE_COMMAND_UI(ID_BUTTON32774, &CMainFrame::OnUpdateViewButton1)

裡寫

pCmdUI->SetCheck(bBTDown);

這裡在view區進行了畫線的操作,工具欄按鈕一直為按下狀態。同時,滑鼠指標也進行了更改,讓起在客戶群為十字架,其他區域為普通指標,方法為響應WM_SETCURSOR訊息,函式裡寫

BOOL CMainFrame::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
	// TODO: Add your message handler code here and/or call default
	if (bBTDown)
	{
		CToolBarView* pView = (CToolBarView*)GetActiveView();
		ASSERT(pView);
		ASSERT(pWnd);
		if (pWnd == pView)
		{
			SetCursor(LoadCursor(NULL,IDC_CROSS));
			return TRUE;//這裡要返回TRUE,否則閃爍
		}
		
	}

	return CFrameWndEx::OnSetCursor(pWnd, nHitTest, message);
}

========================================2014.12.25=============

今天找到新增提示的方法,很簡單,在第二張圖繪製工具欄圖示的時候,在屬性視窗的promt裡直接輸入資訊

返回上一步操作\n返回按鈕

就可以了,特別是\n一定要有,效果如圖

如果我的文字解決了你的問題,請打個賞的,讓我更有動力:)