MFC DialogBar

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());
       }

 

附:

[cpp] view plaincopy

  1. #if !defined(AFX_MYDLGBAR_H__2AFF8EA8_A746_4608_AA10_04CEC54260A7__INCLUDED_)  

  2. #define AFX_MYDLGBAR_H__2AFF8EA8_A746_4608_AA10_04CEC54260A7__INCLUDED_  

  3.   

  4. #if _MSC_VER > 1000  

  5. #pragma once  

  6. #endif // _MSC_VER > 1000  

  7. // MyDlgBar.h : header file  

  8. //  

  9.   

  10. /////////////////////////////////////////////////////////////////////////////  

  11. // CMyDlgBar dialog  

  12.   

  13. class CMyDlgBar : public CDialogBar  

  14. {  

  15. // Construction  

  16. public:  

  17.     CMyDlgBar();   // standard constructor  

  18.   

  19. // Dialog Data  

  20.     //{{AFX_DATA(CMyDlgBar)  

  21.     enum { IDD = CG_IDD_MYDIALOGBAR };  

  22.         // NOTE: the ClassWizard will add data members here  

  23.     //}}AFX_DATA  

  24.   

  25.   

  26. // Overrides  

  27.     // ClassWizard generated virtual function overrides  

  28.     //{{AFX_VIRTUAL(CMyDlgBar)  

  29.     protected:  

  30.     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support  

  31.     //}}AFX_VIRTUAL  

  32.   

  33. // Implementation  

  34. protected:  

  35.   

  36.     // Generated message map functions  

  37.     //{{AFX_MSG(CMyDlgBar)  

  38.     afx_msg LONG OnInitDialog(UINTLONG);  

  39.     //}}AFX_MSG  

  40.     DECLARE_MESSAGE_MAP()  

  41. };  

  42.   

  43. //{{AFX_INSERT_LOCATION}}  

  44. // Microsoft Visual C++ will insert additional declarations immediately before the previous line.  

  45.   

  46. #endif // !defined(AFX_MYDLGBAR_H__2AFF8EA8_A746_4608_AA10_04CEC54260A7__INCLUDED_)  


 

 

[cpp] view plaincopy

  1. // MyDlgBar.cpp : implementation file  

  2. //  

  3.   

  4. #include "stdafx.h"  

  5. #include "2011082603.h"  

  6. #include "MyDlgBar.h"  

  7.   

  8. #ifdef _DEBUG  

  9. #define new DEBUG_NEW  

  10. #undef THIS_FILE  

  11. static char THIS_FILE[] = __FILE__;  

  12. #endif  

  13.   

  14. /////////////////////////////////////////////////////////////////////////////  

  15. // CMyDlgBar dialog  

  16.   

  17.   

  18. CMyDlgBar::CMyDlgBar()  

  19. {  

  20.     //{{AFX_DATA_INIT(CMyDlgBar)  

  21.         // NOTE: the ClassWizard will add member initialization here  

  22.     //}}AFX_DATA_INIT  

  23. }  

  24.   

  25.   

  26. void CMyDlgBar::DoDataExchange(CDataExchange* pDX)  

  27. {  

  28.     CDialogBar::DoDataExchange(pDX);  

  29.     //{{AFX_DATA_MAP(CMyDlgBar)  

  30.         // NOTE: the ClassWizard will add DDX and DDV calls here  

  31.     //}}AFX_DATA_MAP  

  32. }  

  33.   

  34.   

  35. BEGIN_MESSAGE_MAP(CMyDlgBar, CDialogBar)  

  36.     //{{AFX_MSG_MAP(CMyDlgBar)  

  37.     ON_MESSAGE(WM_INITDIALOG, OnInitDialog)  

  38.     //}}AFX_MSG_MAP  

  39. END_MESSAGE_MAP()  

  40.   

  41. /////////////////////////////////////////////////////////////////////////////  

  42. // CMyDlgBar message handlers  

  43.   

  44. LONG CMyDlgBar::OnInitDialog(UINT wParam, LONG lParam)  

  45. {  

  46.     BOOL bRet = HandleInitDialog(wParam, lParam);  

  47.     if(!UpdateData(FALSE))  

  48.     {  

  49.         TRACE0("Warning, Unalbe to init update. ");  

  50.     }  

  51.     // Add Code here  

  52.     return bRet;  

  53. }  


你可能感兴趣的:(DialogBar)