Entwickler-Ecke

Windows API - Tastatur überwachen!


Borlox - Sa 22.02.03 15:28
Titel: Tastatur überwachen!
Hi Leute,

ich möchte gerne den Text überwachen, der auf meiner Tastatur geschrieben wird! Also habe ich ein Programm geschrieben, dass im Hintergrund läuft, aber dann kann ich ja nicht mehr auf das Ereigniss OnKeyPress zugreifen, da die Form nicht mehr angeklickt ist, gibt es noch eine eine andere Möglichkeit die Tastatur zu überwachen?

THX


Anonymous - Sa 22.02.03 15:48

Such mal unter dem Begriff Hooks und im Turorial.


Delete - Sa 22.02.03 18:14

Wenn es nur dein Programm betrifft, dann wäre RegisterHotKey das richtige.


Borlox - Sa 22.02.03 18:18
Titel: RegisterHotKey
Es soll nur mein Program betreffen!
Wie funktioniert das denn mit dem RegisterHotKey??

Habe leider nichts darüber gefunden!!!


Delete - Sa 22.02.03 18:25

Hier ein Beispiel für die Drcuk-Taste:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
TForm1 = class(TForm)
  private
  { Private-Deklarationen }
  procedure WMHotKey(var Msg : TWMHotKey); message WM_HOTKEY;

  public
  { Public-Deklarationen }

end;

const id_SnapShot =101;

procedure TForm1.WMHotKey(var Msg : TWMHotKey);
begin
  if Msg.HotKey=id_SnapShot then
  begin
    // ...;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  RegisterHotKey(Form1.Handle,id_SnapShot,0,VK_Snapshot);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  UnRegisterHotKey(Form1.Handle,id_SnapShot);
end;


Borlox - Sa 22.02.03 18:37
Titel: Cool
Danke, das ist auf jeden Fall schon mal eine super Idee!
Es klappt auch so weit, aber wie kann ich anstatt der Drucktaste z.B. ein Buchstaben dafür nehmen??


Delete - Sa 22.02.03 18:42

Einfach für VK_SNAPSHOT einen andern virtuellen KeyCode angeben. Mit Buchstaben wird es da aber etwas komplizierter, glaube ich.


Borlox - Sa 22.02.03 18:49
Titel: d
Aber das mit den Buchstaben ist genau das, was ich brauche!

Da muss es doch irgendeine Möglichkeit geben!???


torstenheinze - Sa 22.02.03 18:54

A = 65
B = 66
C = 67


wenn du das meinst :?


Delete - Sa 22.02.03 18:55

Das Problem ist, RegisterHotkey will im letzten Parameter einen virtuellen KeyCode haben und Buchstaben haben keinen soweit ich weiß.


torstenheinze - Sa 22.02.03 18:58

eigendlich müssen alle tsten einen haben, sonnst könnte man sie doch nicht benutzen? :?


Delete - Sa 22.02.03 19:01

Ich habe gerade im PSDK gekuckt. Ich glaube, da kann man wirklich das
Zitat:

A = 65
B = 66
C = 67
... = ...

nehmen.

Obwohl im PSDK sind es hex-Werte:
Zitat:

(41)
A key

(42)
B key

(43)
C key

(44)
D key

(45)
E key

(46)
F key

(47)
G key

(48)
H key

(49)
I key

(4A)
J key

(4B)
K key

(4C)
L key

(4D)
M key

(4E)
N key

(4F)
O key

(50)
P key

(51)
Q key

(52)
R key

(53)
S key

(54)
T key

(55)
U key

(56)
V key

(57)
W key

(58)
X key

(59)
Y key

(5A)
Z key


DelphiMan - So 23.02.03 00:38
Titel: QuasiHook - wie?
Wie kann ich alle Tasten auf einmal Registrieren - dann hätte man ja nämlich einen systemweiten Hook mit dem man arbeiten kann, oder wo liegt der unterschied? Jedenfalls: gibt es vielleicht einen eleganteren weg, als im oncreate ereignis folgendes für alle tasten zu machen?

RegisterHotKey(Form1.Handle,ord('0'),0,ord('0'));
RegisterHotKey(Form1.Handle,ord('1'),0,ord('1'));
...

Vielen Dank im Voraus!

MfG
DelphiMan


Borlox - So 23.02.03 00:41
Titel: Danke
Danke, das hat mir schon sehr viel weitergeholfen! Danke an alle!

Nun noch eine letzte kleine Frage, was ist denn mit den kleinen Buchstaben???
Wie kann ich den Unterschied zwischen groß und klein herausfinden?


Raphael O. - So 23.02.03 00:53

Musst einfach überprüfen ob die Shift-Taste gedrückt ist und wenn ja, dann ist es ein GROßBUCHSTABE :wink:


