CDialogBarEx : A Dialog bar with initialization

Environment: ****** -->

In the MFC architecture CDialogBar can provide more flexible ways to create a control bar in the application than traditional toolbars using CToolBar. Apart from standard button like controls of toolbar, a dialog bar can include other windows controls (such as combobox ) and OCX controls as well. They also provide very flexible layout since we can use dialog editor to create a dialog template for the dialog bar.

Limitations of CDialogBar:

However, one limitation of CDialogBar is it lacks suitable initialisation function such as OnInitDialog() which is available in all standard CDialog derived classes. This creates trouble in subclassing windows controls created through dialog template. We need to subclass windows controls with suitable MFC class objects to send messages to the control and to alter their behaviour. Without the help of MFC supplied classes, changing the property of Active X controls will require   complex code, not so easy to comprehend.

With the help of Class Wizard, subclassing the controls created from dialog template,    becomes very easy as the Class Wizard automatically adds DDX_Control( CDataExchange* pDX, int nIDC, CWnd& rControl ); statements in DoDataExchange() override of CDialog derived class. DoDataExchange is called by UpdateData( BOOL bSaveandValidate) function, which in turn is called by OnInitDialog() in response to WM_INITDIALOG message.

All these steps of initialising does not automatically  occur in the CDialogbBar as it is derived from CControlBar and not from CDialog. 

Solution:

    We write a class which does the job of initialising the dialog bar, which can be reused whenever we want to create a dialog bar.  Let's call this class CDialogBarEx which would provide functionality of initialising the dialog bar.

    The function which initialise the dialog bar should normally be called immediately after the dialog bar is created. We can not use OnCreate() override alone, for this purpose as OnCreate is called during the window creation ( before CreateEx returns ) and not after that. We so we just post a custom WM_INITDIALOGBAR message ( WM_USER + 1)) to the dialog bar itself from our override of OnCreate. This assures that handler for WM_INITDIALOGBAR will called immediately after the dialog bar is fully created and ready to use. We also write handler for WM_INITDIALOG bar ( lets call it OnInitHandler() ) which should call a virtual function OnInitDialogBar() and from the same handler we call UpdateData(FALSE) before we call OnInitDialogBar() ;

The bottom line:

  • Users of this class  can put DDX_Control   statements  in side DoDataExchange,  as done by Class Wizard for CDialog and its derived classes.
  • Users can override OnInitDialogBar to perform other custom initialisation.

How to use CDialogBarEx:

  • Add files DialogBarEx.h and DialogBarEx.cpp to your Visual C++ project
  • Derive your own class ( for example say "CYourClass" ) from CDialogBarEx ;
  • Add DDX_Control statements in your override of DoDataExchange as done by class wizard, to subclass the dialog bar controls with MFC classes.
  • Override OnInitDialogBar() function to do any further initialisation of this class.

Other steps to create the dialog bar are the same as recommended by MFC documentation..

  1. Create dialog resource template . Set child property on, visible off.
  2. Declare one CDialogBarEx derived member in CMainFrame class;
  3. In the CMainFrame::OnCreate override call create function of CDialogBarEx derived class.

The demo contains both source and sample program. The demo shows how to set hyperlink in dialog bar using CLabel and how to set initial null ( null means not yet defined and not NULL of C++) value in SysDateTime32 control.

ACKNOWLEDGEMENTS:

To make this demo I have used following classes from www.codeguru.com

  • CDateTimeCtrl class written by Chris Maunder 
  • CLabel class downloaded from codeguru with modifications.
  • I have also incorporated a modification to CLabel class suggested to me by Ed Dixon of Mountain System Inc. via e-mail.

Download demo project - 42KB



