[Delphi] keyboardhook

Pagina: 1
Acties:

  • MerijnB
  • Registratie: Oktober 2000
  • Laatst online: 00:20
Ik heb een class die een keyboardhook maakt met SetWindowsHookEx

code:
1
  fKeyboardHook := SetWindowsHookEx(WH_KEYBOARD, @KeyboardProc, hInstance, 0);


de callback ziet er als volgt uit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
function KeyboardProc(nCode: UINT; wParam: wParam; lParam: lParam): LRESULT; stdcall;
begin
 if nCode = HC_ACTION then
 begin
  if GenerateEvent(wParam, lParam) then
   result := 1
  else
   result := 0;
 end
 else
  result := CallNextHookEx(fKeyboardHook, nCode, wParam, lParam);
end;


GenerateEvent zoekt uit wat voor een event naar de user te genereren (keyup, keydown, etc) en geeft een boolean terug of de toetsaanslag wel of niet geblokkeerd moet worden voor de rest van de chain.

het werkt redelijk maar ik heb hier 2 problemen mee:

1: als er een nieuwe toetsaanslag is terwijl de oude nog niet afgewikkeld is (als de user van de class dus lang bezig is met het event af te handelen) krijg ik die nieuwe callback niet. Sterker nog: dan krijg ik daarna helemaal geen callbacks meer.

2: als je naar een andere app switched met alt-tab (dus niet met muis) heb ik hetzelfde probleem, d'r komen dan geen callbacks meer. Zal wel errug met het vorige probleem te maken hebben.

probleem 1 heb ik redelijkerwijs opgelost maar dat lijkt meer op symptoom bestrijding dan dat het een echte oplossing is....

A software developer is someone who looks both left and right when crossing a one-way street.

Dé antenne-innovatie voor de korte golf


  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Als je een systemwide hook wilt maken dan moet deze in een DLL zitten.

Zoek es op Google, zijn 100-en voorbeelden te vinden.

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • MerijnB
  • Registratie: Oktober 2000
  • Laatst online: 00:20
Als je een systemwide hook wilt maken dan moet deze in een DLL zitten.
ik wil geen system-wide hook hebben (die heb ik ook, maar is in dit geval niet echt een optie)
Zoek es op Google, zijn 100-en voorbeelden te vinden.
en dit is (helaas) ook niet het eerste forum waar ik dit op post of de eerste plek waar ik zoek ...

A software developer is someone who looks both left and right when crossing a one-way street.

Dé antenne-innovatie voor de korte golf


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

MerijnB schreef op 12 November 2002 @ 10:56:
[...]

ik wil geen system-wide hook hebben (die heb ik ook, maar is in dit geval niet echt een optie)


[...]


en dit is (helaas) ook niet het eerste forum waar ik dit op post of de eerste plek waar ik zoek ...
Geen systen wide hook = Geen system wide toetsafvaning...klaar

Dan moet je beter zoeken. Maar goed, je code ziet er goed uit...maar je moet er gewoon voor zorgen dat je GenerateEvent niet de boel ophoud. Stuur je zelf een message, dat ontkoppelt de boel en laat windows weer netjes verder gaan met toetsaanslagen terwijl jij je ding doet

We adore chaos because we like to restore order - M.C. Escher


  • MerijnB
  • Registratie: Oktober 2000
  • Laatst online: 00:20
