![]() |
ClassName von Edit
Hallo Zusammen,
ich versuche gerade auf ein anderes Programm zuzugreifen und habe da meine Schwierigkeiten...
Delphi-Quellcode:
var
fwnd: THandle; wnd: HWND; wnd_edit: HWND; CName: array [0..255] of Char; begin fwnd := FindWindow(nil, 'Das andere Programm'); GetClassName(fWND, CName, 256); wnd := FindWindowEx(wnd, 0, CName, nil); wnd := FindWindowEx(wnd, 0, CName, nil); wnd := FindWindowEx(wnd, 0, CName, nil); wnd := FindWindowEx(wnd, 0, CName, 'Empfänger'); //Bis hierhin passt es. Der ClassName der App ist 'WindowsForms10.Window.8.app.0.141b42a_r6_ad1' wnd_edit := FindControlByNumber(wnd, 'WindowsForms10.EDIT.app.0.141b42a_r6_ad1', 1); //Wenn ich jetzt aber auf das Edit zugreifen möchte, muss ich den ClassName ändern if wnd_edit<>0 then SendMessage(wnd_edit,WM_SETTEXT,0,Integer(Pchar(Edit_HausNr.Text))); //Wenn ich das händisch mach geht das. //wnd_edit:= FindControlByNumber(FindWindow(CName, nil),'Edit', 1) ///Das klappt nicht, dann wird wnd_edit=0 end; Das Problem ist, dass ich das Edit mit der ControllNr finde:
Delphi-Quellcode:
Dafür brauche ich den ClassName. Der ändert sich aber:
function TTMSForm2.FindControlByNumber(hApp: HWND; ClassName: string; ControlNr: Word = 1): HWND;
var i: Word; hControl: HWND; begin Result := 0; if IsWindow(hApp) then begin Dec(ControlNr); hControl := 0; for i := 0 to ControlNr do begin hControl := FindWindowEx(hApp, hControl, PChar(ClassName), nil); if hControl = 0 then Exit; end; end; Result := hControl; end; Von der App : WindowsForms10.Window.8.app.0.141b42a_r6_ad1 Von dem Edit : WindowsForms10.EDIT.app.0.141b42a_r6_ad1 Ich glaube nicht, dass es sinnvoll ist, den ClassName "händisch" zu ändern. Wenn die App auf einem anderen Rechner läuft, wird es nicht mehr klappen. Kann mir jemand einen Tip geben, wie ich das hinbekomme? Vielen Dank Patrick |
AW: ClassName von Edit
Ändert sich auch die Caption andauernd?
Wenn beides dynamisch ist, würde ich über PID ein Handle ermitteln. Ist Control-ID auch dynamisch muss man sich durch alle Childs durchiterieren. |
AW: ClassName von Edit
Das Problem ist, dass das Edit kein Caption hat...
Was meinst Du mit PID? |
AW: ClassName von Edit
Ich meinte Caption vom Ziel-Fenster.
PID = ProcessID |
AW: ClassName von Edit
Andersrum, wenn ich was Fernsteuern mag, schau ich mir mit WinSpy ö.ä. erstmal das Ziel an.
Wenn ich darüber eine feste Control-Id bekomme für das Edit ist die halbe Miete schon im Sack. Dann nurnoch eine Möglichkeit finden mich mit dem Ziel zu verbinden. Also per FindWindow() ein Handle holen. Vom Fenster, nicht vom Edit! Wenn das nicht möglich ist halt über die ProcessID. Dann zum Beispiel sowas machen
Code:
Um text zu ändern.
SendMessage(GetDlgItem(dasHandle, dieControlID), WM_SETTEXT, 0, Integer(PChar('neuer Text')));
|
AW: ClassName von Edit
Liste der Anhänge anzeigen (Anzahl: 1)
Am Ende ist das mein Problem: Der ClassName ändert sich...
Ich hatte folgendes probiert, aber damit komme ich nicht weiter:
Delphi-Quellcode:
Ich wollte einfach mal sehen, welche ID's er findet - leider immer 0.
fwnd := FindWindow(nil, 'WmD_VersandLabel');
GetClassName(fWND, CName, 256); wnd := FindWindowEx(wnd, 0, CName, nil); wnd := FindWindowEx(wnd, 0, CName, nil); wnd := FindWindowEx(wnd, 0, CName, nil); wnd := FindWindowEx(wnd, 0, CName, 'Empfänger'); for I := 0 to 50 do begin wnd_edit:= GetDlgItem(wnd, I); end; Ich habe mal den Tree in den Anhang gestellt, vielleicht gibt das ja Aufschluss... An die Edits von Empfänger möchte ich ran... Vielen Dank Patrick |
AW: ClassName von Edit
Zitat:
Wenn du meinen vorschlag von oben folgst, ist classname oder handle dank GetDlgItem() überflüssig. |
AW: ClassName von Edit
Zitat:
Ein 0 bis 50 durchiterieren bringt da nichts. |
AW: ClassName von Edit
Zitat:
Ich habe es jetzt so versucht:
Delphi-Quellcode:
wnd hat dann des Wert von Empfänger (263610)
fwnd: THandle;
wnd: HWND; wnd_edit: HWND; CName: array [0..255] of Char; I: integer; begin fwnd := FindWindow(nil, 'WmD_VersandLabel'); GetClassName(fWND, CName, 256); wnd := FindWindowEx(fwnd, 0, CName, nil); wnd := FindWindowEx(wnd, 0, CName, nil); wnd := FindWindowEx(wnd, 0, CName, 'Empfänger'); SendMessage(GetDlgItem(fwnd, 5), WM_SETTEXT, 0, Integer(PChar(Edit_Strasse_E.Text))); Dort liegen auf die Felder an die ich möchte. Aber leider ändert sich ja dann der ClassName von WindowsForms10.Window.8.app.0.141b42a_r6_ad1 nach WindowsForms10.EDIT.app.0.141b42a_r6_ad1 Ich habe mal geguckt, was er mit
Delphi-Quellcode:
zurückliefert - leider immer nur eine 0.
GetDlgItem(fwnd, 5)
Irgendwie habe ich es noch nicht geblickt... |
AW: ClassName von Edit
Ist das eine .NET-Exe? Die Klassennamen lassen zumindest darauf schließen. Ich bin da kein Experte, aber bist Du sicher, dass sich das Ding einfach so fernsteuern lässt?
|
AW: ClassName von Edit
Zitat:
Delphi-Quellcode:
Das einzige Problem ist, dass es nur auf der Entwicklungsmaschine läuft, aber auf anderen nicht. Das liegt daran, dass sich der ClassName (WindowsForms10.EDIT.app.0.141b42a_r6_ad1) von Maschine zu Maschine ändern kann.
procedure TTMSForm2.AdvGlowButton1Click(Sender: TObject);
var wnd: HWND; wnd_edit: HWND; begin wnd := FindWindow('WindowsForms10.Window.8.app.0.141b42a_r6_ad1', 'AndereAppName'); wnd := FindWindowEx(wnd, 0, 'WindowsForms10.Window.8.app.0.141b42a_r6_ad1', nil); wnd := FindWindowEx(wnd, 0, 'WindowsForms10.Window.8.app.0.141b42a_r6_ad1', nil); wnd := FindWindowEx(wnd, 0, 'WindowsForms10.Window.8.app.0.141b42a_r6_ad1', 'Absender'); wnd_edit := FindControlByNumber(wnd, 'WindowsForms10.EDIT.app.0.141b42a_r6_ad1', 1); //HNr if wnd_edit<>0 then SendMessage(wnd_edit,WM_SETTEXT,0,Integer(Pchar(Edit_HNr_A.Text))); wnd_edit := FindControlByNumber(wnd, 'WindowsForms10.EDIT.app.0.141b42a_r6_ad1', 2); //Land if wnd_edit<>0 then SendMessage(wnd_edit,WM_SETTEXT,0,Integer(Pchar(Edit_Land_A.Text))); Deshalb bin ich jetzt auf der Suche, den ClassName zu identifizieren und als Variable zu verwenden. Das kann ich erreichen, wenn ich folgenden Code ausführe:
Delphi-Quellcode:
Aber die Schwierigkeit besteht darin, dass sich der ClassName nach dem Element "Empfänger" ändert. Dann wird aus
var
fwnd: THandle; wnd: HWND; wnd_edit: HWND; CName: array [0..255] of Char; begin fwnd := FindWindow(nil, 'AndereAppName'); GetClassName(fWND, CName, 256); wnd := FindWindowEx(fwnd, 0, CName, nil); wnd := FindWindowEx(wnd, 0, CName, nil); wnd := FindWindowEx(wnd, 0, CName, 'Empfänger'); WindowsForms10.Window.8.app.0.141b42a_r6_ad1 für die App ein WindowsForms10.EDIT.app.0.141b42a_r6_ad1 für ein Edit-Feld oder ein WindowsForms10.BUTTON.app.0.141b42a_r6_ad1 für ein Button. Und damit verstehe ich nicht umzugehen. Ich kann die Edits nur über die Reihenfolge ermitteln, da sie kein Caption haben...
Delphi-Quellcode:
Aber den ClassName bekomme ich irgendwie nicht zusammengebaut. Entweder händisch zusammenfrickeln, was ich nicht gerne möchte, oder ich brauche eine Möglichkeit, eine Function wie FindControlByNumber ohne den ClassName zu bauen.
function TTMSForm2.FindControlByNumber(hApp: HWND; ClassName: string; ControlNr: Word = 1): HWND;
var i: Word; hControl: HWND; begin Result := 0; if IsWindow(hApp) then begin Dec(ControlNr); hControl := 0; for i := 0 to ControlNr do begin hControl := FindWindowEx(hApp, hControl, PChar(ClassName), nil); if hControl = 0 then Exit; end; end; Result := hControl; end; Macht das mein Problem verständlich? Gruß Patrick |
AW: ClassName von Edit
Diese ID scheint ja bei allen Controls gleich zu sein.
Dann brauchst doch nur einmal nach irgendeinem Control zu suchen, also mit FindWindowEx ohne ClassName über alle Controls einer Form laufen und über GetClassName den Namen auslesen, bis was Passendes gefunden wurde. Da dann die ID extrahieren und, für alle deine weiteren Zugriffe, an deine ClassName's anhängen. Und ja, das sind die generierten Namen der .NET Winforms (C# oder VB.NET) ![]() ![]() Es gibt aber auch genügend Test-Frameworks, welche damit zurecht kommen und die man bestimmt auch zum Steuern nutzen könnte. |
AW: ClassName von Edit
Ist das Ziel Programm öffentlich?
Wenn ja, teil doch mal Link dahin. |
AW: ClassName von Edit
Guten Morgen Zusammen,
@himitsu: ich werde später mal gucken, ob ist so weiterkomme. Ich komme zwar zu dem Parent-Fenster, muss jetzt noch gucken, wie ich die darauf befindlichen auslesen kann... @KodeZwerg: Leider ist das kein öffentlichen Programm, daher kann ich es nicht teilen. Ich werde später berichten Einen guten Tag Patrick |
AW: ClassName von Edit
Wie kann ich die Childs eines Handels abrufen?
Delphi-Quellcode:
bringt mich leider nicht weiter?
GetNextWindow(hWnd, GW_HWNDNEXT)
|
AW: ClassName von Edit
Versuch mal
![]() |
AW: ClassName von Edit
FindWindowEx GetNextWindow EnumChildWindows ... das liefert alles (auch) die Childs und Find/Get kann man mehrmals aufrufen (mit passenden Parametern) und bekommt so, wie auch beim Enum "alle" Childs.
|
AW: ClassName von Edit
Ich mache es dir einfach.
|
AW: ClassName von Edit
Ullala, dass ich noch nicht mein Thema!
Erst einmal vielen Dank und auch für das Beispiel! Das habe ich wirklich gebraucht... :oops: Ich habe jetzt die ersten Aktionen hinbekommen und sie laufen auch auf einem anderen Rechner... Ich habe es jetzt erst einmal so gelöst - mit Sicherheit noch nicht der Weisheit letzter Schluss...
Delphi-Quellcode:
function EnumChildProc(AHandle: THandle; Rows: TRows): BOOL; stdcall;
var buffer: array[0..255] of Char; caption: array[0..255] of Char; I: integer; begin while (Rows[0,I]<>'') or (I=Length(Rows[0]) -0) do begin INC(I); end; Result := True; GetClassName(AHandle, buffer, SizeOf(buffer)-1); SendMessage(AHandle, WM_GETTEXT, 256, Integer(@caption)); Rows[0,I] := IntToStr(AHandle); Rows[1,I] := string(buffer); Rows[2,I] := Caption; end;
Delphi-Quellcode:
procedure TTMSForm2.Write_Empfaenger(Rows: TRows);
var wnd_temp: HWND; I: integer; begin for I := 0 to Length(Rows[0]) -1 do begin wnd_temp:=StrToInt(Rows[0,I]); case I of 0: SendMessage(wnd_temp,WM_SETTEXT,0,Integer(Pchar(Edit_HNr_E.Text))); //HNr. //1: // TButton 2: SendMessage(wnd_temp,WM_SETTEXT,0,Integer(Pchar(Edit_Land_E.Text))); //Land 3: SendMessage(wnd_temp,WM_SETTEXT,0,Integer(Pchar(Edit_Ort_E.Text))); //Ort 4: SendMessage(wnd_temp,WM_SETTEXT,0,Integer(Pchar(Edit_PLZ_E.Text))); //PLZ 5: SendMessage(wnd_temp,WM_SETTEXT,0,Integer(Pchar(Edit_Strasse_E.Text))); //Strasse 6: SendMessage(wnd_temp,WM_SETTEXT,0,Integer(Pchar(Edit_Name_E.Text))); //Nachname 7: SendMessage(wnd_temp,WM_SETTEXT,0,Integer(Pchar(Edit_Firma_E.Text))); //Firma 8: SendMessage(wnd_temp,WM_SETTEXT,0,Integer(Pchar(Edit_Vorname_E.Text))); //Vorname end; end; end;
Delphi-Quellcode:
Ich guck mal, wie weit ich jetzt komme. Muss noch Menü's, ComboBoxen und Tabellen abgreifen.
procedure TTMSForm2.AdvGlowButton2Click(Sender: TObject);
var fwnd: THandle; wnd: HWND; CName: array [0..255] of Char; Rows: TRows; begin fwnd := FindWindow(nil, 'AndereApp'); GetClassName(fWND, CName, 256); wnd := FindWindowEx(fwnd, 0, CName, nil); wnd := FindWindowEx(wnd, 0, CName, nil); wnd := FindWindowEx(wnd, 0, CName, 'Empfänger'); SetLength(Rows,3,9); EnumChildWindows(wnd, @EnumChildProc, Integer(Rows)); Write_Empfaenger(Rows); end; Vielen Dank!!! Patrick |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:35 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