|
Tried adding hints but without success. Tell me how to add tooltips
|
|
|
|
|
There is no explicit license defined, could you please consider licensing it? My suggestion is the Code Project Open License. We are not able to use your code in our project, if there is no license defined.
Thanks and best regards!
|
|
|
|
|
very useful but need to clean up implementation
|
|
|
|
|
Hey, just a quick question before I try this my self.
Has anyone modified and compiled this as a DLL? Has it worked?
|
|
|
|
|
Hi, sorry for the late reply.
We use this code without any problem in several of our DLLs so I don't see any problem for your usage
|
|
|
|
|
I've posted info about another kind of dynamic dialog that can complement this one. Here are some links:
http://sourceforge.net/projects/dyndlgdemo[^]
http://en.wikipedia.org/wiki/Differential_Execution#Dynamic_Dialog[^]
The basic idea is that you write a method (deContents ) to create the controls you want in the dialog as a function of the current state of application data. Once you have done that, you're done. That function is executed via a function (Run ), and each time it is run it determines what is different and only updates what is necessary. There is no need to store the controls in instance variables because you don't have to send them messages. There is no need to write event handler functions because the controls themselves update the application data. Code to respond to button presses is written immediately adjacent to the button control itself. If whole blocks of controls are to appear conditionally on the state of the application data, that is easily expressed with IF, FOR, and other conditional statements in the procedure.
It is based on a simple control structure called differential execution. The idea is that, as the deContents procedure runs, it simultaneously serializes its state and deserializes its prior state, using the difference between the two to incrementally update the controls in the dialog, all of which happens very quickly.
The overall result is that complex dialogs can be written with an order of magnitude less source code than by the usual event-driven means. The example given on sourceforge uses about 40 lines of C++ code to edit a variable list of employees. It takes several hundred lines by the usual methods.
-- modified at 9:16 Saturday 24th November, 2007
MikeDunlavey
|
|
|
|
|
I created a new dialog class using an existing dialog class as its base class. This base class has no button resource. I want to add a button resource to the dialog. Modifying the base class is not allowed. I was able to add and display the button. However, I can't detect the button click event. Is there a way to detect the button click event from the new dialog class?
I have already tried adding a message map and it didn't work.
I have also tried the OnCommand function and it also didn't work.
Hope you can help me with my problem.
Best regards,
Odette
|
|
|
|
|
salu2. . . bueno me parece muy bueno tu programa pero tengo una duda muy grande.. pues tu estas creando los dialogos dinamicos que tienen como padre tu vntana principal . . . como hago para crearlo directamente si tengo un proycto creado sin el wizard y x lo tnto no tngo rc. . . y mi padre es una clase derivada de CFrameWnd. . . me gustaria un ejemplo simple de como crear un objeto derivado de la clase CDialog sin el Wizard . . . Gracias
|
|
|
|
|
No creo que te entiendan mucho si posiblemente solo habla ingles.
|
|
|
|
|
Utiliza el Servicio de Traducción Automática del Instituto Cervantes (http://oesi.cervantes.es/traduccionAutomatica.html)
salu2.. . good your program seems very good to me but I have a very great doubt. then your these creating the dinamicos dialogos that have like father your main vntana. . . since I make to create it directly if I have proycto created without wizard and x tnto not tngo rc.. . and my father is a class derived from CFrameWnd.. . gustaria me a simple example of like creating an object derived from the CDialog class without the Wizard. . . Thanks
Y luego, acaba de 'pulir' la traducción.
Antes deberás pasar tu texto por un corrector ortográfico: salu2 dinamicos dialogos vntana proycto tnto tngo gustaria
Y también, no escribir tus mensajes desde el móvil.
|
|
|
|
|
Is it possible to add a new control to an existing dialog?
I would like to set an instance of CDynDialogEx do an existing dialog, and after call the AddDlgControl(_T("BUTTON")...
thank you.
|
|
|
|
|
No, you cannot attach a existing dialog to the <b>Dynamic Dialog Class</b>. You 'd better create and positon the control yourself.
And handle the Command for the button
In header of Dialog class
<code>CButton m_ButtonToAdd</code>
In cpp of Dialog class in ::OnInitDialog()
<code>//Add button
GetDlgItem(IDOK)->GetWindowRect(&rect); //Get position of OK button
ScreenToClient(&rect);
GetClientRect(rectWnd);
rect.MoveToX(rectWnd.left + 7);
rect.MoveToY(rect.top);
m_ButtonToAdd.Create(_T("ButtonText"), WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON, rect, this, <b>IDD_BUTTONTOADD</b>);
m_ButtonToAdd.SetFont(GetFont());
</code>
In cpp of Dialog class in ::OnCommand(WPARAM wParam, LPARAM lParam)
<code>
//wParam
//The low-order word of wParam identifies the command ID of the menu item, control, or accelerator.
//The high-order word of wParam specifies the notification message if the message is from a control.
//If the message is from an accelerator, the high-order word is 1.
//If the message is from a menu, the high-order word is 0.
//lParam
//Identifies the control that sends the message if the message is from a control. Otherwise, lParam is 0.
WORD wControlID = LOWORD(wParam);
WORD wMessageID = HIWORD(wParam);
if (wControlID == <b>IDD_BUTTONTOADD</b>) {
switch(wMessageID) {
default:
OnButtonToAdd();
break;
}
return TRUE;
}</code>
|
|
|
|
|
Can I add a button on the dialog box with Caption 'Dynamic dialog : Window Title........
by clicking on the button on the same dialog box with the caption 'Press me!'
dd
-- modified at 4:59 Thursday 6th April, 2006
|
|
|
|
|
No, you can't.
You will have to add the control befor calling DoModal().
It could be invisable when you add the control to the dialog and in the event handler of the button you can than make it visible.
|
|
|
|
|
Hi, for those who are using a non-modal dialog, and neither the DoDataExchange function here is my solution.
I am using controls inside a Dockable controlbar, and I had the problem i didn't receive any kind of message from OnCommand when the user clicks over the Spinner button arrows.
That's because that message is received from OnNotify, wich is not added in CDynDialogEx...
BOOL CDynDialogEx::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
//if we have a parent send the message to the parent, so we can handle the message over there.
WORD wControlID = LOWORD(wParam);
if (wControlID != 0)
{
if (m_pParentWnd != NULL) {
::SendMessage(m_pParentWnd->GetSafeHwnd(), WM_NOTIFY, wParam, lParam);
}
}
return CDialog::OnNotify(wParam, lParam, pResult);
}
If you have any better solution, please let me know.
BYE!!!
// Savior
-- modified at 19:25 Tuesday 28th February, 2006
|
|
|
|
|
I thought you may be interested in knowing that some of the techniques I learned from this article was integral in the formation of the "eureka moment" that led to the creation of the XMLForms project which is now part of the project posted at:
http://www.codeproject.com/tools/ToolPublic.asp[^]
Just trying to keep the forces of entropy at bay
|
|
|
|
|
Everything is great but I found on bug.
Click on the "Create modeless dialog" button and click on "Press me" button
message box will be displayed and click "OK". Now close the modeless dialog by clicking Close ("X") at the right top. The main dialog will minimize!
If you have a solution for this, then it will be of greate help to many.
Thanks
Murthy
|
|
|
|
|
Try it:
A) Use MessageBox instead of AfxMessageBox
or
B) Before the AfxMessageBox do SetActiveWindow().
Don't ask me about an explanation about it.
|
|
|
|
|
Ho to add the string to Combo Box
Salman
Live and Let live
|
|
|
|
|
Did you ever find out how to add items to the combo box??? I'm hoping to do the same, but there isn't anything which indicates how to deal with the Combo box after you create it.
|
|
|
|
|
See the example of the Listbox.
It's basicly copy-paste-replace (List With ComboBox)
|
|
|
|
|
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<cstring *,="" cstring="" *=""> 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);<br />
<br />
virtual UINT AddDlgControl(LPCSTR lpszClassName, LPCTSTR lpszCaption, DWORD dwStyle, DWORD dwExtendedStyle, LPRECT pRect = NULL, void *pData = NULL, UINT nID = 0, void *pData2 = 0);<br />
<br />
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....
<br />
nRet = pDynDialogItemEx->InitDialogItem(TypeControl, dwStyle, dwExtendedStyle, pRect, lpszCaption, nID, FALSE, pData, pData2);<br />
<br />
nRet = pDynDialogItemEx->InitDialogItem(lpszClassName, dwStyle, dwExtendedStyle, pRect, lpszCaption, nID, FALSE, pData, pData2);<br />
<br />
nRet = pDynDialogItemEx->InitDialogItem(lpszClassName, dwStyle, dwExtendedStyle, pRect, lpszCaption, nID, TRUE, NULL, pData2);<br />
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);<br />
<br />
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....
..<br />
.<br />
.<br />
CWnd::DoDataExchange(pDX);<br />
if(m_pData2 != NULL)<br />
{<br />
switch(m_eTypeControl)<br />
{<br />
case COMBOBOX:<br />
{
CList<CString *, CString *> *pListComboData = (CList<CString *, CString *> *)m_pData2;<br />
POSITION posComboData = pListComboData->GetHeadPosition();<br />
while(posComboData)<br />
{<br />
((CComboBox *)this)->AddString(*pListComboData->GetNext(posComboData));<br />
}<br />
break;<br />
}<br />
default:<br />
break;<br />
}<br />
}
Okay, that's the original code updated, now to make use of it.
<br />
CList<CList<CString *, CString *> *, CList<CString *, CString *> *> listComboBoxStringLists;<br />
<br />
CList<CString *, CString *> *pListComboBoxStrings = new CList<CString *, CString *>;<br />
<br />
CString *pNewString1 = new CString(_T("String 1"));<br />
CString *pNewString2 = new CString(_T("String 2"));<br />
pListComboBoxStrings.AddTail(pNewString1);<br />
pListComboBoxStrings.AddTail(pNewString2);<br />
<br />
listComboBoxStringLists.AddTail(pListComboBoxStrings);<br />
<br />
dlg.AddDlgControl(_T("COMBOBOX"), _T(""), STYLE_COMBOBOX_DROPDOWN, EXSTYLE_COMBOBOX, NULL, NULL, 0, pListComboBoxStrings);<br />
<br />
..<br />
.<br />
int nEditRtn = dlg.DoModal();<br />
if(nEditRtn == IDOK)<br />
{<br />
}<br />
<br />
POSITION posCStringList = listComboBoxStringLists.GetHeadPosition();<br />
while(posCStringList)<br />
{<br />
CList<CString *, CString *> *pListList = listComboBoxStringLists.GetNext(posCStringList);<br />
POSITION posCString = pListList->GetHeadPosition();<br />
while(posCString)<br />
{<br />
delete pListList->GetNext(posCString);<br />
}<br />
delete pListList;<br />
}<br />
------------------------------------------------------------------
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."
|
|
|
|
|
Adding a callback function after the dynamic dialog has been instantiated will give
you much more flexibility - you will be able to get to all the dialog items via the
GetDlgItem() method and then you may modify your combo box (add/delete entries) and
perhaps SetCurSel(), etc.
In DynDialogEx.h:
class CDynDialogEx;<br />
typedef void (CALLBACK * CDynDialogExInitCBF)(CDynDialogEx * dlg);<br />
<br />
<br />
class CDynDialogEx : public CDialog<br />
{<br />
public:<br />
CDynDialogEx(CWnd * pParent = NULL, CDynDialogExInitCBF cbFunc = NULL);<br />
~CDynDialogEx();<br />
...<br />
...<br />
protected:<br />
...<br />
CDynDialogExInitCBF m_cbFunc;<br />
}
In DynDialogEx.cpp:
CDynDialogEx::CDynDialogEx(CWnd * pParent, <br />
CDynDialogExInitCBF cbFunc ) : CDialog()<br />
{<br />
...<br />
m_cbFunc = cbFunc;<br />
...<br />
}<br />
<br />
...<br />
<br />
BOOL CDynDialogEx::OnInitDialog()<br />
{<br />
...<br />
CDialog::OnInitDialog();<br />
if (m_cbFunc != NULL)<br />
{<br />
m_cbFunc(this);<br />
}<br />
CenterWindow();<br />
...<br />
}
In your own application:
void CALLBACK CondBPCallback(CDynDialogEx * dlg)<br />
{<br />
CComboBox * myCombo = (CComboBox *)dlg->GetDlgItem(IDC_MY_COMBOLISTBOX);<br />
if (myCombo != NULL)<br />
{<br />
myCombo->AddString(str0);<br />
myCombo->AddString(str1);<br />
myCombo->AddString(str2);<br />
myCombo->AddString(str3);<br />
myCombo->AddString(str4);<br />
myCombo->AddString(str5);<br />
myCombo->AddString(str6);<br />
myCombo->SetCurSel(3);<br />
}<br />
}
...
void CTestDynDialogDlg::OnButton1()
{
...
CDynDialogEx dlg(this, CondBPCallback);
..
}
That's all. There is no need to modify any other parts of this excellent utility.
Rudy Wang
|
|
|
|
|
Very Good!
Another question: Is it possible to add event handle function for controls, such as Button Click?
Thank you!
|
|
|
|
|
It does work! But I still don't know how to get the selected value of the Combo Box control.
|
|
|
|
|