Click here to Skip to main content
Licence 
First Posted 14 Feb 2000
Views 184,009
Bookmarked 73 times

Dynamic Dialog Class

By | 19 Jun 2002 | Article
Create dialogs dynamically, and easily, without the need for a dialog resource script.

Sample Image Testappliction - TestDynDialog.gif Sample Image Dynamic dialog - DynamicDialog.gif

Sample Image Dynamic dialog with List control - DynDialogList.gif Sample Image Dynamic dialog with ActiveX control - DynDialogActiveX.gif

Dynamic Dialog class

These classes are being used for displaying a modal/modelles dialog, on which the controls are dynamically added, without the need of having a dialog template as resource. These classes were developed as base classes for use in a script parser, where users can build there own dialogs, using a VB-script alike language. So basically there can be any number of controls on the dialog, at any place on the dialog.

Global structure of the CDynDialogEx class:

  • class is derived of CDialog
  • in the class there is an array of CDynDialogItemEx pointers, the dialog controls
  • class includes DoDataExchange() function.
  • add controls to dialog through function AddDlgControl()

Global structure of the CDynDialogItemEx class:

  • class is derived of CWnd
  • holds the data of the control that was added to the dialog, like the caption, the rectangle, etc.
  • creates the controls on the dialog

Small piece of sample code on how to use the classes

void CTestDynDialogDlg::OnButton1();
{
    int nRadio1 = 0;
    //Create a rectangle in dialog units, where the control should be placed
    CRect rect(10,5,60,19);
    
    CDynDialogEx dlg(this);     //create the dynamic dialog, using this as parent window
    dlg.SetWindowTitle(_T("Dynamic Dialog : WindowTitle....."));

    //Add a button control at the given position
    dlg.AddDlgControl(_T("BUTTON"),    // Type of control OR classname of the control
            _T("Press me!"),    // Caption of control
            STYLE_BUTTON,    // dwStyle of control
            EXSTYLE_BUTTON,    // dwStyleEx of control
            &rect,    // Position of control on dialog in dialog units, default = NULL
            NULL,    // void pointer to variable use for DDX, default = NULL
            IDC_DYN_BUTTON);    // ID of the contol, default = zero

    //Add a group of radio buttons
    //variable nRadio1 is used for DDX
    dlg.AddDlgControl(_T("BUTTON"), _T("Radio1Caption 1"), 
                      STYLE_RADIO_GROUP, EXSTYLE_RADIO, NULL, (void*)&nRadio1);
    dlg.AddDlgControl(_T("BUTTON"), _T("Radio1Caption 2"), 
                      STYLE_RADIO, EXSTYLE_RADIO);

    //Now show me the dialog
    dlg.DoModal()
}

Working explained

  • CDynDialogEx::AddDlgControl() function creates new object of class CDynDialogItemEx and adds it to the array of controls. Function also checks/sets the size of the dialog, so the control is seen on the dialog.
  • CDynDialogEx::DoModal() function initializes the DLGTEMPLATE structure using the selected font and calls CDialog::InitModalIndirect() for modal dialogs or CDialog::CreateIndirect() for modless dialogs
  • CDynDialogEx::OnCreate() function creates all the controls on the dialog
  • CDynDialogItemEx::CreateEx() does nothing (ActiveX controls) or creates the window
  • CDynDialogEx::OnInitDialog() function repositions all the controls on the dialog or creates the ActiveX controls
  • CDynDialogItemEx::SetWindowPos() function converts from dialog units to screen units and creates ActiveX control

Update 18-06-2002

  • Class CDynDialogItemEx now derived from CWnd instead of heaving a CWnd member
  • Added modless gialog possibility as supposed by CodeBuddy. (CDynDialogEx::SetUseModeless())
  • Added subclassed controls, because I needed them. After adding the control you can use SubclassDlgItem with the Control_ID returned by calling CDynDialogEx::AddSubclassedDlgControl()
  • Improved DDX_Control support for dialog items
  • Added partial ActiveX controls support. Partial because the controls are created, but there is no support for the EVENT_SINK! But there is code for creating licensed controls dynamicly.
  • Added examples for modeless dialog, adding and filling a CListbox, an ActiveX control on a dialog

Tip!

Possible extensions:

  • improving ActiveX controls support, specially EVENT_SINK related
  • adding Menus dynamically to the dialog
  • ...

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Marcel Scherpenisse

