Can OnNotify be used with CEdit or NEdit (a child class)? I want to do more to control user input.
Based on work/help of others, I have NEdit : CEdit as noted below:
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// NEdit.inc
class NEdit : CEdit
{
declare virtual OnChar( unsigned int nChar, int nRepCnt ), int;
declare virtual OnNotify( int code, int nID, NMHDR *pnmhdr ), int;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// NEdit.src
// 05/22/2007
// a child class of CEdit which filters user input and restricts
// input to numeric (decimal, scientific) format
// #include "nedit.inc"
NEdit :: OnChar( unsigned int nChar, int nRepCnt), int
{
if(( nChar >= '0' && nChar <= '9' )||( nChar == 8 ))
return false;
int startsel, endsel, count;
GetSel( startsel, endsel );
string *text = NULL;
int textlen;
int slen = len(GetText());
//StrLower returns memory allocated from the heap and should not be directly
//assigned to a pointer, use a STRING type or allocated memory to copy to
text = new(byte,slen+1);
*text = StrLower(GetText( ));
nChar = ToAscii(StrLower(ToChar(nChar)));
if(( nChar == '.' )||( nChar == ',' ))
{ // There can only be one '.' and it must be before the 'E'
if( (StrFind( *text, "." ) == 0 ) && (StrFind( *text, "," ) == 0 )
&& ( *text[startsel] != '+' ) && ( *text[startsel] != '-' ))
{
delete text;
return false;
}
if( (StrFind( StrMid(*text, startsel, endsel-startsel ), "." ) != 0 )
|| (StrFind( StrMid(*text, startsel, endsel-startsel ), "," ) != 0 ) )
{
delete text;
return false;
}
}
if( nChar == 'e' )
{ // There can only be one 'E', also, it can't be at the beginning of the number
if( StrFind( *text, "e" ) == 0 && startsel != 0 )
{
delete text;
return false;
}
}
if( (nChar == '+') || (nChar == '-') )
{
count = StrFind(StrLeft(*text,1),"+") + sgn(StrFind(*text,"+",2))
+ StrFind(StrLeft(*text,1),"-") + sgn(StrFind(*text,"-",2));
// There can only a maximum of two (2) '+' or (2) '-' or one "+" and one "-"
// and they must be at the beginning or behind an E
if( (startsel == 0) && ((*text[0] != '+')&&(*text[0] != '-'))
&& ( count < 2 ) )
{
delete text;
return false;
}
if( (*text[startsel-1] == 'e') && (*text[startsel] != '+') && (*text[startsel] != '-')
&& ( count < 2 ) )
{
delete text;
return false;
}
}
delete text;
return true;
}
NEdit :: OnNotify( int code, int nID, NMHDR *pnmhdr ), int
{
return CEdit!!OnNotify(code, nID, pnmhdr);
}
NEdit::OnNotify will be called only if NEdit control has a child window that sends WM_NOTIFY. The WM_NOTIFY is send always to the 'mother' window of the control.
You probably need to redirect CWindow::OnNotify to NEdit::OnNotify:
// replace CWindow with your main window class
CWindow::OnNotify(int code,int nID,NMHDR *pnmhdr),int
{
// if this control can handle this message, redirect
if (GetProp(pnmhdr->hwndFrom, "iCanHandleNotify"))
return GetControl(pnmhdr->idFrom)->OnNotify(code, nID, pnmhdr);
// else the control is a standard CConrol like, process message here
}
Now if you wish to process OnNotify inside control class, in control::OnCreate set a property:
SetProp(m_hwnd, "iCanHandleNotify", 1);
And do not redirect unhandled codes to the base class. Remember to call RemoveProp(m_hwnd, "iCanHandleNotify") in OnDestroy, to release system resources.