![]() |
Programm soll Tastendruck in einem anderen Programm ausführen
Guten Tag,
kurz zum Hintergrund: Ich saß heute an meinem Tablet und las ein E-Book. Dabei Markiere ich fleißig mit meinem Windows Pen Stellen. Leider kommt es vor, dass man sehr häufig Markierungen entfernen muss. Etwas nervig ist bei PDF-Programmen, dass das "Undo" so klein ist, da man ja eher die Tastenkürzel verwendet. Aus diesem Grund kam mir die Idee, dass ich einfach eine Konsolenanwendung erstelle, die den Tastenkürzel durch das Klicken der Taste auf dem Stift (Man kann ein Programm auswählen, was dann gestartet wird), ausführt. So habe ich mich vorhin direkt hingesetzt und eine Konsolenanwendung erstellt. Leider hat er nicht die Tastenkürzel ausgegeben, so dachte ich mir, dass eventuell der Fokus auf das Programm gesetzt werden muss, bevor der Tastendruck simuliert wird. Jedoch auch dies hat nicht funktioniert. Es wird weder das Programm in den Vordergrund gerufen, der Fokus gesetzt oder der Tastendruck simuliert. Fehlermeldungen gibt es keine. Mein Code sieht so aktuell aus:
Delphi-Quellcode:
Was habe ich hierbei nicht beachtet?
program strg_z;
uses Winapi.Windows, System.SysUtils; {$R *.res} begin try SetForegroundWindow(Findwindow(nil, 'NitroPDF')); SetFocus(Findwindow(nil, 'NitroPDF')); keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), 0, 0); keybd_event(Ord('Z'), MapVirtualKey(Ord('Z'), 0), 0, 0); keybd_event(Ord('Z'), MapVirtualKey(Ord('Z'), 0), KEYEVENTF_KEYUP, 0); keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), KEYEVENTF_KEYUP, 0) except on E: Exception do Writeln(E.ClassName, 'Fehler: Fokus konnte nicht gesetzt werden.', E.Message); end; Exit; end. |
AW: Programm soll Tastendruck in einem anderen Programm ausführen
keybd_event sended natürlich an das Fenster, was den Fous hat. (bzw. genauer was die Keyboardevents gefangen hat ... meistens ist Beides das Gleiche, aber muß nicht)
Etwas warten (Sleep), nach dem Fokus-ändern? Kann ja sein es dauert ein bissl. Und hat dein Programm überhaupt das Recht den Fokus umzusetzen? Eventuell nicht, da es selber nicht den Fokus hat, weil es ja kein Fenster besitzt. ![]() PS: SendMessage/PostMessage der entsprechenden WM_KEY***, welche man an ein "bestimmtes" Fenster schicken kann. |
AW: Programm soll Tastendruck in einem anderen Programm ausführen
Um sicher zu gehen bin ich nun für das erste in VLC umgestiegen.
Ich habe das mit Sleep ausprobiert, leider ohne Erfolg. Ich bin also erstmal dann an die Prüfung gegangen, ob er überhaupt das Handle findet.
Delphi-Quellcode:
Habe es auch mit der Funktion IsWindow probiert. Beides zeigt mir die Nachricht an, dass es nicht gefunden wurde.
procedure TForm1.Button1Click(Sender: TObject);
var Handle: HWND; begin Handle := FindWindow('NitroPDF', nil); if handle <> 0 then ShowWindow(handle, SW_SHOW) else ShowMessage('Nicht gefunden'); end; Ich habe im Task-Manager aber nachgeschaut unter Details steht das PDF Programm aber unter "NitroPDF.exe". Also setzen die ersten Probleme überhaupt daran an, dass er gar nicht das Handle findet und somit auch nicht in den Vordergrund setzen kann. Gibt es hierfür Alternativen? |
AW: Programm soll Tastendruck in einem anderen Programm ausführen
Sicher...:!:
Syntax:
Delphi-Quellcode:
FindWindow(lpClassName: PChar; {a pointer to a null-terminated class name string}
lpWindowName: PChar {a pointer to a null-terminated window name string} ): HWND; {returns a handle to a window} |
AW: Programm soll Tastendruck in einem anderen Programm ausführen
Ich habe nun die Funktion "FindWindowByTitle" genommen, die ich hier gefunden habe:
![]() Leider musste ich das nun über eine VCL erledigen. Doch nun funktioniert es, wie ich es mir vorgestellt habe. Hier der Code dafür:
Delphi-Quellcode:
Ich muss aber sagen, dass ich die Lösung lieber über ein Konsolenprogramm erstellt hätte. Aber gut, durch die Eigenschaft Hide bemerkt man es so gut wie gar nicht, dass das ausgeführt wird.
function FindWindowByTitle(WindowTitle: string): Hwnd;
var NextHandle: Hwnd; NextTitle: array[0..260] of char; begin // Get the first window NextHandle := GetWindow(Application.Handle, GW_HWNDFIRST); while NextHandle > 0 do begin // retrieve its text GetWindowText(NextHandle, NextTitle, 255); if Pos(WindowTitle, StrPas(NextTitle)) <> 0 then begin Result := NextHandle; Exit; end else // Get the next window NextHandle := GetWindow(NextHandle, GW_HWNDNEXT); end; Result := 0; end; procedure TSTRG.FormCreate(Sender: TObject); var Handle:HWND; begin STRG.Hide; Handle := FindWindowByTitle('Nitro'); if handle <> 0 then begin SendMessage(handle,WM_SYSCOMMAND, SC_MAXIMIZE, 0); SetForegroundWindow(handle); end else showmessage('Fehler im Finden des Handles'); sleep(200); keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), 0, 0); keybd_event(Ord('Z'), MapVirtualKey(Ord('Z'), 0), 0, 0); keybd_event(Ord('Z'), MapVirtualKey(Ord('Z'), 0), KEYEVENTF_KEYUP, 0); keybd_event(VK_CONTROL, MapVirtualKey(VK_CONTROL, 0), KEYEVENTF_KEYUP, 0); Application.Terminate; end; Für weitere Empfehlungen oder Verbesserungsvorschläge bin ich offen! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:45 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz