15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


Dynamic Subclassing

Michael Smolinski 4444 -- msmolins@glenayre.com
Friday, June 21, 1996

Hello everyone....

VC++ 1.51
Windows 3.1

I want to create an edit box that only accepts digits as input.  The way I
went about it was to do the following:
1. I Put a normal Edit box in a Dialog via AppStudio
2. I derived a class called CNumEdit from the class CEdit and overrode the
   OnChar function as follows:

void CNumEdit::OnChar( ... )
{
	if ( nChar >= '0' && nChar <= '9' )
	{
		CEdit::OnChar( ... );
	}
}
I also added the WM_CHAR message to the class CNumEdit.

3. I put a new private member in the dialog source code like this:
private:
	CNumEdit	m_NumEdit;

4. I overrode the OnInitDialog member function of the Dialog  and
 added the following dynamic subclassing call to OnInitDialog:

m_NumEdit.SubclassDlgItem( IDC_EDIT1, this );
                            ^^^---The ID of the Edit box created in Appstudio

5. Then I opened the dialog box with "DoModal".

The call to SubclassDlgItem causes an assertion error.  It says that the window
IDC_EDIT1 (it was actually a number, but it equalled this macro) is not of type
CNumEdit.  But, isn't this the whole idea of dynamic subclassing.  So you can
route for example CEdit messages through CNumEdit first?

I also found that if I click on the "Ignore" button when the run-time error
occurs, the program works fine.

This is an example that I got from "Inside Visual C++ 1.5" by Microsoft Press.

I didn't have much time to delve into the code of wincore.cpp but can anyone see
any fundamental problems with what I did.  Or, is there a bug with the SubclassDlgItem
routine that I should know about.

Thanks for the help...
	Mike






John Addis -- jaddis@erols.com
Sunday, June 23, 1996

[Mini-digest: 3 responses]

Michael Smolinski [4444] wrote:
> 
> Hello everyone....
> 
> VC++ 1.51
> Windows 3.1
> 


 
> The call to SubclassDlgItem causes an assertion error.  It says that the window
> IDC_EDIT1 (it was actually a number, but it equalled this macro) is not of type
> CNumEdit.  But, isn't this the whole idea of dynamic subclassing.  So you can
> route for example CEdit messages through CNumEdit first?

Sounds like you need to override GetSuperWndProcAddr() for your CNumEdit class.

-- 
John Addis        Master of Time and Space
jaddis@erols.com  C++, MFC, Win32, Win95, TCP/IP
"Invalid or missing REALITY.COM Universe halted."

-----From: Roger Onslow/Newcastle/Computer Systems Australia/AU 

>4. I overrode the OnInitDialog member function of the Dialog  and
 >added the following dynamic subclassing call to OnInitDialog:
>
>m_NumEdit.SubclassDlgItem( IDC_EDIT1, this );
>                            ^^^---The ID of the Edit box created in Appstudio
>
>5. Then I opened the dialog box with "DoModal".
>
>The call to SubclassDlgItem causes an assertion error.  It says that the window
>IDC_EDIT1 (it was actually a number, but it equalled this macro) is not of type
>CNumEdit.  But, isn't this the whole idea of dynamic subclassing.  So you can
>route for example CEdit messages through CNumEdit first?

Use ClassWizard to generate a control variable of type CEdit.
Then edit the .h and change the CEdit to CNumEdit and you
shouldn't need to do any subclassing at all.
(DoDataExchange DDX_Control will do the subclassing for you)


Roger Onslow


-----From: Sheir Rahman Ali 

At 07:11 AM 6/21/96 -0700, you wrote:
>Hello everyone....
>
>VC++ 1.51
>Windows 3.1
>
>I want to create an edit box that only accepts digits as input.  The way I
>went about it was to do the following:
>1. I Put a normal Edit box in a Dialog via AppStudio
>2. I derived a class called CNumEdit from the class CEdit and overrode the
>   OnChar function as follows:
>
>void CNumEdit::OnChar( ... )
>{
>	if ( nChar >= '0' && nChar <= '9' )
>	{
>		CEdit::OnChar( ... );
>	}
>}
>I also added the WM_CHAR message to the class CNumEdit.
>
>3. I put a new private member in the dialog source code like this:
>private:
>	CNumEdit	m_NumEdit;
>
>4. I overrode the OnInitDialog member function of the Dialog  and
> added the following dynamic subclassing call to OnInitDialog:
>
>m_NumEdit.SubclassDlgItem( IDC_EDIT1, this );
>                            ^^^---The ID of the Edit box created in Appstudio
>
>5. Then I opened the dialog box with "DoModal".
>
>The call to SubclassDlgItem causes an assertion error.  It says that the window
>IDC_EDIT1 (it was actually a number, but it equalled this macro) is not of type
>CNumEdit.  But, isn't this the whole idea of dynamic subclassing.  So you can
>route for example CEdit messages through CNumEdit first?
>
>I also found that if I click on the "Ignore" button when the run-time error
>occurs, the program works fine.
>
>This is an example that I got from "Inside Visual C++ 1.5" by Microsoft Press.
>
>I didn't have much time to delve into the code of wincore.cpp but can
anyone see
>any fundamental problems with what I did.  Or, is there a bug with the
SubclassDlgItem
>routine that I should know about.
>
>Thanks for the help...
>	Mike
>

I needed to do something similar.  I need to have only a 9 digit number
and only currency amounts (still working on perfecting the currencyEdit).
How I did this was to subclass CEdit twice.
For example, for the 9 digit..
I override the OnChar message to only accept numbers (like you did).

I had ClassWizard make a CONTROL member variable for
my Edit control on the dialog (==> gives CEdit as the control).
In my dialog class, I replaced the CEdit with my subclass (in your case,
CNumEdit).
You would also needed to add a private CString member to hold the value of
the your CNumEdit (say m_NumEditStr).
You would have to use GetWindowText() and SetWindowText() to get & set
your CNumEdit, using the CString member variable.

OnInitDialog is where you would do any initialization.  
Like ...
m_NumEditStr = "0";
m_NumEdit.SetWindowText(m_NumEditStr);
m_NumEdit.LimitText(9);

Use GetWindowText() in your override of OnOK() to store the value of your
CNumEdit.  
ie.   m_NumEdit.GetWindowText(m_NumEditStr);

I did not use SubclassDlgItem(), and my dialogs work just fine.  Of course,
I put my subclassing in the stdfx (sp?) .h & .cpp files.  That way I could
use them whenever where ever I want.

Hope that helps
rahman


*******************************************
*   Sheir Rahman Ali                      *
*   "Licensed Remote Controll Operator"   *
*******************************************




beriksen@cda.com
Monday, June 24, 1996

[Mini-digest: 3 responses]

     I can see nothing wrong with your approach.  I have my own CNumberEdit 
     class that works similarly to what you describe.  The only thing I can 
     think of is did the SubclassDlgItem() call come beforee 
     CDialog::OnInitDialog()?
     
     Brian Eriksen
     CDA/Wiesenberger
     beriksen@cda.com


______________________________ Reply Separator _________________________________
Subject: Dynamic Subclassing
Author:  mfc-l@netcom.com at Internet_Mail
Date:    6/23/96 3:57 AM


Hello everyone....
     
VC++ 1.51
Windows 3.1
     
I want to create an edit box that only accepts digits as input.  The way I 
went about it was to do the following:
1. I Put a normal Edit box in a Dialog via AppStudio
2. I derived a class called CNumEdit from the class CEdit and overrode the
   OnChar function as follows:
     
void CNumEdit::OnChar( ... )
{
 if ( nChar >= '0' && nChar <= '9' )
 {
  CEdit::OnChar( ... );
 }
}
I also added the WM_CHAR message to the class CNumEdit.
     
