AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi Programm soll Tastendruck in einem anderen Programm ausführen
Thema durchsuchen
Ansicht
Themen-Optionen

Programm soll Tastendruck in einem anderen Programm ausführen

Ein Thema von Asura · begonnen am 11. Mai 2020 · letzter Beitrag vom 11. Mai 2020
Antwort Antwort
Asura

Registriert seit: 10. Jun 2013
87 Beiträge
 
#1

Programm soll Tastendruck in einem anderen Programm ausführen

  Alt 11. Mai 2020, 12:32
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:
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.
Was habe ich hierbei nicht beachtet?

Geändert von Asura (11. Mai 2020 um 12:36 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.062 Beiträge
 
Delphi 12 Athens
 
#2

AW: Programm soll Tastendruck in einem anderen Programm ausführen

  Alt 11. Mai 2020, 14:14
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.
https://www.delphipraxis.net/203758-...ml#post1460199


PS: SendMessage/PostMessage der entsprechenden WM_KEY***,
welche man an ein "bestimmtes" Fenster schicken kann.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Asura

Registriert seit: 10. Jun 2013
87 Beiträge
 
#3

AW: Programm soll Tastendruck in einem anderen Programm ausführen

  Alt 11. Mai 2020, 18:16
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:
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;
Habe es auch mit der Funktion IsWindow probiert. Beides zeigt mir die Nachricht an, dass es nicht gefunden wurde.

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?
  Mit Zitat antworten Zitat
Benutzerbild von FriedrichAT
FriedrichAT

Registriert seit: 25. Mai 2019
Ort: Wien
30 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Programm soll Tastendruck in einem anderen Programm ausführen

  Alt 11. Mai 2020, 18:35
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}
Friedrich
  Mit Zitat antworten Zitat
Asura

Registriert seit: 10. Jun 2013
87 Beiträge
 
#5

AW: Programm soll Tastendruck in einem anderen Programm ausführen

  Alt 11. Mai 2020, 19:36
Ich habe nun die Funktion "FindWindowByTitle" genommen, die ich hier gefunden habe: https://www.swissdelphicenter.ch/en/showcode.php?id=327

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:
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;
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.

Für weitere Empfehlungen oder Verbesserungsvorschläge bin ich offen!
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:51 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