Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
General hook for keyboard.
#1
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?
#2
It is bad idea because then the hook will run in QM main thread. Avoid it where possible.
#3
ok. safer to launch the hook from QM trigger start I suppose then.
#4
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
Code:
Copy      Help
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
Code:
Copy      Help
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.
#5
in TraiteTouches:
ret 1

in generic_hook_Proc:
if(TraiteTouches(win time code)) ret 1
#6
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....
#7
save k.time in an int- variable
#8
what I did

put int+ timeold in hook function declaration (not proc)

then

Function TraiteTouches
Code:
Copy      Help
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
#9
If double output, maybe 2 threads running, look in Running Items. Or SetWindowsHookEx called 2 times in thread.
#10
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)
#11
Ok here is the whole code, to be debugged and corrected.

Function generic_hook
Code:
Copy      Help
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
Code:
Copy      Help
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
Code:
Copy      Help
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
#12
WORKS AS EXPECTED, but does not release keys, eg SHIFT>
#13
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...


Forum Jump:


Users browsing this thread: 1 Guest(s)