rickatseasoft
asked on
Change control type at runtime. SubclassWindow()
Change a control class at runtime. For reasons that are not real important here, I have a dialog with about a hundred controls on it that sometimes sum columns and/or rows. This begs for treatment as an array.
It works perfectly except for one thing, and that is the subclassing. Some of the controls need to become CDollarEdits or CDateEdits, and rather than do this by declaring a large number of control variables, I would like to use SubclassDlgItem or SubclassWindow.
I'm not using variables at all, just GetDlgItem() for the controls all line up nicely in resource.h. In other words, there is no conflict with DDX.
Something like
CDollarEdit CtrlDollars[20];
CWnd *pWnd;
for(ii=0;ii<20;ii++){
pWnd=GetDlgItem(IDC_XXXXXX XXXX+ii);
//perform some operations on pWnd
CtrlDollars[ii].SubclassWi ndow(pWnd- >m_hWnd);
}
This compiles and executes without complaint except that the behavior of the controls doesn't change at all.
Any ideas, Rick
It works perfectly except for one thing, and that is the subclassing. Some of the controls need to become CDollarEdits or CDateEdits, and rather than do this by declaring a large number of control variables, I would like to use SubclassDlgItem or SubclassWindow.
I'm not using variables at all, just GetDlgItem() for the controls all line up nicely in resource.h. In other words, there is no conflict with DDX.
Something like
CDollarEdit CtrlDollars[20];
CWnd *pWnd;
for(ii=0;ii<20;ii++){
pWnd=GetDlgItem(IDC_XXXXXX
//perform some operations on pWnd
CtrlDollars[ii].SubclassWi
}
This compiles and executes without complaint except that the behavior of the controls doesn't change at all.
Any ideas, Rick
ASKER
Andy:
Once again, it compiled without complaint, and ran without complaint, but didn't exhibit the desired the desired behaviour.
Maybe I am asking the wrong question. or trying to use the wrong function to accomplish the task.
I want to create a CEdit using the standard dialog editor. Normally, I would use the ClassWizard to attach a variable to that control, let's call it m_ctrlDollar0. The ClassWizard would then place in the code a line that looked something like CEdit m_ctrlDollar0. I would then come back and change the control type by changing "CEdit m_ctrlDollar0" to "CDollarEdit m_ctrlDollar0" and viola, my control is a CDollarEdit control exhibiting all of the characteristics of that type of control.
In this case, I want to do the same thing, but instead of using a variable, I want to step through an array of Dialog Control IDs.
Thanks, Rick
Once again, it compiled without complaint, and ran without complaint, but didn't exhibit the desired the desired behaviour.
Maybe I am asking the wrong question. or trying to use the wrong function to accomplish the task.
I want to create a CEdit using the standard dialog editor. Normally, I would use the ClassWizard to attach a variable to that control, let's call it m_ctrlDollar0. The ClassWizard would then place in the code a line that looked something like CEdit m_ctrlDollar0. I would then come back and change the control type by changing "CEdit m_ctrlDollar0" to "CDollarEdit m_ctrlDollar0" and viola, my control is a CDollarEdit control exhibiting all of the characteristics of that type of control.
In this case, I want to do the same thing, but instead of using a variable, I want to step through an array of Dialog Control IDs.
Thanks, Rick
What you are currently doing should work.
Also nothing wrong with code like the following in the DoDataExchange (just the wizard doesn't support it)
for(UINT n = IDC_EDIT1; n <= IDC_EDIT5; n++)
DDX_CONTROL(pDX, n, myctrl[n-IDC_EDIT1]);
Also nothing wrong with code like the following in the DoDataExchange (just the wizard doesn't support it)
for(UINT n = IDC_EDIT1; n <= IDC_EDIT5; n++)
DDX_CONTROL(pDX, n, myctrl[n-IDC_EDIT1]);
ASKER
Andy:
Thanks, found the problem----It was me. Your advice helped me ferret out the problem.
Just two more questions please.
The place where Subclass... is called, is itself called every time that the dialog is resized (NOT by the user, bu tby the needs of the code). I'm using something like if(!m_CtrlDollard[ii]._hWn d)m_CtrlDo llar[ii].S ubclassDlg Item(...); Is this the correct way to do this.
When the CDialog closes, do I need to Unsubclass(), or just let them die a natural death. The m_CtrlDollars[], etc. are members of the class, so they lose scope (I'm grasping for the C++ term here), and the controls obviously die with the destructor for their parent dialog.
Thanks again, Rick
Thanks, found the problem----It was me. Your advice helped me ferret out the problem.
Just two more questions please.
The place where Subclass... is called, is itself called every time that the dialog is resized (NOT by the user, bu tby the needs of the code). I'm using something like if(!m_CtrlDollard[ii]._hWn
When the CDialog closes, do I need to Unsubclass(), or just let them die a natural death. The m_CtrlDollars[], etc. are members of the class, so they lose scope (I'm grasping for the C++ term here), and the controls obviously die with the destructor for their parent dialog.
Thanks again, Rick
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
You may also use DDX_Control() loop in your DoDataExchange.....
void CMyDlg::DoDataExchange(CDa taExchange * pDX)
{
CDialog::DoDataExchange(pD X);
//{{AFX_DATA_MAP(CMyDlg)
// Other DDX statements here...Dont put loop manually here
//}}AFX_DATA_MAP
for (int ii = 0; ii < 20; ii++)
DDX_Control(pDX, IDC_XXXXXXXXXX+ii, CtrlDollars[ii]);
}
-MAHESH
void CMyDlg::DoDataExchange(CDa
{
CDialog::DoDataExchange(pD
//{{AFX_DATA_MAP(CMyDlg)
// Other DDX statements here...Dont put loop manually here
//}}AFX_DATA_MAP
for (int ii = 0; ii < 20; ii++)
DDX_Control(pDX, IDC_XXXXXXXXXX+ii, CtrlDollars[ii]);
}
-MAHESH
hmmm.. cause of too late posting sorry agin !
CtrlDollars[ii].SubclassDl