Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Warten auf Keine Taste Gedrückt


holger - Sa 08.05.10 22:55
Titel: Warten auf Keine Taste Gedrückt
Guten Abend,

ich bin auf der Suche nach einer einfachen Funktion, welche erkennt wenn keine Taste gedrückt ist.

Problem:

Ein im Hintergrund laufendes Programm soll z.B. auf CTRL + U reagieren ( geht mit RegisterHotKey). Daraufhin wird u.A. ein Text in der Zwischenablage deformatiert (geht auch). Nun wird der Inhalt der Zwischenablage in das aktuell aktive Fenster eingefügt.


Delphi-Quelltext
1:
2:
3:
4:
// virtuell STRG + V senden;
    keybd_event(86,0,KEYEVENTF_EXTENDEDKEY,MOD_CONTROL);
    // virtuell STRG + V loslassen;
    keybd_event(86,0,KEYEVENTF_KEYUP,MOD_CONTROL);


Soweit klappt alles.

Will ich aber auf z.B ALT + U (Tastenkombination soll frei deffinierbar sein) reagieren funktioniert das STRG + V nicht mehr.

In diesem Fall kommt eine Mischung aus der real (noch) betätigten ALT-Taste und der virtuell gesendeten STRG-Taste an.

Desshalb will ich vor dem

Delphi-Quelltext
1:
2:
// virtuell STRG + V senden;
    keybd_event(86,0,KEYEVENTF_EXTENDEDKEY,MOD_CONTROL);

darauf warten, daß keine Taste mehr gedrückt ist.

Ich könnte jetzt das 256Byte große Array von GetKeyboardState auswerten.
Aber das gestaltet sich etwas schwierig.

Wahrscheinlich gibts auch was ganz Einfaches.
Kennt jemand eine Lösung wie z.B. keypressed in alten Dos-Zeiten.


Vielen Dank im Voraus
Holger


ConditionZero - So 09.05.10 04:52

Moin,

user profile iconholger hat folgendes geschrieben Zum zitierten Posting springen:


Delphi-Quelltext
1:
2:
3:
4:
// virtuell STRG + V senden;
    keybd_event(86,0,KEYEVENTF_EXTENDEDKEY,MOD_CONTROL);
    // virtuell STRG + V loslassen;
    keybd_event(86,0,KEYEVENTF_KEYUP,MOD_CONTROL);


Du willst doch auf das KeyPressed-Ereignis eingehen, richtg? Wozu simulierst du dann Tastendrücke? :shock:
Der Benutzer soll doch dann später Hotkeys benutzen können, und auf die möchtest du gerade eingehen oder habe ich da jetzt was falsch verstanden?


user profile iconholger hat folgendes geschrieben Zum zitierten Posting springen:

Kennt jemand eine Lösung wie z.B. keypressed in alten Dos-Zeiten.


Du meinst dann die Keyboard-Events. Da gibt es einmal Form1.OnKeyDown, dann noch Form1.OnKeyUp und zu guter letzt Form1.OnKeyPressed. Der Name spricht ja für sich ;).
In allen drei Events gibts eine Variable Key vom Typ Char (außer im OnKeyPressed, da vom Typ Word). Durch eine simple if-Abfrage lässt sich da auf einzelne Tastendrücke und/oder Tastenkombinationen eingehen. Für Tasten wie Strg brauchst du die jeweiligen Suche in der Entwickler-Ecke VIRTUELLEN TASTENCODES.

Wenn ich mich recht erinnere liefert Delphi sogar ein Objekt THotkey mit, das könntest dir auch mal anschauen. Delphi-Hilfe kann da sicher helfen.



Grüße
ConditionZero


jaenicke - So 09.05.10 08:37

Das hast du falsch verstanden: Es geht nicht darum, dass innerhalb eines Fensters eines Delphiprogramms darauf reagiert wird sondern global, wenn die Tastenkombination gedrückt wird. Und dann soll das Delphiprogramm etwas machen und danach Strg + V simulieren um den Text in das aktuelle Programm einzufügen.

