AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Tastaturhook -> Tasten manupulieren
Thema durchsuchen
Ansicht
Themen-Optionen

Tastaturhook -> Tasten manupulieren

Ein Thema von webby · begonnen am 16. Apr 2003 · letzter Beitrag vom 20. Jun 2003
Antwort Antwort
Seite 2 von 3     12 3      
Benutzerbild von S - tefano
S - tefano

Registriert seit: 16. Dez 2002
Ort: Dülmen
477 Beiträge
 
Delphi 2009 Professional
 
#11
  Alt 19. Jun 2003, 12:42
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:
  {$EXTERNALSYM WH_KEYBOARD}
  WH_KEYBOARD = 2;
Nur halt mir KeyBoard_ll anstatt KeyBoard.
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
"Sir, we are surrounded!" - "Excellent, we can attack in every direction!"
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.105 Beiträge
 
Delphi 11 Alexandria
 
#12
  Alt 19. Jun 2003, 12:50
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:
const // aus WINUSER.H
  WH_KEYBOARD_LL = 13;
diese Konstante funktioniert aber nur unter NT, W2K und XP.
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
Benutzerbild von S - tefano
S - tefano

Registriert seit: 16. Dez 2002
Ort: Dülmen
477 Beiträge
 
Delphi 2009 Professional
 
#13
  Alt 19. Jun 2003, 13:21
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:
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;
Key ist ein globaler Integer, list ist meine Stringlist die ich zuvor initialisiert habe.
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:

  setwindowshookex(WH_KEYBOARD_LL, hookproc, Hinstance, 0); Ist irgendwo irgendwas falsch? Oder gibts in der hookproc auch noch Teile, die so nur unter 9x funktionieren können?
Hoffe ihr könnt was finden.

Bis dann,

S - tefano
"Sir, we are surrounded!" - "Excellent, we can attack in every direction!"
  Mit Zitat antworten Zitat
Benutzerbild von S - tefano
S - tefano

Registriert seit: 16. Dez 2002
Ort: Dülmen
477 Beiträge
 
Delphi 2009 Professional
 
#14
  Alt 19. Jun 2003, 18:13
Kann doch nich sein, dass das keiner weiß...
"Sir, we are surrounded!" - "Excellent, we can attack in every direction!"
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.105 Beiträge
 
Delphi 11 Alexandria
 
#15
  Alt 19. Jun 2003, 19:51
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?
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
Benutzerbild von S - tefano
S - tefano

Registriert seit: 16. Dez 2002
Ort: Dülmen
477 Beiträge
 
Delphi 2009 Professional
 
#16
  Alt 19. Jun 2003, 21:42
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.

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
"Sir, we are surrounded!" - "Excellent, we can attack in every direction!"
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.105 Beiträge
 
Delphi 11 Alexandria
 
#17
  Alt 19. Jun 2003, 22:04
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:
type
  PKBDLLHOOKSTRUCT = ^KBDLLHOOKSTRUCT;

  KBDLLHOOKSTRUCT = packed record
    vkCode : DWORD; // message
    scanCode : DWORD; // ParamL
    flags : DWORD; // ParamH
    time : DWORD; // time
    dwExtraInfo : DWORD; // hwnd
  end;
Vergleich doch mal, ob auch alles überall dort steht, wo's soll.

ggf. könntest Du ja vielleicht mal die Sourcen anhängen.
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
Benutzerbild von S - tefano
S - tefano

Registriert seit: 16. Dez 2002
Ort: Dülmen
477 Beiträge
 
Delphi 2009 Professional
 
#18
  Alt 20. Jun 2003, 00:03
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!!!!!

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
"Sir, we are surrounded!" - "Excellent, we can attack in every direction!"
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.105 Beiträge
 
Delphi 11 Alexandria
 
#19
  Alt 20. Jun 2003, 00:57
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.
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
Benutzerbild von S - tefano
S - tefano

Registriert seit: 16. Dez 2002
Ort: Dülmen
477 Beiträge
 
Delphi 2009 Professional
 
#20
  Alt 20. Jun 2003, 10:53
Hi,

also dieses MSDN is schon ne feine Institution...

Zitat:
flags
Specifies the extended-key flag, event-injected flag, context code, and transition-state flag. This member is specified as follows. An application can use the following values to test the keystroke flags. Value Purpose
LLKHF_EXTENDED Test the extended-key flag.
LLKHF_INJECTED Test the event-injected flag.
LLKHF_ALTDOWN Test the context code.
LLKHF_UP Test the transition-state flag.

0
Specifies whether the key is an extended key, such as a function key or a key on the numeric keypad. The value is 1 if the key is an extended key; otherwise, it is 0.
1-3
Reserved.
4
Specifies whether the event was injected. The value is 1 if the event was injected; otherwise, it is 0.
5
Specifies the context code. The value is 1 if the ALT key is pressed; otherwise, it is 0.
6
Reserved.
7
Specifies the transition state. The value is 0 if the key is pressed and 1 if it is being released.
Heißt also dass ich gucken muss ob dieses LLKHF_UP 0 oder 1 ist.
Kann ich das einfach über flags.LLKHF_UP ansprechen, oder muss ich sowas machen wie

if flags[7] = 0 then ... ? Also schonmal vorweg, durch Rumprobieren hab ich rausgefunden dass die obigen zwei Sachen nich gehen.
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
"Sir, we are surrounded!" - "Excellent, we can attack in every direction!"
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:30 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz