Help ! Subclassing edit control 
Author Message
 Help ! Subclassing edit control

Hello everyone :

    I have a edit control embeded in a dialog which I want to change the
behave of
the edit control to :

    (1) Only accept numeric character and BACKSPACE
    (2) If another character typed,then beep
    (3) if another character typed ,then erase it

   I construct a CEdit derived class call CNumEdit,and override the OnChar(
),
and in the dialog's InitDialog( ) ,call
_numEdit.SubClassDlgItem(IDC_NumEdit,this),
everything works instead of ( 3 ),how shold I do ?


   Thankx very much !!!!!!!!!!!!!!!!!

/////////////////////////// OnChar ( )
void CNumEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
        // TODO: Add your message handler code here and/or call default
        if((nChar>='0'&& nChar<='9')||(nChar==VK_BACK))
                CEdit::OnChar(nChar,nRepCnt,nFlags);    
    else
        {
                MessageBeep(MB_ICONASTERISK);
                CEdit::OnChar(VK_BACK,nRepCnt,nFlags);
        }

Quote:
}      



Wed, 05 May 1999 03:00:00 GMT  
 Help ! Subclassing edit control

Quote:

>Hello everyone :

>    I have a edit control embeded in a dialog which I want to change the
>behave of
>the edit control to :

>    (1) Only accept numeric character and BACKSPACE
>    (2) If another character typed,then beep
>    (3) if another character typed ,then erase it

>   I construct a CEdit derived class call CNumEdit,and override the OnChar(
>),
>and in the dialog's InitDialog( ) ,call
>_numEdit.SubClassDlgItem(IDC_NumEdit,this),
>everything works instead of ( 3 ),how shold I do ?


>   Thankx very much !!!!!!!!!!!!!!!!!

>/////////////////////////// OnChar ( )
>void CNumEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
>{
>    // TODO: Add your message handler code here and/or call default
>    if((nChar>='0'&& nChar<='9')||(nChar==VK_BACK))
>            CEdit::OnChar(nChar,nRepCnt,nFlags);    
>    else
>    {
>            MessageBeep(MB_ICONASTERISK);
>            CEdit::OnChar(VK_BACK,nRepCnt,nFlags);
>    }

>}  

If the character typed is not in your range, just call MessageBeep and
do not call CEdit::OnChar().

void CNumEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
        if(nChar>='0'&& nChar<='9')
                CEdit::OnChar(nChar,nRepCnt,nFlags);    
        else
                MessageBeep(MB_ICONASTERISK);

Quote:
}      

Gabriel


Thu, 06 May 1999 03:00:00 GMT  
 Help ! Subclassing edit control

I don't think you need to send a backspace to the edit control when you
reject a character. You should just be able to beep and that's it.

From your first if statement, a non-numeric character will not get put into
the edit control in the first place, so there is no reason to backspace
over it. Or do I read you wrong? Do you want the character to show up and
then be backed over?

HTH,
Chris



Thu, 06 May 1999 03:00:00 GMT  
 Help ! Subclassing edit control


Quote:

>Hello everyone :
>    I have a edit control embeded in a dialog which I want to change the
>behave of the edit control to :

>    (1) Only accept numeric character and BACKSPACE
>    (2) If another character typed,then beep
>    (3) if another character typed ,then erase it

>   I construct a CEdit derived class call CNumEdit,and override the OnChar(),
>and in the dialog's InitDialog( ) ,call
>_numEdit.SubClassDlgItem(IDC_NumEdit,this),
>everything works instead of ( 3 ),how shold I do ?

>   Thankx very much !!!!!!!!!!!!!!!!!
>/////////////////////////// OnChar ( )
>void CNumEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
>{
>        // TODO: Add your message handler code here and/or call default
>        if((nChar>='0'&& nChar<='9')||(nChar==VK_BACK))
>                CEdit::OnChar(nChar,nRepCnt,nFlags);    
>    else
>        {
>                MessageBeep(MB_ICONASTERISK);
>                CEdit::OnChar(VK_BACK,nRepCnt,nFlags);
>        }

>}

     Gabriel Kziknik already gave the right answer to this; in the "wrong
character" case, just don't call CEdit::OnChar at all, rather than calling
it with a backspace.  But I thought it might be a good idea to give a bit
more explanation as to _why_ that's the right answer. :-)
     If you check the OnChar() documentation, it has a last paragraph that
shows up in a number of other OnSomethingOrOther message handlers:  "This
member function is called by the framework to allow your application to
handle a Windows message.  The parameters passed to your function reflect
the parameters received by the framework when the message was received.
If you call the base-class implementation of this function, that
implementation will use the parameters originally passed with the message
and not the parameters you supply to the function."
     In other words:  A message, in this case WM_CHAR, showed up in your
