轉自:
DialogBar相比Dialog有很多優勢。因CDialogBar繼承於CControlBar,因此其可以Docking在窗口一邊,而把CView擠壓開,但是
CDialogBar 的使用並不是很容易,因爲 MFC 裏面並沒有提供直接可以使用的CDialogBar,我們需要自己動手,打造自己的完美的
DialogBar。
首先,你需要建立一個CDialog的子類(比CMyDlgBar)。然後,我們來把他一步步轉換成CDialogBar的子類。
1、改變基類和消息映射
我們頭文件中把CMyDlgBar的基類改成CDialogBar (原來CDialog),並且在cpp文件中的BEGIN_MESSAGE_MAP也做同樣的修改。
修改頭文件和cpp文件裏的構造函數,並且修改DoDataExchange()的三處地方:
CMyDlgBar:: CMyDlgBar (CWnd* pParent /*=NULL*/)
: CDialog(CMyDlgBar::IDD, pParent)
{
...
void CMyDlgBar::DoDataExchange(CDataExchange* pDX)
CDialog::DoDataExchange(pDX);
...
修改爲:
CMyDlgBar (); //標準構造函數
CMyDlgBar:: CMyDlgBar (){
...
void CMyDlgBar::DoDataExchange(CDataExchange* pDX)
CDialogBar::DoDataExchange(pDX);
...
2、改寫OnInitDialog
在頭文件的消息函數聲明中插入:
afx_msg LONG OnInitDialog(UINT, LONG);
在cpp文件的消息映射中插入:
ON_MESSAGE(WM_INITDIALOG, OnInitDialog);
並且在cpp文件中實現這個函數:
LONG CPfctDlgBar::OnInitDialog(UINT wParam, LONG lParam){
BOOL bRet = HandleInitDialog(wParam, lParam);
if(!UpdateData(FALSE)){
TRACE0("Warning, Unalbe to init update. ");
}
// Add Code here
return bRet;
}
不錯,現在你可以在DialogBar裏面初始化控件了。
3、使用CMyDlgBar
首先確定CMyDlgBar的屬性,如果不是以下設置,就修改過來:
Style: Child
Boarder: None
Visible: Unchecked
好了,現在讓我們來使用這個CMyDlgBar,比如在CMainFrame裏面聲明一個:
class CMainFrame : public CFrameWnd
{
...
CMyDlgBar m_myDlgBar;
...
}
然後在CMainFrame::OnCreate()函數裏面這樣寫:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
...
if (!m_myDlgBar.Create(this, IDD_DLGBAR1, CBRS_LEFT, IDD_DLGBAR1))
{
TRACE0("Failed to create dialog bar ");
return -1; // fail to create
}
...
}
或者如果你想讓其動態的停靠在面板的任何一個地方,那就加上CBRS_FLYBY和CBRS_SIZE_DYNAMIC,這兩個都是CControlBar的屬性,具體可查詢MSDN:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
....
if (!m_myDlgBar.Create(this, IDD_DLGBAR1, CBRS_LEFT| CBRS_FLYBY | CBRS_SIZE_DYNAMIC, IDD_DLGBAR1))
{
TRACE0("Failed to create dialog bar ");
return -1; // fail to create
}
m_myDlgBar.EnableDocking(CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_myDlgBar);
...
}
到此,你基本上可以像使用其它控件一樣使用CDialogBar了,當然,還有一些小技巧。
4、實用技巧
(1)、如果有很多個CDialogBar同時出現在你的面板上,那可能會出現顯示錯誤的問題,你可以在ShowWindow()之後,調用MainFrame的RecalcLayout()來將屏幕位置合理調整。
(2)、CButton不能使用,如何解決?
同樣是添加函數,頭文件中插入:
afx_msg void OnUpdateButton(CCmdUI * pCmdUI);
在cpp文件中插入:
ON_UPDATE_COMMAND_UI(IDC_BUTTON, OnUpdateButton)
並且在cpp文件中實現之:
void CMyDlgBar::OnUpdateButton(CCmdUI * pCmdUI){
pCmdUI -> Enable(TRUE);
}
(3)、如何在Button上添加bitmap?
還是消息函數,在OnInitDialog中添加:
OnInitDialog(){
…;
HBITMAP hBitmap = LoadBitmap(AfxGetApp() ->m_hInstance,
MAKEINTRESOURCE(IDB_BITMAP);
HWND hwnd = ::GetDlgItem(this -> GetSafeHwnd(), IDOK);
::SendMessage(hwnd, BM_SETIMAGE, IMAGE_BITMAP, (long)hBitmap);
…;
}
(4)、改變CMyDlgBar的大小,比如永遠爲主窗口的左1/3:
在頭文件的重載函數聲明中插入:
Virtual CSize CalcDynamicLayout(int nLength, DWORD nMode);
在cpp文件中實現:
CSize CMyDlgBar::CalcDynamicLayout(int nLength, DWORD nMode){
CRect rcFrame;
GetDockingFrame() ->GetClientRect(&rcFrame);
return CSize(rcFrame.width() / 3, rcFrame.Height());
}
一、添加並顯示Dialogbar:
2.爲DialogBar添加一個類MyDlgBar
3.打開MainFrm.h
添加CDialogBar m_wndDlgBar;
4.打開MainFrm.cpp在OnCreate()函數裏添加
if (!m_wndDlgBar.Create(this, IDD_DIALOGBAR, CBRS_ALIGN_TOP, IDD_DIALOGBAR))
{
TRACE0( "Failed to create dialogbar ");
return -1;
}
這樣就把DialogBar添加到單文檔窗體中了。
DialogBar就相當於工具條一樣。
在Create()函數裏可以控制DialogBar的位置。
5.如果在DialogBar放個按鈕,添加事件處理程序的時候,在類列表裏選擇CMainFrame
如果選擇MyDlgBar則按鈕呈不可用狀態。
{
if(m_wndMyDialogBar.IsWindowVisible())
{
ShowControlBar(&m_wndMyDialogBar, FALSE, FALSE);
}
else
{
ShowControlBar(&m_wndMyDialogBar, TRUE, TRUE);
}
}