Borlox - So 23.02.03 15:08
Titel: Frage
Hi Leute,

mir ist gerade aufgefallen, wenn ich etwas z.B. in Word schreiben möchte, dann geht das nicht mehr, wenn mein Program gestartet ist!
Ich wollte zwar die Tastaturbefehle abfangen, aber ich wollte nicht, dass man nicht mehr weiterarbeiten kann!

Hat jemand ne Idee?


GSE - So 23.02.03 15:31

Ich glaube du musst in deiner Prozedur(WMHotKey) einfach am Ende noch inherited(WMHotKey); aufrufen.

mfg
GSE


Borlox - So 23.02.03 17:17
Titel: Frage
Klappt leider nicht!

Er gibt folgende Fehlermeldung aus:

[Error] Netz.pas(88): Missing operator or semicolon


THX


Raphael O. - So 23.02.03 17:37

schreib mal den Quelltext mit dem "inherited(..);" und das davor/dahinter stehthier rein


GSE - So 23.02.03 18:05

Mein Fehler :oops:
Du musst natürlich den Parameter Msg mit übergeben:

Quelltext
1:
inherited WMHotKey(Msg);                    


mfg
GSE[/code]


Borlox - So 23.02.03 18:23
Titel: Leider
Klappt leider auch nicht:

Fehlermeldung:
[Error] Netz.pas(87): Undeclared identifier: 'WMHotKey'

THX


Borlox - Mo 24.02.03 13:01
Titel: Richtig
Da bin ich wieder!

Wiß denn keiner, wie der folgende Befehl richtig heißt:
inherited WMHotKey(Msg);

Ich habe ihn ans Ende der HotKey Procedure geschrieben!

THX


Anonymous - Mo 24.02.03 14:09

Es gibt eine einfache und gute Kompunente mit dem Namen "KeySpy". Die Zeichnet dir alle Tastenklicks auf. Vielleicht wäre das etwas für dich.


Borlox - Mo 24.02.03 15:18
Titel: KeySpy
Hat jemand eine Ahnung, wo ich die Komponente KeySpy finden kann?

Habe schon gesucht, aber nichts gefunden!
Lieder funktioniert Google gerade nicht bei mir!


Anonymous - Mo 24.02.03 17:46

Wie kann Google gerade nicht funktionieren? Versuchs mit:

http://www.google.de ;)

Wenn du

KeySpy Delphi

eingibst, dann bekommst du gleich als erstes die Seite von Torry. Dann einfach runterladen.


Borlox - Mo 24.02.03 17:49
Titel: Google
Ich weiß nicht wieso, aber Google funktioniert leider überhaupt nicht mehr!

Es gibt immer einen Fehler wenn ich auf die Seite gehe!


Moritz M. - Mo 24.02.03 17:58

Hi

Ich hab mir nicht alles durchgelesen. Aber hier mal meine Methode, wie ich den Hook umgangen hab:

