Laden...

Knopf einer Fremdanwendung drücken?

Erstellt von winx vor 15 Jahren Letzter Beitrag vor 15 Jahren 1.404 Views
W
winx Themenstarter:in
136 Beiträge seit 2007
vor 15 Jahren
Knopf einer Fremdanwendung drücken?

Hi,

ist es irgendwie möglich aus meinem Programm heraus eine beliebige Anwendung zu starten und einen Knopf der Anwendung zu drücken?

Oder irgendwie nen "Mausdruck" am Bildschirm zu simulieren?

danke

268 Beiträge seit 2008
vor 15 Jahren

ich denke das musste mit Findwindow() und FindWindowEx() machen .

//Edit: Unteranderem Hier findest du Infos darüber.
Viel Erfolg!

MFG Scarecraft

Name: Scarecraft
Language:C#
learning since:winter 2007
IDE: Visual Studio 2005/08 Professional Editon
Skill:Medium
qualifications: MCP - Microsoft Certified Professional
Homepage : FX RPG Maker

195 Beiträge seit 2006
vor 15 Jahren

Das Automation Framework kann soetwas sehr komfortabel erledigen.
In diesem Namespace sind die Klassen die du brauchst: UIAutomationClientsideProviders.

Es müssen 4 Assemblies UIAutomation... referenziert werden.

Dann kannst du in etwa vorgehen wie mein Beispiel:


#region Open App
            OpenFileDialog op = new OpenFileDialog();
            System.Diagnostics.Process p = new System.Diagnostics.Process();
            if (op.ShowDialog() == DialogResult.OK)
            {
                p = System.Diagnostics.Process.Start(op.FileName);
            }
            #endregion

            #region Zugriff auf Desktop
            AutomationElement ae = AutomationElement.RootElement;
            #endregion
            DateTime je = DateTime.Now;

            System.Threading.Thread.Sleep(2000);
            
            //Form
            AutomationElement asForm = ae.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, "Form1"));
            //Button
            AutomationElement asBtn1 = asForm.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.NameProperty, "button1"));
            //Declare Pattern for Event
            InvokePattern btnclick = (InvokePattern)asBtn1.GetCurrentPattern(InvokePattern.Pattern);
            //TextBox
            AutomationElement asTB = asForm.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.AutomationIdProperty, "textBox1"));
            //Declare Pattern for Event
            ValuePattern TBSet = (ValuePattern)asTB.GetCurrentPattern(ValuePattern.Pattern);
            
            
            //Invoke aufrufen
            for (int i = 0; i < 200; i++)
			{
                TBSet.SetValue(i.ToString());
                btnclick.Invoke();
                System.Threading.Thread.Sleep(500);
			}

            p.Kill();

Mfg

Chris

915 Beiträge seit 2006
vor 15 Jahren

Beides ist möglich.

[PostMessage, WindowsNachricht versenden]
Der einfachste Weg wäre über Process den Prozess zu starten über WMI bekommst mit wann die Fremdanwendung wirklich da ist. Den es gibt immer einen gewissen zeitintervall bis das Programm wirklich komplett gestartet ist. Nun kannst du entweder über Prozess das MainWindowHandle finden und über Subclassing bei der WindowsMessage WM_CREATE, das Fenster ausfindig machen auf dem sich der Button befindet sollte das MainFenster nicht zufällig jenes sein auf dem sich der Button befindet. Oder du kannst ebenso versuchen das über WMI zu lösen, z.B. wenn ein Fenster erstellt wird mit dem Namen XYZ und dir dann das Handle davon holen. Anhand des Fensterhandels auf dem sich der Button befindet kannst du nun über die Windows API Funktion FindWindowEx anhand des Klassennamens des Buttons (wird wohl einfach "Button" heissen) alle Buttons auf dem Fenster raussuchen. Alle Buttons die du nun gefunden hast kannst du durchgehen und über z.B. WIn API GetWindowText oder SendMessage dir die Captions der Buttons zurückliefern lassen. Wenn die Caption mit dem gesuchten Button übereinstimmt dann hast du deinen gewünschten Button gefunden.

Nun gilt es mit Spy++ herauszufinden wie der Button reagiert und welche Windows Nachricht des Buttons wie z.B. WM_CLICK /WM_LBUTTONDOWN verarbeitet werden, direkt auf dme Button oder vielleicht sogar nur im Parent. Wenn im Parent kannst dir eh die Suche nach dne Button spaaren und direkt die NAchricht an das Fenster schicken auf dem sich der Button befindet. Wie gesagt, je nachdem was Spa++ auspuckt musst das verhallten immitieren. Zum versenden der Nachricht nutze PostMessage.
**
[Click immitieren]**
Dieser Weg ist der schlechteste da man hierbei die Maussteuerung übernimmt und soweiso den Button lokalisieren muss um über dessen Possition die Maus positionierne zu lassen. Würde daher davon abraten.

Ansonsten, wieder über Process den Prozess satrten, mit WMI schauen ob der Prozess gestartet wurde und dir über den SCOPE ein Event schmeissen lassen. Wieder über das Fensterhandle dne Button suchen oder über WMI. Dannach über GetClientRect dir über das Handle des Buttons die Location holen. Die (Rect.X + Rect.Width) / 2 berechnen wie (Rect.Y + Rect.Height) / 2 berechnen um das Center des Buttons als Point zu zuzuweisen. Dannach über Win API Funktion mouse_event den Point übergeben als X und Y Koordinaten wie das MouseEventFlag, LEFTDOWN und das wars.

/ps
Da waren andere schneller als ich Zeit zum Tippen gebraucht habe 😉

Wie vernichtet stand Andreas unter den flammenden Augen seiner Kunden.
Ihm war's, als stünde des Schicksals dunkle Wetterwolke über seinem Haupte X(