News:

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

Using the HotKey input box

Started by Telefunken, July 17, 2006, 02:07:36 AM

Previous topic - Next topic

Telefunken

I see that RadASM has an option to add a hotkey input box into your dialog. This would be very helpful to me but i have no idea how to use it. Anyone knows?

Telefunken

Ok so I did some reasearching on the MSDN Network and found a couple of things, but im a noob so I still don't know what to do.

QuoteUsing a Hot Key Control

Typical usage of a hot key control follows the pattern below:

    *

      The control is created. If the control is specified in a dialog box template, creation is automatic when the dialog box is created. (You should have a CHotKeyCtrl member in your dialog class that corresponds to the hot key control.) Alternatively, you can use the Create member function to create the control as a child window of any window.
    *

      If you want to set a default value for the control, call the SetHotKey member function. If you want to prohibit certain shift states, call SetRules. For controls in a dialog box, a good time to do this is in the dialog box's OnInitDialog function.
    *

      The user interacts with the control by pressing a hot key combination when the hot key control has focus. The user then somehow indicates that this task is complete, perhaps by clicking a button in the dialog box.
    *

      When your program is notified that the user has selected a hot key, it should use the member function GetHotKey to retrieve the virtual key and shift state values from the hot key control.
    *

      Once you know what key the user selected, you can set the hot key using one of the methods described in Setting a Hot Key.
    *

      If the hot key control is in a dialog box, it and the CHotKeyCtrl object will be destroyed automatically. If not, you need to ensure that both the control and the CHotKeyCtrl object are properly destroyed.


Any help with this is welcome

zooba

That looks like MFC documentation, which won't do you much good at all using assembly.

You can use the HKM_GETHOTKEY and HKM_SETHOTKEY messages to get/set the value displayed. I can't remember the exact format of the value but it all fits into 1 DWORD.

IIRC, the value can be passed straight to RegisterHotKey, but to use accelerator tables or WM_GET/SETHOTKEY you need to change it slightly.

Look up these messages on MSDN, it should be enough to get you going.

Cheers,

Zooba :U

ToutEnMasm

Hello,

When we are some questions about a controle see
http://www.microsoft.com/msj/1298/controlspy3/controlspy3.aspx
It's a real reference and you can play with the controls and test them.
It is written in C (very similar to masm) and you can recompile it with the c++ express edition.
To made it , there is some problems to knoW.
The resource cannot be compiled without included the .... Masm32 file \MASM32\INCLUDE\RESOURCE.H instead of the file that you haven't "#include "afxres.h".
Some other errors occured,but you can correct them puting the line in comment .
                 ToutEnMasm


Telefunken

ToutEnMasm, ControlSpy looks VERY useful, thanks for showing that to me  :dance:

So this is what i have so far

invoke SendDlgItemMessage,hWin,1002,HKM_GETHOTKEY,NULL,NULL
mov hotkey,eax


Will this work?

ToutEnMasm


If hwin is the handle of the dialog box,10... the id of the control in the dialogbox,this can work,but I am not in the computer.
         ToutEnMasm

Telefunken

Ok, so i checked that and it worked. Now, how to pass this value on to RegisterHotKey?

Telefunken

#7
I got it working using GetAsyncKeyState  :U

Is RegisterHotKey superior to GetAsyncKeyState in any way?

EDIT: I got it working with RegisterHotKey as well. But, both of these methods take up A TON of CPU power. Whenever i run my program my CPU usage goes all the way up to 100%. Any ideas?

zooba

If your CPU usage is going that high you probably have an infinite loop somewhere. If you're constantly polling GetAsyncKeyState then this will do it.

RegisterHotKey only needs to be called once. Then whenever the key combination is pressed, a WM_HOTKEY message will be sent to the window you specified.

Post the code for that section, but I'm pretty sure you've got an infinite/semi-infinite loop somewhere.

Cheers,

Zooba :U

Telefunken

Heres the code for that section...

mainfunc:
invoke MessageBox,NULL,addr intboxText,addr intboxCap,MB_OK
keyloop:
invoke RegisterHotKey,NULL,065h,NULL,hotkey1
.if eax!=WM_HOTKEY
invoke MoveFileEx, addr dir,addr newdir,MOVEFILE_REPLACE_EXISTING
.endif
invoke RegisterHotKey,NULL,066h,NULL,hotkey2
.if eax!=WM_HOTKEY
invoke MoveFileEx, addr newdir,addr dir,MOVEFILE_REPLACE_EXISTING
.endif
.if check==0
invoke GetAsyncKeyState,exithotkey
.if eax!=0
jmp kill
.endif
jmp keyloop
.endif
jmp kill


EDIT: I just realized that this doesn't work at all... heh... any ideas?

Telefunken

GAAAAHH... I am going insane with frustration....

I'm just going to post my enitre source here, because I can't seem to find the problem

.386
.model flat, stdcall  ;32 bit memory model
option casemap :none  ;case sensitive

include const.bypassv3.inc

.code

start:

invoke GetModuleHandle,NULL
mov hInstance,eax

    invoke InitCommonControls
invoke DialogBoxParam,hInstance,IDD_DIALOG1,NULL,addr DlgProc,NULL
invoke ExitProcess,0

;########################################################################

DlgProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM

mov eax,uMsg
.if eax==WM_INITDIALOG
   