application.  In order to make things easier for you, the framework's call
that lets you intercept that message (OnChar) conceals the actual message
from you; instead, it breaks it up into its more easily-digestable parts
(character code, repeat count, flags).  But that original WM_CHAR message
is still there behind the scenes.  And if you pass the OnChar call back
into the bowels of MFC itself (CEdit::OnChar, in this case), it's going to
pass the original WM_CHAR message on to Windows for processing; it's not
going to use the parameters you pass, and it's not going to check to make
sure that they still agree with the WM_CHAR message.  So in this case, the
two CEdit::OnChar calls both do exactly the same thing--process the
original WM_CHAR message--even though they have different parameters.
     Now, in this particular case, when the user types a bad key, simply
not making the CEdit::OnChar() call--therefore preventing the WM_CHAR
message from getting processed--does the trick.  But let's say that you
did want to send a backspace message to the control, maybe even from a
different handler.  You still wouldn't want to use
"myEditCtrl->OnChar(VK_BACK, blah, blah)", for the same reason; OnChar is
written with the assumption that there's an underlying WM_CHAR message,
and there isn't in this case.  So instead, you would want to use
"myEditCtrl->SendMessage(WM_CHAR, VK_BACK, 0)".  In other words, if you
want to make something happen, don't call the message handler; send the
message that calls the handler.
     (By the way, if you want to make an edit control that only allows
certain characters, don't forget that people don't necessarily have to
type to put things in; they can paste things too.  So if you want to be
bulletproof, you'll have to check for that case too.)

--
Mark Phaedrus, Software Engineer, Luminous Technology Corporation (an Imation
company; developers of digital prepress software for commercial printing)

Correct ideas are the property of Luminous.  Incorrect ideas are mine. :)



Fri, 07 May 1999 03:00:00 GMT  
 Help ! Subclassing edit control

Quote:

> If the character typed is not in your range, just call MessageBeep and
> do not call CEdit::OnChar().

> void CNumEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
> {
>         if(nChar>='0'&& nChar<='9')
>                 CEdit::OnChar(nChar,nRepCnt,nFlags);
>         else
>                 MessageBeep(MB_ICONASTERISK);
> }

You might also want to include the '-' character in the range of valid characters.
This will allow you to enter negative values.

BTW, it is not legal (at least under Win32) to specify a different value for nChar
to the base class implementation of OnChar.  The system will ignore whatever you
specify and will send the original value to the OnChar function anyway.  This is
true of most message handlers.  You will find the following note in the docs for
OnChar and others:

Note   This member function is called by the framework to allow your application
to handle a Windows message. The parameters passed to your function reflect the
parameters received by the framework when the message was received. If you call
the base-class implementation of this function, that implementation will use the
parameters originally passed with the message and not the parameters you supply to
the function.

BillS



Fri, 07 May 1999 03:00:00 GMT  
 Help ! Subclassing edit control


Quote:


>> If the character typed is not in your range, just call MessageBeep and
>> do not call CEdit::OnChar().

>> void CNumEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
>> {
>>         if(nChar>='0'&& nChar<='9')
>>                 CEdit::OnChar(nChar,nRepCnt,nFlags);
>>         else
>>                 MessageBeep(MB_ICONASTERISK);
>> }

>You might also want to include the '-' character in the range of valid
characters.
>This will allow you to enter negative values.

     You might also want to include the VK_BACK, or people won't be able
to backspace in the first place. :-)
     Cases like this are why writing an OnChar() handler to screen text
out of an edit control is a very hazardous undertaking, it's extremely
difficult to correctly handle all cases, to screen out what you don't want
(and prevent the user pasting in invalid characters rather than typing
them, etc.) and allow what you want (without preventing the user from
backspacing, moving the cursor, using keyboard commands to copy and paste,
etc.).  You're generally better off using an ON_EN_UPDATE or ON_EN_CHANGE
handler to monitor when the text itself changes, rather than monitoring
the UI actions that change it.  Keep a copy of the last "known good"
contents of the field, and the last selection range; then your
ON_EN_UPDATE/CHANGE handler should scan the field for invalid characters.
If everything looks valid, it should update the stored field contents and
selection range based on the current contents of the field.  If an invalid
character is found, it should beep, and restore the field contents and
selection to the saved "known good" values.  This approach gives you much
simpler, more reliable code.

--
Mark Phaedrus, Software Engineer, Luminous Technology Corporation (an Imation
company; developers of digital prepress software for commercial printing)

Correct ideas are the property of Luminous.  Incorrect ideas are mine. :)



Fri, 07 May 1999 03:00:00 GMT  
 Help ! Subclassing edit control

Quote:

