|
hi Jordan Walters:
when I use there's code in DodataExchange.
((CComboBox *)this)->AddString(*pListComboData->GetNext(posComboData));
It's not works.
I move there's code in CreateEx function than it works.
so this code can't add in DoDataExChange funtion.
|
|
|
|
|
I think this is good work. F.e. it can be used for creation and distribution
some controls as lib projects.
Vitali
http://www.creative-case.com
|
|
|
|
|
Good, but perhaps a C++ implementation of the method Java AWT uses would have been better
|
|
|
|
|
Very nice!
A iactually coocked up something quite simmilar recently, but i ran across one big problem... How on Earth do you add a bitmap (preferebly from a file, not a resource) to a button???
|
|
|
|
|
Hi,
I would like to add a scrollbar when the number of controls added make the
dialog not fit on the screen. In the OnInitDialog method, I called EnableScrollBarCtrl,
and ShowScrollBar(SB_VERT,FALSE);
In the AddDlgControl method, I tried to do GetDlgRect, and if the rect.bottom-top
exceeds some limit - I tried ShowScrollBar(TRUE). This does not work as the m_hWnd
is 0? Any tips/hints/code would be great.
|
|
|
|
|
Hi,
Excuse my english, I´m a brazilian.
What can i do to use Tab Control ? If you have any source sample, i appreciate.
Thank´s for any help.
Mauro Cordon.
mcordon@usa.com
|
|
|
|
|
If there any way to deal with Tab Control?
|
|
|
|
|
I want to put a control, controled by a class included by me, in a dialog dynamicly created by DynDialogEx class. I think the subclassed controls are this, but after try to implementated I'm not sure. I Registered my class, and I create the control with the function AddSubclassedDlgControl. After that I execute the function SubclassDlgItem with de ID returned by AddSubclassedDlgControl, but my control is not created yet, in consecuence the control is not properly created in dynamic dialog.
Is possible add support for a new class in this class?. I seen the example CListDynDialogEx in DynamicDialog_demo, but I don't want a new dialog, and my control is from a other class!.
Any suggestion
Thanks in advance.
Amauta
|
|
|
|
|
One method which works for me (quick & dirty):
1. Add a new enum to the DLGITEMTEMPLATECONTROLS enum in DynDlgItemEx.h. I added USER_DEF at the end.
2. Alter a bit of the CDynDialogItemEx::CreateEx function to say:
else if (m_pData != NULL && IsDataMemberPointerToWnd ()) // exisiting code
{
// change call to pass NULL if classname is ""
bRet = ((CWnd*)m_pData)->CreateEx (m_dwStyleEx,
m_strClassName.GetLength () ? (LPCTSTR) m_strClassName : NULL,
m_strCaption,
m_dwStyle,
m_Rect,
pParent,
m_ControlID);
3. Add your pre-existing class instance (CWnd based but dont call Create ()) using
AddDlgControl (USER_DEF,......, pData...)
where pdata is a pointer to your instance
4. This works as follows: USER_DEF type results in a zero-length classname. If you detect the zero-length and substitute NULL, then CreateEx will cause a call thru to your CWnd class OnCreate handler, if you have set the pData paramter to point to your class.
Its rough, but it works for me. If you want to get fancier by actually using the classname of a class you have registered, a bit more work is involved, you probably need to add another AddDlgControl function that takes a classname and USER_DEF type, because the GetClassNameByType () function used in the exsiting code only recognises pre-defined types, so you'll always get an empty string.
Hope this helps
Chris
|
|
|
|
|
I dont know if I'm missing something, but the source and demo projects have the old versions. Where are the new ones?
|
|
|
|
|
The author resubmitted the downloads and I've updated them.
cheers,
Chris Maunder
Rub your belly and pat your head simultaneously. Sometimes that helps me make sense of things - Jon Sagara
|
|
|
|
|
How can I add a -ClistCtrl object- in the dynamic dialog?.
if I do:
OnButton(){
CListCtrl m_List;
CDynDialogEx dynDlg;
dynDlg.AddDlgControl(LISTCTRL, _T(""), WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_BORDER | LVS_SINGLESEL,0,rect,(void *) &m_List);
if (dynDlg.DoModal()== IDOK)){
MessageBox("OK");
}
}
I get a running error in the
DDX_Control(pDX, m_ControlID, *(CWnd*)m_pData); on DoDataExchange()
Any suggestion
Thanks
Tximist
|
|
|
|
|
I've got the same problem in a similar use case.
|
|
|
|
|
I simply add:
<br />
if (SingleSelection_)<br />
sListCtrl.CtlID = AddDlgControl(_T("SysListView32"), _T(""), LVS_SHOWSELALWAYS | LVS_REPORT | WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_BORDER | LVS_SINGLESEL, 0, pRect);<br />
else<br />
sListCtrl.CtlID = AddDlgControl(_T("SysListView32"), _T(""), LVS_SHOWSELALWAYS | LVS_REPORT | WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_BORDER, 0, pRect);<br />
I insert the CListCtrl's data in OnInitDialog().
I process the selected data in OnOK() using the saved CtlID.
|
|
|
|
|
Hi !
I try to use your classes but I cannot use the DDX with a CButton for example, or CWnd.
If I try to use in your example:
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
(void*)&btn,// void pointer to variable use for DDX, default = NULL
IDC_DYN_BUTTON);// ID of the contol, default = zero
where btn is a CWnd, I have an ASSERT in wincore.cpp, saying that "only attach once, detach on destroy".
I tried to detach the controls, after createing, in CreateEx function, but it did not work.
I'll apreciate any help.
Thanks!
evolution_man.
|
|
|
|
|
Could anyone give me some hints on how to resize the dialog?
|
|
|
|
|
A easy way to resize the dialog. On "OnInitDialog" derived CDialog, use MoveWindow.
BOOL CDynDialogEx::OnInitDialog()
{
CDialog::OnInitDialog();
...
MoveWindow( x,y, width, height );
...
}
|
|
|
|
|
How can I use a listbox, and populate the list with text
|
|
|
|
|
Save the returned CtlID from:
<br />
CtlID = MyDlg.AddDlgControl(_T("SysListView32"), _T(""), LVS_SHOWSELALWAYS | LVS_REPORT | WS_VISIBLE | WS_CHILD | WS_TABSTOP | WS_BORDER | LVS_SINGLESEL, 0, pRect);<br />
(if you were adding a CListCtrl).
In OnInitDialog(), use the CtlID to get the control:
<br />
CListView* pList = static_cast<CListView*>(GetDlgItem(CListList(i).CtlID));<br />
and populate the list.
|
|
|
|
|
Greg Niswonger wrote: In OnInitDialog(), use the CtlID to get the control:
In what OnInitDialog()?
|
|
|
|
|
In CDynDialogEx, there is an ::OnInitDialog() routine. Before it calls the base class, i.e. CDialog::OnInitDialog();, you can add a call to your own routine that you'll add, e.g. SetDlgControlData(), in which you can initialize the controls in your dialog. When you add a control via CDialog::AddDlgControl(...), save the returned UINT CtlID and place it in a member structure within CDynDialogEx where it's accessable to OnInitDialog(). In your own SetDlgControlData(), which will be called when the dialog is invoked, you can use the saved CtlID in a GetDlgItem() call to retrieve the pointer to the control. Using the pointer to the control, you can then add data via InsertItem() or other MFC calls. Obviously, you'll have to design a method that allows your code in your SetDlgControlData() to have access to the data with which you want to place in your CListCtl. I place my data in an internal structure that's tailored for each type of control and maintain a list of these structures so that I can add as many controls to the dialog of each type as I need.
I added additional methods that accepted the data that I wanted to load into each control and saved the data in the internal structure along with the CtlID returned from the CDynDialogEx::AddDlgControl(...). Then my SetDlgControlData() initializes any control that that I have added to the dialog with the data that has been provided.
Then you'll need to do the reverse by providing your own GetDlgControlData() in CDynDialogEx::OnOK() to retrieve the data from the control, again using the saved CtlID. Using the CtlID, the retrieval methods will be via the standard MFC calls like, GetNextItem(-1,LVNI_SELECTED). You'll need to do this for any control for which the basic data passing mechanism in AddDlgControl(...) is not satisfactory. Eventually, you'll be able to add any type of control and populate your controls with any type of data that is passed in the calls of your design. For instance, to add data to a COMBOBOX control, I provided a call that will accept a list of items with which to populate the drop-down box.
The preferred method would be to subclass CDynDialogEx in which you will provide all these additional methods and internal structures.
|
|
|
|
|
You mention that adding ActiveX controls would be an interesting extension. I am working on a project that creates dynamic dialogs just as you demonstrate here, but
I need to accept a GUID of an ActiveX control and then create that control dynamically on the dialog. I'm not sure how best to approach the problem.
When I examine a .RC file I see the quoted GUID of any ActiveX control on my dialog. But apparently I can't use that when creating DLGITEMTEMPLATE structures; it seems to want a window class name.
So, I thought about using the GUID to create a control, then ask it for it's window class name, or somethinglike that. Of course, I don't know what I'm doing, so I'm not even sure if I'm on the right track.
Perhaps you could nudge me in the right direction. Thanks in advance
|
|
|
|
|
When you look at the Create function generated when adding an OCX to the dialog editor in VC++ this function calls the fuction :
CreateControl(GetClsid(), lpszWindowName, dwStyle, rect, pParentWnd, nID);
And as you can see the parameters "lpszClassName" and "pContext" are not passed to the CreateControl function.
So when I take the code from my article, then a change should be made to the CDynDialogItemEx::CreateEx() funtion in a way that when a ActiveX control is specified it calls the ActiveX control's CreateControl() function.
I hope this will help you.
Please keep me informed about your progress
|
|
|
|
|
After adding one, say a Slider, how can I adjust the Min/Max. Every call I try to get a CWnd or HWND results in NULL. I should be able to do CWnd thisCtrl=dlg.AddControl..... It'd be alot more handy than returning an int I think.
Anyway, I really need to know how to do this.
TIA
|
|
|
|
|
Thanks for your interest in my code.
I haven't worked with a slider control so far, but below is a sample for a CCombobox.
This sample is teaches how to catch some actions on a dynamic dialog.
When you add a dialog control the function returns the control ID which is added.
With this ID you can call GetDlgItem(ID). This gives you a Cwnd*.
You can cast this pointer for example to a CCombobox* and than you can add your text-items to the combo-box,
as usual.
In the OnCommand of the parent window you can catch a Message for example CBN_KILLFOCUS
Here you use the same method as above.
From the CWnd* you can call GetWindowText() or if you cast it to a CComboBox* you can call GetLBText()
Below is some sample code.
Regards,
Marcel
BOOL CUseDynDialog::OnCommand(WPARAM wParam, LPARAM lParam)
{
//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 != 0) {
int nIndex = CB_ERR;
CString strBuf;
CComboBox *pCombo = NULL;
switch (wMessageID) {
case CBN_KILLFOCUS:
pCombo =(CComboBox*)GetDlgItem(ID);
if (pCombo != NULL) {
nIndex = pCombo->GetCurSel();
if (nIndex != CB_ERR) {
pCombo->GetLBText(nIndex, strBuf);
}
}
}
}
return CDynDialogEx::OnCommand(wParam, lParam);
}
|
|
|
|
|