打造完美的CDialogBar

本文来自:http://fdujohn.spaces.live.com/blog/cns!4FEAD632772E9F9A!144.entry

 

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./n");
              }
              // 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/n");
            return -1;      // fail to create
        }
        ...
    }

 

        或者如果你想让其动态的停靠在面板的任何一个地方,那就加上CBRS_FLYBY和CBRS_SIZE_DYNAMIC,这两个都是CControlBar的属性,具体可查询MSDN:

 

    int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
           ...
        m_myDlgBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
               CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
        m_myDlgBar.EnableDocking(CBRS_ALIGN_ANY);
        DockControlBar(&m_myDlgBar);
        return 0;
    }


  到此,你基本上可以像使用其它控件一样使用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());
       }

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值