![]() |
Text an Eingabezeile schicken
Hallo Leute,
also ich hab ein bisschen gestöbert, aber nix Passendes gefunden. Mein Problem sieht so aus, dass ich einen (vordefinierten) Text an ein Spiel (sehr alt) schicken will. Wie ich gelesen habe, geht das mit SETTEXT oder so, aber ich weiß schonmal gar nicht, wie ich das handle dieser Eingabezeile herausbekomme, konnte dazu auch nichts Sinnvolles im Forum finden (kenne mich da kaum aus). Was ich gefunden habe, war die Funktion "FindWindow", aber dazu konnte ich in der Delphi-Hilfe nichts finden und auch hier im Forum nicht. In dieser Beziehung hab ich kaum Ahnung, also nicht hauen :zwinker: Liebe Grüße ... |
Re: Text an Eingabezeile schicken
FindWindow(nil,'Titel der oben im fenster drinsteht');
mach ich auch grad was mit... :wink: wie du die eingabezeile dann ansprichst...keine ahnung achso: findwindow gibt ein THandle zurück...also:
Delphi-Quellcode:
danach steht das handle der anwendung bzw des fensters in handle und du kannst damit arbeiten...
handle:THandle;
begin handle:=FindWindow(nil,'xyz'); |
Re: Text an Eingabezeile schicken
Hi,
Mit ![]() ![]() ![]() Das funktioniert aber nur, wenn der Text deines Spiels z.B. ein Static ist. Wird der Text direkt auf die Zeichenfläche des Hauptfensters gezeichnet, kannst du mit ![]() ![]() |
Re: Text an Eingabezeile schicken
Mein Kumpel meint, es sei die erste Variante.
Dazu also: Ich habe mit ![]() Wie ich mit EnumChildWindows umgehen kann, sagt mir die MSDN leider nicht wirklich. Ist das eine Funktion? Als was wird das Ergebnis gespeichert und wie kann ich darauf zugreifen? |
Re: Text an Eingabezeile schicken
Also ich bin echt am Verzweifeln. Hab mir 'ne Stunde lang im iNet und im DP-Forum Beiträge zu EnumChildWindows durchgelesen und bin kaum schlauer geworden. Von rekursivem Aufruf, Pointer und seltsamen functions hab ich was gelesen, aber das war so kompliziert, dass ich überhaupt nichts verstanden hab.
Ich will doch (vorerst) nur herausfinden, wie das handle einer Eingabezeile heißt :wiejetzt: :firejump: |
Re: Text an Eingabezeile schicken
Das geht wirklich einfach mit EnumChildWindows. Der Code könnte z.B. so aussehen:
Delphi-Quellcode:
//Diese funktion wird so lange von EnumChildWindows aufgerufen, bis sie FALSE zurück gibt.
function EnumTargetWindow(WindowHandle: HWND; lParam1: lParam): Boolean; stdcall; var buf: Pchar; dwSize: DWORD; chRect: TRect; begin Result := True; //Alle Fenster werden aufgelistet dwSize := 265; //Speicher für Klassenname reservieren buf := AllocMem(dwSize); //Klassenname des gefundenen Fensters speichern If GetClassName(WindowHandle, buf, dwSize)<>0 then //Wenn das Control ein "Static" ist... If buf='Static' then begin //Dessen Koordinaten in chRect speichern GetWindowRect(WindowHandle, chRect); ///... irgendetwas mit den ausgelesenen Daten tun end; //Allozierten Speicher freigeben FreeMem(buf, dwSize); end; procedure foo; var TargetWnd: HWND; begin TargetWnd := FindWindow('TForm1', nil); If TargetWnd <> 0 then begin EnumChildWindows(TargetWnd, @EnumTargetWindow, lParam(0)); end; end; |
Re: Text an Eingabezeile schicken
Wow, vielen Dank!
Aber er gibt mir diese Fehlermeldung zurück: "@EnumTargetWindow: Variable erforderlich" Da muss aber schon in der Deklaration stehen "From1.EnumTargetWindow(...)", oder? Und müssen nicht bei "FindWindow('TForm1', nil);" die beiden Werte vertauscht sein? |
Re: Text an Eingabezeile schicken
Zitat:
[size=3]PS: Mach in Methoden von TForm1 lieber "Self.Irgendwas" als "Form1.Irgendwas". Das ist wichtig, falls du Instanzen von TForm1 dynmisch erzeugen möchstest oder mal eine Klasse von TForm1 ableitest[/size] Die Reihenfolge bei FindWindow ist absicht. Man sollte eigentlich nicht (nur) nach dem Fenstertitel suchen, sondern falls möglich nach dem Klassennamen. Ist der Klassenname nicht eindeutig, wird's problematisch. Sich auf den Fenstertitel zu verlassen ist ein wenig riskant, da es ein paar Programme gibt, die den Fenstertitel des aktiven Fensters verändern, was dazu führen würde, dass dein Programm es nicht mehr findet :-/ |
Re: Text an Eingabezeile schicken
Das mit dem Pointer und so verstehe ich nicht wirklich, ist aber egal - hauptsache es funktioniert :angel2:
Wie kann ich denn die handles der ChildWindows auflisten lassen (Listbox1)? |
Re: Text an Eingabezeile schicken
Mit IntToStr :mrgreen:
Edit: Ist es normal, dass da ein Leerzeichen bei der Quelltext-Einrückung verschluckt wird?
Delphi-Quellcode:
function EnumTargetWindow(WindowHandle: HWND; lParam1: lParam): Boolean; stdcall;
begin Result := True; //Alle Fenster werden aufgelistet Form1.Listbox1.Items.Add(IntToStr(WindowHandle)); end; |
Re: Text an Eingabezeile schicken
Hm, da passiert nichts.
Ich habe mal den Windows Taschenrechner gestartet und es mit dem ausprobiert - ohne Ergebnis :-/ Es wird zwar ein handle gefunden, aber in der Listbox tut sich nix. [edit]Bei mir funktioniert das immer korrekt.[/edit] |
Re: Text an Eingabezeile schicken
Liste der Anhänge anzeigen (Anzahl: 1)
Das Projekt im Anhang funktioniert bei mir...
|
Re: Text an Eingabezeile schicken
Hm, ja, bei mir auch.
Also mit ...
Delphi-Quellcode:
Bekomme ich als Ergebnis: The 4th Coming:AppClass ... Rechner:SciCalc
var
wlist : TWindowList; begin wlist := TWindowList.Create; // Objekt erzeugen try wlist.AddClassname := True; // zusätzlich den Windows-Classname anfügen wlist.EnumTopLevelWindows; // Alle Windows auflisten ListBox1.Items.Assign(wlist); // Ergebnis in eine Listbox kopieren finally wlist.Free; end; end; Aber "handle:=FindWindow('AppClass',nil);" liefert wieder nichts :cat: Jetzt muss ich aber leider in 's Bett. Bin über 's WE nicht da, also nicht wundern. Aber ich hoffe, wir können das Prob Montag wieder bearbeiten ;-) |
Re: Text an Eingabezeile schicken
Wenn du TWindowList aus
![]()
Delphi-Quellcode:
function GetD4OHandle: HWND;
var wlist : TWindowList; idx: Integer; begin Result := 0; wlist := TWindowList.Create; try wlist.AddClassname := True; wlist.EnumTopLevelWindows; idx := wList.IndexOf('The 4th Coming:AppClass'); If idx <> -1 then Result := wlist.Handles[idx]; finally wlist.Free; end; end; |
Re: Text an Eingabezeile schicken
So, bin wieder da :witch:
Was ist denn das jetzt für eine Funktion? Ersetzt die die EnumTargetWindow-Funktion? Und wo gibt mir diese Function, wenn überhaupt, das handle für die Eingabezeile zurück? sry, wenn ich auf 'm Schlauch steh', aber ich steig echt nicht durch :duck: btw. woher weißt du, dass The 4th Coming das deutsche Die 4te Offenbarung ist? :gruebel: |
Re: Text an Eingabezeile schicken
Zitat:
"The 4th Coming:AppClass" ist nicht das Fenster, das du suchst, sondern der Taskbar Eintrag. Das gesuchte Fenster hat den Klassennamen "#32770" und den Titel "Die 4. Offenbarung". Daher:
Delphi-Quellcode:
//Findet das erste Edit Control im D4O Fenster und speichert das Handle in einer globalen Variable
var D4OEdit: HWND = 0; ... function EnumWindowCallback(WindowHandle: HWND; lParam1: lParam): Boolean; stdcall; var sClassName: array[0..255] of Char; begin Result := True; FillChar(sClassName[0], 256, 0); If GetClassName(WindowHandle, @sClassName, 256) <> 0 then If sClassName='Edit' then begin {Hier kannst du z.B prüfen, ob sich das Edit an einer bestimmten Position im Fenster befindet} D4OEdit := WindowHandle; Result := false; end; end; procedure FindD4OEdit; var D4OHandle: HWND; begin D4OHandle := FindWindow('#32770', 'Die 4. Offenbarung'); If D4OHandle <> 0 then begin EnumChildWindows(D4OHandle, @EnumWindowCallback, 0)); end else begin //D4O läuft nicht end; end; Zitat:
|
Re: Text an Eingabezeile schicken
*Total perplex*
Jetzt, tja, ähm, ich weiß nich' so genau :?:
Delphi-Quellcode:
... gibt immer die msg zurück, wenn das D4O Fenster geöffnet ist. Dazu muss die Eingabezeile gar nicht existieren (sprich: man muss nicht eingelogg sein), aber das wusstest du, denk ich mal :bouncing4:
begin
D4OEdit := WindowHandle; Result := false; showmessage('Result := false'); end; Jetzt müsste ich das/die handle(s) (alle) in eine Listbox eintragen oder per showmessage() anzeigen können, damit ich das richtige handle herauskriegen und dorthin einen Text schicken kann :coder: |
Re: Text an Eingabezeile schicken
Achso, ich dachte du willst dir einen Loader schreiben, der dich automatisch einlogt :stupid:
Du musst wohl die Koordinaten der Controls mitinander vergeichen, um herauszufinden, ob das richtige dabei ist. (-> ![]() |
Re: Text an Eingabezeile schicken
Oh, automatisch einloggen ist auch nicht schlecht *rofl* Danach wurde ich schon gefragt, hab 's aber als nicht möglich abgestempelt :dp: Aber das ist wohl ein anderes Thema (weil umfangreich).
Diese MSDN ist mir schleierhaft. Zitat:
Und dieser "Pointer to a structure" ... :freak: |
Re: Text an Eingabezeile schicken
Zitat:
Zitat:
![]() |
Re: Text an Eingabezeile schicken
Ich bin mit meinem Latein am Ende ...
Delphi-Hilfe:
Delphi-Quellcode:
Ich werd' noch bekloppt hier! :wall:
type
TRect = packed record case Integer of 0: (Left, Top, Right, Bottom: Integer); 1: (TopLeft, BottomRight: TPoint); end; |
Re: Text an Eingabezeile schicken
Ganz ruhig :)
in einem TRect kannst du einen rechteckigen Bereich speichern (-> Rectangle).Aber Vorsicht: GetWindowRect speichert laut Beschreibung die absoluten Koordinaten des Controls, nicht dessen relative Position zum Parent-Fenster... Wenn dir alles zu viel wird, beschreib doch mal was du genau machen willst und ich lass dir mal ein Delphi-Projekt zukommen... |
Re: Text an Eingabezeile schicken
Eigentlich find ich 's ziemlich ... doof, wenn du das für mich schreibst, aber mir fällt absolut nix besseres ein :cry:
Es ist so, dass die Nutzer meines Programmes die Möglichkeit haben sollen, einen (oder mehr) Sätze abspeichern zu können und diese per Makro oder Texteingabe aufrufen zu können; Beispiel: Strg+1 -> "Hallo, Welt!" bzw. "welt" -> "Hallo, Welt!". Dazu muss ich zu allererst wissen, wie das handle der Eingabezeile lautet. Alles weitere dürfte klar sein: Mit SETTEXT (?) soll dann Text in die Eingabezeile geschrieben werden. [edit]Nebenbei: "TRect.Create;" geht nicht. Muss ich ein Rect erst erzeugen? Oder wie kann ich damit arbeiten? im DP-Forum finde ich eigentlich nur Prozeduren, die das nutzen.[/edit] |
Re: Text an Eingabezeile schicken
Liste der Anhänge anzeigen (Anzahl: 1)
So, hab mir D4O mal runtergeladen...
das Chat-Eingabefeld ist kein Windows-Control und man kann daher auch den Text nicht mit SendMessage setzen. Was du höchstens machen könntest ist Tastaturanschläge zu simulieren. Schau dir mal das kleine Programm im Anhang an, da sind auch Komponenten dabei, mit denen du ganz einfach Tastatureingaben an ein Fenster senden kannst. Zitat:
|
Re: Text an Eingabezeile schicken
Das bringt mich gleich zum Heulen.
Zum einen funktioniert das Programm nicht, denn WComp.dcu fehlt in SysHot. Aber SendKeys sieht komplex aus. Da kommen mir schon die Tränen, wenn ich mir das durchlese. Hab jetzt aber doch ein bisschen herumprobiert und es geschafft, "b" von "bla" an den Editor zu senden. Wenn ich allerdings ein zweites "b(la)" schicke, kriege ich eine Access-Violation, nachdem das "b" geschickt wurde. Außerdem bekomme ich die Fehlermeldung, dass "SendKey1 möglicherweise nicht initialisiert" worden ist.
Delphi-Quellcode:
Die Violation tritt durch SendKey1.Keys auf, wie ich gerade herausgefunden hab. Alle anderen Zeilen funktionieren. Wenn ich "SendKey1.Keys:='bla';" weglasse, wird ein "t" gesandt ;-)
procedure TForm1.Button1Click(Sender: TObject);
var SendKey1:TSendKey; begin TSendKey.Create(SendKey1); SendKey1.Keys:='bla'; SendKey1.TitleText:='Unbenannt - Editor'; SendKey1.execute; end; |
Re: Text an Eingabezeile schicken
Delphi-Quellcode:
Vielleicht wäre es besser, wenn du vor diesem Projekt noch ein wenig Grundlagenforschung zum Thema OOP und Delphi-Language betreibst (Bücher...) :angel:
procedure TForm1.Button1Click(Sender: TObject);
var SendKey1:TSendKey; begin SendKey1 := TSendKey.Create(Self); try SendKey1.Keys:='bla'; SendKey1.TitleText:='Unbenannt - Editor'; SendKey1.execute; finally SendKey1.Free; end; end; |
Re: Text an Eingabezeile schicken
Boar, wir hatten OOP in der schule (letztes Jahr) und es war einfach nur Müll ;-)
Der Fehler war ... dumm von mir. Hab nicht nachgedacht, denn normalerweise kenn' ich die Technik(en) von regist, ini und StringList :coder: Das funktioniert jetzt also schonmal, zumindest mit dem Editor. Bei D4O funktioniert es irgendwie nicht. Ich habe es mit TitleText:='4';, TitleText:='Offenbarung'; und TitleText:='Coming'; probiert, hat aber alles keinen Erfolg gezeigt. Jetzt ist aber die Frage, wie ich Makros erstellen kann, sodass z.b. STRG+1 den Text "bla" erzeugt. Im Idealfall sollte es auch möglich sein, den Text "bla" auszugeben, sobald "bl" geschrieben wurde, aber das ist nicht so wichtig und sicher zu kompliziert. Natürlich müssen diese Makros aus D4O gestartet werden können, ohne dass mein eigenes Programm im Vordergrund bzw. fokusiert ist. [edit] Haha! Es macht sich alles! Also Shortcuts erstellen kann ich jetzt (quasi und improvisiviert) über eine HotKey-Komponente einen Shortcut erzeugen. Allerdings funktioniert das ja nicht global. Kann ich dazu einen ActionListener (Gibt 's das überhaupt? Das klingt einfach passend.) benutzen? [/edit] |
Re: Text an Eingabezeile schicken
Mit der Komponente aus SysHot.pas kannst du globale Hotkeys erzeugen. Du findest sie
![]() Damit würde ich zunächst mal schauen, welches Fenster während des Spiels den Fokus hat ( ![]() Die Eigenschaft TitleText kannst du leer lassen, prüfe lieber "manuell" mit GetForeGroundWindow, GetWindowText und GetWindowClassName, ob D4O im Vordergrund ist. Wenn du dennoch TitleText verwenden willst, denke daran, dass du hier den *exakten* Fenstertitel eingeben musst, nicht nur einen Teilstring. |
Re: Text an Eingabezeile schicken
Ok, das ist ... kompliziert. Ich werde nicht ganz schlau aus der .pas bzw. dem Beispielprogramm (welches sich nicht starten lässt).
Die Funktion AddHotKey(VirtKey: TVirtKey; Modifiers: THKModifiers) kommt mir Spanisch vor. Ich kann zum Beispiel Alt+F5 regisitrieren (AddHotKey(vkF5, [hkAlt])), aber wo wird denn angegeben, wofür Alt+F5 stehen soll? Dann gibt 's da auch noch die Funktionen "HotKeyItem" und "KeyToVirtKey", von denen ich nicht weiß, ob ich die irgendwie brauche :pale: |
Re: Text an Eingabezeile schicken
Liste der Anhänge anzeigen (Anzahl: 1)
Die Komponente TSyshotKey erzeugt einen Event OnHotKey, wenn einer der registrierten Hotkeys gedrückt wurde. Du kannst durch einen Index überprüfen, welcher der Hotkeys es war. In den Anhang findest du die fehlende WComp.pas, habbisch vergessen in das Archiv zu packen :oops:
Damit sollte sich das Programm starten lassen! Du musst nur die Units Sendkeys.pas, SysHot.pas und WComp.pas in das LIB-Verzeichnis (oder irgendein Verzeichnis das in der Bibliothek eingetragen ist) kopieren. |
Re: Text an Eingabezeile schicken
Gut, ähm, dann stellt sich die Frage, wie OnHotKey zu deklarieren ist. Es ist keine procedure, also fällt "procedure (T)SysHot.OnHotKey();" weg. "SysHotKey.OnHotKey:=procedure1" geht auch nicht, genauso wenig wie "SysHotKey.OnHotKey:=Button2Click(Sender);".
Diese Möglichkeiten kenne ich und die haben bis jetzt auch immer gereicht. Wie muss ich das denn aufrufen? :?: btw: ist echt schade, dass es dazu noch nix anderes im Forum gibt (OnHotKey). Habe nur einen Thread gefunden, in dem jemand die Möglichkeit anbot, F-Tasten auf Buttons zu legen, aber ich brauche auch STRG etc. :cyclops: |
Re: Text an Eingabezeile schicken
Joah... TSyshotKey ist eine plazierbare nicht-visuelle Komponente, du musst sie nur installieren :)
|
Re: Text an Eingabezeile schicken
Also ich hab die Komponente installiert, indem ich ...
Komponente -> Neue Komponente -> Vorfahrtyp=TCustomHotKey [ComCtrls] -> KlassenName=SysHotKey -> (Palettenseite=Beispiele) -> Name der Unit=SysHotKey.pas Aber es tritt immer noch der selbe Fehler auf. [edit]Ich bin doof. Hab vergessen, die Komponente zu platzieren ;D Aber was mache ich jetzt damit? Die hat keine Ereignis-Methoden und keine sinnvollen Eigenschaften :-/[/edit] [edit2]Interessant wäre auch die Möglichkeit, "Enter" an die Anwendung zu schicken. "SendKey1.Keys:=vk_return;" geht nicht, weil vk_return ein Integer ist. Oder soll ich doch (später) die Buttons des Clients herausfinden und dann einen Schalter "drücken"?[/edit2] |
Re: Text an Eingabezeile schicken
Komponenten installierst du so:
Komponente -> Komponente installieren -> in neues Package die Taste Enter kannst du entweder mit #13 oder als '[enter]' senden. |
Re: Text an Eingabezeile schicken
Ok, die Komponente ist installiert, zumindest in der Palette verfügbar, aber was fange ich jetzt damit an?
Langsam fühle ich mich echt scheiße :-/ Ah ja,
Delphi-Quellcode:
... funktioniert sehr schön, allerdings kann ich das nicht zwei Mal hintereinander ausführen (hat jedenfalls keinen Effekt). Auch mit einer Delay dazwischen (500=500ms?) kann ich keinen Effekt erzielen. Eigentlich hat Delay überhaupt keinen Effekt, nichtmal bei 5000.
SendKey1.Keys:=#13;
SendKey1.TitleText:='Offenbarung'; SendKey1.execute; Ich könnte aber einen Timer einbauen! *kniffel* [edit]Mit einem Timer gelöst. Aber wozu ist dann die Delay-Funktion? :idea: [/edit] |
Re: Text an Eingabezeile schicken
Hm, Dani, kannst du mir noch bei dem GlobalHotKey helfen? Dann hätte ich 's eigentlich schon fast geschafft :drunken:
|
Re: Text an Eingabezeile schicken
Joah, mal schauen...
- Deine SysHotKey Komponente auf dem Formular platzieren (Active = true). - Im OnHotKey Event der Komponente deinen Code einfügen. - Im OnCreate des Formulars einen Hotkey hinzufügen
Delphi-Quellcode:
- Compilieren
SysHotKey1.AddHotKey(vkB, [hkAlt, hkCtrl]);
|
Re: Text an Eingabezeile schicken
Ich hab die HotKey-Komponente platziert, aber die hat keine Events und auch keine Active-Eigenschaft. Hab ich die vielleicht falsch installiert?
[edit]Ich antworte zu schnell. Hab 's nochmal neu installiert und jetzt geht 's. Ich werde morgen daran rumschrauben ;-) Na ja, aber ein OnHotKey gibt 's nicht. Ich sehe nur OnChange, OnContextPopUp, OnEnter, OnExit, OnMouseDown/Up/Move, PopupMenu.[/edit] |
Re: Text an Eingabezeile schicken
Gibt es eine Möglichkeit, "SendKey1.TitleText:='Offenbarung';" so zu umgehen, dass ich da ein Handle reinschreiben kann? Mir ist aufgefallen, dass es vorkommen kann, dass mehr als eine Anwendung mit dem selben Titil gestartet ist. Das Handle kriege ich ja recht unkompliziert mit "GetForegroundWindow".
|
Re: Text an Eingabezeile schicken
Du musst die Eigenschaft TitleText nicht ausfüllen. Lass sie leer, dann wird der Text an das Fenster geschickt, das aktuell den Fokus hat.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:13 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