一、創建DialogBar的派生類
首先,創建對話框資源:在對話框資源編輯器內生成一個Dialog資源,并將其風格(Style)屬性必須設置為Child,不能設置為Overlapped或Popup,否則運行肯定出錯;至于邊界屬性則隨用戶自己喜歡,一般都是選擇None。其余屬性也隨用戶選擇,一般沒有特殊要求還是選擇默認的好。
其次,創建基于CDialog的派生類:打開ClassWizard,為以上創建的資源添加一個以CDialog為基類的派生類(因為ClassWizard沒有將CDialogBar列在基類目錄清單中,所以用戶只能先以CDialog類派生)。
再次,修改派生類以CDialogBar為基類:通常需要手工修改幾處代碼,在本例中派生類以CDataStatus命名。(注:以后講解中凡是手工改動都是以灰背景顯示)
1、 在頭文件中修改繼承關系
將class CDataStatus : public CDialog 改為class CDataStatus : public CDialogBar
2、 在代碼文件中修該構造函數繼承關系
將CDataStatus::CDataStatus(CWnd* pParent /*=NULL*/)
: CDialog(CDataStatus::IDD, pParent)
{
//{{AFX_DATA_INIT(CDataStatus)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
改為
CDataStatus::CDataStatus(CWnd* pParent /*=NULL*/)
{
//{{AFX_DATA_INIT(CDataStatus)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
3、 將DDX綁定函數中的繼承關系去掉
即將void CDataStatus::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CCurrentCheckDlg)
………..
//}}AFX_DATA_MAP
}
改為
void CDataStatus::DoDataExchange(CDataExchange* pDX)
{
//{{AFX_DATA_MAP(CCurrentCheckDlg)
………….
//}}AFX_DATA_MAP
}
4、 重新初始化函數(這個相當重要,如果不這么做的話,DDX函數形同虛設,當然用戶的工具條如果沒有用到DDX的話當然可以不加這段代碼):
首先在ClassWizard的MessageMap中對消息該CDataStatus類的WM_INITDIALOG消息添加處理函數默認名為OnInitDialog。
其次手工修改代碼如下:
1、 添加消息映射函數。由于對話框形式的初始化函數消息并未加載到消息映射內,為此我們需要手工添加,要不然代碼無法攔截該工具條的初始化消息,形式如下:
將BEGIN_MESSAGE_MAP(CDataStatus, CDialogBar)
//{{AFX_MSG_MAP(CDataStatus)
.......
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
改為:
BEGIN_MESSAGE_MAP(CDataStatus, CDialogBar)
//{{AFX_MSG_MAP(CDataStatus)
.......
ON_MESSAGE(WM_INITDIALOG,OnInitDialog)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
2、 修改OnInitDialog函數,此函數并未傳遞參數,但是在這里我們需要讓它傳遞參數,代碼如下修改(當然頭文件中,對聲明也要做修改,在這里就不作贅述了)
將BOOL CDataStatus::OnInitDialog()
{
CDialogBar::OnInitDialog();
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
改為:
BOOL CDataStatus::OnInitDialog(UINT wParam,LONG lParam)
{
//CDialogBar::OnInitDialog();
// TODO: Add extra initialization here
BOOL bRet = HandleInitDialog(wParam,lParam);
if (!UpdateData(FALSE))
{
TRACE("InitCDataStatus Failed!");
}
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
二、在框架類中實現該派生類的對象化
首先,在框架類的頭文件內聲明實例對象,本例實例化:CDataStatus m_wndDataStatus;當然頭文件中不可避免要包含新派生類的頭文件。
其次,在框架類的OnCreate函數內創建對象并將對象綁定對話框資源。形式與創建ToolBar原理一樣,本例實例如下:
if (!m_wndDataStatus.Create(this,IDD_DATASTATUS,WS_VISIBLE|WS_CHILD
|CBRS_SIZE_DYNAMIC|CBRS_BOTTOM,IDD_DATASTATUS))
{
TRACE0("Failed to create CDataStatus bar!");
return -1;
}
再次,最為關鍵的一點就是重寫框架類的OnCmdMsg虛函數。如果不重寫該函數,那么不光DDX功能無法實現,連最基本的OnCommand事件都無法實現。而且還得手工添加代碼,形式如下:
BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra,
AFX_CMDHANDLERINFO* pHandlerInfo)
{
// TODO: Add your specialized code here and/or call the base class
return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}
改為:
BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
// TODO: Add your specialized code here and/or call the base class
if (m_wndDataStatus.OnCmdMsg(nID,nCode,pExtra,pHandlerInfo))
return TRUE;
return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}
三、在CReBar上添加該實例化對象
其實這一步倒是相當簡單,只是自己以前沒用過這個類,所以在這里也順便用了一下。
首先,在框架類的頭文件中用CRebar聲明一個對象,如CReBar m_wndReBar;
其次,在框架類的代碼文件中的OnCreat函數體內,生成對象,代碼如下:
if (!m_wndReBar.Create(this,RBS_BANDBORDERS,WS_CHILD |
WS_VISIBLE| CBRS_BOTTOM|WS_CLIPSIBLINGS|WS_CLIPCHILDREN))
{
TRACE0("Failed to create Rebar \n");
return -1;
}
再次,就是將所要添加的toolbar以及新生成的CDataStatus對象m_wndDataStatus加進Rebar的對象m_wndReBar中,代碼如下:
m_wndReBar.AddBar(&m_wndDataStatus,NULL,NULL,
RBBS_GRIPPERALWAYS|RBBS_FIXEDBMP);