I was just wondering, is there a way to restrict what characters a user can input in an edit control.
By that I mean I only what the characters 0 to 9 and A to F - the edit control will be used for hex values only.
Thanks,
Andy.
Quote from: Andy on August 27, 2017, 12:25:44 AM
I was just wondering, is there a way to restrict what characters a user can input in an edit control.
By that I mean I only what the characters 0 to 9 and A to F - the edit control will be used for hex values only.
Thanks,
Andy.
Just subclass the edit control and use lookup table for masking the input:
$INCLUDE "windowssdk.inc"
WINDOW win
ENUM win_const
win_EDIT1 = 100
ENDENUM
OpenWindow win,0,0,416,339,@SIZE|@MINBOX|@MAXBOX|@CAPTION|@SYSMENU,0,"Form2",&win_handler
CONTROL win,@EDIT,"",79,74,186,25,@CTEDITAUTOH|@CTEDITLEFT,win_EDIT1
MaskEditControl(win, win_EDIT1, "0123456789ABCDEFabcdef\x8")
WAITUNTIL ISWINDOWCLOSED(win)
END
sub win_handler(), int
select @MESSAGE
case @IDCREATE
centerwindow win
case @IDCONTROL
select @CONTROLID
case win_EDIT1
endselect
case @IDCLOSEWINDOW
closewindow win
endselect
return 0
endsub
sub maskedEditHandler(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam),LRESULT
pointer mask
select uMsg
case WM_NCDESTROY
RemovePropA(hWnd,"edit_handler")
mask = GetPropA(hWnd,"mask_addr")
delete mask
RemovePropA(hWnd,"mask_addr")
case @IDCHAR
mask = GetPropA(hWnd,"mask_addr")
if #<int>mask[wParam & 0xff] = FALSE
return 0
endif
endselect
return CallWindowProcA(GetPropA(hWnd,"edit_handler"),hWnd,uMsg,wParam,lParam)
endsub
sub MaskEditControl(WINDOW parent, INT id, string szMask)
HWND hEdit = GETCONTROLHANDLE(parent,id)
LONG lpFn = SetWindowLongA(hEdit,GWL_WNDPROC,&maskedEditHandler)
SetPropA(hEdit,"edit_handler",lpFn)
pointer mask = new(int, 256)
int i
for i = 0 to 255
#<int>mask[i] = FALSE
next i
for i = 0 to len(szMask)
#<int>mask[szMask[i]] = TRUE
next i
SetPropA(hEdit,"mask_addr", mask)
return
endsub
sub UnMaskEditControl(WINDOW parent,INT id)
HWND hEdit = GETCONTROLHANDLE(parent,id)
LONG lpFn = SetWindowLongA(hEdit,GWL_WNDPROC, GetPropA(hEdit,"edit_handler"))
RemovePropA(hEdit,"edit_handler")
pointer mask = GetPropA(hEdit,"mask_addr")
delete mask
RemovePropA(hEdit,"mask_addr")
return
endsub
Jalih to the rescue again - thanks!
Sub classing is something I'm not too hot on, I must try to find a little time to study the process.
I've amended it slightly to receive only uppercase characters, and restrict the input box to 8 characters.
$include "windowssdk.inc"
WINDOW win
CONST EDIT1=100
CONST ES_UPPERCASE = 0x8 'Uppercase letters only.
OpenWindow win,0,0,416,339,@SIZE|@MINBOX|@MAXBOX|@CAPTION|@SYSMENU,0,"Form2",&win_handler
CONTROL win,@EDIT,"",79,74,186,25,@CTEDITAUTOH|@CTEDITLEFT|ES_UPPERCASE,EDIT1
SETFOCUS win,EDIT1
MaskEditControl(win,EDIT1,"0123456789ABCDEFabcdef\x8")
CONTROLCMD win,EDIT1,@EDSETLIMITTEXT,8 'Set maximum number of characters.
WAITUNTIL ISWINDOWCLOSED(win)
END
sub win_handler(),int
select @MESSAGE
case @IDCREATE
centerwindow win
case @IDCONTROL
select @CONTROLID
case EDIT1
endselect
case @IDCLOSEWINDOW
closewindow win
case WM_DESTROY
UnMaskEditControl(win,EDIT1)
endselect
return 0
endsub
sub maskedEditHandler(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam),LRESULT
select uMsg
case @IDCHAR
pointer mask=GetPropA(hWND,"mask_addr")
if #<int>mask[wParam & 0xff]=FALSE
return 0
endif
endselect
return CallWindowProcA(GetPropA(hWnd,"edit_handler"),hWnd,uMsg,wParam,lParam)
endsub
sub MaskEditControl(WINDOW parent,INT id,string szMask)
HWND hEdit=GETCONTROLHANDLE(parent,id)
LONG lpFn=SetWindowLongA(hEdit,GWL_WNDPROC,&maskedEditHandler)
SetPropA(hEdit,"edit_handler",lpFn)
pointer mask=new(int,256)
int i
for i=0 to 255
#<int>mask[i]=FALSE
next i
for i=0 to len(szMask)
#<int>mask[szMask[i]]=TRUE
next i
SetPropA(hEdit,"mask_addr",mask)
return
ENDSUB
SUB UnMaskEditControl(WINDOW parent,INT id)
HWND hEdit=GETCONTROLHANDLE(parent,id)
LONG lpFn=SetWindowLongA(hEdit,GWL_WNDPROC,GetPropA(hEdit,"edit_handler"))
RemovePropA(hEdit,"edit_handler")
pointer mask=GetPropA(hEdit,"mask_addr")
delete mask
return
ENDSUB
Thanks again!!
Just working my way through the mask input code and I have a few questions on it:
What is the purpose of \x8 in the line
MaskEditControl(win,EDIT1,"0123456789ABCDEFabcdef\x8")
In the line:
pointer mask=GetPropA(hWND,"mask_addr") I presume "mask_addr" could be any old name?
And finally, what is the purpose of & 0XFF
if #<int>mask[wParam & 0xff]=FALSE
return 0
endif
Thanks.
Andy,
The \x8 is the Back Delete key. Wondered about the 0xFF myself,
only that it is OR'd with the wparam result
Brian
The "& 0xFF" is "AND"ed with the wParam. It returns the last 8 bits (or byte) of the wParam.
Later Clint
Thanks for that Clint - cheers!
Whoops! Got my ANDs and ORs mixed up. The mask_addr can be anything as long as it is unique
Brian
Quote from: Andy on August 29, 2017, 12:07:45 AM
In the line:
pointer mask=GetPropA(hWND,"mask_addr") I presume "mask_addr" could be any old name?
And finally, what is the purpose of & 0XFF
if #<int>mask[wParam & 0xff]=FALSE
return 0
endif
"& 0xFF" just makes sure we keep within boundaries of our lookup table.
You should probably get rid of from using properties and just reserve space for lookuptable+WNDPROC and store the address in window long:
$INCLUDE "windowssdk.inc"
WINDOW win
ENUM win_const
win_EDIT1 = 100
ENDENUM
OpenWindow win,0,0,416,339,@SIZE|@MINBOX|@MAXBOX|@CAPTION|@SYSMENU,0,"Form2",&win_handler
CONTROL win,@EDIT,"",79,74,186,25,@CTEDITAUTOH|@CTEDITLEFT,win_EDIT1
MaskEditControl(win, win_EDIT1, "0123456789ABCDEFabcdef\x8")
WAITUNTIL ISWINDOWCLOSED(win)
END
sub win_handler(), int
select @MESSAGE
case @IDCREATE
centerwindow win
case @IDCONTROL
select @CONTROLID
case win_EDIT1
endselect
case @IDCLOSEWINDOW
closewindow win
endselect
return 0
endsub
sub MaskedEditHandler(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam),LRESULT
pointer mask = GetWindowLong(hwnd, GWL_USERDATA)
SELECT uMsg
case WM_NCDESTROY
delete mask
CASE @IDCHAR
if #<int>mask[wParam & 0xff] = FALSE
return 0
endif
ENDSELECT
RETURN CallWindowProcA(#<int>mask[256],hWnd,uMsg,wParam,lParam)
ENDSUB
SUB MaskEditControl(WINDOW parent, INT id, string szMask)
HWND hEdit = GETCONTROLHANDLE(parent,id)
LONG lpFn = GetWindowLong(hEdit, GWL_WNDPROC)
pointer mask
int i
if lpFn <> &MaskedEditHandler
mask = new(int, 257)
else
mask = GetWindowLong(hEdit, GWL_USERDATA)
endif
for i = 0 to 255
#<int>mask[i] = FALSE
next i
for i = 0 to len(szMask)
#<int>mask[szMask[i]] = TRUE
next i
if lpFn <> &MaskedEditHandler
#<int>mask[256] = SetWindowLongA(hEdit,GWL_WNDPROC,&MaskedEditHandler)
SetWindowLong(hEdit, GWL_USERDATA, mask)
endif
ENDSUB