Posts: 795
Threads: 136
Joined: Feb 2009
Hi Gintaras, hi all,
i'd like to put a generic keyboard hook using Hook_WH_KEYBOARD_LL example for multi purpose actions.
The Hook_WH_KEYBOARD_LL2 procedure will handle keyboards events and decide actions based on the application
which is active at key pressed time.
To be sure it is always active and starts at QM launching, i was thinking putting the Hook_WH_KEYBOARD_LL as
the main QM toolbar callback procedure (QM Toolbar hook function).
Is it safe or a bad idea?
Posts: 12,090
Threads: 142
Joined: Dec 2002
It is bad idea because then the hook will run in QM main thread. Avoid it where possible.
Posts: 795
Threads: 136
Joined: Feb 2009
ok. safer to launch the hook from QM trigger start I suppose then.
Posts: 795
Threads: 136
Joined: Feb 2009
i want to handle keys to remap action on specific application.
So for instance, I want to override F1 to do special action instead of launching help , but F2 does the normal action.
Function generic_hook_Proc
function# nCode message KBDLLHOOKSTRUCT&k
if(nCode<0) goto gNext
if(!(k.flags&LLKHF_UP)) goto gNext ;;Si key down, on passe
int time=k.time
int code=k.vkCode
TraiteTouches(win time code)
;gNext
ret CallNextHookEx(0 nCode message &k)
Function TraiteTouches
function int'hwnd int'time int'code
_i=0
_s.getwinexe(hwnd)
str jj
str chacun g
str monitor="qm[]firefox"
foreach chacun monitor
,if(findrx(_s chacun 0 1 g)!=-1)
,,_i+1
,,break
if(_i=0) ret
I don't know what code to put next in the TraiteTouches function so that for chosen keys, it does not pass action to CallNextHookEx
and for key not monitored, it does.
Posts: 12,090
Threads: 142
Joined: Dec 2002
in TraiteTouches:
ret 1
in generic_hook_Proc:
if(TraiteTouches(win time code)) ret 1
Posts: 795
Threads: 136
Joined: Feb 2009
if(TraiteTouches(win time code)) ret 1, would never have think about that...
last step:
i want to determine the time between two keystrokes, but I don't know which is the best way to
do that. The aim is to do something like the taptap program
http://www.donationcoder.com/Software/Mouser/TapTap/
which is able to trigger action if a key is double keyed...
so, in TraiteTouche, somthing be able to do:
timeold is previous time for keystroke
time is the current
time-timeold>400 ms ret 1
many tries, no joy....
Posts: 12,090
Threads: 142
Joined: Dec 2002
save k.time in an int- variable
Posts: 795
Threads: 136
Joined: Feb 2009
what I did
put int+ timeold in hook function declaration (not proc)
then
Function TraiteTouches
function int'hwnd int'time int'code
_i=0
int+ timeold
_s.getwinexe(hwnd)
str jj
str chacun g
str monitor="qm"
int h=time-timeold
out h
timeold=time
foreach chacun monitor
,if(findrx(_s chacun 0 1 g)!=-1)
,,_i+1
,,break
if(_i=0) ret 1
;_s.getwintext(hwnd)
FormatKeyString code 0 &jj;
but the output is double, like this, and don't know which number is the real elapsed time. Can't understand why....
171
719
156
391
188
546
172
422
188
515
188
422
203
797
187
391
172
140
157
171
Posts: 12,090
Threads: 142
Joined: Dec 2002
If double output, maybe 2 threads running, look in Running Items. Or SetWindowsHookEx called 2 times in thread.
Posts: 795
Threads: 136
Joined: Feb 2009
no for both hypothesis.
Maybe related to key up / down? would find a way to act on only key up without counting key down,
but i thought it was handled by
if(!(k.flags&LLKHF_UP)) goto gNext
gNext
ret CallNextHookEx(0 nCode message &k)
Posts: 795
Threads: 136
Joined: Feb 2009
Ok here is the whole code, to be debugged and corrected.
Function generic_hook
int hh=SetWindowsHookEx(WH_KEYBOARD_LL &generic_hook_Proc _hinst 0)
str+ OldKey
int+ OldTime
out "Press a key"
opt waitmsg 1
wait -1
UnhookWindowsHookEx hh
Function generic_hook_Proc
function# nCode message KBDLLHOOKSTRUCT&k
int- TimeOld
if(nCode<0) goto gNext
if(!(k.flags&LLKHF_UP)) goto gNext ;;Si key down, on passe
int time=k.time
int code=k.vkCode
if(TraiteTouches(win time code)) ret 1
;gNext
ret CallNextHookEx(0 nCode message &k)
Function TraiteTouches
function int'hwnd int'time int'code
_i=0
int- timeold
_s.getwinexe(hwnd)
str jj
str chacun g
str monitor="qm"
FormatKeyString code 0 &jj
;out "%s %s%s" _s iif(k.flags&LLKHF_UP "up" "down") iif(k.flags&LLKHF_INJECTED ", injected" "") ;;debug
str+ CurrentKey=jj
out "CurrentKey: %s" CurrentKey
out "OldKey: %s" OldKey
OldKey=CurrentKey
int h=time-timeold
out h
timeold=time
foreach chacun monitor
,if(findrx(_s chacun 0 1 g)!=-1)
,,_i+1
,,break
if(_i=0) ret 1
the output is this one, pressing two key one after the other rapidly...seems near to do it, but miss something for being functional...
CurrentKey: P
OldKey: O
250
CurrentKey: M
OldKey: P
2422
CurrentKey: L
OldKey: M
297
CurrentKey: K
OldKey: L
5328
CurrentKey: I
OldKey: K
266
CurrentKey: J
OldKey: I
297
CurrentKey: U
OldKey: J
234
CurrentKey: H
OldKey: U
266
CurrentKey: Y
OldKey: H
250
CurrentKey: J
OldKey: Y
3453
CurrentKey: J
OldKey: J
156
CurrentKey: J
OldKey: J
719
CurrentKey: J
OldKey: J
156
Posts: 12,090
Threads: 142
Joined: Dec 2002
WORKS AS EXPECTED, but does not release keys, eg SHIFT>
Posts: 795
Threads: 136
Joined: Feb 2009
well i'm pleased the code is right in sense of "working", but it not right in terms of "do what I want"...
I should receive only one output, and not two, because I want to calculate the time between 2 key UP event, not 2 key press..
I try hard with trying to skip the first key up event at the moment...
|