Page 1 of 1

MASM - Restricting characters typed in edit control

#1 GunnerInc   User is offline

  • "Hurry up and wait"
  • member icon

Reputation: 917
  • View blog
  • Posts: 2,358
  • Joined: 28-March 11

Posted 31 July 2011 - 05:09 PM

Huh? What do you mean? Doesn't Windows Edit control already provide this by styles? Yes, you are correct! One of the many reasons us crazy people :wink: use Assembly is to get a finer understanding of how things work, plus we like to do things our way.

If you don't have the MASM32 package (includes samples, header files, pre made libs etc) get it from MASM32

We are going to use Subclassing to accomplish this fairly easy task. What is subclassing? Well, windows sends many different messages to your app. Each control has its own internal message handler to handle different messages like painting, coloring, mouse clicks just to name a few.

Without Subclassing, windows "Dispatches" the messages (events) to the controls handler and we are stuck with the default way the edit control works...

Now enter subclassing... We are basically telling windows we want to be the "middle man". Windows will dispatch the message, we get it before the control does, so we can process the messages and act on the ones we want then send the message on to the controls handler, for the ones we don't want to process, we just pass them on so the control can process them. In our case, we will discard any characters we don't want. We won't pass them on.

Complete source is attached.

First we create an edit control the normal way:
        ;#####  Hex Edit
        invoke  CreateWindowEx, 
                    offset szWndClsEdit, 
                    WS_CHILD or WS_VISIBLE or WS_TABSTOP, 
                    5, 200, 
                    285, 20, 
                    hWin, 0, 
                    hInst, 0

Next we will subclass the control and tell windows to send all messages to our procedure.
        invoke  SetWindowLong, eax, GWL_WNDPROC, addr SubClassNumbers

That is it, we will now be the "middle man", but we need the address of the original procedure for the control, so we can pass messages to it. Lucky for us, the return value of SetWindowLong with the style GWL_WNDPROC is the address of the original proc!
So save it...
        mov     lpNumberProc, eax

Now we need to have to make a callback proc called SubClassNumbers in this example:
SubClassNumbers proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM

	mov		eax,uMsg
	.if eax == WM_CHAR
	    mov     eax, wParam
	    .if (al >= 48 && al <= 57) || al == 8
	        ;#####  Only allow 0 - 9 and backspace keys
	        invoke 	CallWindowProc, lpUpperProc, hWin, uMsg, eax, lParam 
	   invoke 	CallWindowProc, lpNumberProc, hWin, uMsg, wParam, lParam 

    xor    eax, eax

SubClassNumbers endp

Now, we will get all the messages meant for this instance of the Edit control first!

Ah, ok I will break it down...
We only want to handle the WM_CHAR message so, the first .if we check to see if it is, if it is not, we pass it on to the original edit proc in the .else handler by passing on uMsg, wParam, lParam all unchanged

The character code is in wParam, so that is what we want...
	.if eax == WM_CHAR
	    mov     eax, wParam
	    .if (al >= 48 && al <= 57) || al == 8
	        ;#####  Only allow 0 - 9 and backspace keys
	        invoke 	CallWindowProc, lpUpperProc, hWin, uMsg, eax, lParam 

Now, the character code (wParam) is in the lower 8 bits of eax, which is al.. so we do our comparisons on al.
So, what the above does is: if the key pressed is 0 - 9 or the backspace key, we pass it on to the original edit proc for display (we modify wParam and pass it on)

If the key pressed is anything else, we discard it, so the original edit proc won't even get it or know it was pressed.

The attached code we have 4 edit controls, one just numbers, one only uppercase, one only lowercase, and one only hex (0-9, A-F and H)

Wait, how about using masks? Ah, that will be another tutorial :D

Subclassing is a very powerful tool to have.

Attached File(s)

This post has been edited by GunnerInc: 31 July 2011 - 05:20 PM

Is This A Good Question/Topic? 1
  • +

Page 1 of 1