Autor Téma: Hook klávesnice  (Přečteno 274 krát)

Offline starous

  • Mladík
  • **
  • Příspěvků: 78
  • Karma: 2
Hook klávesnice
« kdy: 03-05-2020, 19:19:49 »
ahoj,

už se to tu řešilo mockrát, ale přesto bych si potřeboval ujasnit nějaké věci. Potřeboval bych v rámci svého obslužného programu zajistit, aby se ve starém DOSovém programu, který používáme, nahrazovala desetinná čárka na numerické klávesnici za tečku.

Snažil jsem se prostudovat různý články na webu, ale není mi úplně všechno jasné, proto bych měl pár otázek:
1. Je mi jasné, že potřebuju použít funkci SetWindowsHookEx, ale opravdu musím dát obslužnou metodu do vlastní DLL? S knihovnami nemám moc zkušeností, tak bych se tomu rád vyhnul.
2. Jak zajistím odchycení klávesy jen pro konkrétní aplikaci? Přes ID procesu nebo handle okna? Jak se dá vůbec zjistit handle okna cizí aplikace?
3. Zahodit konkrétní klávesu jsem si našel, ale jak zároveň pošlu vlastní znak? Keybd_event asi přímo v obslužné metodě použít nemůžu, protože se mi ty znaky zdvojí. Zkoušel jsem rovnou podhodit jiný vkCode podobně jako se to dělá v obsluze události onKeyDown, ale to nemá žádný efekt.



Díky za odpovědi.

Láďa Starý

Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 2611
  • Karma: 103
    • Verze Delphi: D2007, DXE + 2 poslední
    • O Delphi v češtině
Re:Hook klávesnice
« Odpověď #1 kdy: 04-05-2020, 00:29:03 »
A nejde spise nastavit pro DOS okno aby se pro danou znakovou stranku pouzival desetinny oddelovac .? Nebo o co ti jde?
Embarcadero MVP - Czech republic

Offline starous

  • Mladík
  • **
  • Příspěvků: 78
  • Karma: 2
Re:Hook klávesnice
« Odpověď #2 kdy: 04-05-2020, 10:18:02 »
Radku, to je právě problém. V dobách, kdy se používali 32bitové Windows a DOS byl podporován nativně systémem, tak nebyl problém. Dnes má většina počítačů Windows 64, kde to přímo nejde a musí se používat nějaký emulátor. Nejdřív jsem používal DosBox, teď už delší dobu vDOS, který má vstup z klávesnice podle prostředí Windows. Na zákadě tvého příspěvku jsem pátral a dočetl se, že vDOS nepodporuje přerušení Int 9, takže použití příkazu keyb nebude fungovat.
Nicméně jsem při tom hledání objevil, že autor vydal na začátku března novou verzi, kde je možné za pomoci příkazu keycode přemapovat znak na klávesnici, aby se tvářil jako jiný. Zdá se tedy, že problém mám vyřešený, jen nahradím čárku posílanou systémem Windows za tečku.

Nicméně, když už jsem do toho investoval tolik času, uvítal bych nějaké vysvětlení, jak to hákování klávesnice funguje. Něco jsem už i rozběhal. Začnu odzadu.

Pokud použiju WH_KEYBOARD_LL, tak se používá call back funkce typu LowLevelKeyboardProc, která v parametru WParam předává typ zprávy klávesnice (WM_KEYDOWN, WM_KEYUP atd). A v tom byl ten zakopaný pes, protože jsem nerozlišoval, jestli byla klávesa stisknuta nebo uvolněna a pokaždé poslal pomocí keybd_event ten svůj nahrazený znak. Jednou se tedy vložil při stisknutí a podruhé při uvolnění. Když na událost WM_KEYDOWN pošlu pomocí keybd_event jen stisknutí a podobně na WM_KEYUP jen uvolnění, vše funguje jak má.

ID vlákna jsem si přes FindWindow a GetWindowThreadProcessId taky našel, nicméně SetWindowsHookEx vrátí nulu a GetLastError mi vrací kód chyby 87 (ERROR_INVALID_PARAMETER). Předpokládám, že důvodem je umístění call back funkce přímo do programu, nikoliv do dynamické knihovny.

Dle jedné diskuze zde na fóru jsem si našel tenhle příklad https://www.swissdelphicenter.ch/en/showcode.php?id=1212, který má zaznamenávat události do logu.
Zdá se, že se hook nastaví správně, ale logovací soubor nikde. Zatím jsem neměl sílu objevit v čem je problém. Nevím, jestli nemusím nastavit knihovně nějaké speciální parametry. Taky jsem zjistil, že tu knihovnu neumím uvolnit. Po spuštění programu a jeho ukončení je knihovna stále aktivní a tak se nedá znovu překompilovat, protože systém odmítne soubor dll přepsat.

Abych nezapomněl. Používám aktuální verzi Delphi Rio, update 3.


Offline vandrovnik

  • Guru
  • *****
  • Příspěvků: 1014
  • Karma: 47
    • Verze Delphi: 10.3
Re:Hook klávesnice
« Odpověď #3 kdy: 04-05-2020, 10:31:11 »
Pokud by to nezafungovalo, zkusil bych ještě program AutoHotKey - možná by přemapování taky zvládnul (a snad by dokázal rozlišit čárku napsanou na numerické klávesnici od normální čárky).

Offline starous

  • Mladík
  • **
  • Příspěvků: 78
  • Karma: 2
Re:Hook klávesnice
« Odpověď #4 kdy: 04-05-2020, 10:50:24 »
Pokud by to nezafungovalo, zkusil bych ještě program AutoHotKey - možná by přemapování taky zvládnul (a snad by dokázal rozlišit čárku napsanou na numerické klávesnici od normální čárky).

Díky za tip. Ten program vypadá zajímavě i pro jiný využití. Trochu jsem kouknul do toho zdrojáku a je to skvěle okomentované. Výborný studijní materiál.

Offline vandrovnik

  • Guru
  • *****
  • Příspěvků: 1014
  • Karma: 47
    • Verze Delphi: 10.3
Re:Hook klávesnice
« Odpověď #5 kdy: 04-05-2020, 10:53:01 »
Já ho používal hlavně na překládání aplikace, protože ten pomalý překládací program, co je k Delphi, se s ním dal jakž takž zvládnout, aniž bych musel půl hodiny zírat na monitor a čekat, kdy budu moci kliknout, že má laskavě pokračovat :-)