News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Enter Key in Edit Control

Started by msmith, January 13, 2006, 04:11:39 AM

Previous topic - Next topic

msmith

How do you "capture" the enter key when the user hits enter when typing into an edit control?

I think subclassing would work, but was hoping for a simpler way.

zooba

If its a single-line edit control then use either your main window procedure (WM_KEYDOWN or WM_CHAR) or your edit control's window procedure.

If its multiline make sure you don't have the ES_WANTRETURN style set and do the same as above.

If it's in a dialog (rather than a window) it's probably easier, but I don't use dialogs so you'll need to wait on someone else.

msmith

zooba,

Thanks for the quick response!

Quote
If its a single-line edit control then use either your main window procedure (WM_KEYDOWN or WM_CHAR) or your edit control's window procedure.

I don't seem to be getting the WM_CHAR event.

zooba

Quote from: msmith on January 13, 2006, 04:22:49 AM
I don't seem to be getting the WM_CHAR event.

You'll only get WM_CHAR if you have TranslateMessage in your message loop and it's working correctly.

msmith

I see the problem, at least in part.

My event handler "directs" events based on the argument that contains the handle. I now see that WM_CHAR does not supply a handle argument.

It looks like I have to keep track of which control has focus in order to use the WM_CHAR message. Do you know of an easy way to do this?

Also, I need to be able to change focus based on the Tab key.

zooba

Quote from: msmith on January 13, 2006, 04:54:05 AMIt looks like I have to keep track of which control has focus in order to use the WM_CHAR message. Do you know of an easy way to do this?

GetFocus function

Quote from: msmith on January 13, 2006, 04:54:05 AMAlso, I need to be able to change focus based on the Tab key.

Put IsDialogMessage in your message loop and ensure your controls have WS_TABSTOP set.

msmith

Thanks again.

Now I have something to work with. Trying these things takes longer than one might expect because this is compiler generated code, so I have to modify the compiler to generate the new code, compile the compiler, and then use a test program to test it.

I think I can just use GetFocus to supply the handle and go from there.

Once I am able to capture this event, I assume I should check for the "ENTER" code and "take" the event for myself, and to pass the event if it is not an ENTER. Is this correct?

msmith

It still is not working.

Here are some code snippets from the event handler.


cmp ebx,WM_CHAR
je !wmChar
.
.
.
!wmChar:
mov [!PassKbdEvent],0
invoke GetFocus
cmp eax,0
je !DefWndProc
invoke GetWindowLong,eax,GWL_USERDATA
cmp eax,0
je !DefWndProc
mov esi,eax
mov eax,[esi+ArrayOffs]
mov [ArrayIndex],eax
mov eax,[esi+evKeyStruckOffs]
cmp eax,0
je !DefWndProc
call dword eax
cmp [!PassKbdEvent],0
jne !DefWndProc
xor eax,eax
jmp !Finish


GWL_USERDATA for each control contains the address of a descriptor for that control which holds event dispatch pointers and other key info. In the case shown, [esi+evKeyStruckOffs] holds the dispatch address for the event.

PS

I changed the code above temporarily to:


!wmChar:
call txt1_keystruck
xor eax,eax
jmp !Finish


I now get the event when the edit box does not have focus, but not when it does.

zooba

I think you'll want to step through this code with a debugger to make sure your descriptor contains the correct values in the correct places.

Also you'll want to make sure that a WM_CHAR event is sent for enter inside an edit control. It's entirely possible that the control is absorbing it based on it's style (not 100% sure on this).

msmith

With the small code segment at the bottom, the descriptor is out of the picture.

It appears that the control IS absorbing the WM_CHAR events.

zooba

In that case you'll need to set up a window proc for the edit control. This isn't as hard as it sounds, and since you've got a descriptor system already working you just need to allocate space in there for the old window proc (or somewhere common to all edit controls):

invoke  GetWindowLong, hEdit, GWL_USERDATA
mov     esi, eax
invoke  SetWindowLong, hEdit, GWL_WNDPROC, OFFSET EditProc
mov     [esi+OldWndProcOffs], eax


Then all the edit proc needs to do is check for a specific message and pass everything else to CallWindowProc (not DefWindowProc). :U

msmith

zooba,

Thanks again for all of your help and advice.

In my original post is said:
Quote
How do you "capture" the enter key when the user hits enter when typing into an edit control?

I think subclassing would work, but was hoping for a simpler way.

In fact, I tried this earlier today and it works as expected.

The problem is that I can't expect my compiler customers to do this. Some of them either don't know or don't care what an API is. They want to code their application, not low level stuff like this.

The goal of the compiler is to give the user the power of a good compiler such as PowerBASIC or c, but with the simplicity of VB. The ability to go to the nuts and bolts level such as API calls in anline asm is there, but is is intended only for those who WANT to use it, not HAVE to.

I may automatically create a separate window process (invisibly) whenever the user creates a single line edit, and add some intuitive support statements to use it.

One the bright side, by having a separate window process for each edit box, there is no doubt about the handle and no need to use GetHandle.

Here's the code:

txt1_intercept:
; LN:27 if wmsg=$102 then
cmp [wmsg],258
jne _Lbl5
; LN:29 if wparam=$0d then
cmp [wparam],13
jne _Lbl6
; LN:30 gosub b1_command
call b1_command
; LN:31 end if
_Lbl6:
; LN:32 end if
_Lbl5:
; LN:33 passinterceptevent
mov [!PassInterceptEvent],1
; LN:34 end event
ret


As you can see, the compiler can output asm with the BASIC lines as comments.

zooba

I'm not sure I can see the exact problem you're having. Perhaps you could post some sample input and output for your compiler?

msmith

zooba,

I'm not having a problem. The code I just posted works fine.

I just hate for a customer to have to go this far "under the hood" to do the job.

zooba

Quote from: msmith on January 14, 2006, 02:11:04 AM
I just hate for a customer to have to go this far "under the hood" to do the job.

There shouldn't be any need for the customer to do this. If the compiler-generated code calls user defined events isn't it just a matter of calling one of these events from a different place?