CMFCToolBar是vs08sp1以后引入的新的工具栏控件,和Ribbon主题结合的很好,不同与CToolBar,它是从CPane派生出来的,用法跟CToolbar 有一些不同,研究了几天,记录在下面。
- 首先给出工具栏四种状态图标BMP文件,这4个文件分别为图标按钮的Cold、Hot、Disabled、Enabled状态,资源是从VS的MSMoney这个Demo里考出来的,每个按钮大小时46*46。效果见下图,这里给出本站下载资源。
- 新建一个空白SDI文档,选用Ribbon主题。找到资源工具栏-Toobar上右键新建一个toolbar,取名IDR_MYTOOLBAR,在右侧的编辑栏里将新建出来的工具栏第一个图标的属性-Height和width改为46*46,此时图标会变大。见下图。用铅笔工具在这个图标上随便画个东西,完成时,它的右侧会多一个图标,继续画,一直第6个图标(此时会有第7个出来,不用画了)。
- 导入下载的四个bmp文件到资源里,如下图,ID分别取好。
- 用类向导从CMFCToolBar里派生一个新类,或者直接拷贝下面的代码到Mainfrm.h文件里
mainfrm类里添加控件变量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); };
CMYToolBar m_wndMyToolBar;
- mainfrm.cpp添加类实现代码
mainfrm.cpp里的OnCreate里添加控件初始化代码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; }
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控件!"));
- 编译运行,就有结果了。
- 还要添加各个按钮的事件代码,按钮就可以enable了,在.h里写
在.cpp里写afx_msg void OnViewButton1(); afx_msg void OnUpdateViewButton1(CCmdUI* pCmdUI);
按钮ID和代码放的位置就不多说了ON_COMMAND(ID_BUTTON32774, &CMainFrame::OnViewButton1) ON_UPDATE_COMMAND_UI(ID_BUTTON32774, &CMainFrame::OnUpdateViewButton1)
- 好了,至此完毕,可以拖动,浮动工具栏了。
========================================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一定要有,效果如图
如果我的文字解决了你的问题,请打个赏的,让我更有动力:)