/// <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)); } }
/// <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_(); }