Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Tastendruck simulieren, Problem mit registerhotkey+sendinput (https://www.delphipraxis.net/37028-tastendruck-simulieren-problem-mit-registerhotkey-sendinput.html)

Keldorn 29. Dez 2004 20:44


Tastendruck simulieren, Problem mit registerhotkey+sendinput
 
Hallo

ich habe ein kleines Problem: ich möchte per Tastenkombination alt oder control + F-Taste jeweils bestimmte Zeichenfolgen an ein anderes Programm senden. zum herausfinden des Drücken der F-Tasten habe ich Registerhotkey und zum Senden der Zeichenfolgen Sendinput verwendet. Einzeln geht das ja recht prima, nur zusammen nicht. Die Alt-Taste ist beim Hotkey bereits gedrückt und beim Fremdprogramm kommt dann nichts an. Ich habe schon versucht, die Alt-Taste per Sendinput wieder "loszulassen", das funktioniert aber nur bedingt (das Erste zu sendendes Zeichen wird verschluckt und man muß die Alt-Taste erstmal wieder loslassen, bevor per Hotkey wieder eine Aktion ausgelöst werden kann)

Hat jemand eine Idee, wie ich das lösen kann?

Danke Frank

jensw_2000 29. Dez 2004 22:24

Re: Tastendruck simulieren, Problem mit registerhotkey+sendi
 
Das Problem hatte ich auch mal ...

So funktioniert es bei mir:

Im Eventhandler des Hotkeys folgenden Code einfügen
Code:
  // Hotkey wurde gedrückt und erkannt,
  // Jetzt warten bis alle Tasten losgelassen werden, die den Shiftstate beeinflussen ...

  While NOT ((GetASYNCKeyState (VK_LSHIFT) = 0) AND
        (GetASYNCKeyState (VK_RSHIFT) = 0) AND
        (GetASYNCKeyState (VK_LSHIFT) = 0) AND
        (GetASYNCKeyState (VK_RCONTROL) = 0) AND
        (GetASYNCKeyState (VK_RCONTROL) = 0) AND
        (GetASYNCKeyState (VK_LMENU) = 0) AND
        (GetASYNCKeyState (VK_RMENU) = 0)) do
  begin
     Application.ProcessMessages;
  end;

  // Jetzt eigene Tastenkombination an das aktive Control senden ...
  // in meinem Beispiel STRG+C zum Kopieren des markierten Textes in die Zwischenablage ...

  keybd_event(VK_CONTROL, 0, 0, 0);
  keybd_event(Ord('C'), 0, 0, 0);
  keybd_event(Ord('C'), 0, KEYEVENTF_KEYUP, 0);
  keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
  sleep(20);

Schöne Grüße,
Jens
:hi:

Keldorn 30. Dez 2004 17:13

Re: Tastendruck simulieren, Problem mit registerhotkey+sendi
 
Danke, auch ne Variante. aber trotzdem etwas unnatürlich, da die Control-taste erstlosgelassen werden muß. Wenn du strg+C und Strg+V verwendest, mußt du die strg-taste ja auch nicht loslassen ;)
noch ne andere Idee?

Mfg Frank

jensw_2000 31. Dez 2004 00:46

Re: Tastendruck simulieren, Problem mit registerhotkey+sendi
 
Das Problem ist nicht die Ctrl Taste :gruebel: .

Wenn dein Hotkey z.B. Alt+F12 ist und im Eventhandler des Hotkeys z.B ein Ctrl+C gesendet werden soll,
dann musst das Program vor dem Senden des CTRL+C warten das die ALT Taste losgelassen wurde ...
Sonst sendest du ungewollt CTRL+ALT+F12 und nix passiert ...

Da der User bei mir seinen "globalen Hotkey" selbst wählen darf, lasse ich mein Prog warten bis ALT, ALTGR, linke+rechte CTRL sowie linke+rechte Shifttaste losgelassen wurden ...