.elseif eax==WM_COMMAND
mov eax,wParam
mov edx,eax
shr edx,16
and eax,0FFFFh
.if edx==BN_CLICKED
.if eax==1008
invoke SendDlgItemMessage,hWin,1009,BM_GETCHECK,0,0
mov check, eax
invoke EndDialog,hWin,0
jmp mainfunc
.endif

.if eax==1007
invoke ExitProcess,0
.endif

.if eax==1006
invoke SendDlgItemMessage,hWin,1002,HKM_GETHOTKEY,0,0
mov hotkey1,eax
invoke SendDlgItemMessage,hWin,1003,HKM_GETHOTKEY,0,0
mov hotkey2,eax
invoke SendDlgItemMessage,hWin,1015,HKM_GETHOTKEY,0,0
mov exithotkey,eax
.endif
.if eax==1017
;jmp aboutdiag
.endif
.endif

.elseif eax==WM_CLOSE
invoke EndDialog,hWin,0
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret

DlgProc endp


mainfunc:
invoke MessageBox,NULL,addr intboxText,addr intboxCap,MB_OK




keyloop:
invoke RegisterHotKey,NULL,065h,NULL,hotkey1
stage1:
.if eax==WM_HOTKEY
invoke MoveFileEx, addr dir,addr newdir,MOVEFILE_REPLACE_EXISTING
invoke UnregisterHotKey,NULL,065h
invoke RegisterHotKey,NULL,066h,NULL,hotkey2
jmp stage2
.endif

jmp stage1

stage2:
.if eax==WM_HOTKEY
invoke MoveFileEx, addr newdir,addr dir,MOVEFILE_REPLACE_EXISTING
invoke UnregisterHotKey,NULL,066h
invoke RegisterHotKey,NULL,067h,NULL,exithotkey
jmp stage3
.endif

jmp stage2

stage3:
.if check==1
invoke ExitProcess,0
.endif
.if eax==WM_HOTKEY
invoke UnregisterHotKey,NULL,067h
invoke ExitProcess,0
.endif
jmp kill

kill:
call ExitProcess

end start



:dazzled:  :dazzled:

Help? Anyone?

zooba

Yep, it's exactly what I said.

RegisterHotKey only needs to be called once per hotkey, then you wait to receive WM_HOTKEY messages. You don't need to unregister the hotkey until the end of your program. (Or when you want to stop receiving WM_HOTKEY messages).

There is no need for the 'keyloop' section, call RegisterHotkey once per key in WM_INITDIALOG, and add code to check for WM_HOTKEY as part of your DlgProc. In that bit you need to look at lParam to see which hotkey it was (hiword = virtual key code, loword = modifier keys) and do the actions there.

Also, you will need to specify the dialog handle in the RegisterHotKey call, you've got NULL there at the moment. If you call RegisterHotKey in WM_INITDIALOG, use hWin instead.

Cheers,

Zooba :U

Telefunken

#12
Quote from: zooba on July 18, 2006, 06:56:59 AM
In that bit you need to look at lParam to see which hotkey it was (hiword = virtual key code, loword = modifier keys) and do the actions there.

How do I do this?

EDIT: Each hotkey has a unique ID, so there must be a way to check witch actual hotkey was pressed, if there are multiple ones like i have. When a hotkey is pressed, how do i check which hotkey it was?

2nd Edit: i went here http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceui40/html/cerefWM_HOTKEY.asp

and found that WM_HOTKEY has an "idHotKey" parameter. But I don't know how to use it...  :'(


3rd EDIT: Nevermind. I got everything working, without the keyloop  :dance:  :dance:  :U

Thanks all, and especially zooba  :U  :8)

zooba

No problem.

Maybe you could post the relevant parts of your code here? So then if someone else is looking for a solution to the same problem they can find it. :wink

Telefunken

Hm, good idea

.if edx==BN_CLICKED

.if eax==1007 ;The exit button
invoke ExitProcess,0
.endif

.if eax==1006 ;This sets and registers the hotkeys, based on the Dialog
invoke SendDlgItemMessage,hWin,1002,HKM_GETHOTKEY,0,0
mov hotkey1,eax
invoke RegisterHotKey,hWin,001h,NULL,hotkey1
invoke SendDlgItemMessage,hWin,1003,HKM_GETHOTKEY,0,0
mov hotkey2,eax
invoke RegisterHotKey,hWin,002h,NULL,hotkey2
invoke SendDlgItemMessage,hWin,1015,HKM_GETHOTKEY,0,0
mov exithotkey,eax
invoke RegisterHotKey,hWin,003h,NULL,exithotkey

invoke SendDlgItemMessage,hWin,1009,BM_GETCHECK,0,0
mov check, eax

.endif
.if eax==1017
;jmp aboutdiag
.endif
.endif

.elseif eax==WM_HOTKEY                   ;What happens when the user presses a hotkey
.if wParam==001h                        ;<--- the hotkey id will be sent to wParam of your dialog
invoke MoveFileEx,addr dir,addr newdir,MOVEFILE_REPLACE_EXISTING
.endif

.if wParam==002h
invoke MoveFileEx,addr newdir,addr dir,MOVEFILE_REPLACE_EXISTING
.if check==1
invoke ExitProcess,0
.endif

.endif


.if wParam==003h
invoke ExitProcess,0
.endif




Hope this saves somebody else the trouble i went through  :wink  :U