bool _FillGrid(out AccProperties p) { var g = _grid; g.ZClear(); if (!_acc.GetProperties("Rnuvdakh@srw", out p)) { _propError = "Failed to get AO properties: \r\n" + ALastError.Message; g.Invalidate(); return(false); } _propError = null; _noeventGridValueChanged = true; bool isWeb = _IsVisibleWebPage(_acc, out var browser, _con.Is0 ? _wnd : _con); _isWebIE = isWeb && browser == _BrowserEnum.IE; var role = p.Role; if (isWeb) { role = "web:" + role; } _AddIfNotEmpty("role", role, true, false, info: c_infoRole); //CONSIDER: path too. But maybe don't encourage, because then the code depends on window/page structure. bool noName = !_AddIfNotEmpty("name", p.Name, true, true, info: "Name.$"); if (noName) { _Add("name", "", info: "Name.$"); } if (_AddIfNotEmpty("uiaid", p.UiaId, noName, true, info: "UIA AutomationId.$")) { noName = false; } //control if (!isWeb && !_con.Is0 && !_useCon) { string sId = TUtil.GetUsefulControlId(_con, _wnd, out int id) ? id.ToString() : _con.NameWinForms; if (sId != null) { _Add("id", sId, sId.Length > 0, info: c_infoId); } _Add("class", TUtil.StripWndClassName(_con.ClassName, true), sId.NE(), info: c_infoClass); } _AddIfNotEmpty("value", p.Value, false, true, info: "Value.$"); if (_AddIfNotEmpty("description", p.Description, noName, true, info: "Description.$")) { noName = false; } _AddIfNotEmpty("action", p.DefaultAction, false, true, info: "Default action.$"); if (_AddIfNotEmpty("key", p.KeyboardShortcut, noName, true, info: "Keyboard shortcut.$")) { noName = false; } if (_AddIfNotEmpty("help", p.Help, noName, true, info: "Help.$")) { noName = false; } foreach (var attr in p.HtmlAttributes as Dictionary <string, string> ) { string na = attr.Key, va = attr.Value; bool check = noName && (na == "id" || na == "name") && va.Length > 0; if (check) { noName = false; } _Add("@" + na, TUtil.EscapeWildex(va), check, info: "HTML attribute.$"); } int elem = _acc.SimpleElementId; if (elem != 0) { _Add("elem", elem.ToString(), info: c_infoElem); } _Add("state", p.State.ToString(), info: c_infoState); _Add("rect", $"{{W={p.Rect.Width} H={p.Rect.Height}}}", tt: "Rectangle in screen: " + p.Rect.ToString(), info: c_infoRect); //CONSIDER: if no name etc, try to get uiaid. Eg winforms control name. Or use prop "wfName=...:". _Check2("also", false); _Check2("skip", false); _Check2("navig", false); if (isWeb && !_waitAutoCheckedOnce) { _waitAutoCheckedOnce = true; _Check2("wait", true); } _Check2(nameof(AFFlags.UIA), _acc.MiscFlags.Has(AccMiscFlags.UIA)); _noeventGridValueChanged = false; g.ZAutoSize(); //tested: suspending layout does not make faster. return(true); bool _AddIfNotEmpty(string name, string value, bool check, bool escape, string tt = null, string info = null) { if (value.NE()) { return(false); } if (escape) { value = TUtil.EscapeWildex(value); } _Add(name, value, check, tt, info); return(true); } void _Add(string name, string value, bool check = false, string tt = null, string info = null) { g.ZAdd(null, name, value, check, tt, info); } }
/// <summary> /// Starts or stops capturing. /// Does nothing if already in that state. /// </summary> public void StartStop(bool start) { if (start == Capturing) { return; } var wForm = (AWnd)_form; if (start) { //let other forms stop capturing wForm.Prop.Set(c_propName, 1); AWnd.Find(null, "WindowsForms*", also: o => { if (o != wForm && o.Prop[c_propName] == 1) { o.Send(c_stopMessage); } return(false); }); if (!Api.RegisterHotKey(wForm, 1, 0, KKey.F3)) { ADialog.ShowError("Failed to register hotkey F3", owner: _form); return; } Capturing = true; //set timer that shows AO rect if (_timer == null) { _osr = TUtil.CreateOsdRect(); _timer = new ATimer(t => { //Don't capture too frequently. // Eg if the callback is very slow. Or if multiple timer messages are received without time interval (possible in some conditions). long t1 = ATime.PerfMilliseconds, t2 = t1 - _prevTime; _prevTime = t1; if (t2 < 100) { return; } //show rect of UI object from mouse AWnd w = AWnd.FromMouse(WXYFlags.NeedWindow); RECT?r = default; if (!(w.Is0 || w == wForm || w.OwnerWindow == wForm)) { r = _cbGetRect(); } if (r.HasValue) { var rr = r.GetValueOrDefault(); rr.Inflate(2, 2); //2 pixels inside, 2 outside _osr.Rect = rr; _osr.Show(); } else { _osr.Visible = false; } }); } _timer.Every(250); } else { Capturing = false; Api.UnregisterHotKey(wForm, 1); wForm.Prop.Remove(c_propName); _timer.Stop(); _osr.Hide(); } }
bool _FillGrid(bool newWindow) { bool isCon = !_con.Is0; var g = _grid; if (newWindow) { g.ZClear(); } else { g.RowsCount = 5; } _WinInfo f = default; if (!_GetClassName(_wnd, out f.wClass)) { return(false); //note: get even if !newWindow, to detect closed window } if (isCon && !_GetClassName(_con, out f.cClass)) { return(false); } _propError = null; _noeventGridValueChanged = true; var wndName = _wnd.NameTL_; if (newWindow) { g.ZAddHeaderRow("Window"); g.ZAdd(null, "name", TUtil.EscapeWindowName(wndName, true), true, info: "Window name.$"); g.ZAdd(null, "class", TUtil.StripWndClassName(f.wClass, true), true, info: "Window class name.$"); f.wProg = _wnd.ProgramName; var ap = new List <string> { f.wProg, "WOwner.Process(processId)", "WOwner.Thread(threadId)" }; if (!_wnd.OwnerWindow.Is0) { ap.Add("WOwner.Window(ow)"); } g.ZAdd(null, "program", ap, wndName.NE(), info: "Program.$", etype: ParamGrid.EditType.ComboText, comboIndex: 0); g.ZAdd(null, "contains", (Func <string[]>)_ContainsCombo_DropDown, false, info: "An accessible object in the window. Format: 'role' name.\r\nName$$", etype: ParamGrid.EditType.ComboText); } else if (wndName != _wndName) { if (TUtil.ShouldChangeGridWildex(g.ZGetCellText("name", 1), wndName)) { g.ZSetCellText("name", 1, TUtil.EscapeWindowName(wndName, true)); } } f.wName = _wndName = wndName; if (isCon) { g.ZAddHeaderRow("Control", check: !_uncheckControl); g.ZAddHidden = _uncheckControl; //name combo f.cName = _con.Name; int iSel = f.cName.NE() ? -1 : 0; var an = new List <string> { TUtil.EscapeWildex(f.cName) }; _ConNameAdd("***wfName ", f.cWF = _con.NameWinForms); /*bool isAcc =*/ _ConNameAdd("***accName ", f.cAcc = _con.NameAcc); //bool isLabel = _ConNameAdd("***label ", f.cLabel = _con.NameLabel); //if(isAcc && isLabel && iSel == an.Count - 2 && f.cAcc == f.cLabel) iSel++; //if label == accName, prefer label if (iSel < 0) { iSel = 0; //never select text, even if all others unavailable } _ConNameAdd("***text ", f.cText = _con.ControlText); bool _ConNameAdd(string prefix, string value) { if (value.NE()) { return(false); } if (iSel < 0) { iSel = an.Count; } an.Add(prefix + TUtil.EscapeWildex(value)); return(true); } bool idUseful = TUtil.GetUsefulControlId(_con, _wnd, out f.cId); if (idUseful) { g.ZAdd(null, "id", f.cId, true); } else { an.Add("***id " + f.cId + " (probably not useful)"); } g.ZAdd("nameC", "name", an, !idUseful, info: "Control name.$", etype: ParamGrid.EditType.ComboText, comboIndex: iSel); g.ZAdd("classC", "class", TUtil.StripWndClassName(f.cClass, true), !idUseful, info: "Control class name.$"); g.ZAddHidden = false; } _uncheckControl = false; _noeventGridValueChanged = false; g.ZAutoSize(); _FillWindowInfo(f); return(true); string[] _ContainsCombo_DropDown() { try { var a1 = new List <string>(); //child foreach (var c in _wnd.Get.Children(onlyVisible: true)) { var cn = c.Name; if (cn.NE()) { continue; } cn = "c '" + TUtil.StripWndClassName(c.ClassName, true) + "' " + TUtil.EscapeWildex(cn); if (!a1.Contains(cn)) { a1.Add(cn); } } //acc var a2 = new List <string>(); var a3 = AAcc.FindAll(_wnd, name: "?*", prop: "notin=SCROLLBAR\0maxcc=100", flags: AFFlags.ClientArea); //all that have a name string prevName = null; for (int i = a3.Length; --i >= 0;) { if (!a3[i].GetProperties("Rn", out var prop)) { continue; } if (prop.Name == prevName && prop.Role == "WINDOW") { continue; } prevName = prop.Name; //skip parent WINDOW string rn = "a '" + prop.Role + "' " + TUtil.EscapeWildex(prop.Name); if (!a2.Contains(rn)) { a2.Add(rn); } } a2.Reverse(); a1.AddRange(a2); return(a1.ToArray()); //rejected: sort } catch (Exception ex) { ADebug.Print(ex); return(null); } } bool _GetClassName(AWnd w, out string cn) { cn = w.ClassName; if (cn != null) { return(true); } _propError = "Failed to get " + (w == _wnd ? "window" : "control") + " properties: \r\n" + ALastError.Message; _grid.ZClear(); _grid.Invalidate(); _winInfo.Z.ClearText(); return(false); } }