Geen systen wide hook = Geen system wide toetsafvaning...klaar
is het nou zo moeilijk ? ik wil helemaal geen system wide toetsafvanging,
alleen binnen mijn applicatie ....
Dan moet je beter zoeken.
hier posten valt niet onder zoeken als ik op bijv google en delphipages niets kan vinden?
Maar goed, je code ziet er goed uit...maar je moet er gewoon voor zorgen dat je GenerateEvent niet de boel ophoud. Stuur je zelf een message, dat ontkoppelt de boel en laat windows weer netjes verder gaan met toetsaanslagen terwijl jij je ding doet
dat is dus de oplossing die ik voor het 1e probleem had bedacht (beetje brak, maar het werkt in principe). Maar met deze 'oplossing' blijft probleem nr 2 bestaan helaas.. :(

A software developer is someone who looks both left and right when crossing a one-way street.

Dé antenne-innovatie voor de korte golf


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

MerijnB schreef op 12 november 2002 @ 11:14:

is het nou zo moeilijk ? ik wil helemaal geen system wide toetsafvanging,
alleen binnen mijn applicatie ....
[...]
dat is dus de oplossing die ik voor het 1e probleem had bedacht (beetje brak, maar het werkt in principe). Maar met deze 'oplossing' blijft probleem nr 2 bestaan helaas.. :(
erm...zoals ik en Delphi begrijpen is probleem 2 een probleem omdat je geen toetsen af kan vangen als je applicatie niet actief is? Daarvoor heb je een system wide hook nodig. En ja, dat is dan verplicht. Als het niet is wat je bedoelt moet je dat nog maar eens beter uitleggen

We adore chaos because we like to restore order - M.C. Escher


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

MerijnB schreef op 12 November 2002 @ 11:14:
dat is dus de oplossing die ik voor het 1e probleem had bedacht (beetje brak, maar het werkt in principe)
Brak?! Brak?! Realizeer je je wel goed dat je op dat moment een deel wordt van Windows?! Als jouw code brak is haal je heel Windows naar beneden. En denk je dat mensen het leuk vinden om zo lang op een toetsaanslag te wachten? Die code die je daar in de hook callback doet moet zo kort mogelijk zijn.

We adore chaos because we like to restore order - M.C. Escher


  • MerijnB
  • Registratie: Oktober 2000
  • Laatst online: 00:20
volgens mij praten we net langs elkaar heen... :) ik zal nog es proberen uit te leggen wat het probleem is.

- ik wil (binnen mijn applicatie, dus niet system-wide) toetsaanslagen afvangen.

- daarbij wil ik evt. een toetsaanslag blokkeren voor de control die op dat moment de focus heeft (dus dat als ik een vk_up afhandel, de combobox die dan de focus heeft niet ook nog eens zijn index gaat veranderen)

- ik hoef NIET alt-tab af te vangen, alleen werkt m'n callback niet meer NADAT ik alt-tab heb gedaan ...

- en waarom ik de oplossing met een windows message 'brak' vind: degene die het event krijgt moet op dat moment beslissen of de keypress geblokt moet worden of niet, dat MOET dus synchroon, terwijl de afhandeling dan asynchroon moet. Dat vind ik zelf niet zo'n hele nette oplossing (ik snap wel dat dit ws de ENIGE oplossing)

A software developer is someone who looks both left and right when crossing a one-way street.

Dé antenne-innovatie voor de korte golf


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

MerijnB schreef op 12 november 2002 @ 11:28:
volgens mij praten we net langs elkaar heen... :) ik zal nog es proberen uit te leggen wat het probleem is.

- ik wil (binnen mijn applicatie, dus niet system-wide) toetsaanslagen afvangen.

- daarbij wil ik evt. een toetsaanslag blokkeren voor de control die op dat moment de focus heeft (dus dat als ik een vk_up afhandel, de combobox die dan de focus heeft niet ook nog eens zijn index gaat veranderen)

- ik hoef NIET alt-tab af te vangen, alleen werkt m'n callback niet meer NADAT ik alt-tab heb gedaan ...

- en waarom ik de oplossing met een windows message 'brak' vind: degene die het event krijgt moet op dat moment beslissen of de keypress geblokt moet worden of niet, dat MOET dus synchroon, terwijl de afhandeling dan asynchroon moet. Dat vind ik zelf niet zo'n hele nette oplossing (ik snap wel dat dit ws de ENIGE oplossing)
NADAT je alt-tab heb gedaan zit je in een andere applicatie. Dan is het niet gek dat je geen toetsen meer afvang, tenzij je een system wide hook maakt. Of bedoelt je nadat je 2x Alt-Tab gedaan hebt? Zeg het dan gewoon simpel: 'Nadat er van active applicatie gewisselt is.'

