SubclassWindow()

I have implemented a property sheet with 8 pages. In each of my propery pages I have lot of controls including edit controls, radio buttons, check boxes etc. I was thinking of a good way to handle these controls. Like, if I use the DDX/DDV for each control its virtually impossible. I heard about using SubclassWindow() for attaining this. But I didn't get it much. I am sure someone out there have done this. It would be appreciated if someone could explain this with a sample code for the same. Waiting for an early response..
prasanthpooyathAsked:
Who is Participating?

Improve company productivity with a Business Account.Sign Up

x
 
DanRollinsConnect With a Mentor Commented:
hi prasanthpooyath,

Do you have any additional questions?  DO any comments need clarification?

-- Dan
0
 
kkarunakarCommented:
Hi there!!
I guess you can use GetDlgItem() in more proper way to get the handle of one control. If you don't want to do DDX/DDV.
Like.Suppose you want the control on page 5 .
CPage5 *pPage5 = (Get your page file pointer using parent class. may be like
GetParent()->GetPage5().)
After getting page5 (that i guess it will derived of some dialog..or may be one window control.
You can access GetDlgItem(IDC_CONTROL1) .
Ex:
CButton *pButton = pPage5->GetDlgItem(IDC_AXXX);
ASSERT(pButton!= NULL);

I guess it will help you .
Thanks
Keshav
0
 
DanRollinsCommented:
Use the ClassWizard to create a variable for each item.  Let MFC doo the work for you!

Now in the case of a CPropertySheet, I have found this technique to work best...

Derive a class from CPropertySheet.  Make members for each of the CPropertySheets.  Before calling DoModal, set all the vars:

CMySheet cSheet;
//---------------------- set vars for Pg 1
cPg1.nFoo= 1;
cPg1.sBlech= "hi there!";

//---------------------- set vars for Pg 2
cPg2.nBar= 7777;
cPg2.sNameLast= "Jones";

int nRet= cSheet.DoModal();
if ( nRet== IDOK ) {
   //----------------------- save vares from pg 1
   gnMySavedVar= cPg1.nFoo;
   ... etc...
   //----------------------- save vares from pg 1
   gsSavedLastName= cPg2.sNameLast;
}

-- Dan

0
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

 
prasanthpooyathAuthor Commented:
Thanx for the info. But I think I know that... This is fine with less controls in the pages. But in my case I am having atleast 150 CEdit controls in a single PropertyPage to be handled.  Just imagine how it would look to have 150 variables for each edit controls/...  So I think there is some other method other than the ClassWizard one by which u code it yoiurselves. I just know that u use SubclassWindow() for that. But don't know anything else. Please give an example code to help me out from this...
0
 
albayCommented:
hi.

you can use ON_CONTROL_RANGE event handler...

define this in your .cpp file

BEGIN_MESSAGE_MAP(CDenemeDlg, CDialog)
     //{{AFX_MSG_MAP(CDenemeDlg)
     ON_WM_SYSCOMMAND()
     ON_WM_PAINT()
     ON_WM_QUERYDRAGICON()
     //}}AFX_MSG_MAP
     ON_CONTROL_RANGE(EN_CHANGE, IDC_EDIT1, IDC_EDIT150, OnChangeEdit)  //you use 150 edit-boxes only define this
END_MESSAGE_MAP()

pay attention to use handler outside //}} AFX_MSG_MAP

and define this in .h file
        //{{AFX_MSG(CDenemeDlg)
     virtual BOOL OnInitDialog();
     afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
     afx_msg void OnPaint();
     afx_msg HCURSOR OnQueryDragIcon();
     //}}AFX_MSG
     afx_msg void OnChangeEdit(UINT nID); //only define this
     DECLARE_MESSAGE_MAP()


and OnChangeEdit:::

void CDenemeDlg::OnChangeEdit(UINT nID)
{
     UINT index=nID - IDC_EDIT1;
     switch(index)
     {
     case 0:
     case 1:
     case 2:
          ...
          ...
     case 149:
     }
}

hope this helps
0
 
albayCommented:
by using above code, you can trap the OnChangeEdit handler on which edit-box is changed.

best regards,
albay
0
 
prasanthpooyathAuthor Commented:
Thanx for the info. But again I was looking for a one-to-one  substitute for DDX/DDV for my 150 Edit Controls.
0
 
DanRollinsCommented:
>>in my case I am having atleast 150 CEdit controls in a single PropertyPage

You should seriously consider a redesign.  That is way too much information to present in one dialog box.

Nevertheless, I will solve your problem for you, even though you offer only 50 pts.

You need to arrange your code so that rather than having 150 CString member variables, you have a single CStringArray.  Then you manually modify your RC file so that the EDIT controls have sequentially-numbered ID.  For instance, the first one is 1000, the second is 1001, etc.

Replace all of the individualy DDX transfers with a loop like so:

void CMyPg::DoDataExchange(CDataExchange* pDX)
{
   CPropertyPage::DoDataExchange(pDX);
   //{{AFX_DATA_MAP(CMyPg)
   //}}AFX_DATA_MAP

    for (int j=0; j<150; j++ ) { // 150= number of controls
          DDX_Text(pDX, 1000+j, m_asEdits[j] );
    }
}

Before calling DoModal(), fill the CStringArray with values from aa file or whatever.  Afterward, the data entered by the user will be in the CStringArray strings.

This will solve your problem.

-- Dan
0
 
prasanthpooyathAuthor Commented:
Thanx a lot friends for all your valuable suggestions. But I found the following method as a li'l more managable in my case. Thanx to Zoppo.

// sample for four edit controls

// in header
const int iEditNum = 4;
const int iEditCtrl[iEditNum] = {
          IDC_EDIT1,
          IDC_EDIT2,
          IDC_EDIT3,
          IDC_EDIT4,
};

class CDtDlg : public CDialog
{
   ...
   public:
   // Dialog Data
   //{{AFX_DATA(CDtDlg)
   enum { IDD = IDD_DT_DIALOG };
   //}}AFX_DATA
   CString     m_szEdit[iEditNum]; // make sure this is outside of AFX_DATA block
   ...
}

// in .cpp file
CDtDlg::CDtDlg(CWnd* pParent /*=NULL*/)
    : CDialog(CDtDlg::IDD, pParent)
{
   //{{AFX_DATA_INIT(CDtDlg)
   //}}AFX_DATA_INIT
   for ( int i = 0; i < iEditNum; i++ ){
      m_szEdit[i] = _T("");
   }
...
}

void CDtDlg::DoDataExchange(CDataExchange* pDX)
{
   CDialog::DoDataExchange(pDX);
   //{{AFX_DATA_MAP(CDtDlg)
   //}}AFX_DATA_MAP
   for ( int i = 0; i < iEditNum; i++ ){
      DDX_Text(pDX, iEditCtrl[i], m_szEdit[i]);
   }
}
0
 
DanRollinsCommented:
That is not ZOPPOs answer, it is mine!

The core of it is the manually-added DDX_Text loop in the AFX_DATA_MAP.  Why don't you give credit where credit is due?  Do you expect people to help you in the future?

-- Dan


0
 
DanRollinsCommented:
hi prasanthpooyath,

Do you have any additional questions?  DO any comments need clarification?

-- Dan
0
 
prasanthpooyathAuthor Commented:
Thanx for your kind help..and sorry for keeping u wait ....
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.