Comments

  • Clas Wizard does not know CDialogBar

    Posted by Legacy on 02/16/2003 12:00am

    Originally posted by: Jason

    Clas Wizard does not know CDialogBar. so how do i derive from this class using the wizard? (vc 6.0)

    thanks!

    Reply
  • Problem with Windows Me?

    Posted by Legacy on 11/26/2002 12:00am

    Originally posted by: Ben Katz

    I am using Windows Me, Visual Studio 6.0 (sp5), with the latest SDK.  The dialogbar works great, but only in release mode.  In debug mode, it crashes before the application appears.  CVScrollArea is my class that derives from CDialogBarEx.  The call stack upon crashing is as follows:
    
    

    KERNEL32! bff66878()
    _CrtDbgReport(int 2, const char * 0x005454f4 THIS_FILE, int 43, const char * 0x00000000, const char * 0x00000000) line 353
    AfxAssertFailedLine(const char * 0x005454f4 THIS_FILE, int 43) line 39 + 19 bytes
    CDataExchange::PrepareCtrl(int 116) line 43 + 21 bytes
    DDX_Control(CDataExchange * 0x007da7ec, int 116, CWnd & {CWnd hWnd=0x00000000}) line 626 + 12 bytes
    CVScrollArea::DoDataExchange(CDataExchange * 0x007da7ec) line 44
    CWnd::UpdateData(int 0) line 3109
    CDialogBarEx::InitDialogBarHandler(unsigned short 0, unsigned long 0) line 66
    CWnd::OnWndMsg(unsigned int 1025, unsigned int 0, long 0, long * 0x007da98c) line 1815 + 17 bytes
    CWnd::WindowProc(unsigned int 1025, unsigned int 0, long 0) line 1585 + 30 bytes
    CControlBar::WindowProc(unsigned int 1025, unsigned int 0, long 0) line 480 + 20 bytes
    AfxCallWndProc(CWnd * 0x01024ef8 {CVScrollArea hWnd=0x00000db8}, HWND__ * 0x00000db8, unsigned int 1025, unsigned int 0, long 0) line 215 + 26 bytes
    AfxWndProc(HWND__ * 0x00000db8, unsigned int 1025, unsigned int 0, long 0) line 368
    KERNEL32! bff63613()
    KERNEL32! bff848f7()


    Are there any known problems with Windows Me?
    Thanks,
    Ben

    Reply
  • Doesnt work in C++.NET (7.0)

    Posted by Legacy on 10/11/2002 12:00am

    Originally posted by: Mike Pliam

    This works great in Visual C++ 6.0. But when I tried to port an app over to C++ 7.0 (C++.NET), I received the following error message pertaining to the message map code in the DialogBarEx.cpp file:

    BEGIN_MESSAGE_MAP(CDialogBarEx, CDialogBar)
    //{{AFX_MSG_MAP(CDialogBarEx)
    ON_WM_CREATE()
    ON_MESSAGE(WM_INITDIALOGBAR, InitDialogBarHandler )
    //{{AFX_MSG>MAP[
    END_MESSAGE_MAP()

    error C2440: 'static_cast': cannot convert from 'void(__thiscall CDialogBarEx::*)(WORD,DWORD)' to'LRESULT (__thiscall CWnd::*)(WPARAM,LPARAM)'

    Does anybody know how to work around or fix this problem?

    Mike Pliam

    Reply
  • Catching SelChange() in Combo Box

    Posted by Legacy on 10/30/2000 12:00am

    Originally posted by: Petr Jodas

    I have class CDirBarDlg which is derived from CDialogBarEx. In this class I have control CComboBoxEx and I need catch message OnSelChange(). How I can do it ? Thanx...

    Reply
  • does CDialogBar work?

    Posted by Legacy on 09/30/2000 12:00am

    Originally posted by: ali nouri

    hi,
    I want to make a structure viewer on the left of an editor(
    like the treeView in the VC environment itself) it should be CControlBar derived class but i couldn't make it with a CDialogBar) what should i do?
    thnx

    Reply
  • How can I draw a Gripper in the DialogBar?

    Posted by Legacy on 07/30/2000 12:00am

    Originally posted by: Andi Hofmann

    I tried to draw a gripper to the DialogBarEx, but overriding OnPaint doesn't work. How can I manage it?

    Reply
  • Another option

    Posted by Legacy on 12/16/1999 12:00am

    Originally posted by: Rick Shide

    Instead of subclassing CDialogBar to initialize controls, just do it in the initial DDX.
    
    NOTE: if you don't base your CDialogBar-derived bar on
    CDialogBarEx, you need to call your own MyDialogBar.OnUpdate(FALSE) after you create it.

    void CMyDialogBar::DoDataExchange(CDataExchange* pDX)
    {
    BOOL bNeedToInit = FALSE;
    if (!m_Label.GetSafeHwnd())
    bNeedToInit = TRUE;

    DDX_Control(pDX, IDC_STATIC_WEBSITE, m_Label) ;
    DDX_Control(pDX, IDC_CUSTOM_DATETIME , m_DateTimeCtrl) ;
    if (bNeedToInit) {
    ASSERT(m_Label.GetSafeHwnd() && m_DateTimeCtrl.GetSafeHwnd());
    HWND hCtrl ;
    CString strFontName = "Arial" ;
    m_Label.SetLinkURL(_T("http://www.zydusmed.com/vrunda";));
    m_Label.SetLink(TRUE)
    .SetTextColor(RGB(0,0,255))
    .SetFontUnderline(TRUE)
    .SetFontName(strFontName).SetFontSize(12)
    .SetLinkCursor(AfxGetApp()->LoadCursor(IDC_HAND));
    m_DateTimeCtrl.SetFormat("dd-MMM-yyyy");
    GetDlgItem(IDC_CUSTOM_DATETIME, &hCtrl) ;
    ASSERT(hCtrl != NULL);
    DateTime_SetSystemtime(hCtrl, GDT_NONE, NULL) ;
    }

    CDialogBarEx::DoDataExchange(pDX);
    }


    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • As all sorts of data becomes available for storage, analysis and retrieval - so called 'Big Data' - there are potentially huge benefits, but equally huge challenges...
  • The agile organization needs knowledge to act on, quickly and effectively. Though many organizations are clamouring for "Big Data", not nearly as many know what to do with it...
  • Cloud-based integration solutions can be confusing. Adding to the confusion are the multiple ways IT departments can deliver such integration...

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date