![]() |
Achja, wo wir dabei gerade sind.
Könnte mal bitte einer von euch in seiner Windows- Unit die Definition von WH_KEYBOARD_LL nachschlagen und posten? Wie gesagt, bei mir fehlt sie. Müsste wie folgt aussehen:
Delphi-Quellcode:
Nur halt mir KeyBoard_ll anstatt KeyBoard.
{$EXTERNALSYM WH_KEYBOARD}
WH_KEYBOARD = 2; Hoffe mal dass es überhaupt geht, einfach die Definition nachzutragen. Aber nen Versuch ist es wert, oder? Oder sollte man das lieber lassen und nicht riskieren seine WindowsUnit zu zerschießen? Danke schonmal, S - tefano |
Moin Stefano,
Du musst dafür ja nicht Deine Windows.pas anpassen, es genügt ja schon, wenn Du Dir eine Unit erstellst, in der Du dann solche Ergänzungen einbindest. Das ExternalSym brauchst Du auch nur, wenn die Unit im C++ Builder benutzt werden soll, ansonsten reicht einfach eine Konstantendeklaration.
Delphi-Quellcode:
diese Konstante funktioniert aber nur unter NT, W2K und XP.
const // aus WINUSER.H
WH_KEYBOARD_LL = 13; |
Hi,
danke erstmal für die Definition, habs dann mal in die ProgrammUnit eingebunden. Aber irgendwie gehts immernoch nicht... Diese Funktion habe ich aus einem anderen Tutorial (irgendwo bei Google gefunden) rausgenommen und so modifiziert, dass ich erstmal zum Gucken was ich da empfange, bevor ich mich an die "Abkürzungsverlängerung" mache, die gedrückten Tasten in eine Stringlist schreibe und später auf Buttonklick in ein Memo übertrage:
Delphi-Quellcode:
Key ist ein globaler Integer, list ist meine Stringlist die ich zuvor initialisiert habe.
function hookproc(ncode: integer; wpara: wparam; lpara: lparam): longint; stdcall;
begin Result := 0; if ncode=Hc_action then begin if (Peventmsg(Lpara).message = wm_keydown) or (Peventmsg(Lpara).message = wm_syskeydown) then begin key:= Peventmsg(Lpara).paraml; key:= Peventmsg(lpara).paramH; key:= mapvirtualkey(key,0); universalkey(key); //gibt String für den jeweiligen key-Integer in keystr aus //den keystring in die Stringlist schreiben if keystr = '[ENTER]' then list.Add(keystr) //wenn Enter gedrückt wurde, neue Zeile anfangen, else list[list.Count - 1]:= list[list.count - 1] + keystr; //sonst einfach anhängen end; if peventmsg(lpara).message = wm_keyup then begin key:= Peventmsg(Lpara).paraml; key:= mapvirtualkey(key,0); end; end; end; Was ich an dieser Funktion schon die ganze Zeit fragwürdig finde ist, warum key drei mal hintereinander verschiedene Werte zugewiesen werden. Als ich den Hook noch mit WH_KEYBOARD gesetzt hab, war es noch so, dass das Programm durch die zweite If-Abfrage durchkam (die wo geguckt wird, ob eine Taste oder eine Systemtaste gedrückt wurde) durchkam, dann aber die Funktion mapvirtualkey eine 0 zurückgab (weil das, was key vorher zugewiesen wurde, fast immer größer als 1000 war, aber auf jeden Fall immer größer als die ASCII- Range). Deswegen wurde auch jede Taste als Pause erkannt, weil universalkey der 0 die Taste Pause zuweist. Mit WH_KEYBOARD_LL geht das Programm aber komplett an der zweiten if- Abfrage vorbei, es wird also durch den Tastendruck über den Hook zwar die Funktion ausgeführt, aber der Tastendruck wird dann als solcher nicht mehr erkannt. So setze ich den Hook:
Delphi-Quellcode:
Ist irgendwo irgendwas falsch? Oder gibts in der hookproc auch noch Teile, die so nur unter 9x funktionieren können?
setwindowshookex(WH_KEYBOARD_LL, hookproc, Hinstance, 0);
Hoffe ihr könnt was finden. Bis dann, S - tefano |
Kann doch nich sein, dass das keiner weiß...
|
Moin Stefano,
das Problem dürfte schlicht sein, dass wParam und lParam bei WH_KEYBOARD_LL ganz andere Daten enthalten als bei WH_KEYBOARD. So wie die Hookproc aussieht könnte das zwar berücksichtigt sein, aber wie ist z.B. PEventMsg deklariert? |
Hi,
is das jetz ne direkte Frage an mich, oder eher ne r(h)et(h)orische Frage? PEventMsg steht in meiner Windows- Unit als Pointer auf TEventMsg, das wiederum der Datenstruktur der EvenMsg, die im Windows SDK nachzulesen ist entspricht. Und diese Strutkur hat die Eigenschaften lParam, hParam und message (wenn ich mich nich vertue). Ich hab mir jetzt mal zum Probieren nen Breakpoint gesetzt um mal zu gucken was da während der Hook sich meldet in der Funktion so passiert. Und irgendwie sind jetzt die Messages, die in der If- Abfrage geprüft werden weder wm_keydown noch wm_syskeydown. Sind wieder irgendwelche Zahlen, meistens zwischen 9000 und 10000, und wenn ich die Überprüfung weglasse wird jede Taste als "Pfeilnachoben" erkannt. Kann denn die Datenstruktur dieses lParams oder von was auch immer denn unter NT- Systemen wirklich so anders sein? Und wenn ja... warum wird sowas nirgendwo (weder in (zumindest meiner) Delphi Hilfe, noch im Netz (jedenfalls auf den 23 Schrott-Seiten die Google mir heute reingewürgt hat)) anständig dokumentiert? grrrr. So langsam bin ich am Verzweifeln. Hätte so tolle Sachen heute machen können, aber nein, ich Schlaubi versuche ausgerechnet heute meinen Einstieg in diese verfluchten Hooks. :evil: :cry: :evil: :cry: :evil: :cry: :evil: :cry: :evil: Hoffe von Herzen, dass einem von euch was einfällt, was mich weiterbringt. Denn nachdem ich heute durch das Niemandsland der Prono- zugemüllten Seiten, vermient mit Dialern und furchtbaren Designs und noch schlimmeren Usern, die absolut nicht in der Lage sind sich verständlich auszudrücken bzw. auf Fragen zu reagieren, bin ich dieses Mal zu dem absolut ernsthaften Schluss gekommen, dass AUQ und die Praxis die absolut unangefochten besten Delphi- Communities in deutscher Sprache sind. Ich hoffe, dass (wenn meine oben erwähnte Verzweiflung das nicht schon bewirkt hat) spätestens diese Liebeserklärung an dieses Forum einen Ansporn bietet, einem armen unschuldigen Kerl der im Glauben ist einen ganzen Tag verschwendet zu haben, zu helfen. Danke im Voraus, S - tefano |
Moin Stefano,
also in meinem PSDK heist die Struktur für WH_KEYBOARD_LL aber KBDLLHOOKSTRUCT OK, da die Länge der Struktur, und die Aufteilung gleich sind, dürfte das nichts ausmachen. Sollte dann so deklariert werden: ( mit // das entsprechende Feld von TEventMsg)
Delphi-Quellcode:
Vergleich doch mal, ob auch alles überall dort steht, wo's soll.
type
PKBDLLHOOKSTRUCT = ^KBDLLHOOKSTRUCT; KBDLLHOOKSTRUCT = packed record vkCode : DWORD; // message scanCode : DWORD; // ParamL flags : DWORD; // ParamH time : DWORD; // time dwExtraInfo : DWORD; // hwnd end; ggf. könntest Du ja vielleicht mal die Sourcen anhängen. |
Hi,
hey, das is cool. Also erstmal ist kurz zu erwähnen dass der obige Code (also der von "meiner" HookProc) unter 9x prima läuft, das also alles tatsächlich daran liegt, dass XP NT basierend ist. Jetz hab ich durch Rumprobieren rausgefunden, dass bei dieser LL-Struktur die Eigenschaft vkCode den ASCII-Code des gedrückten Zeichens enthält. Irgendwie scheints zwar so zu sein, dass die Eigenschaften dieser Struktur unter der 9x- Struktur so heißen würden wie in deinen Kommentaren, aber sie enthalten andere Daten. Unter 9x enthielt message ja ganz normal die Message, ob keyup, keydown oder sonstwas, und hier wie gesagt den ASCII- Code. Deshalb hats auch zuerst nich geklappt, einfach den Code von Oben zu nehmen und einfach nur die Eigenschaften die angesprochen werden umzubenennen. Ich frag mich nur, aus welcher Eigenschaft man jetz die Message lesen kann, um spezifisch auf Drücken und Loslassen reagieren zu können. Meine Hilfe kann mir dazu ja schlecht was sagen, kannte sie ja nichtmal diese Datenstruktur. Und zu time: Kann man daraus auslesen, wie lange eine Taste gedrückt gehalten wird? Könnt mir nicht vorstellen wie, weil doch nach diesem Wiederholungsintervall von Windows (also wenn man einen Buchstaben länger gedrückt hält, erscheint er im Endeffekt so oft wie der Intervall in die Zeit des Gedrückthaltens reinpasst) der Hook wieder aufgerufen wird. Aber wichtig wäre mir erstmal rauszufinden welche Eigenschaft ich für die Message auslesen muss. Wenn man nochn bissken mit den vkCodes rumprobiert, findet man auch die Werte raus, die so Sachen wie Shift und so wiedergeben. 160 lShift, 161 rShift, 162 lStrg, 163 rStrg, 164 Alt, 165 AltGr (wobei vor 165 immer ein 162 mitkommt). Is halt nur wie gesagt ohne die Unterscheidung für keyup und keydown blöd, weil man sonst für jeden Tastendruck zwei identische Werte bekommt. Aber nichts desto Trotz: VIELEN DANK!!!!! :bouncing4: :firejump: :bounce1: :bounce2: :hello: :bounce2: :bounce1: :firejump: :bouncing4: Hast mir ganz schön weitergeholfen mit der Datenstruktur. Insgeheim machts mich ja schon ein Bisschen stolz den größten Teil (halt bis auf wm_keyup und wm_keydown) selbst rausgefunden zu haben... Würd mich freuen, wenn sich auch dieses Problem aus dem Weg schaffen ließe. Bis dann und nochmal danke, S - tefano |
Moin Stefano,
am besten schaust Du Dir die Struktur mal im MSDN oder im PSDK an. Da sind die Felder alle erklärt. Das mit dem AltGr ist auch leicht zu erklären: Es werden unmittelbar nacheinander die Codes für CTRL und ALT generiert AltGr selber hat keinen. Warum man trotzdem mit AltGr+Del keinen CTRL+ALT+DEL simulieren kann ich mir nicht so ganz erklären, es scheint da noch mehr mitzuspielen. |
Hi,
also dieses MSDN is schon ne feine Institution... Zitat:
Kann ich das einfach über flags.LLKHF_UP ansprechen, oder muss ich sowas machen wie
Delphi-Quellcode:
? Also schonmal vorweg, durch Rumprobieren hab ich rausgefunden dass die obigen zwei Sachen nich gehen.
if flags[7] = 0 then ...
Ich kann allerdings einfach die flag an sich abfragen. Wenn die Taste gedrückt wird, kommt ganz normal 0, aber wenn man sie loslässt 128. Warum? Und. Wie kann ich denn überhaupt die verschiedenen Flags voneinander unterscheiden? Bis dann, S - tefano |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:56 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz