I'm so sorry for not searching as well as I could but I was just wondering this..

what's the easiest way to restrict an edit box so that only numbers between 0-255 can be written in it, and when a user hits the button, it'll write it to a buffer(as a byte or so).
Posted on 2003-05-29 23:06:44 by EEDOK
It's tutorial 20 from Iczelion and called subclassing.
http://spiff.tripnet.se/~iczelion/tut20.html
Posted on 2003-05-30 00:27:58 by bitRAKE
I think you missed my question on how to restrict it so only values under 255 could be entered? And how to recieve what's in the edit box, and move it to a buffer that's defined as a byte?
Posted on 2003-05-30 12:11:58 by EEDOK
Maybe there is many different solutions, but I did this: subclass edit control, and wait for WM_CHAR message.
When it hits, check the char entered, only allow backspace, and numbers 0-9.
If not return 0.
Then keep a counter how many characters entered, only allow 3 of course.
If backspace is hit, decrease the counter if it's not already 0.
then just check each character entered, if first only allow number 0-2, if second 0-5 etc

Here is that procedure I did, it's not perfect though, you could enter number like 050 and 000 etc.
in code pEditProc is the address of the old WindowProcedure for editbox, and
charPos is a variable initialized to zero to keep track of how many characters user typed.




MyEditProc proc USES EBX ESI EDI hWnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD

mov eax, uMsg
cmp eax, WM_CHAR
jnz _passOn

mov eax, wParam
cmp eax, 8 ; is key typed backspace?
jnz _checkForNum
mov eax, charPos ; handle backspace, ie. keep track of character position in string of the edit box
test eax, eax
jz _passOn
dec charPos
jmp _passOn

_checkForNum:
cmp eax, '0'
jb _dontAllow ; if char typed below 0 discard keystroke
cmp eax, '9'
ja _dontAllow ; if char typed above 9 discard keystroke

sub eax, '0' ; it is a number, convert key stroke ascii to number

mov ecx, charPos
test ecx, ecx
jnz @F
; handle first digit
cmp eax, 2
ja _dontAllow
inc charPos
jmp _passOn
@@:
cmp ecx, 1
jnz @F
_five:
cmp eax, 5
ja _dontAllow
inc charPos
jmp _passOn
@@:
cmp ecx, 2
jnz _dontAllow
jmp _five ; handle third digit

_passOn:
invoke CallWindowProc, pEditProc, hWnd, uMsg, wParam, lParam
ret
_dontAllow:
xor eax, eax
ret
MyEditProc endp


btw use SendMessage with WM_GETTEXT for getting edit box contents

I added this stuff to some Iczelion tutorial edit box, I'll attach it
Posted on 2003-05-30 20:50:04 by david
I would do it a little differently, I haven't tried this but the following is sort of pseudo code to explain the process:

Set the style of the control to numeric only
>>> Subclass routine


.If uMsg == WM_CHAR
GetDialogItemInt,OldValue > Get the value in the control
CallWindowProc > process the character
GetDialogItemInt,NewValue > Get the value in the control
.IF NewValue > 255
SetDlgItemInt,OldValue > Set the old value
.ENDIF
.ELSE
CallWindowProc > default processing
.ENDIF
Posted on 2003-05-30 22:11:41 by donkey
ouch David non-Masm code, both these methods don't seem to like me so i guess I'll just not restrict values that could be typed in but put in an error when value entered is over 255..
Posted on 2003-05-30 22:24:25 by EEDOK
It is masm code. you're welcome.
Posted on 2003-05-30 22:26:03 by david
nah that's basic asm code, it does work with Masm, but Masm is a little easier to read..
Posted on 2003-05-30 22:29:04 by EEDOK
Trust him, it's MASM. Any other assembler would spit out more than a coupleof errors (no dereferencing, proc, invoke, uses, etc...)
Posted on 2003-05-30 22:32:06 by donkey
Here, this will allow values up to but not over 255. Use SetWindowLong to subclass the edit (numeric only), store the old window proc in OldWndProc it automatically gets all the other info it needs:
LimitWndProc PROC hEdit:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD

LOCAL hParent :DWORD
LOCAL idCtrl :DWORD
LOCAL lpTranslated :DWORD
LOCAL OldValue :DWORD

.if uMsg==WM_CHAR
invoke GetParent,hEdit
mov hParent,eax
invoke GetDlgCtrlID,hEdit
mov idCtrl,eax
invoke GetDlgItemInt,hParent,idCtrl,ADDR lpTranslated,FALSE
mov OldValue,eax
invoke CallWindowProc,OldWndProc,hEdit,uMsg,wParam,lParam
push eax
invoke GetDlgItemInt,hParent,idCtrl,ADDR lpTranslated,FALSE
.IF eax > 255
invoke SetDlgItemInt,hParent,idCtrl,OldValue,FALSE
.endif
pop eax