Ich nehm folgende Komponente:
TSysHotKey(download) [http://torry.net/vcl/system/keys/syshot.zip]
Beim start des programms registriere ich alle Tasten als HotKey, die ich brauche:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
  With Hook do
  begin
    AddHotKey(vkA,[hkShift]);
    AddHotKey(vkB,[hkShift]);
    AddHotKey(vkC,[hkShift]);
    AddHotKey(vkD,[hkShift]);
    AddHotKey(vkE,[hkShift]);
    AddHotKey(vkF,[hkShift]);
    AddHotKey(vkG,[hkShift]);
    AddHotKey(vkH,[hkShift]);
    AddHotKey(vkI,[hkShift]);
    AddHotKey(vkJ,[hkShift]);
    AddHotKey(vkK,[hkShift]);
    AddHotKey(vkL,[hkShift]);
    AddHotKey(vkM,[hkShift]);
    AddHotKey(vkN,[hkShift]);
    AddHotKey(vkO,[hkShift]);
    AddHotKey(vkP,[hkShift]);
    AddHotKey(vkQ,[hkShift]);
    AddHotKey(vkR,[hkShift]);
    AddHotKey(vkS,[hkShift]);
    AddHotKey(vkT,[hkShift]);
    AddHotKey(vkU,[hkShift]);
    AddHotKey(vkV,[hkShift]);
    AddHotKey(vkW,[hkShift]);
    AddHotKey(vkX,[hkShift]);
    AddHotKey(vkY,[hkShift]);
    AddHotKey(vkZ,[hkShift]);
    AddHotKey(vk0,[]);
    AddHotKey(vk1,[]);
    AddHotKey(vk2,[]);
    AddHotKey(vk3,[]);
    AddHotKey(vk4,[]);
    AddHotKey(vk5,[]);
    AddHotKey(vk6,[]);
    AddHotKey(vk7,[]);
    AddHotKey(vk8,[]);
    AddHotKey(vk9,[]);
    AddHotKey(vkReturn,[]);
    AddHotKey(vkA,[]);
    AddHotKey(vkB,[]);
    AddHotKey(vkC,[]);
    AddHotKey(vkD,[]);
    AddHotKey(vkE,[]);
    AddHotKey(vkF,[]);
    AddHotKey(vkG,[]);
    AddHotKey(vkH,[]);
    AddHotKey(vkI,[]);
    AddHotKey(vkJ,[]);
    AddHotKey(vkK,[]);
    AddHotKey(vkL,[]);
    AddHotKey(vkM,[]);
    AddHotKey(vkN,[]);
    AddHotKey(vkO,[]);
    AddHotKey(vkP,[]);
    AddHotKey(vkQ,[]);
    AddHotKey(vkR,[]);
    AddHotKey(vkS,[]);
    AddHotKey(vkT,[]);
    AddHotKey(vkU,[]);
    AddHotKey(vkV,[]);
    AddHotKey(vkW,[]);
    AddHotKey(vkX,[]);
    AddHotKey(vkY,[]);
    AddHotKey(vkZ,[]);
  end;

(Hook heißt bei mir die TSysHotKey-Kompinente)
Dann, wenn ein Tastendruck kommt mache ich folgendes:
-Eingabe speichern
-HotKeys ausschalten
-Tastendruck simulieren(Funktion siehe unten)
-HotKeys anschalten

So, ein perfekter Hook - ohne DLL und komplizierten sachen

-------------------------------------------------------------

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
procedure PostKeyEx32(key: Word; const shift: TShiftState; specialkey: Boolean);
type
  TShiftKeyInfo = record 
    shift: Byte;
    vkey: Byte;
  end;
  byteset = set of 0..7;
const 
  shiftkeys: array [1..3of TShiftKeyInfo = 
    ((shift: Ord(ssCtrl); vkey: VK_CONTROL), 
    (shift: Ord(ssShift); vkey: VK_SHIFT), 
    (shift: Ord(ssAlt); vkey: VK_MENU)); 
var 
  flag: DWORD; 
  bShift: ByteSet absolute shift; 
  i: Integer; 
begin 
  for i := 1 to 3 do 
  begin 
    if shiftkeys[i].shift in bShift then 
      keybd_event(shiftkeys[i].vkey, MapVirtualKey(shiftkeys[i].vkey, 0), 00); 
  end;
  if specialkey then 
    flag := KEYEVENTF_EXTENDEDKEY 
  else 
    flag := 0;
  keybd_event(key, MapvirtualKey(key, 0), flag, 0); 
  flag := flag or KEYEVENTF_KEYUP; 
  keybd_event(key, MapvirtualKey(key, 0), flag, 0); 

  for i := 3 downto 1 do
  begin 
    if shiftkeys[i].shift in bShift then 
      keybd_event(shiftkeys[i].vkey, MapVirtualKey(shiftkeys[i].vkey, 0), 
        KEYEVENTF_KEYUP, 0); 
  end;
end;


Wir so aufgerufen:

Delphi-Quelltext
1:
2:
PostKeyEx32(ord('H'), [], false);//Drückt H
PostKeyEx32(ord('H'), [ssShift], false);//Drückt Shift+H


Moderiert von user profile iconAXMD: Code- durch Delphi-Tags ersetzt.


Anonymous - Mo 24.02.03 18:03

Es gibt noch AltaVista, Excite, Lycos usw.

Ganz besonders kann ich dir die Seite http://www.suchfibel.de empfehlen. Dort sind alle deutschsprachigen Suchmaschinen aufgelistet, beurteilt und beschrieben. Weiterhin hat http://www.suchlexikon.de fast 2700 Suchmaschinen aufgelistet (ist eine Art Suchmaschine für Suchmaschinen). Wenn davon 2699 nicht funktionieren, dann hast du immer noch eine übrig.

Ansonsten frag ich mich wie lange du schon das Internet kennst, daß du bei einem nichtfunktionierenem Google nichts im Internet findest.


Borlox - Mo 24.02.03 20:48
Titel: Popov
Hi Popov,

natürlich war ich auch bei den Suchmaschinen, aber leider gibt es da keine Ergebnisse! Er findet nichts!

Ich war bei 9 verschiedenen Suchmaschinen, aber alle hatten 0 Results!!!


Delete - Mo 24.02.03 22:07
Titel: Re: Popov
Borlox hat folgendes geschrieben:
Hi Popov,

natürlich war ich auch bei den Suchmaschinen, aber leider gibt es da keine Ergebnisse! Er findet nichts!

Ich war bei 9 verschiedenen Suchmaschinen, aber alle hatten 0 Results!!!

Hm. Entweder kannst du die Suchmaschinen nicht bedienen oder was weiß ich was du da machst:
Google: delphi tastatur hook [http://www.google.de/search?hl=de&lr=lang_de&ie=UTF-8&oe=UTF-8&q=delphi+tastatur+hook&spell=1].

Ohne Worte. Und das sind nur die Ergebnisse auf deutsche Seiten beschränkt!


Borlox - Mo 24.02.03 22:25
Titel: Rechtfertigung
Ich glaube ich kann sehr wohl eine Suchmaschine bedienen!

Ich habe nach der Komponente KeySpy gesucht! Aber bei allen Suchmaschinen gabe es damit kein Ergebnis: Delphi KeySpy!

Das das bei Google geklappt hätte ist mir klar! Aber wie du sicherlich weiter oben gelesen hast, klappt diese Seite bei mir einfach nicht!

Auch jetzt sagt mein Browser immer noch:

Server nicht gefunden: Seite kann nicht angezeigt werden!


Anonymous - Mo 24.02.03 23:22

Also mit AltaVista klappt es wunderbar.

Hier ein Link zu Torry:

http://www.torry.net/keysandkeyboard.htm

Sucht dann mit eder Seitensuche nach dem Wort "SendKey".


HellAngel28 - Fr 15.08.03 17:04

http://www.delphipraxis.net/topic7114_liste+der+virtuellen+tastencodes+vk.html

hier findet man die VK_Keys..

aber jetz noch ne frage zu dem code von Luckie..



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
procedure TForm1.WMHotKey(var Msg : TWMHotKey); 
begin 
  if Msg.HotKey=id_SnapShot then 
  begin 
    // ...; 
  end
end;


sagen wir, ich will abfragen ob Shift UND F10 gedrückt wird.. wie finde ich das heraus?

Moderiert von user profile iconAXMD: Code- durch Delphi-Tags ersetzt.


Delete - Fr 15.08.03 18:52

In dem du ihn registrierst:

Delphi-Quelltext
1:
RegisterHotKey(Form1.Handle, id_SnapShot, MOD_SHIFT, VK_Snapshot);                    


hansa - Fr 15.04.05 22:21

Ich muß für einen Schüler so was in der Richtung basteln. Dafür habe ich mir die Taste VK-RIGHT ausgesucht. Das geht soweit auch. Allerdings wäre es schön, zu sehen, ob diese Taste gedrückt wird, wenn mein Programm die Kontrolle hat oder eben ein anderes. Wie geht das ?


prote - Fr 15.04.05 23:55

Geht bestimmt auch einfacher, aber eine Idee wäre, sich'nen Flag zu schnappen (Bsp.: var b:boolean;) und dieses mit Hilfe von TCustomForm.OnActivate und TCustomForm.OnDeactivate entsprechend zu setzen. Dann reicht ein simples if(dieFktfürVK_RIGHT)and(b)then machirgendwas; ;)


hansa - Sa 16.04.05 11:33

Geht nicht. OnDeactivate wird nicht benutzt. Vorab : OnHide genauso wenig. Vielleicht habe ich das auch falsch erklärt. Angenommen ich bin im Word und drücke VK_RIGHT. Dann soll was passieren. Daß sich Word dadurch nicht mehr gut bedienen lassen würde ist schon klar.


prote - Sa 16.04.05 22:20

Dann hilft Dir nur die richtige Tastenabfrage und dafür gibt es meines Wissens 3 Wege:
1. getasynckeystate(i:integer);
2. Hooks
3. ein neuer Tastaturtreiber

Nun, 3. wirst Du nicht entwickeln wollen, für 2. gibt's eine schöne Anleitung hier im Forum unter http://www.delphi-forum.de/topic_Hooks_101.html und 1. wäre eine sehr einfache und trotzdem gut funktionierende Lsg., spiel ein bissel damit herum ;)


F34r0fTh3D4rk - Do 21.04.05 13:14

tastenschläge registrieren:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
procedure keycheck;
var
  i: byte;
begin
  while true do
    begin
      if boolean(getasynckeystate(vk_f9)) then
        showmessage('F9 gedrückt !');
      sleep(50);
    end;
end;

createthread(nil0, @keycheck, nil0, tid);

und groß und kleinschreibung unterscheiden:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
var
  str: string;
begin
  str:= '';
  if key <> vk_shift then
    if ssshift in shift then
      label1.Caption:= label1.Caption + chr(key) else
        label1.Caption:= label1.Caption + lowercase(chr(key));
end;