Thema: [C#] UIAutomation
-
07. 12. 2011, 00:25 #1Mitglied
- Registriert seit
- Jun 2010
- Ort
- Australia
- Beiträge
- 223
[C#] UIAutomation
Hi Folkz,
ich steh mal wieder vor einem problem
bei dem ich nicht mehr weiter komme.
Ich habe eine 3rd Party application die ich fernsteuern/automatisieren will.
Ich habe mich bereits bis zum MDI child window pointer durchgekaempft und mir dessen ListView geholt. Ich hab dann eine function geschrieben die mir den Item Text
zu einem bestimmten index der listview geben sollte - funktionierte leider nicht udn ha dann per zufall die ManagedWinAPI gefunden (http://mwinapi.sourceforge.net/)
mit der hat das alles wunderbar geklappt und ich konnte mir die einzelnen Items anschauen.
Ich wollte jetzt ein bestimmtest Item selectieren via dessen index und es dann auswaehlen (SendKey Enter). Leider besitzt die API keinerlei funktion ein bestimmtes ITEM zu selektieren. Google gab mir zwar code samples aber irgendwie funktionierte keines (keine auswirkung)..
Das letzte item bleibt selektiert (heighlight).. also gehe ich davon aus dass nichts passiertPHP-Code:LVITEM lvi = new LVITEM();
lvi.iItem = 1;//index i want to select
lvi.iSubItem = 0;
lvi.stateMask = 0xffffffff; //?
lvi.mask = 0x0002 | 0x0004; //found this on the INET select/focus
ProcessMemoryChunk lc = ProcessMemoryChunk.AllocStruct(sw.Process, lvi);
SystemWindow.SendMessage(new HandleRef(sw, sw.HWnd), SystemListView.LVM_SETITEMSTATE, IntPtr.Zero, lc.Location);// LVM_SETITEMSTATE = (0x1000 + 43);

Weiteres Problem:
Momentan hab ich es so geloest dass (sehr unschoen) dass ich so oft {UP} sende wie meine listview items hat (so weiss ich, mein erstes item hat highlight) und ueberpruefe ob mein erstes item(.Text) das item ist was ich suche, wenn nicht sende ich {DOWN} and checke das naechste item, wenn ich es gefunden habe, sende ich ein {ENTER}. Jetzt oeffnet sich ein dialog als MDI window, was den selben parent hat wie das window mit der listview, wie komme ich an das window ran?! das problem ist dass sich mit SPY++ die beiden windows nur durch das handle unterscheiden
wie bekomme ich das richtige handle?!Geändert von tomekpl (15. 12. 2011 um 23:31 Uhr)
-
09. 12. 2011, 09:12 #2Mitglied
- Registriert seit
- Nov 2005
- Beiträge
- 252
Re: [C# ManagedWinAPI]
Hallo,
das ganze Vorgehen halte ich für überhaupt nicht zielführend. Es gibt spezielle Frameworks zur Automatisierung und Testen von UIs wie z.B. White. Ich würds eher darüber probieren.
-
12. 12. 2011, 01:40 #3Mitglied
(Threadstarter)
- Registriert seit
- Jun 2010
- Ort
- Australia
- Beiträge
- 223
Re: [C# ManagedWinAPI]
Ok, wusste garnicht dass es sowas gibt. Ich hab's mit White probiert und da scheint auch soweit zu gehen (mehr oder weniger) nur es ist sau langsam.. um ein combobox item zu wechseln braucht der fast ne minute
hmm liegt es an dem log4net logger oder einfach wegen dem ganzen boxing etc?
Das dauert ewigkeiten (30min++)
da bin ich schneller per hand ... das problem ist aber es soll automatisiert werden 
PHP-Code:w.Get<White.Core.UIItems.ListBoxItems.ComboBox>("cboOption77761").Select("Summary ");
w.Get<White.Core.UIItems.ListBoxItems.ComboBox>("cboOption77791").Select("All Areas ");
w.Get<White.Core.UIItems.ListBoxItems.ComboBox>("cboOption777121").Select("Stock On Hand");
w.Get<White.Core.UIItems.ListBoxItems.ComboBox>("cboOption777152").Select("No ");
w.Get<White.Core.UIItems.ListBoxItems.ComboBox>("cboOption777182").Select("Yes");
w.Get<White.Core.UIItems.ListBoxItems.ComboBox>("cboOption777212").Select("No ");
w.Get<White.Core.UIItems.ListBoxItems.ComboBox>("cboOption777243").Select("No ");
w.Get<White.Core.UIItems.ListBoxItems.ComboBox>("cboOption777273").Select("No ");
w.Get<White.Core.UIItems.ListBoxItems.ComboBox>("cboOption777304").Select("Bottling QC");
w.Get<White.Core.UIItems.ListBoxItems.ComboBox>("CBOSEQUENCE").Select("Stock Item");
w.Get<White.Core.UIItems.ListBoxItems.ComboBox>("cboPrinter").Select("VIEW");
loginScreen.Get<White.Core.UIItems.Button>("Print").Click();
Geändert von tomekpl (12. 12. 2011 um 01:58 Uhr)
-
15. 12. 2011, 23:36 #4Mitglied
(Threadstarter)
- Registriert seit
- Jun 2010
- Ort
- Australia
- Beiträge
- 223
Re: [C#] UIAutomation
Ich hab WHite framework weggelassen bzw suche die Items per UIAutomation (worauf White ja aufbaut) das geht ein wenig schneller .. mein problem ist jetzt das ich eine
ComboBox habe deren Wert ich nicht aendern kann zumindest weiss ich nicht wie ?!
Ich habe das ValuePattern versucht, was aber eine Exception wirft, als ich mir angeschaut habe welche Pattern das Control ueberhaupt supported ist es nur das "AutomationPattern" ...
Gibt es noch irgendwelche tricks/tips die ich versuchen koennte ausser "SendKeys" ?
-
20. 12. 2011, 22:49 #5
Re: [C#] UIAutomation
Ich hab als ich mit UIAutomation rum gespielt habe solche Probleme so gelöst:
Das visuelle Container Element deiner ComboBox müsste eigentlich das Scroll Pattern unterstützen. Da gilt es nur noch das entsprechende Container Element zu finden, was sicher nicht ganz einfach ist. Die Dinger sind ja schwer mit UISpy und Co. zu untersuchen, da sie ja die Angewohnheit haben wieder zu zu gehen wenn du mit der Maus andere Aktionen ausführst. Dein "target" Automation Element müsstest du auf die selbe weise raus finden können.Code:private static void BringInToView(AutomationElement container, AutomationElement target) { var patterns = container.GetSupportedPatterns(); if (patterns.Contains(ScrollPatternIdentifiers.Pattern)) { if (Rect.Intersect(target.Current.BoundingRectangle, container.Current.BoundingRectangle) == Rect.Empty) { var pattern = container.GetCurrentPattern(ScrollPatternIdentifiers.Pattern) as ScrollPattern; TestCaseHelper.MouseClick(container); if (pattern.Current.VerticallyScrollable) { pattern.SetScrollPercent(pattern.Current.HorizontalScrollPercent, 0.0); } do { InputSimulator.SimulateKeyPress(VirtualKeyCode.NEXT); } while (Rect.Intersect(target.Current.BoundingRectangle, container.Current.BoundingRectangle) == Rect.Empty && pattern.Current.VerticalScrollPercent < 100); if (Rect.Intersect(target.Current.BoundingRectangle, container.Current.BoundingRectangle) == Rect.Empty) { Assert.Fail("Cant Scroll " + target.Current.AutomationId + " in to View"); } } } }
Die if mit dem Assert kannst im Prinzip rausschmeissen.
Die InputSimulator Klasse hatte ich damals glaube ich von Codeplex.
TestCaseHelper ist eine Klasse von mir. Macht in dem Fall nichts anderes als das entsprechende Container Element zu selektieren.
Ist sicher nicht perfekt aber ich hatte damals wenig zeit für Nachforschungen und für deinen Zweck sollte es reichen. Ging bei mir damals auch recht fix.
Edit:
Es hilft sich den Aufbau eines Controls/Forms usw. als Wirklichen Baum vorzustellen. Jedes Control was eine Scrollbar hat muss auch das Scroll Pattern unterstützen. Die Frage ist halt auf welcher verschachtelungs Ebene liegt der eigentliche Scroll Container versteckt.
-


Zitieren

mehr lesen...







Mechwarrior Online: Closed Beta...
Heute, 12:36 in gulli:news