3. I put a new private member in the dialog source code like this: 
private:
 CNumEdit m_NumEdit;
     
4. I overrode the OnInitDialog member function of the Dialog  and
 added the following dynamic subclassing call to OnInitDialog:
     
m_NumEdit.SubclassDlgItem( IDC_EDIT1, this );
                            ^^^---The ID of the Edit box created in Appstudio
     
5. Then I opened the dialog box with "DoModal".
     
The call to SubclassDlgItem causes an assertion error.  It says that the window 
IDC_EDIT1 (it was actually a number, but it equalled this macro) is not of type 
CNumEdit.  But, isn't this the whole idea of dynamic subclassing.  So you can 
route for example CEdit messages through CNumEdit first?
     
I also found that if I click on the "Ignore" button when the run-time error 
occurs, the program works fine.
     
This is an example that I got from "Inside Visual C++ 1.5" by Microsoft Press.
     
I didn't have much time to delve into the code of wincore.cpp but can anyone see
any fundamental problems with what I did.  Or, is there a bug with the 
SubclassDlgItem
routine that I should know about.
     
Thanks for the help...
 Mike
     
     
     

-----From: kitk@mudshark.sunquest.com (Kit Kauffmann)

BTW, it would help us a LOT if you'd tell us which assertion it was, and the 
MSDN contains a large list of common assertions and probably reasons, which 
I'd suggest checking).  Note, also, that I use SubclassDlgItem in vast 
quantities with no problems.  The MSDN provides a listing of common 
assertions & possible reasons - read it...  My first search came back with:

1. Trying to subclass a field that has already been subclassed 

2. Failing to override the GetSuperWndProcAddr virtual

There may be others, but that was what the MSDN came up with on my first 
search attempt...

IAC, SubclassDlgItem is not the culprit...  You are!  :) :) :)

HTH!
Kit
I'm as confused as a baby in a topless bar.

-----From: beriksen@cda.com

     You shouldn't have to do anything with GetSuperWndProcAddr() from my 
     experience.
     
     Brian Eriksen
     CDA/Wiesenberger
     beriksen@cda.com


-----From: Roger Onslow/Newcastle/Computer Systems Australia/AU 

     
Use ClassWizard to generate a control variable of type CEdit. 
Then edit the .h and change the CEdit to CNumEdit and you 
shouldn't need to do any subclassing at all.
(DoDataExchange DDX_Control will do the subclassing for you)
     
     
Roger Onslow
     
     
-----From: Sheir Rahman Ali 
     
I needed to do something similar.  I need to have only a 9 digit number 
and only currency amounts (still working on perfecting the currencyEdit). 
How I did this was to subclass CEdit twice.
For example, for the 9 digit..
I override the OnChar message to only accept numbers (like you did).
     
I had ClassWizard make a CONTROL member variable for
my Edit control on the dialog (==> gives CEdit as the control).
In my dialog class, I replaced the CEdit with my subclass (in your case, 
CNumEdit).
You would also needed to add a private CString member to hold the value of 
the your CNumEdit (say m_NumEditStr).
You would have to use GetWindowText() and SetWindowText() to get & set 
your CNumEdit, using the CString member variable.
     
OnInitDialog is where you would do any initialization.  
Like ...
m_NumEditStr = "0";
m_NumEdit.SetWindowText(m_NumEditStr); 
m_NumEdit.LimitText(9);
     
Use GetWindowText() in your override of OnOK() to store the value of your 
CNumEdit.  
ie.   m_NumEdit.GetWindowText(m_NumEditStr);
     
I did not use SubclassDlgItem(), and my dialogs work just fine.  Of course, 
I put my subclassing in the stdfx (sp?) .h & .cpp files.  That way I could 
use them whenever where ever I want.
     
Hope that helps
rahman
     
     
******************************************* 
*   Sheir Rahman Ali                      * 
*   "Licensed Remote Controll Operator"   * 
*******************************************
     





| Вернуться в корень Архива |