CDialogBar

How to initialize child controls in a derived CDialogBar

When creating a simple CDialogBar, such as one with only CButtons similar to MFC's print preview, it is not necessary to derive from CDialogBar because the parent of CControlBar receives the notification messages from any child controls.

However, in the case of a more complex CDialogBar, which might have a drop- down combo box, a treeview, or ActiveX control, it might be useful to derive from CDialogBar to provide initialization for the child controls.

Because ClassWizard does not support deriving a class from CDialogBar, this article shows the steps necessary to create a class from CDialog and then "convert" the class to CDialogBar.

 

To start out, create a CDialog class with the child controls you want to use. You can transform the CDialog class into a CDialogBar class using the following nine steps:


1.       Change the base class from CDialog to CDialogBar in the class declaration. Don't forget to also change the base class in BEGIN_MESSAGE_MAP in the .cpp file.

2.       Change the constructor in both the .h and the .cpp files. Also make the change to the DoDataExchange(). Below are three items to change.

Change the following from

3.                                   CMyDlgBar (CWnd* pParent = NULL);   // standard constructor

4.                              

5.                                   CMyDlgBar:: CMyDlgBar (CWnd* pParent /*=NULL*/)

6.                                      : CDialog(CMyDlgBar::IDD, pParent)

7.                                   {

8.                                      ...

9.                              

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

11.                               {

12.                                  CDialog::DoDataExchange(pDX);

13.                                  ...

                                

to the following:

      CMyDlgBar ();   // standard constructor

 

      CMyDlgBar:: CMyDlgBar ()

      {

         ...

 

      void CMyDlgBar::DoDataExchange(CDataExchange* pDX)

      {

         CDialogBar::DoDataExchange(pDX);

         ...

                                

The key to the transformation is the conversion of the virtual OnInitDialog() member function to the WM_INITDIALOG message mapped method by changing the OnInitDialog method and by adding the ON_MESSAGE() handler. You may not have an override of OnInitDialog(). If not, add one before proceeding.

14.   Remove "virtual BOOL OnInitDialog();" from the class header and add "afx_msg LONG OnInitDialog ( UINT, LONG );" in its place. For example:

15.                               class CMyDlgBar : public CDialogBar

16.                               {

17.                                  ...

18.                               // Implementation

19.                               protected:

20.                          

21.                                  // Generated message map functions

22.                                  //{{AFX_MSG(CMyDlgBar)

23.                                  virtual BOOL OnInitDialog();                // <-Remove this line.

24.                                  //}}AFX_MSG

25.                          

26.                                  afx_msg LONG OnInitDialog ( UINT, LONG );   // <-Add this line.

27.                                  DECLARE_MESSAGE_MAP()

28.                               };

                                       

Now, in the class implementation section, make the corresponding changes.

29.   Add "ON_MESSAGE(WM_INITDIALOG, OnInitDialog );" to the message map in the .CPP implementation file. For example:

30.                               BEGIN_MESSAGE_MAP(CMyDlgBar, CDialogBar)

31.                          

32.                                  //{{AFX_MSG_MAP(CMyDlgBar)

33.                                  ...

34.                                  //}}AFX_MSG_MAP

35.                                  ON_MESSAGE(WM_INITDIALOG, OnInitDialog )    // <-- Add this line.

36.                               END_MESSAGE_MAP()

                                       

Now, convert the virtual OnInitDialog() to the message-mapped OnInitDialog().

37.   Make the OnInitDialog() conversion as follows:

38.                            Change the following:

39.                          

40.                               BOOL CMyDlgBar::OnInitDialog()

41.                               {

42.                                  CDialog::OnInitDialog();   // <-- Replace this line:

43.                                     ...

                                       

to the following:

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

         {

                          // <-- with these lines. -->

 

            BOOL bRet = HandleInitDialog(wParam, lParam);

 

            if (!UpdateData(FALSE))

            {

               TRACE0("Warning: UpdateData failed during dialog init./n");

            }

            ...

 

            return bRet;

                                       

The CDialogBar class doesn't have a virtual OnInitDialog(), and therefore calling one does not work. UpdateData is called to subclass or initialize any child controls.

44.   Make sure the dialog box resource styles to the following:

Style: Child
Boarder: None
Visible: Unchecked

At this point, everything has been reconnected to make the transformation from a CDialog class to a CDialogBar class work correctly. Now, create and use it.

45.   Add an instance of the derived CDialogBar to the CframeWnd-derived class (normally called CMainFrame). For example:

46.                               class CMainFrame : public CFrameWnd

47.                               {

48.                                   ...

49.                                   CMyDlgBar m_myDlgBar;

50.                                   ...

51.                               };

                                

52.   Call the create method for the m_myDlgBar variable in the CFrameWnd::OnCreate() method similar to the following:

53.                               int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

54.                               {

55.                                  ...

56.                                  if (!m_myDlgBar.Create(this, IDD_DLGBAR1, CBRS_LEFT,

57.                                     IDD_DLGBAR1))

58.                                  {

59.                                     TRACE0("Failed to create dialog bar/n");

60.                                     return -1;      // fail to create

61.                                  }

62.                                  ...

63.                               }

                                

64.   Finally, if you want to support dynamic docking and resizing of the CDialogBar, add the following lines to the end of CMainFrame::OnCreate():

65.                               int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

66.                               {

67.                                  ...

68.                                  m_myDlgBar.SetBarStyle(m_wndToolBar.GetBarStyle() |

69.                                     CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);

70.                                  m_myDlgBar.EnableDocking(CBRS_ALIGN_ANY);

71.                                  DockControlBar(&m_myDlgBar);

72.                          

73.                                  return 0;

      }

 

http://support.microsoft.com/default.aspx?scid=kb;EN-US;q185672

 

另外还有CButton的使用,如果不加其他说明,CButton显示出来将会是灰色,无法点击,即使你用Class Wizard添加了Click的代码。

 

解决方法:在h文件中添加

 

afx_msg void OnUpdateButton(CCmdUI * pCmdUI);

 

cpp文件中添加消息映射

 

ON_UPDATE_COMMAND_UI(IDC_BUTTON, OnUpdateButton)

 

以及响应函数

 

void CDlgbarXXX::OnUpdateButton(CCmdUI * pCmdUI)

 

{

    pCmdUI -> Enable(TRUE);

}

 

现在,你就可以象使用CDialog一样,使用CDialogBar了……

  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值