Und er möchte jetzt vorher warten bis die Tasten, die den mit RegisterHotkey eingetragenen Hotkey ausgelöst haben, wieder losgelassen sind. Dafür sollten GetKeyState [http://msdn.microsoft.com/en-us/library/ms646301.aspx] bzw. GetAsyncKeyState [http://msdn.microsoft.com/en-us/library/ms646293.aspx] die richtigen Funktionen sein.


ConditionZero - So 09.05.10 10:28

Ok, verstehe. Wobei mir noch immer ein Rätsel ist, warum mit den keybd_events ein Zwischenschritt eingelegt wird. Momentan ist: Strg+X wird gedrückt -> Event X wird ausgelöst, darin wird Strg+X im Programm geklickt -> Das OnKeyPressed-Event springt an. Könnte man doch auch direkt machen...)

Ansonsten gibts in der DL einen guten Thread dazu, dort wird mit ReigsterHotkey(); gearbeitet: http://www.delphi-library.de/topic_einen+Hotkey+global+verarbeiten_19371,0.html

Grüße
ConditionZero


jaenicke - So 09.05.10 10:44

user profile iconConditionZero hat folgendes geschrieben Zum zitierten Posting springen:
warum mit den keybd_events ein Zwischenschritt eingelegt wird
Das ist kein Zwischenschritt. Damit wird am Ende im Zielprogramm Strg + V simuliert um den Text aus der Zwischenablage dort einzufügen. Und genau das klappt nicht solange der aktuelle Hotkey noch auf der echten Tastatur gedrückt ist.

Das Delphiprogramm wird nie überhaupt sichtbar.


ConditionZero - So 09.05.10 14:48

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconConditionZero hat folgendes geschrieben Zum zitierten Posting springen:
warum mit den keybd_events ein Zwischenschritt eingelegt wird
Das ist kein Zwischenschritt. Damit wird am Ende im Zielprogramm Strg + V simuliert um den Text aus der Zwischenablage dort einzufügen. Und genau das klappt nicht solange der aktuelle Hotkey noch auf der echten Tastatur gedrückt ist.

Das Delphiprogramm wird nie überhaupt sichtbar.


Hoppla, da hät ich wohl doch erst denken sollen und dann schreiben. Vielleicht auch noch eine Portion gründlicher Lesen dazu... :roll:

Na dann ist ja doch alles rechtens ;)
Wobei man das wiederum je nach Situation auch mit .CopyToClipBoard und .PasteToClipBoard machen könnte, dann würde auch das Problem mit den aktiv gedrückten Tasten wegfallen.

@holger: Die Funktionen GetKeyState bzw. GetAsyncKeyState (//Edit: Ach, die Befehle hat jaenicke ja schon im Post oben genannt) könnten dir da helfen, bin aber gerade am arbeiten und habe keine Zeit dir den Code zu schreiben. Wahrscheinlich ist das bis heute Abend schon geschehen, falls nicht bekommste ihn wie ich dazu komm ;).


Grüße
ConditionZero


holger - So 09.05.10 19:21

Vielen Dank für euer Interesse.

Ich hinterlasse jetzt einfach mal das komplette aktuelle Projekt "CBT-ClipBoardTool" mit Quellcode und exe hier.

Will ja nicht immer nur Fragen stellen, sondern auch mal was nützliches tun :-)

Es ist nicht perfekt programmiert, aber trotzdem ein geniales Tool, wie ich denke.

Nach dem Start der Exe erscheint ein Icon in der Taskbar . . .

Das oben genannte Problem habe ich noch nicht beseitigt ( siehe procedure TForm1.StrgV(keyenable,autoinsert:boolean); )

Alles ander müsste funktionieren.

Eine Schöne Woche wünscht
Holger