![]() |
Tastaturkommandos an ein Handle senden (Remote)
Hallo,
ich verwende eine externe Anwendung. Diese Anwendung kann ich per Tastatur bedienen. Nun möchte ich dieses gerne automatisieren. Ich habe ich hier im Forum code gefunden um mir das Handle der Anwendung zu holen. Klappt gut. Meine Frage ist wie ich die Tastaturcodes an dieses Handle schicke. Für einen Tipp oder ein Stück Code wär ich schon sehr dankbar. :-) Gruß Holger. :gruebel: |
Re: Tastaturkommandos an ein Handle senden (Remote)
hallo,
ich habe im Forum den Tipp auf SendMessages gefunden Aber mit folgendem
Delphi-Quellcode:
klappt es nicht.
SendMessage(
extProgHandle, // Handle des externen Programmes 82, // KeyCode von "ALT+R" 0, // Erster Parameter 0 // Zweiter Parameter ); Der Compiler meckert nicht, aber meine Anwendung reagiert auch nicht. Was mach ich denn da falsch? :gruebel: |
Re: Tastaturkommandos an ein Handle senden (Remote)
der zweite parameter lautet WM_CHAR. im dritten parameter uebergibst du dann deinen key.
siehe msdn: ![]() //edit was du als message uebergeben hast war WM_TCARD ;) |
Re: Tastaturkommandos an ein Handle senden (Remote)
Danke,
kann es leider erst morgen früh testen. |
Re: Tastaturkommandos an ein Handle senden (Remote)
Hallo,
habe den Tipp von 1234588 ausprobiert. Klappt nicht. Ich poste hier noch mal meinen Code. Vielleicht klappt ja auch die Handle-Ermittlung nicht ... ? ...
Delphi-Quellcode:
Vielleicht hat ja noch jemand einen Tipp für mich.
var frm_main: Tfrm_main;
extProgHandle: THandle; ... function GetProcessID(Exename: string): DWORD; var hProcSnap: THandle; pe32: TProcessEntry32; begin result := 0; hProcSnap := CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS, 0); if hProcSnap <> INVALID_HANDLE_VALUE then begin pe32.dwSize := SizeOf(ProcessEntry32); if Process32First(hProcSnap, pe32) = true then begin while Process32Next(hProcSnap, pe32) = true do begin if pos(Exename, pe32.szExeFile) <> 0 then result := pe32.th32ProcessID; end; end; CloseHandle(hProcSnap); end; end; function GetProcessHandleFromID(ID: DWORD): THandle; begin result := OpenProcess(SYNCHRONIZE, False, ID); CloseHandle(result); end; ... procedure Tfrm_main.btn_getHandleClick(Sender: TObject); begin extProgHandle := GetProcessHandleFromID(GetProcessID('WINFx4.exe')); if extProgHandle = 0 then begin Label1.Caption := 'Fx4 läuft nicht'; btn_sendKey.enabled := false; end else begin Label1.Caption := 'Fx4 läuft'; btn_sendKey.enabled := true; end; Application.HandleMessage; end; procedure Tfrm_main.btn_sendKeyClick(Sender: TObject); begin SendMessage (extProgHandle, // Handle des externen Programmes WM_CHAR, // Übergabe = Keycode 68, // KeyCode von "ALT+D" (DateiMenü) 0 // Dritter Parameter ); end; :gruebel: |
Re: Tastaturkommandos an ein Handle senden (Remote)
ich weiß zwar nicht obs stimmt, aber versuch es mal mit dem Windowhandle. Ich glaube mit dem Processhandle klappt da snicht so ganz...
|
Re: Tastaturkommandos an ein Handle senden (Remote)
Hallo,
ich habe jetzt das Windows Handle verwendet. Hier der Code:
Delphi-Quellcode:
Aber es klappt trotzdem nicht.
const sWinFinkExe : string = 'WINFx4.exe';
var frm_main : Tfrm_main; extWindowsHandle : THandle; ... function GetWindowThreadProcessId(hWnd: HWND; var dwProcessId: DWORD): DWORD; stdcall; external 'user32.dll' name 'GetWindowThreadProcessId'; function MyEnumWindowProc(AHandle: THandle; LParam: LongWord): boolean; stdcall; var ProcessID: THandle; begin ProcessID := 0; GetWindowThreadProcessID(AHandle, ProcessID); Result := not (ProcessID = LParam); if not Result then extWindowsHandle := AHandle; end; function GetWindowHandleByExeName(const AExeName: string): THandle; var SnapShot: THandle; p: TProcessEntry32; ProcessHandle: THandle; begin extWindowsHandle := 0; ProcessHandle := 0; p.dwSize := SizeOf(p); SnapShot := CreateToolhelp32Snapshot(TH32CS_SnapProcess, 0); try if Process32First(SnapShot, p) then repeat if AnsiLowerCase(AExeName) = AnsiLowerCase(p.szExeFile) then ProcessHandle := p.th32ProcessID; until (ProcessHandle <> 0) or not Process32Next(SnapShot, p); EnumWindows(@MyEnumWindowProc, ProcessHandle); Result := extWindowsHandle; finally CloseHandle(SnapShot); end; end; ... procedure Tfrm_main.btn_sendKeyClick(Sender: TObject); var iSendKeyCode : integer; begin extWindowsHandle := GetWindowHandleByExeName(sWinFx4Exe); iSendKeyCode:= 68; SendMessage (extWindowsHandle, // Handle des externen Programmes WM_CHAR, // Übergabe = Keycode 68, // KeyCode von "ALT+D" (DateiMenü) 0 // Dritter Parameter ); end; Ich habe den KeyCode schon mal über eine Schleife höchzählen lassen (0-255) falls mein KeyCode falsch sein sollte aber meine externe Anwendung reagiert nicht. Im Forum habe ich gelesen das es statt über "SendMessage" auch über "PostMessage" gehen soll.?.? Leider kenne ich den Unterschied nicht. Vielleicht hat ja noch jemand eine Idee für mich. :gruebel: |
Re: Tastaturkommandos an ein Handle senden (Remote)
Hallo,
guter Tipp "PostMessage" zu verwenden. Mit folgendem Code kann ich meine Anwendung ereichen und das Menü bedienen.
Delphi-Quellcode:
So weit, so gut.
PostMessage (extWindowsHandle, // Handle des externen Programmes
WM_CHAR, // Übergabe = Keycode iSendKeyCode, // KeyCode 0 // Dritter Parameter ); Dazu nun zwei Fragen: A: Mit dem code kann ich nit "normale" Tasten abschicken. Aber wie schicke ich den beispielsweise ein ALT + F8 oder ein STRG + B? In der Hilfe (F1) zu WM_CHAR steht ich muss den dritten Parameter auf 24 setzen, aber das bringt mich nicht nach vorne... B: Nun komme ich an meinem Eingabefeld an. Der Inhalt wird markiert aber ich kann den Inhalt nicht ändern. Warum nicht? Klappt WM_CHAR nicht für EDIT-Felder? :gruebel: |
Re: Tastaturkommandos an ein Handle senden (Remote)
Hallo,
habe hier im Forum Code gefunden zum setzen von Editfeldern. Aber er trägt mir nichts ein...
Delphi-Quellcode:
Ich bin mir nicht wirklich sicher ob ich die Umwandllung in "Buffer " brauche
procedure Tfrm_main.btn_setTextClick(Sender: TObject);
var sEditValue : string; Buffer : array of Char; ix, iMax : integer; begin sEditValue := ed_text.text; // Text aus dem Edit lesen iMax := length(sEditValue); // Länge ermitteln setlength(Buffer, iMax); // Array setzen for ix := 1 to iMax do Buffer[ix - 1] := sEditValue[ix]; // Array füllen // PostMessage(extWindowsHandle, WM_SETTEXT, iMax, Integer(@Buffer)); // Text auf das Handle schreiben SendMessage(extWindowsHandle, WM_SETTEXT, iMax, Integer(@Buffer)); // Text auf das Handle schreiben oder ob ein String schon automatisch als Array of Char angesehen wird ... Tipps? Vorschläge? :gruebel: |
Re: Tastaturkommandos an ein Handle senden (Remote)
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Holger,
Du kannst die Sendkey.pas benutzen, einfach als in das Projekt aufnehmen, da brauchst Du nur das Fensterhandle, der Rest geht super. Einfach mal reinschauen. Gruß Franz |
Re: Tastaturkommandos an ein Handle senden (Remote)
Ich hab nur ne kleine Bemerkung zu deiner Verwendung von GetWindowThreadProcessID(): Soviel ich weiß darfst du nicht die Variable direkt übergeben, sondern musst die Adresse der Variable übergeben:
Delphi-Quellcode:
GetWindowThreadProcessID(AHandle, @ProcessID);
|
Re: Tastaturkommandos an ein Handle senden (Remote)
Hallo.
@wotan98: Wenn ich die Adresse angebe bekomme ich einen Fehler vom Compiler [Fehler] main.pas(62): Die Typen der tatsächlichen und formalen Var-Parameter müssen übereinstimmen @Franz Kogler: Danke für die Unit. Wenn ich es wie folgt aufrufe, bekomme ich immer eine Exeption "Zugriffsverletzung" ...
Delphi-Quellcode:
Könnte ich eventuell noch einen Tipp zur Verwendung bekommen?
procedure Tfrm_main.btn_setTextClick(Sender: TObject);
var sEditValue : string; sendKeyBlock : TSendKeys; begin sEditValue := ed_text.text; sendKeyBlock.WindowHandle := extWindowsHandle; sendKeyBlock.SendKeys(Pchar(sEditValue)); <- Hier wird die Exeption ausgelöst ... |
Re: Tastaturkommandos an ein Handle senden (Remote)
Zitat:
|
Re: Tastaturkommandos an ein Handle senden (Remote)
Wenn ich die Adresse übergebe, muss die Variable ProcessID eine LongWord-Variable sein. Ich wusste nicht, dass Delphi es einem wieder so komfortabel macht :-D . Da ist es natürlich besser einfach nur die Variable zu übergeben.
|
Re: Tastaturkommandos an ein Handle senden (Remote)
Hallo,
ich habe es nun mal probiert mit "AttachThreadInput" (Hab ich im Forum gefunden)
Delphi-Quellcode:
Aber der Erfolg will sich nicht einstellen ...
procedure Tfrm_main.btn_setTextClick(Sender: TObject);
var sEditValue : string; begin sEditValue := ed_text.text; // Einloggen AttachThreadInput( Application.Handle, extWindowsHandle, true ); // Text zum Objektes schreiben PostMessage(extWindowsHandle, WM_SETTEXT, 0, Integer(Pchar(sEditValue))); // Auslogen AttachThreadInput( Application.Handle, extWindowsHandle, false ); end; :gruebel: |
Re: Tastaturkommandos an ein Handle senden (Remote)
Es ist wichtig, dass das Window, welches den Tastendruck empfängt, den Focus hat! Deswegen kannst du dein altes Script mit Sendmessage verwenden, aber du musst noch den focus setzen:
Delphi-Quellcode:
Du musst aber auch das richtige ChildWindow haben :-D .
sendmessage(extWindowHandle,WM_SetFocus,0,0);
sendmessage(extWindowHandle,WM_Char,iSendKeyCode,0); |
Re: Tastaturkommandos an ein Handle senden (Remote)
Das Senden der Taste klappt ja, nur das Senden von Text nicht.
Aber da es ein anderes Thema ist mache ich dafür einen neuen Thread auf. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:34 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