Seitdem gibts keine Probleme mehr beim Senden von CTRL+C :mrgreen:

Cicaro 9. Mär 2010 21:24

Re: Tastendruck simulieren, Problem mit registerhotkey+sendi
 
Hallo, ich experimentiere auch mit diesen Events herum. Allerdings hab ich das Problem, dass mir die rechte Shift-Taste nicht losgelassen wird, nachdem ich folgenden Code ausführe:
Delphi-Quellcode:
keybd_event(VK_RSHIFT, 0, 0, 0);
keybd_event(VK_DOWN, 0, 0, 0);
keybd_event(VK_DOWN, 0, KEYEVENTF_KEYUP, 0);
keybd_event(VK_RSHIFT, 0, KEYEVENTF_KEYUP, 0); // <- sollte eigentlich losgelassen werden
Also Sinn ist es eine Zeile zu markieren. Sie wird zwar markiert aber die Shift-Taste wird immer noch "festgehalten". Und die linke Shift-Taste funktioniert irgendwie nicht mit diesen 4 Zeilen Code.

Weiß jemand, wo der Fehler liegt ?

Nachtrag:
Delphi-Quellcode:
keybd_event(VK_RSHIFT, 0, 0, 0); // Funktioniert wie erwartet. Shift-Taste wird gedrückt gehalten.
Delphi-Quellcode:
keybd_event(VK_RSHIFT, 0, 0, 0);
keybd_event(VK_RSHIFT, 0, KEYEVENTF_KEYUP, 0); // Funktioniert ebenfalls wie (theoretisch) erwartet. Shift-Taste ist losgelassen.
Warum funktioniert das Loslassen nicht, wenn dazwischen andere Tasten gedrückt wurden ?

jensw_2000 9. Mär 2010 22:30

Re: Tastendruck simulieren, Problem mit registerhotkey+sendi
 
Also bei mir funktioniert es so ...


Delphi-Quellcode:
 
  // Cursor links in der Zeile positionieren (CTRL + LEFT)
  keybd_event(VK_LCONTROL, 0, 0, 0);
  keybd_event(VK_LEFT, 0, 0, 0);
  // Shortcurt [CTRL + LEFT] aufheben
  keybd_event(VK_LEFT, 0, KEYEVENTF_KEYUP, 0);
  keybd_event(VK_LCONTROL, 0, KEYEVENTF_KEYUP, 0);

  // Text ab Cursorposition bis zum Ende der markieren (LSHIFT + END)
  keybd_event(VK_LSHIFT, 0, 0, 0);
  keybd_event(VK_END, 0, 0, 0);
  // Shortcurt [LSHIFT + END] aufheben
  keybd_event(VK_END, 0, KEYEVENTF_KEYUP, 0);
  keybd_event(VK_LSHIFT, 0, KEYEVENTF_KEYUP, 0);
Vorher solltest du warten, bis alle Tasten des Hotkeys losgelassen wurden. S.o.


MFG
Jens

Cicaro 9. Mär 2010 23:07

Re: Tastendruck simulieren, Problem mit registerhotkey+sendi
 
Zitat:

Zitat von jensw_2000
Also bei mir funktioniert es [...]

Bist du sicher ? Ich hab meine Events zum Testen direkt an den Delphi Editor gesendet und es funktionierte nie so, wie es theoretisch sollte. Und wenn du genauer hinschaust, kannst du sehen, dass sich unsere Codestücke gar nicht so sehr (bis auf die gewählten Tasten) unterscheiden. Ich fürchte keybd_event() ist etwas fehlerhaft (Microsoft hat sie auch mittlerweile durch SendInput() ersetzt http://msdn.microsoft.com/en-us/library/ms646304(VS.85).aspx).

Ich hab mir gerade SendInput() angeschaut und die Funktion funktioniert, wie sie soll. Ist etwas umständlicher dafür aber (so weit) fehlerfrei.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:35 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