.else
invoke CallWindowProc,OldWndProc,hEdit,uMsg,wParam,lParam
.endif
ret
LimitWndProc endp
Posted on 2003-05-30 23:05:35 by donkey
yea I'm still new to coding in Masm.. So can I subclass a dialog, that's been defined in a resource and used as a main window?
Posted on 2003-05-30 23:32:53 by EEDOK
donkey's method of subclassing the edit control and letting windows restrict character level entry is very appealing as it allows cut-n-paste and other functionality of the edit control.
Posted on 2003-05-30 23:49:34 by bitRAKE

yea I'm still new to coding in Masm.. So can I subclass a dialog, that's been defined in a resource and used as a main window?

This subclassing method should work with an edit control on any type of window. You do not subclass the dialog but the edit control itself. For example if you know the ID of the edit control:
DlgProc proc uses ebx esi edi hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM

LOCAL hEdit :DWORD

.IF uMsg == WM_INITDIALOG
invoke GetDlgItem,hWin,IDEdit
mov hEdit,eax
invoke SetWindowLong,hEdit,GWL_WNDPROC,OFFSET LimitWndProc
mov OldWndProc,eax

etc...
Posted on 2003-05-31 00:47:57 by donkey
now if I use
invoke GetDlgItemText,hWnd,ID_EDIT,ADDR buffer,512
can I make it so it converts what's in the messagebox to hex, then write it to a byte?
Posted on 2003-06-01 23:54:38 by EEDOK
-Get the string via GetDlgItemTextA
-Use some atodw function to convert it to dword value.
-Store the byte
:)

http://www.asmcommunity.net/board/index.php?topic=606&highlight=atodw
http://www.asmcommunity.net/board/index.php?topic=7265&highlight=atodw



My mistake, should be looking at htodw and not atodw

http://www.asmcommunity.net/board/index.php?topic=4362&highlight=htodw
Posted on 2003-06-01 23:58:12 by roticv
Use GetDialogItemInt - it will do the conversion during the textbox read. No need to convert it yourself.

eg

LOCAL lpTranslated:DWORD
invoke GetDlgItemInt,hParent,idCtrl,ADDR lpTranslated,FALSE
mov MyByte,al
Posted on 2003-06-02 00:06:08 by donkey
Hi Donkey, I like your method too, 'cause as Bitrake said it allows pasting and stuff.
But I found a problem with it.
It is possible to paste in letters with ctrl+v, even though it is number-only.

Actually, it is possible to paste in letters in a completely normal number-only edit box ( I use winXP pro, don't know about other winVersions )
it's gotta be a bug or something they (M-soft) didn't think about.

Can you think any good way of avoiding it?
Posted on 2003-06-02 04:40:00 by david
OK, this should just about cover everything. I decided that this might actually be a very useful little subclass so I stored the limit number in USERDATA to make it re-usable and allow for multiple controls with different limits: (Numeric only is no longer needed)
[b];Set up control[/b]

invoke SetWindowLong,hEdit,GWL_WNDPROC,OFFSET LimitWndProc
mov OldWndProc,eax
invoke SetWindowLong,hEdit,GWL_USERDATA,255 ; upper limit to number (255)

LimitWndProc PROC hEdit:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
LOCAL hParent :DWORD
LOCAL idCtrl :DWORD
LOCAL lpTranslated :DWORD
LOCAL OldValue :DWORD
LOCAL Limit :DWORD

.if uMsg==WM_CHAR || uMsg==WM_PASTE
invoke GetParent,hEdit
mov hParent,eax
invoke GetDlgCtrlID,hEdit
mov idCtrl,eax
invoke GetWindowLong,hEdit,GWL_USERDATA
mov Limit,eax
invoke GetDlgItemInt, hParent, idCtrl, ADDR lpTranslated, FALSE
mov OldValue,eax
invoke CallWindowProc, OldWndProc, hEdit, uMsg, wParam, lParam
push eax
invoke GetDlgItemInt, hParent, idCtrl,ADDR lpTranslated, FALSE
.IF eax > Limit || lpTranslated == FALSE
invoke SetDlgItemInt,hParent,idCtrl,OldValue,FALSE
.endif
pop eax
.else
invoke CallWindowProc, OldWndProc, hEdit, uMsg, wParam, lParam
.endif
ret
LimitWndProc endp
Posted on 2003-06-02 12:04:00 by donkey
:alright: :alright:

I found another thing to fix, at least I experience when I write some digits then try backspace them away, the first digit written,
always remains and can't be deleted.
Posted on 2003-06-02 16:44:34 by david
Better to set ES_NUMBERIC and not grab WM_PASTE. Also, might want to ignore lpTranslated, but this results in blank or oversized numbers being interpreted as zero! Personally, I'd limit the edit control to a few digits and it'd be okay to assume blank controls are zero. Kind of lazy I guess. :grin:
Posted on 2003-06-02 19:59:31 by bitRAKE