Ja, je hebt gelijk als je een key wil blokkeren is het brak, maar zorg dan dat die code niet zolang hoeft te duren.

Overgens denk ik niet dat dit de oplossing is voor je probleem. Het is een beetje een rare oplossing om een toets voor een combobox af te vangen. Het lijkt me netter/beter/logisher/modulairder als je dat bij het component zelf oplost. IMHO

We adore chaos because we like to restore order - M.C. Escher


  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Idd, gewoon bij de OnKeyPress/OnKeyDown (welke ook alweer?) event de Key op #0 zetten mocht het nodig zijn.

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • MerijnB
  • Registratie: Oktober 2000
  • Laatst online: 00:20
mea culpa...

idd na 2x alt-tab |:(

ik ben het met LordLarry eens dat de afhandeling niet lang mag duren, maar goed, hoe lang is niet lang? Daarbij hoopte ik iets te kunnen maken dat ik later zou kunnen gebruiken zonder me alle haken en ogen te hoeven herinneren.

Over onKeyUp en onKeyDown: dit heb ik uiteraard eerst geprobeerd maar dat was toch zo moeilijk werkbaar te maken dat ik dus met een hook aan de slag ging.

Op zich werkt de oplossing prima, met als enige echte probleem dat als de user met alt-tab switched (en weer terug O-)) dat ik dan geen callbacks meer krijg.

Ik heb zelf geprobeerd om in de OnAppActivate en OnAppDeactivate m'n hook te unhooken en weer aan te zetten, maar dit werkte ook niet ...

A software developer is someone who looks both left and right when crossing a one-way street.

Dé antenne-innovatie voor de korte golf


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

MerijnB schreef op 12 november 2002 @ 11:53:
mea culpa...

idd na 2x alt-tab |:(

ik ben het met LordLarry eens dat de afhandeling niet lang mag duren, maar goed, hoe lang is niet lang? Daarbij hoopte ik iets te kunnen maken dat ik later zou kunnen gebruiken zonder me alle haken en ogen te hoeven herinneren.
nauwelijks enkele ms. Je vetraagd het typen..erger kan bijna niet :)
Over onKeyUp en onKeyDown: dit heb ik uiteraard eerst geprobeerd maar dat was toch zo moeilijk werkbaar te maken dat ik dus met een hook aan de slag ging.
Waarom? Ik kan me voorstellen dat je niet overal elke keer een OnKeyDown aan een combobox wil hangen.

Oplossing: Een afgeleide maken van de combobox. Daarin de functie KeyDown overriden, voortaan altijd je eigen combobox gebruiken en klaar. Hoef je er ook nooit meer bij na te denken.
Op zich werkt de oplossing prima, met als enige echte probleem dat als de user met alt-tab switched (en weer terug O-)) dat ik dan geen callbacks meer krijg.

Ik heb zelf geprobeerd om in de OnAppActivate en OnAppDeactivate m'n hook te unhooken en weer aan te zetten, maar dit werkte ook niet ...
Vreemd, ik zou zo niet weten. Behalve dat je het zo ie zo al niet zo op had moeten lossen :p

Weet je ook van het event TApplication.OnMessages?

We adore chaos because we like to restore order - M.C. Escher


  • MerijnB
  • Registratie: Oktober 2000
  • Laatst online: 00:20
een paar ms zijn een heleboel cycles, vandaar dat het zo lastig is ergens een grens te trekken

het vervelende is alleen dat ik dan niet allen een TComboBox moet overriden, maar nog een handje vol andere controls ook ....

