Hallo @all!
Ich möchte Textboxen eines anderen Programmes füllen und anschließend den OK Button drücken. Wie funktioniert das?
Ich bin mir nicht mehr sicher, aber ich glaube ich hatte in diesem Forum schon einmal zufällig etwas darüber gelesen, aber da mir das Zauberwort fehlt suchte ich erfolglos.
Gruß
Brovning
Stichworte für die Boardsuche
SendMessage
PostMessage
SendKeys
Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...
Hallo Programmierhans,
SendMessage geht soweit ich weiß nur innerhalb eines Prozesses. Aber PostMessage tuts.
herbivore
Original von herbivore
SendMessage geht soweit ich weiß nur innerhalb eines Prozesses. Aber PostMessage tuts.
Danke für die Ergänzung herbivore
Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...
Hm...
Ich habe etwas gefunden, um Keys zu senden und um Zeichen zu senden, aber wie kann ich einen Button drücken oder eine bestimmte Textbox selektieren um die Zeichen dort hinein zu schreiben.
Gruß
Brovning
Hallo Brovning,
PostMessage WM_CLICK an das betreffende Control.
herbivore
Nehmen wir mal an ich öffne den Taschenrechner in Windows. Wie würde ich das dann machen?
Ich weis doch nicht, wie die TextBox heißt oder?
Gruß
Brovning
Hallo Brovning,
mit EnumWindows kann man alle Fenster durchgehen. Entweder gibt es eine Extra-Funktion zum Durchgehen der Controls oder das geht so gar mit EnumWindows selbst (kann mich nicht genau erinnern, was davon). Von einem Control kann man weiterhin verschiedene Informationen abfragen (z.B. den Typ). Da die Controls zudem vermutlich immer in der gleichen Reihenfolge durchgegangen werden, sollte sich mit etwas Knobeln da schon was machen lassen.
herbivore
Hallo herbivore!
Bin am verzweifeln!
Das Control erhalte ich so.
EnumChildProcDelegate childDelegate = new EnumChildProcDelegate(this.EnumChildProc);
EnumChildWindows(hwndTemp, childDelegate, 0);
Anschließend erhält man mit
GetWindowTextA(lhWnd,sb,255);
den Inhalt des 1. Controls und mit
GetClassNameA(lhWnd,sb,255);
den Namen des 1. Controls.
Aber wie erhalt ich den Inhalt und Namen des 2. Controls?
Gruß
Brovning
Irgendwie verstehe ich das mit dem Enumerate nicht.
Wenn ich mir das Beispiel Creating, Enumerating, and Sizing Child Windows ansehe, dann nutzen die darin EnumChildProc um die Fenster zu bekommen. Genau das würde ich für die Controls benötigen, aber EnumChildProc wird doch nur einmal aufgerufen, wie kann es dann in diesem Beispiel alle Fenster resizen?
Gruß
Brovning
size ändern??
einfach
Form1.Size = new Size(200,200)
/edit habe mich verlesen und geglaubt das es ein eigenes Fenster ist Sorry
Wir Arbeiten eigendlich nicht wir nehmen nur das geld
Hallo Brovning,
The EnumChildWindows function enumerates the child windows that belong to the specified parent window by passing the handle to each child window, in turn, to an application-defined callback function. EnumChildWindows continues until the last child window is enumerated or the callback function returns FALSE.
Gibst du auch immer true zurück?
herbivore
Original von herbivore
Gibst du auch immer true zurück?
herbivore
Vermutlich nicht, da er ein Sample von mir kopiert hat....
Hier die angepasste Version:
[DllImport("user32.dll", SetLastError=true)]
public static extern IntPtr FindWindow(String lpClassName,String lpWindowName);
[DllImport("user32.dll", SetLastError=true)]
static extern int SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll", SetLastError=true)]
static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, string lParam );
[DllImport("user32.dll", SetLastError=true)]
static extern IntPtr FindWindowEx(IntPtr hWnd1,IntPtr hWnd2,string lpsz1,string lpsz2);
[DllImport("user32.dll", SetLastError=true)]
static extern int EnumChildWindows (IntPtr hWndParent ,EnumChildProcDelegate pEnumChildProcDelegate ,int lParam );
[DllImport("user32.dll", SetLastError=true)]
static extern int GetClassNameA (int hwnd ,System.Text.StringBuilder lpClassName,int nMaxCount);
[DllImport("user32.dll", SetLastError=true)]
static extern int GetWindowTextA(int hwnd,System.Text.StringBuilder lpString ,int cch);
private System.Windows.Forms.Button button1;
private const int WM_SETTEXT= 0x000C;
private void button1_Click(object sender, System.EventArgs e)
{
//suche den Taschenrechner
IntPtr hwndTemp = FindWindow("SciCalc", null);
SetForegroundWindow(hwndTemp);
EnumChildWindows(hwndTemp,new EnumChildProcDelegate(this.EnumChildProc),0);
}
private delegate int EnumChildProcDelegate(int lhWnd ,int lParam );
private int EnumChildProc(int lhWnd ,int lParam )
{
string strName=string.Empty;
string strValue=string.Empty;
System.Text.StringBuilder sb=new System.Text.StringBuilder(new string('0',255),0,255,255);
GetWindowTextA(lhWnd,sb,255);
strValue=sb.ToString().Trim();
sb=sb=new System.Text.StringBuilder(new string('0',255),0,255,255);
GetClassNameA(lhWnd,sb,255);
strName=sb.ToString().Trim();
System.Diagnostics.Debug.WriteLine(string.Format("Name: {0} Wert:{1}",strName,strValue));
return -1;
}
}
delegate void NoParamDelegate();
PS: danke für den Tipp Frank
Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...
Arg... Das war alles?! Die 0 zu einer anderen Zahl umzuändern. X(
Vielen Dank ! ! !
Jetzt habe ich aber noch eine Frage:
Ich habe soeben erkannt, dass ich damit doch nur den Klassennamen des Controls erhalte, aber nicht den eigentlichen Namen, mit welchem ich mit Hilfe von
IntPtr hwndChild = FindWindowEx(hwndTemp, IntPtr.Zero, "FELDNAME", string.Empty);
SendMessage(hwndChild,WM_SETTEXT,0, "TextText...");
etwas in diese TextBox schreiben könnte.
Wie bekomme ich denn den Control-Namen heraus?
Gruß
Brovning
Hallo Brovning,
ich glaube die Name-Eigenschaft hat keine Entsprechung in Win32. Sprich die Controls sind nicht bekannt. Ich meine aber, dass es eine ID (Integer) gibt.
herbivore
Jetzt verstehe ich bald gar nichts mehr.
Ich kann doch mit folgendem:
IntPtr hwndTemp = FindWindow("Notepad", "Unbenannt - Editor");
SetForegroundWindow(hwndTemp);
Thread.Sleep(1000);
IntPtr hwndChild = FindWindowEx(hwndTemp, IntPtr.Zero, "Edit", string.Empty);
SendMessage(hwndChild, WM_SETTEXT, 0, "Text im Eingabefeld von Notepad");
Notepad suchen und in den Vordergrund bringen und anschließend in das Feld "Edit" einen Text hineinschreiben.
Jetzt bin ich wieder bei meiner ersten Frage, welche ich vor dem Beispiel von Programmierhans hatte:
Wie bekomme ich den Namen der TextBox(en) heraus?
Gruß
Brovning
Hallo Brovning,
das widerspricht ja nicht meiner Ausage. "Edit" ist der Name der Klasse und nicht dieses bestimmten Controls. Und da Notepad nur ein Control der Klasse "Edit" enthält, bekommtst du halt das richtige.
herbivore
Achso... 8o
Wie kann ich dann mehrere Textfelder in einem Fenster befüllen, wenn die alle von der gleichen Klasse sind? Da befüllt er mir logischerweise immer nur das erste.
Gruß
Brovning
Indem du die Caption (Bechriftung) oder die Position kennst. So machen es Capture-Replay-Tools.
Hallo Brovning,
oder die ID 🙂 Alle diese Werte findest du heraus, wenn du mal alle Controls enummerieren lässt (den Code hast du ja) und diese Werte ausgibst.
herbivore
Die ID ist lhWnd würde ich behaupten, aber wie finde ich die Caption(Bechriftung) oder die Position heraus?
Wenn ich die ID habe, dann funktioniert dass wohl nicht mit?
IntPtr hwndChild = FindWindowEx(hwndTemp, IntPtr.Zero, "Edit", string.Empty);
Gruß
Brovning
Hallo Brovning,
nein, WindowHandle wird bei jedem Programmstart neu vergeben und identifiziert ein Control nur während der Laufzeit des Programms.
Vielleicht hat jemand parat, wie du Location u.ä. ermittelst. Steht aber alles auch in der Win32-SDK-Doku. Links auf die Doku habe ich ja schon gepostet.
herbivore
Neue Spielwiese
[DllImport("user32.dll", SetLastError=true)]
public static extern IntPtr FindWindow(String lpClassName,String lpWindowName);
[DllImport("user32.dll", SetLastError=true)]
static extern int SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll", SetLastError=true)]
static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, string lParam );
[DllImport("user32.dll", SetLastError=true)]
static extern int SendMessage(int hwnd, int wMsg, int wParam, string lParam );
[DllImport("user32.dll", SetLastError=true)]
static extern IntPtr FindWindowEx(IntPtr hWnd1,IntPtr hWnd2,string lpsz1,string lpsz2);
[DllImport("user32.dll", SetLastError=true)]
static extern int EnumChildWindows (IntPtr hWndParent ,EnumChildProcDelegate pEnumChildProcDelegate ,int lParam );
[DllImport("user32.dll", SetLastError=true)]
static extern int GetClassNameA (int hwnd ,System.Text.StringBuilder lpClassName,int nMaxCount);
[DllImport("user32.dll", SetLastError=true)]
static extern int GetWindowTextA(int hwnd,System.Text.StringBuilder lpString ,int cch);
[DllImport("user32.dll", SetLastError=true)]
static extern int GetWindowLong(int hWnd, int nIndex);
[DllImport("user32.dll", SetLastError=true)]
static extern int GetWindowLong(IntPtr hWnd, int nIndex);
private const int WM_SETTEXT= 0x000C;
private void button1_Click(object sender, System.EventArgs e)
{
IntPtr hwndTemp = FindWindow("Notepad", null);
SetForegroundWindow(hwndTemp);
//suche das Feld mit der ID 15 im Notepad
this._IntDesiredID=15;
this._IntDesiredChildWindow=0;
EnumChildWindows(hwndTemp,new EnumChildProcDelegate(this.EnumChildProc),0);
if (this._IntDesiredChildWindow!=0)
{
//mülle das Edit Feld voll
SendMessage(this._IntDesiredChildWindow,WM_SETTEXT,0, "Text im Eingabefeld von Notepad");
}
}
private int _IntDesiredID=0;
private int _IntDesiredChildWindow=0;
private delegate int EnumChildProcDelegate(int lhWnd ,int lParam );
private int EnumChildProc(int lhWnd ,int lParam )
{
try
{
string strName=string.Empty;
string strValue=string.Empty;
System.Text.StringBuilder sb=new System.Text.StringBuilder(new string('0',255),0,255,255);
GetWindowTextA(lhWnd,sb,255);
strValue=sb.ToString().Trim();
sb=new System.Text.StringBuilder(new string('0',255),0,255,255);
GetClassNameA(lhWnd,sb,255);
strName=sb.ToString().Trim();
int intID=GetWindowLong(lhWnd,-12);
if (intID==this._IntDesiredID)
{
this._IntDesiredChildWindow=lhWnd;
}
System.Diagnostics.Debug.WriteLine(string.Format("Name: {0} Wert:{1} ID:{2}",strName,strValue,intID));
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return -1;
}
}
delegate void NoParamDelegate();
Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...
@Programmierhans
Du bist einfach der Beste ! ! !
Hast du die Beispiele selbst geschrieben oder kennst du eine Seite, welche Beispiele in der Richtung hat?
Gruß
Brovning
Auf http://www.pinvoke.net gibts ne Menge mit der Deklaration und manchmal auch Codebeispielen in C#.
Gruß,
SimonKnight6600
Original von Brovning
@Programmierhans
Hast du die Beispiele selbst geschrieben oder kennst du eine Seite, welche Beispiele in der Richtung hat?
Ein bisserl Google.... um nicht alle Konstanten und API-Deklarationen selber tippen zu müssen (abgeleitet aus VB.Net Beispielen) .... dann ein wenig Intuition und ein Kännchen Erfahrung 🙂
Gruss
Programmierhans
Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...
Original von Brovning
Vielen Dank, für deine Mühe, die du dir machst! 👍
Bitte 😉
Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...