How to initialize child controls in a derived CDialogBar

原创 2006年06月05日 03:45:00



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      CMyDlgBar (CWnd* pParent = NULL);   // standard constructor

      CMyDlgBar:: CMyDlgBar (CWnd* pParent /*=NULL*/)
         : CDialog(CMyDlgBar::IDD, pParent)

      void CMyDlgBar::DoDataExchange(CDataExchange* pDX)

to the following:       CMyDlgBar ();   // standard constructor

      CMyDlgBar:: CMyDlgBar ()

      void CMyDlgBar::DoDataExchange(CDataExchange* 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. 
3. Remove "virtual BOOL OnInitDialog();" from the class header and add "afx_msg LONG OnInitDialog ( UINT, LONG );" in its place. For example:       class CMyDlgBar : public CDialogBar
      // Implementation

         // Generated message map functions
         virtual BOOL OnInitDialog();                // <-Remove this line.

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

Now, in the class implementation section, make the corresponding changes.
4. Add "ON_MESSAGE(WM_INITDIALOG, OnInitDialog );" to the message map in the .CPP implementation file. For example:       BEGIN_MESSAGE_MAP(CMyDlgBar, CDialogBar)

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

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

5. Make the OnInitDialog() conversion as follows:    Change the following:

      BOOL CMyDlgBar::OnInitDialog()
         CDialog::OnInitDialog();   // <-- Replace this line:

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. 

6. 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. 

7. Add an instance of the derived CDialogBar to the CframeWnd-derived class (normally called CMainFrame). For example:      class CMainFrame : public CFrameWnd
          CMyDlgBar m_myDlgBar;

8. Call the create method for the m_myDlgBar variable in the CFrameWnd::OnCreate() method similar to the following:      int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
         if (!m_myDlgBar.Create(this, IDD_DLGBAR1, CBRS_LEFT,
            TRACE0("Failed to create dialog bar/n");
            return -1;      // fail to create

9. Finally, if you want to support dynamic docking and resizing of the CDialogBar, add the following lines to the end of CMainFrame::OnCreate():      int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
         m_myDlgBar.SetBarStyle(m_wndToolBar.GetBarStyle() |

         return 0;


How to Use OLE in Rich Edit Controls

This section contains information about using object linking and embedding (OLE) in rich edit contro...

How to: Host Controls in Windows Forms DataGridView Cells(介绍如何在datagridview中自定义列)

The DataGridView control provides several column types, enabling your users to enter and edit valu...

How to: Work Item Tracking Custom Controls


How to: Create and Initialize Trace Listeners

System.Diagnostics.Debug 和 System.Diagnostics.Trace 类向接收和处理消息的对象(成为侦听器)中发送消息。 在启用跟踪或调试后将自动创建并初始化一个如上...
  • ztzi321
  • ztzi321
  • 2016年07月04日 08:46
  • 222

Neat Stuff to Do in List Controls Using Custom Draw

微软4.70 版本的common controls 提供了一个叫custom draw的特性。这个名字给了你一个模糊的提示关于custom draw是干什么。MSDN文档给了冗长的解释和例子,但是它没...

Shows how to Add Controls at run time.

  • 2006年02月23日 09:05
  • 7KB
  • 下载

#409 – 加入Grid中的子元素默认占满所在单元格(Child Elements in a Grid Size to Fit the Containing Cell)

默认情况下,Grid的子元素会自动调整大小占满其所在单元格。你通常不需要为其设置大小,它的大小会根据所在单元格变化而与单元格保持一致。 你也可以通过设置子元素的Margin 属性来设定其与单元格边距...
您举报文章:How to initialize child controls in a derived CDialogBar