>     Gabriel Kziknik already gave the right answer to this; in the "wrong
>character" case, just don't call CEdit::OnChar at all, rather than calling
>it with a backspace.  But I thought it might be a good idea to give a bit
>more explanation as to _why_ that's the right answer. :-)
>     If you check the OnChar() documentation, it has a last paragraph that
>shows up in a number of other OnSomethingOrOther message handlers:  "This
>member function is called by the framework to allow your application to
>handle a Windows message.  The parameters passed to your function reflect
>the parameters received by the framework when the message was received.
>If you call the base-class implementation of this function, that
>implementation will use the parameters originally passed with the message
>and not the parameters you supply to the function."
>     In other words:  A message, in this case WM_CHAR, showed up in your
>application.  In order to make things easier for you, the framework's call
>that lets you intercept that message (OnChar) conceals the actual message
>from you; instead, it breaks it up into its more easily-digestable parts
>(character code, repeat count, flags).  But that original WM_CHAR message
>is still there behind the scenes.  And if you pass the OnChar call back
>into the bowels of MFC itself (CEdit::OnChar, in this case), it's going to
>pass the original WM_CHAR message on to Windows for processing; it's not
>going to use the parameters you pass, and it's not going to check to make
>sure that they still agree with the WM_CHAR message.  So in this case, the
>two CEdit::OnChar calls both do exactly the same thing--process the
>original WM_CHAR message--even though they have different parameters.
>     Now, in this particular case, when the user types a bad key, simply
>not making the CEdit::OnChar() call--therefore preventing the WM_CHAR
>message from getting processed--does the trick.  But let's say that you
>did want to send a backspace message to the control, maybe even from a
>different handler.  You still wouldn't want to use
>"myEditCtrl->OnChar(VK_BACK, blah, blah)", for the same reason; OnChar is
>written with the assumption that there's an underlying WM_CHAR message,
>and there isn't in this case.  So instead, you would want to use
>"myEditCtrl->SendMessage(WM_CHAR, VK_BACK, 0)".  In other words, if you
>want to make something happen, don't call the message handler; send the
>message that calls the handler.
>     (By the way, if you want to make an edit control that only allows
>certain characters, don't forget that people don't necessarily have to
>type to put things in; they can paste things too.  So if you want to be
>bulletproof, you'll have to check for that case too.)

>--
>Mark Phaedrus, Software Engineer, Luminous Technology Corporation (an Imation
>company; developers of digital prepress software for commercial printing)

>Correct ideas are the property of Luminous.  Incorrect ideas are mine. :)

Borland's framework comes with a helper class (TValidator) which
performs an excelent validation of edit controls. I wish MFC had a
class like this, handling all the details of data entry controls,
instead of the headache of subclassing.

Gabriel    



Sat, 08 May 1999 03:00:00 GMT  
 Help ! Subclassing edit control

Hi,
Check out the Microsoft Picture Edit Controls example that is present
in MSDN. It is targetted to Win16 but I have updated an application to
Win32 and I only had to change 1 function call in the CPictureEdit
class.
You can use it as is or use it to roll your own since it shows you
exactly what you need to do.

Hope this helps.
Ivo



Sun, 09 May 1999 03:00:00 GMT  
 Help ! Subclassing edit control

        I have an application demonstrating the communications port interface that
also subclasses the front panel edit control to only accept hex character
inputs.  It will beep if you enter anything else.  You may look at it by
downloading CommDemo.zip at:

         www.in.net/~jhcosand

Good Luck!

Jim



Quote:
> Hello everyone :

>     I have a edit control embeded in a dialog which I want to change the
> behave of
> the edit control to :

>     (1) Only accept numeric character and BACKSPACE
>     (2) If another character typed,then beep
>     (3) if another character typed ,then erase it

>    I construct a CEdit derived class call CNumEdit,and override the
OnChar(
> ),
> and in the dialog's InitDialog( ) ,call
> _numEdit.SubClassDlgItem(IDC_NumEdit,this),
> everything works instead of ( 3 ),how shold I do ?


>    Thankx very much !!!!!!!!!!!!!!!!!

> /////////////////////////// OnChar ( )
> void CNumEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
> {
>    // TODO: Add your message handler code here and/or call default
>    if((nChar>='0'&& nChar<='9')||(nChar==VK_BACK))
>            CEdit::OnChar(nChar,nRepCnt,nFlags);    
>     else
>    {
>            MessageBeep(MB_ICONASTERISK);
>            CEdit::OnChar(VK_BACK,nRepCnt,nFlags);
>    }

> }  



Thu, 13 May 1999 03:00:00 GMT  
 
 [ 9 post ] 

 Relevant Pages 

1. Help ! Subclassing edit control

2. Subclassing an edit control to do custom word wrapping

3. Subclassing edit-control of CComboBox

4. Subclassing the edit control in CEditView

5. Subclassing Edit control

6. Trouble subclassing the edit control of a CComboBox

7. (Q) Subclassing CComboBox edit control

8. SubClassing Edit Control in CEditView

9. SubClassing a CEdit Control for Masked Edit.

10. Edit Control...Edit Control...Edit Control...Edit Control...Edit Control...

11. Help:ACIVEX controls- subclassing Windows Control

12. Edit Control---- Edit control ----------------------

 

 
Powered by phpBB® Forum Software