Software Developer

Netherlands Netherlands

Member



Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
QuestionCompile as DLL? Pinmembernamezero11111110:21 8 Jul '10  
AnswerRe: Compile as DLL? PinmemberAlbert van Peppen21:37 12 Sep '10  
Generalanother approach to dynamic dialogs [modified] PinmemberMikeDunlavey2:42 24 Nov '07  
QuestionAdding a button to an existing dialog class dynamically Pinmemberodette77614:43 29 Nov '06  
GeneralCrear con otra vntana padre Pinmemberucsm15:03 14 Oct '06  
GeneralRe: Crear con otra vntana padre Pinmemberlexugax22:38 22 Mar '07  
GeneralRe: Crear con otra vntana padre PinmemberKeia20:37 26 May '08  
GeneralIs possible to add a control to an existing dialog Pinmemberdtgarry3:25 15 Jun '06  
AnswerRe: Is possible to add a control to an existing dialog PinmemberMarcel Scherpenisse5:21 15 Jun '06  
Questionto add new control to dynamic dialog box at runtime Pinmemberwavesss22:50 5 Apr '06  
AnswerRe: to add new control to dynamic dialog box at runtime PinmemberMarcel Scherpenisse22:58 5 Apr '06  
GeneralSpinner message solution ! Pinmembersaviorman3:39 28 Feb '06  
GeneralInspiration PinmemberRedZenBird8:33 17 Sep '05  
GeneralDynamic Modeless dialog bug PinmemberMNN Murthy8:38 6 May '04  
GeneralRe: Dynamic Modeless dialog bug PinsussAnonymous0:30 7 Mar '05  
QuestionHOw to Add the Contents to Combo Box PinmemberDELIVER THE PROMISE19:35 16 Dec '03  
AnswerRe: HOw to Add the Contents to Combo Box PinmemberPaul Wolfensberger12:01 4 Aug '04  
GeneralRe: HOw to Add the Contents to Combo Box PinmemberMarcel Scherpenisse2:46 5 Aug '04  
GeneralRe: How to Add the Contents to Combo Box PinmemberJordan Walters22:56 4 Jan '05  
Following the example provided for a list control (and changing things for a combo box) is okay if you know in advance how many such controls you wish to appear on your dialog box, and this number of list boxes is invariant.
I use Marcel's stuff to generate dialogs with from 0 (zero) to whatever number of combo box's on it. So extending CDynDialogEx is not much use as I don't know in advance how many combo boxes I need.
So to get around this I just add the combo boxes to the CDynDialogEx dialog as I need them (as shown in the CTestDynDialogDlg::OnButton2 example - but I include an extra parameter at the end which is a pointer to a CList object.....
 
First I changed the following bits of code:-
 
DynDialogEx.h
virtual UINT AddDlgControl(DLGITEMTEMPLATECONTROLS TypeControl, LPCTSTR lpszCaption, DWORD dwStyle, DWORD dwExtendedStyle, LPRECT pRect = NULL, void *pData = NULL, UINT nID = 0, void *pData2 = 0);
 
virtual UINT AddDlgControl(LPCSTR lpszClassName, LPCTSTR lpszCaption, DWORD dwStyle, DWORD dwExtendedStyle, LPRECT pRect = NULL, void *pData = NULL, UINT nID = 0, void *pData2 = 0);
 
virtual UINT AddSubclassedDlgControl(LPCSTR lpszClassName, LPCTSTR lpszCaption, DWORD dwStyle, DWORD dwExtendedStyle, LPRECT pRect = NULL, UINT nID = 0, void *pData2 = 0);

 
and its implementation in DynDialogEx.cpp, for the 3 respective functions change their function definitions and then the 3 appropriate lines to be as follows....

nRet = pDynDialogItemEx->InitDialogItem(TypeControl, dwStyle, dwExtendedStyle, pRect, lpszCaption, nID, FALSE, pData, pData2);
 
nRet = pDynDialogItemEx->InitDialogItem(lpszClassName, dwStyle, dwExtendedStyle, pRect, lpszCaption, nID, FALSE, pData, pData2);
 
nRet = pDynDialogItemEx->InitDialogItem(lpszClassName, dwStyle, dwExtendedStyle, pRect, lpszCaption, nID, TRUE, NULL, pData2);

 
DynDialogItemEx.h
Add a new member variable...
void *m_pData2;
 
and modify the 2 InitDialogItem function definitions....
UINT InitDialogItem(DLGITEMTEMPLATECONTROLS TypeControl, DWORD dwStyle, DWORD dwExtendedStyle, LPRECT pRect, LPCTSTR lpszCaption, UINT nID = 0, BOOL bSubclassed = FALSE, void *pData = NULL, void *pData2 = NULL);
 
UINT InitDialogItem(LPCSTR lpszClassName, DWORD dwStyle, DWORD dwExtendedStyle, LPRECT pRect, LPCTSTR lpszCaption, UINT nID = 0, BOOL bSubclassed = FALSE, void *pData = NULL, void *pData2 = NULL);

 
In the corresponding implementation file DynDialogItemEx.cpp ensure that the function definitions match what you have just changed in the header file and add the following line to each function after the m_pData = pData; line....
m_pData2 = pData2;
 
Add some extra stuff in CDynDialogItemEx::DoDataExchange to populate the combobox with whatever is in m_pData2....
..
.
.
CWnd::DoDataExchange(pDX);
if(m_pData2 != NULL)
{
switch(m_eTypeControl)
{
case COMBOBOX:
{ // m_pData2, it it's valid, points to a list of CString *
CList *pListComboData = (CList *)m_pData2;
POSITION posComboData = pListComboData->GetHeadPosition();
while(posComboData)
{
((CComboBox *)this)->AddString(*pListComboData->GetNext(posComboData));
}
break;
}
default:
break;
}
}

 
Okay, that's the original code updated, now to make use of it.
 

// For each combo box added, keep a note of the list created to hold the list of strings added to this list (so that it and its contents can be deallocated after use).
CList<CList<CString *, CString *> *, CList<CString *, CString *> *> listComboBoxStringLists;
 
// I will add just one combo box for this example, although this would ordinarily
// be enclosed in some sort of decision-loop adding any number of combo-boxes....
CList<CString *, CString *> *pListComboBoxStrings = new CList<CString *, CString *>;
 
// Add some strings to this combo box. Again this would normally be a varying
// number of strings, different for each combo box.
CString *pNewString1 = new CString(_T("String 1"));
CString *pNewString2 = new CString(_T("String 2"));
pListComboBoxStrings.AddTail(pNewString1);
pListComboBoxStrings.AddTail(pNewString2);
 
// And add the whole list to our list of lists so we can remove it after
// closing the dialog....
listComboBoxStringLists.AddTail(pListComboBoxStrings);
 
dlg.AddDlgControl(_T("COMBOBOX"), _T(""), STYLE_COMBOBOX_DROPDOWN, EXSTYLE_COMBOBOX, NULL, NULL, 0, pListComboBoxStrings);
 
..
.
// Open the dialog and once closed do whatever with the results.....I have not implemented this bit yet but Marcel's code shows how to do this.
int nEditRtn = dlg.DoModal();
if(nEditRtn == IDOK)
{
}
 
// And finally deallocate all the allocated memory
POSITION posCStringList = listComboBoxStringLists.GetHeadPosition();
while(posCStringList)
{
CList<CString *, CString *> *pListList = listComboBoxStringLists.GetNext(posCStringList);
POSITION posCString = pListList->GetHeadPosition();
while(posCString)
{
delete pListList->GetNext(posCString);
}
delete pListList;
}

 
------------------------------------------------------------------
I'm sorry this is so complicated but this is the only way I could come up with to achieve having a variable number of combo boxes on a dialog, and being able to add strings to the list.
 
There are bound to be syntax errors in this code, so please let me (and everyone else know).
 
"On this day at least 13 people fell off their bicycles, and some of the sea evaporated."
GeneralRe: How to Add the Contents to Combo Box Pinmemberrudywang19:39 20 Sep '06  
GeneralRe: How to Add the Contents to Combo Box PinmemberLieWei14:12 6 Apr '12  
GeneralGood work PinmemberVitali Halershtein5:01 30 Sep '03  
GeneralAWT PinmemberGeMe_Hendrix1:21 23 Jul '03  
Generalbuttons with bitmaps PinmemberFreespirit2:48 13 Feb '03  
QuestionHow to add Scrolling Pinmembermarigapudi5:02 6 Jan '03  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web02 | 2.5.120528.1 | Last Updated 20 Jun 2002
Article Copyright 2000 by Marcel Scherpenisse
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid