[Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Change control type at runtime. SubclassWindow()

Posted on 2007-08-01
7
Medium Priority
?
559 Views
Last Modified: 2013-11-20
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_XXXXXXXXXX+ii);
  //perform some operations on pWnd
   CtrlDollars[ii].SubclassWindow(pWnd->m_hWnd);
}

This compiles and executes without complaint except that the behavior of the controls doesn't change at all.

Any ideas, Rick
0
Comment
Question by:rickatseasoft
  • 3
  • 2
  • 2
7 Comments
 
LVL 45

Expert Comment

by:AndyAinscow
ID: 19615105
Have a try with SubclassDlgItem instead

CtrlDollars[ii].SubclassDlgItem(IDC_XXXXXXXXXX+ii, pWnd);
0
 

Author Comment

by:rickatseasoft
ID: 19615429
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
0
 
LVL 45

Expert Comment

by:AndyAinscow
ID: 19615469
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]);
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:rickatseasoft
ID: 19615555
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]._hWnd)m_CtrlDollar[ii].SubclassDlgItem(...);   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
0
 
LVL 45

Accepted Solution

by:
AndyAinscow earned 2000 total points
ID: 19615597
:-)
NO - just subclass the once eg OnInitDialog
No - no requirement to unsubclass (as you aren't re-using them)
0
 
LVL 22

Expert Comment

by:mahesh1402
ID: 19615612
You may also use DDX_Control() loop in your DoDataExchange.....

void CMyDlg::DoDataExchange(CDataExchange* pDX)
{
      CDialog::DoDataExchange(pDX);
      //{{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
0
 
LVL 22

Expert Comment

by:mahesh1402
ID: 19615614
hmmm.. cause of too late posting sorry agin !
0

Featured Post

Vote for the Most Valuable Expert

It’s time to recognize experts that go above and beyond with helpful solutions and engagement on site. Choose from the top experts in the Hall of Fame or on the right rail of your favorite topic page. Look for the blue “Nominate” button on their profile to vote.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
Ready to get certified? Check out some courses that help you prepare for third-party exams.
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
Suggested Courses

867 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question