public FormAAcc(AAcc acc = null) { InitializeComponent(); Action <SG.CellContext> f = _grid_ZValueChanged; _grid.ZValueChanged += f; _grid2.ZValueChanged += f; _InitTree(); _acc = acc; //will be processed in OnLoad }
int _GetAccCheckState(AAcc a) { var state = a.State; if (state.Has(AccSTATE.INDETERMINATE)) { return(2); } if (state.Has(AccSTATE.CHECKED)) { return(1); } return(0); }
/// <summary> /// Sends a "click" message to this button control. Does not use the mouse. /// </summary> /// <param name="useAcc">Use <see cref="AAcc.DoAction"/>. If false (default), posts <msdn>BM_CLICK</msdn> message.</param> /// <exception cref="AuWndException">This window is invalid.</exception> /// <exception cref="AuException">Failed.</exception> /// <remarks> /// Works not with all button controls. Sometimes does not work if the window is inactive. /// Check boxes and radio buttons also are buttons. This function can click them. /// </remarks> /// <example> /// <code><![CDATA[ /// AWnd.Find("Options").Child("Cancel").AsButton.Click(); /// ]]></code> /// </example> public void Click(bool useAcc = false) { W.ThrowIfInvalid(); if (useAcc) { using var a = AAcc.FromWindow(W, AccOBJID.CLIENT); //throws if failed a.DoAction(); } else { _PostBmClick(); //async if other thread, because may show a dialog. } W.MinimalSleepIfOtherThread_(); //FUTURE: sync better }
/// <summary> /// Gets check state of this check box or radio button. /// Returns 0 if unchecked, 1 if checked, 2 if indeterminate. Also returns 0 if this is not a button or if failed to get state. /// </summary> /// <param name="useAcc">Use <see cref="AAcc.State"/>. If false (default) and this button has a standard checkbox style, uses API <msdn>BM_GETCHECK</msdn>.</param> public int GetCheckState(bool useAcc = false) { if (useAcc || !_IsCheckbox()) { //info: Windows Forms controls are user-drawn and don't have one of the styles, therefore BM_GETCHECK does not work. try { //avoid exception in property-get functions using var a = AAcc.FromWindow(W, AccOBJID.CLIENT, flags: AWFlags.NoThrow); if (a == null) { return(0); } return(_GetAccCheckState(a)); } catch (Exception ex) { ADebug.Print(ex); } //CONSIDER: if fails, show warning. In all AWnd property-get functions. return(0); } else { return((int)W.Send(BM_GETCHECK)); } }
public Cpp_Acc(AAcc a) { acc = a._iacc; elem = a._elem; misc = a._misc; }
/// <summary> /// Sets checkbox state. Does not use the mouse. /// </summary> /// <param name="state">0 unchecked, 1 checked, 2 indeterminate.</param> /// <param name="useAcc">Use <see cref="AAcc.DoAction"/>. If false (default), posts <msdn>BM_SETCHECK</msdn> message and also BN_CLICKED notification to the parent window; if that is not possible, instead uses <msdn>BM_CLICK</msdn> message.</param> /// <exception cref="ArgumentOutOfRangeException">Invalid state.</exception> /// <exception cref="AuWndException">This window is invalid.</exception> /// <exception cref="AuException">Failed.</exception> /// <remarks> /// Does nothing if the check box already has the specified check state (if can get it). /// Works not with all button controls. Sometimes does not work if the window is inactive. /// If this is a radio button, does not uncheck other radio buttons in its group. /// </remarks> public void SetCheckState(int state, bool useAcc = false) { if (state < 0 || state > 2) { throw new ArgumentOutOfRangeException(); } W.ThrowIfInvalid(); int id; if (useAcc || !_IsCheckbox() || (uint)((id = W.ControlId) - 1) >= 0xffff) { using var a = AAcc.FromWindow(W, AccOBJID.CLIENT); //throws if failed int k = _GetAccCheckState(a); if (k == state) { return; } if (useAcc) { a.DoAction(); } else { _PostBmClick(); } bool clickAgain = false; switch (state) { case 0: if (k == 1) { W.MinimalSleepIfOtherThread_(); if (GetCheckState(true) == 2) { clickAgain = true; } else { return; } } break; case 1: if (k == 2) { clickAgain = true; } break; case 2: if (k == 0) { clickAgain = true; } break; } if (clickAgain) { if (useAcc) { a.DoAction(); } else { _PostBmClick(); } } } else { if (state == W.Send(BM_GETCHECK)) { return; } W.Post(BM_SETCHECK, state); W.Get.DirectParent.Post(Api.WM_COMMAND, id, (LPARAM)W); } W.MinimalSleepIfOtherThread_(); }
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); } }