Solved

SubclassWindow()

Posted on 2001-08-06
12
370 Views
Last Modified: 2013-11-20
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..
0
Comment
Question by:prasanthpooyath
  • 5
  • 4
  • 2
  • +1
12 Comments
 
LVL 1

Expert Comment

by:kkarunakar
ID: 6358420
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
 
LVL 49

Expert Comment

by:DanRollins
ID: 6358607
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
 

Author Comment

by:prasanthpooyath
ID: 6358626
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
Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

 
LVL 4

Expert Comment

by:albay
ID: 6358834
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
 
LVL 4

Expert Comment

by:albay
ID: 6358874
by using above code, you can trap the OnChangeEdit handler on which edit-box is changed.

best regards,
albay
0
 

Author Comment

by:prasanthpooyath
ID: 6358888
Thanx for the info. But again I was looking for a one-to-one  substitute for DDX/DDV for my 150 Edit Controls.
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 6360673
>>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
 

Author Comment

by:prasanthpooyath
ID: 6370573
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
 
LVL 49

Expert Comment

by:DanRollins
ID: 6375332
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
 
LVL 49

Expert Comment

by:DanRollins
ID: 6420421
hi prasanthpooyath,

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

-- Dan
0
 
LVL 49

Accepted Solution

by:
DanRollins earned 50 total points
ID: 6443875
hi prasanthpooyath,

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

-- Dan
0
 

Author Comment

by:prasanthpooyath
ID: 6443908
Thanx for your kind help..and sorry for keeping u wait ....
0

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

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

Suggested Solutions

Introduction: Dynamic window placements and drawing on a form, simple usage of windows registry as a storage place for information. Continuing from the first article about sudoku.  There we have designed the application and put a lot of user int…
If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
In a recent question (https://www.experts-exchange.com/questions/28997919/Pagination-in-Adobe-Acrobat.html) here at Experts Exchange, a member asked how to add page numbers to a PDF file using Adobe Acrobat XI Pro. This short video Micro Tutorial sh…

808 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