Entwickler-Ecke

Windows API - CAPS LOCK systemweit abfangen


Dusty - Fr 26.09.08 00:26
Titel: CAPS LOCK systemweit abfangen
Ich möchte die CAPS LOCK Taste sytemweit abfangen bzw. dafür sorgen, dass sie ausgeschaltet bleibt. Ich habe jetzt ein Programm, welches diese Taste abfängt. Hier mal ein Code-Schnipsel:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
...
RegisterHotKey(Handle, ID_CAPS, 0, VK_CAPITAL)
...

function IsCapsLockOn : boolean;
var
  KeyboardState: TKeyboardState;
begin
  GetKeyboardState(KeyboardState);
  if KeyboardState[VK_CAPITAL]=1 then result := true
  else result := false;
end;

procedure TForm1.WMHotKey(var Msg : TWMHotKey);
begin
  if (Msg.HotKey = ID_CAPS) then begin
     if IsCapsLockOn then 
        Label2.Caption := 'Caps Lock OFF - ' + IntToStr(GetTickCount)
     else 
        Label2.Caption := 'Caps Lock ON - ' + IntToStr(GetTickCount);
  end;  // Problematisch ist, wenn Caps Lock On ist, kann man es nicht AUS schalten!
end;


GetTickCount ist dabei, damit ich sehe, dass das Label verändert wurde.
Bei Setzen eines Haltepunkts wird das Fenster gewechselt und zwischen OFF und ON gewechselt.
Ohne Fensterwechsel bleibt der Status immer gleich!

Ein Problem ist, dass die LED Anzeige und das Verhalten der Tastatur nicht mehr übereinstimmen.
Ein anderes, das bei Fensterwechsel (!) der Status der CAPS LOCK Taste geändert wird.
Also in meinem Programm ist CAPS LOCK aus, aber bei Notepad Aufruf ist CAPS LOCK dann ein.
Bei Rückkehr in mein Programm kann ich dann CAPS Lock nicht mehr ausschalten - ziemlich schlecht!

Hat da jemand ein Idee?

Hinweis: Ich kann nicht ins System eingreifen, da ich keine ADMIN Rechte habe. Sonst wäre es ja einfach ;-)

Wichtig ist, dass CAPS LOCK in ANDEREN Programmen verhindert wird!

Versteht mich jemand? :?

Moderiert von user profile iconGausi: Schnipp-Schnapp durch Delphi-Tags ersetzt.
Moderiert von user profile iconNarses: Topic aus Sonstiges (Delphi) verschoben am Fr 26.09.2008 um 10:19


Xion - So 28.09.08 11:22

hi,

denkansatz:

Zu Beginn des Programms den CapsLock-Status lesen und in eine boolsche Variable schreiben.

Immer wenn GetAsyncKeyState(VK_CAPITAL)<>0 die Variable umstellen

Wenn du Caps-Lock austellen willst, Timer auf Intervall=50 setzen und im OnTimer Event CapsLock ausstellen. Wie man CapsLock austellt, steht sicherlich irgendwo im Forum.


Delete - So 28.09.08 15:46

Hast du dir mal GetAsyncKeystate angeguckt? Aber warum systemweit?


Hidden - So 28.09.08 18:02

user profile iconLuckie hat folgendes geschrieben:
Hast du dir mal GetAsyncKeystate angeguckt? Aber warum systemweit?

Naja, weil ihn die Feststelltaste wohl auch in anderen Programmen nervt.

E: Oder hab' ich jetzt irgendetwas übersehen? :gruebel:


Timosch - So 28.09.08 18:33

AFAIR konnte man die übrigens auch einfach per Registry deaktivieren.


Dusty - Mo 29.09.08 11:09

Mal von hinten nach vorne ...

@Timosch: Ja, kann man in der Registry deaktivieren, aber nur mit ADMIN Rechten. Siehe Posting: KEINE Admin Rechte vorhanden. Deshalb gehts so leider nicht :-(

Systemweit abschalten - weil die Taste in allen Programmen nervt, insbes. bei dem Programm, was ich hauptsächlich an meinem Arbeitsplatz benutze. Und genau DA will ich die CapsLock Funktion eliminieren.

@Xion: Das mit dem Timer hatte ich mir auch schon überlegt, wäre aber nur eine Notlösung, denn ich will das System nicht mit Abfragen bombardieren, wenn es nicht unbedingt sein muss. (Mein Programm hat schon einen Timer.)

Erstaunlicherweise kann mein Programm den Status der Taste nicht tatsächlich feststellen.

Merkwürdig ist auch, dass ich mit dem Abfangen der CapsLock Taste zwar die Funktion unterbinden kann (es wird weiterhin klein geschrieben), aber die Tastatur LED geht trotzdem an!! Es funktioniert alles - bis zu dem Zeitpunkt wo ein neues Fenster geöffnet wird (z. B. Notepad) - dann schaltet sich Caps Lock ein und ich kann es nicht wieder ausschalten, weil ich ja die Taste abfange. Und das ist wirklich übel :shock:

Die Abfrage des Status der Taste ist nicht möglich. Soll ich mal ein ein Beispielprogramm zum testen dranhängen? (D5)

GetAsyncKeystate habe ich mir noch nicht angeguckt. Werde gleich mal googlen ...


Hidden - Mo 29.09.08 11:20

Sollte es nicht genügen, einen zweiten Tastendruck zu simulieren, um LED und Capslock wieder auszuschalten :?:


Dusty - Mo 29.09.08 11:50

Optimal wäre es eigentlich, die Caps Lock Taste wie eine normale Umschalt-Taste arbeiten zu lassen. Eigentlich will man ja groß schreiben - aber nur einen Buchstaben. Das wäre wirklich optimal .... Also CAPS LOCK abfangen und dafür ein SHIFT "unterschieben". Ist das möglich? (Systemweit!)


elundril - Mo 29.09.08 11:57

user profile iconDusty hat folgendes geschrieben:
Optimal wäre es eigentlich, die Caps Lock Taste wie eine normale Umschalt-Taste arbeiten zu lassen. Eigentlich will man ja groß schreiben - aber nur einen Buchstaben. Das wäre wirklich optimal .... Also CAPS LOCK abfangen und dafür ein SHIFT "unterschieben". Ist das möglich? (Systemweit!)


für sowas bräuchte man einen keyboardhook nehm ich an.


Delete - Mo 29.09.08 12:01

Endlich fällt das Stichwort Hook *g*. Dazu habe ich auch gleich Lesestoff [http://assarbad.net/stuff/tutorials/hooks/hook_tutorial.pdf] parat.


Dusty - Mo 29.09.08 15:20

In dem Tutorial steht aber auch gleich, dass man "Kopfstände" machen müsste, um so Dinge wie Strg-Alt-Entf oder Caps-Lock an den Haken zu nehmen. Ins Betriebssystem eingraben will ich mich eigentlich nicht so gerne ... Aufwand und Nutzen stehen das außer Verhältnis. Ich dachte mehr an etwas einfaches. Aber wenn es nicht geht, dann werde ich mich eben weiter über die Taste ärgern müssen :(


elundril - Mo 29.09.08 16:28

vielleicht geht es auch anders aber so spontan ist mir nur das stichwort hook eingefallen. Es kann sein das es einen einfacheren weg gibt den im großen und ganzen bin ich eigentlich auch noch programmieranfänger.