Hi all!
I have been away from masm32 and radasm for a couple of years. I was seduced by the simplicity of Delphi. I am now trying to learn again what I once knew. It's so much fun and some times frustrating.
My simple question is: I have a program with an edit control. The user enters some text. The text is then processed by the program. For now the user must press a button control to start the processing. Is it possible to start it when the user presses enter inside the edit control? Without subclassing? From what I remember I was able to do it before. If I catch WM_KEYDOWN or something, how do I know it was from inside the edit control?
Regards,
Gantry
I have been away from masm32 and radasm for a couple of years. I was seduced by the simplicity of Delphi. I am now trying to learn again what I once knew. It's so much fun and some times frustrating.
My simple question is: I have a program with an edit control. The user enters some text. The text is then processed by the program. For now the user must press a button control to start the processing. Is it possible to start it when the user presses enter inside the edit control? Without subclassing? From what I remember I was able to do it before. If I catch WM_KEYDOWN or something, how do I know it was from inside the edit control?
Regards,
Gantry
If u dont wont to subclass it u can make ur own variable, something like state if your edit is focused or not and then while WM_KEYDOWN or sth like this
.IF uMsg==WM_KEYDOWN
.IF wParam==13 <----or sth like this i do not remember what was ENTER value
.IF EditFocus==1
invoke DO,sth,here :P
.ENDIF
.ENDIF
.IF uMsg==WM_KEYDOWN
.IF wParam==13 <----or sth like this i do not remember what was ENTER value
.IF EditFocus==1
invoke DO,sth,here :P
.ENDIF
.ENDIF
Thanx!
Sounds like it could work. I will try it tomorrow. Time is 01:03 am and it starts to feel like bedtime!
/Gantry
Sounds like it could work. I will try it tomorrow. Time is 01:03 am and it starts to feel like bedtime!
/Gantry
I doesn't work. I can only catch WM_CHAR or WM_KEYDOWN when the edit control is NOT in focus. I guess I will have to use subclassing. The only problem is that I can't get that to work either. Could it be because my app is in a dialog box? Any ideas?
Meantime I will try some more...
C ya!
/Gantry
Meantime I will try some more...
C ya!
/Gantry
Sorry for confusion :tongue: . But if u realy dont like subclassing, I have got some crazy solution for you.
When somebody try focus the edit box then you set state that edit box is focused and than set focus to your main window so u can us WM_CHAR and so on without subclassing, but than forget about vertical prompt (if i can call it that way :tongue: )
So if the edit box state is set to 1 (for egzample) than all CHARs are sent to edit box
When somebody try focus the edit box then you set state that edit box is focused and than set focus to your main window so u can us WM_CHAR and so on without subclassing, but than forget about vertical prompt (if i can call it that way :tongue: )
So if the edit box state is set to 1 (for egzample) than all CHARs are sent to edit box
Subclassing is the way to do this. Any other solutions would just be tricks and if there was a problem it would be difficult to track the source. NOTE - untested
.IF uMsg == WM_INITDIALOG
invoke GetDlgItem,hWin,1001
mov hEdit,eax
invoke SetWindowLong,hEdit,GWL_WNDPROC,OFFSET EdSubProc
mov OldWndProc,eax
...
EdSubProc PROC hEdit:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
.if uMsg==WM_CHAR
.IF wParam == VK_RETURN
mov ax,BN_CLICKED
shl eax,16
mov ax,IDOK
invoke SendMessage,hDlg,WM_COMMAND,eax,hEdit
.ENDIF
.ENDIF
invoke CallWindowProc,OldWndProc,hEdit,uMsg,wParam,lParam
RET
EdSubProc ENDP
Oh, you read the return like this in your dialog proc. It is sent as an IDOK button click (id=1) you can also add VK_ESCAPE and send IDCANCEL for more advanced stuff. Here's the WM_COMMAND processing for it...
.IF uMsg == WM_COMMAND
xor ebx,ebx
mov eax,wParam
mov bx,ax
shr eax, 16
.IF ebx == IDOK && eax == BN_CLICKED
; Return was hit in the edit control
.endif
and there is an error in the code above, use some other label than hEdit for the WM_INITDIALOG, it is used in the subclassing and will cause a redefinition error.Give the edit control the ES_WANTRETURN style. Process the EN_UPDATE message (high-order word of WM_COMMAND msg). It is sent for every char entered. Get the text using EM_GETLINE in response to EN_UPDATE. The last char in your buffer will be a CR if the user pressed pressed ENTER.
Thank you all for some great support. I can't understand why I ever left this place. I'll be back... :)
Regards,
/Gantry
Regards,
/Gantry
Donkey:
I want cause a invoke SendMessage, , WM_CLOSE, BN_CLICKED shl 16 + ID_CANCEL, 0 whenever the Escape key is hit.
I have a dialog with 16 check boxes on it.
With your code, it looks like I'll need 16 variables to hold the PTR to the original handle, call GetDlgItem and SetWindowLong 16 times, and have 16 different SubclassCheck procs.
Is there a simpler way to implement this?
I want cause a invoke SendMessage, , WM_CLOSE, BN_CLICKED shl 16 + ID_CANCEL, 0 whenever the Escape key is hit.
I have a dialog with 16 check boxes on it.
With your code, it looks like I'll need 16 variables to hold the PTR to the original handle, call GetDlgItem and SetWindowLong 16 times, and have 16 different SubclassCheck procs.
Is there a simpler way to implement this?
create a button with BS_DEFPUSHBUTTON style pressing enter in the edit control will now press this button.
This also works in an ordinary window as long as you use the IsDialogMessage function in your main message loop.
This also works in an ordinary window as long as you use the IsDialogMessage function in your main message loop.
Donkey:
I want cause a invoke SendMessage, , WM_CLOSE, BN_CLICKED shl 16 + ID_CANCEL, 0 whenever the Escape key is hit.
I have a dialog with 16 combo boxes on it.
With your code, it looks like I'll need 16 variables to hold the PTR to the original handle, call GetDlgItem and SetWindowLong 16 times, and have 16 different SubclassCombo procs.
Is there a simpler way to implement this?
You only need one variable for the original combobox procedure, it is the same for all comboboxes. If you have 16 I would create a superclass for that instead of a subclass.
SuperClassCB proc
LOCAL wcx :WNDCLASSEX
jmp @F
cbclass db "ComboBox",0
cbnewclass db "NewComboBox",0
@@:
mov wcx.cbSize,SIZEOF WNDCLASSEX
invoke GetClassInfoEx,NULL,offset cbclass,ADDR wcx
mov eax,hInstance
mov wcx.hInstance,eax
mov eax, wcx.lpfnWndProc
mov OldComboProc,eax
mov eax,OFFSET NewComboProc
mov wcx.lpfnWndProc,eax
mov wcx.lpszClassName,OFFSET cbnewclass
invoke RegisterClassEx,ADDR wcx
ret
SuperClassCB endp
Create the combo boxes with the new class name then set it up the same as the subclass, but without the SetWindowproc.
NewComboProc PROC hWin:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
.if uMsg==WM_xxxx
.ENDIF
invoke CallWindowProc, OldComboProc, hWin, uMsg, wParam, lParam
RET
NewComboProc ENDP
i can study something in this community
Correction, Combo Boxes should be Check Boxes; I don't think it matters though.
ENF: I do have BS_DEFPUSHBUTTON, but it is used for the ID_OK button
Donkey: Currently my dialog box is created from a resource. With superclassing, do I have to create the check boxes at runtime?
ENF: I do have BS_DEFPUSHBUTTON, but it is used for the ID_OK button
Donkey: Currently my dialog box is created from a resource. With superclassing, do I have to create the check boxes at runtime?
Correction, Combo Boxes should be Check Boxes; I don't think it matters though.
ENF: I do have BS_DEFPUSHBUTTON, but it is used for the ID_OK button
Donkey: Currently my dialog box is created from a resource. With superclassing, do I have to create the check boxes at runtime?
Hi,
No, they can be created inside the RC file by using the CONTROL resource type that allows for user defined classes. This is for the combo box but you can change it for your check box. Any control however needs the input focus to be able to recieve keyboard messages.
CONTROL "ControlText",IDC_CB1,"NewComboBox",WS_CHILD | WS_VISIBLE,134,96,29,17,NULL
I'm using fasm and the win32 macros. Below is a simple dialog box with one check box.
The resource section is created by fasm, with the assistance of macros.
Here is the dialogitem macro:
Translating what you provided, I get:
So, at WM_Create I need to register my Control Class, specifying my function as the handler.
Then my Control Handler links to the old one.
Simple enough. I'll implement it tommorow.
The resource section is created by fasm, with the assistance of macros.
dialog myDialog,'MyDialogCaption',70,70,190,175,WS_CAPTION+WS_POPUP+WS_SYSMENU+DS_MODALFRAME
dialogitem 'BUTTON','&Download Tempates',ID_DLT,20,108,60,13,WS_VISIBLE+WS_TABSTOP+BS_CHECKBOX
enddialog
Here is the dialogitem macro:
macro dialogitem class,title,id,x,y,cx,cy,style,exstyle
{ dd style or WS_CHILD,exstyle +0
dw x,y,cx,cy,id
if class eq 'BUTTON'
dw 0FFFFh,80h
else if class eq 'EDIT'
dw 0FFFFh,81h
else if class eq 'STATIC'
dw 0FFFFh,82h
else if class eq 'LISTBOX'
dw 0FFFFh,83h
else if class eq 'SCROLLBAR'
dw 0FFFFh,84h
else if class eq 'COMBOBOX'
dw 0FFFFh,85h
else
du class,0 ; This lets me fill in any class name
end if
if title eqtype 0
dw 0FFFFh,title
else
du title,0
end if
dw 0
align 4
dialog_items_counter = dialog_items_counter + 1 }
Translating what you provided, I get:
dialogitem 'SuperClassedCheckBox','&Download Tempates',ID_DLT,20,108,60,13,WS_VISIBLE+WS_TABSTOP+BS_CHECKBOX
So, at WM_Create I need to register my Control Class, specifying my function as the handler.
Then my Control Handler links to the old one.
Simple enough. I'll implement it tommorow.
DialogParamA returns with ERROR_CANNOT_FIND_WND_CLASS and ExitProcess returns ERROR_CLASS_DOES_NOT_EXIST
I don't get the error if I change 'MY_BTN' back to 'BUTTON' in the dialogitem
Here are the relevent portions, in fasm:
I don't get the error if I change 'MY_BTN' back to 'BUTTON' in the dialogitem
Here are the relevent portions, in fasm:
proc DialogProc, hwnddlg, uMsg, wParam, lParam
.n dd ?
.icon dd ?
enter
push ebx esi edi
.if [uMsg], e, WM_INITDIALOG
call RegisterSuperClassButton
.....
return
proc RegisterSuperClassButton
.wcx WNDCLASSEX
enter
jmp @f
.bclass db "BUTTON", 0
.bnewclass db "MY_BTN", 0
@@:
mov [.wcx.cbSize], sizeof.WNDCLASSEX
lea eax, [.wcx]
invoke GetClassInfoEx, 0, .bclass, eax
mov eax, [hInstance]
mov [.wcx.hInstance], eax
mov eax, [.wcx.lpfnWndProc]
mov [lpOldButtonProc], eax
mov [.wcx.lpfnWndProc], NewButtonProc
mov [.wcx.lpszClassName], .bnewclass
lea eax, [.wcx]
invoke RegisterClassEx, eax
return
proc NewButtonProc, hWin, uMsg, wParam, lParam
enter
.if [uMsg], e, WM_CHAR
.and [wParam], e, VK_ESCAPE
invoke SendMessage, [hWin], WM_CLOSE, BN_CLICKED shl 16 + ID_CANCEL, 0
.endif
invoke CallWindowProc, [lpOldButtonProc], [hWin], [uMsg], [wParam], [lParam]
return
dialogitem 'MY_BTN','&Text Files', ID_txt, 034,082,100,13,WS_VISIBLE or WS_TABSTOP or BS_AUTOCHECKBOX