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. :)