检查是否仅通过 WINAPI 检查 Winform CheckBox

Check if a Winform CheckBox is checked through WINAPI only

我的问题是这样的: 我需要检查是否仅通过 WINAPI 检查来自不同程序的 winform 复选框。

这里是我如何捕捉底层的 C# HWND: 首先,我使用 EnumWindows 获取桌面的所有 HWND,然后使用 EnumChildWindows 获取桌面的所有 HWND,然后我继续使用 GetWindowText 将我想要的文本与 window 文本进行比较,如果有匹配 - 我 return 它.

只是为了让事情更清楚——我可以捕捉到底层的 HWND。如果我打印它的文本和 class 名称,它就是想要的 winform 复选框。

现在,我要检查的复选框具有 WindowsForm.10.BUTTON.app.0.33c0d9d5 class 名称。有了这个功能,我问它是否是一个有效的复选框:

bool isValid(){
    if(!handleToControl) return false;
    LONG_PTR styles = GetWindowLongPtr(handleToControl, GWL_STYLE);
    bool isCheckBox = ((styles & BS_AUTO3STATE) == BS_AUTO3STATE);
    isCheckBox = isCheckBox || ((styles & BS_AUTOCHECKBOX) == BS_AUTOCHECKBOX);
    isCheckBox = isCheckBox || ((styles & BS_CHECKBOX) == BS_CHECKBOX);
    return isCheckBox;
}

现在,该功能确实有效(我在许多本机复选框和 winform 复选框上都选中了它)并且它可以验证它是否是一个有效的复选框(包括我要选中的复选框)

然后,我尝试使用此功能查看是否选中了 winform 复选框:

bool isChecked(){
    LRESULT _isChecked = SendMessage(handleToControl, BM_GETCHECK, 0, 0);
    bool ic = !(_isChecked == BST_UNCHECKED);
    if (ic)
        return ic;
    ic = ((Button_GetState(handleToControl) & BST_CHECKED) == BST_CHECKED);
    if (ic)
        return ic;

    return false;
}

但我惨遭失败。有人可以看出我的想法/代码有什么问题或建议不同的解决方案吗?

使用 IAccessibility 是一个选项吗?

例如

(取自http://bytes.com/topic/net/answers/637107-how-find-out-if-check-box-checked

[DllImport("oleacc.dll")]
internal static extern int AccessibleObjectFromWindow(IntPtr hwnd, uint id, ref Guid iid, [In, Out, MarshalAs(UnmanagedType.IUnknown)] ref object ppvObject); 

internal enum OBJID : uint
{
    WINDOW = 0x00000000,
    SYSMENU = 0xFFFFFFFF,
    TITLEBAR = 0xFFFFFFFE,
    MENU = 0xFFFFFFFD,
    CLIENT = 0xFFFFFFFC,
    VSCROLL = 0xFFFFFFFB,
    HSCROLL = 0xFFFFFFFA,
    SIZEGRIP = 0xFFFFFFF9,
    CARET = 0xFFFFFFF8,
    CURSOR = 0xFFFFFFF7,
    ALERT = 0xFFFFFFF6,
    SOUND = 0xFFFFFFF5,
}

public const long UNCHECKED = 1048576;
public const long CHECKED = 1048592;
public const long UNCHECKED_FOCUSED = 1048580; // if control is focused
public const long CHECKED_FOCUSED = 1048596; // if control is focused

private static bool IsChecked(IntPtr handle) {
    Guid guid = new Guid("{618736E0-3C3D-11CF-810C-00AA00389B71}");
    Object obj = null;
    int retValue = AccessibleObjectFromWindow(handle, (uint) OBJID.CLIENT, ref guid, ref obj);

    if (obj is IAccessible) {
        IAccessible accObj = (IAccessible) obj;
        Object result = accObj.get_accState(0);
        if (result is int) {
            int state = (int) result;
            return (state == CHECKED || state == CHECKED_FOCUSED);
        }
    }
    return false;
}