"Behalve dat je het zo ie zo al niet zo op had moeten lossen"
klinkt beetje cru aangezien d'r niet echt een goed alternatief lijkt te zijn

OnMessages zou interresant kunnen zijn, maar kan je dan ook nog de keystroke blokkeren ?

A software developer is someone who looks both left and right when crossing a one-way street.

Dé antenne-innovatie voor de korte golf


  • MerijnB
  • Registratie: Oktober 2000
  • Laatst online: 00:20
ik ben d'r achter, d'r ging toch iets fout bij het setten van de hook

A software developer is someone who looks both left and right when crossing a one-way street.

Dé antenne-innovatie voor de korte golf


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

MerijnB schreef op 12 November 2002 @ 12:17:
het vervelende is alleen dat ik dan niet allen een TComboBox moet overriden, maar nog een handje vol andere controls ook ....

"Behalve dat je het zo ie zo al niet zo op had moeten lossen"
klinkt beetje cru aangezien d'r niet echt een goed alternatief lijkt te zijn
Het kinkt inderdaad wat cru, sorry daarvoor.

Ik vind persoonlijk elk alternatief die ik heb opgenoemd beter dan een local hook. Ik weet nog niet welk effect je percies wil bereiken met het negeren van toetsen, maar het oplossen bij het component in kwestie is veruit preferent.
OnMessages zou interresant kunnen zijn, maar kan je dan ook nog de keystroke blokkeren ?
Ja, maar kijk er even naar zou ik zeggen...

We adore chaos because we like to restore order - M.C. Escher


  • MerijnB
  • Registratie: Oktober 2000
  • Laatst online: 00:20
Ik vind persoonlijk elk alternatief die ik heb opgenoemd beter dan een local hook. Ik weet nog niet welk effect je percies wil bereiken met het negeren van toetsen, maar het oplossen bij het component in kwestie is veruit preferent.
ik ben het op dat punt niet helemaal met je eens, ik wil graag bij somige toetsaanslagen een speciale afwikkeling hebben waarbij het component dat op dat moment de focus heeft de toetsaanslag niet krijgt, ongeacht welk component het is. Bij jou oplossing zou ik voor elk component dat ik ooit wil gebruiken een overerving moeten maken omdat ik ergens anders iets wil bereiken. Terwijl een lokale hook het probleem aanpakt waar het speelt, namelijk voordat de keystroke bij de rest van de componenten aankomt ...

zou een leuke discussie kunnen zijn :)

enniewees bedankt voor het meedenken ..

A software developer is someone who looks both left and right when crossing a one-way street.

Dé antenne-innovatie voor de korte golf


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 22:17

Creepy

Tactical Espionage Splatterer

Ik vraag me af waarom de onkeydown events onwerkbaar zijn? Je kan de onkeydown events van alle objecten toch laten wijzen naar dezelfde functie zodat je in 1 functie je toetsafhandeling kan doen. Nog steeds geen windows hook voor nodig.

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • MerijnB
  • Registratie: Oktober 2000
  • Laatst online: 00:20
Ik vraag me af waarom de onkeydown events onwerkbaar zijn? Je kan de onkeydown events van alle objecten toch laten wijzen naar dezelfde functie zodat je in 1 functie je toetsafhandeling kan doen. Nog steeds geen windows hook voor nodig.
om heel eerlijk te zijn; ik weet het zelf ook niet meer precies :). Maar iig gaf het genoeg ellende om d'r niet mee door te gaan (volgens mij bijv. ook iets van dat je bij een TSpinEdit d'r niet goed tussen kon komen ofzo).

Hoe dan ook, dan krijg je dus wel dat als je dan nog een control op je form zet je niet moet vergeten om het OnKeyDown event af te vangen, terwijl je op dat moment met hele andere problematiek bezig bent ....

A software developer is someone who looks both left and right when crossing a one-way street.

Dé antenne-innovatie voor de korte golf

Pagina: 1