David Haim
David Haim

Reputation: 26496

Check if a Winform CheckBox is checked through WINAPI only

my problem goes like this : I need to check if a winform checkbox from a different program is checked or not by WINAPI only.

here how I catch the underlyined C# HWND: first I get all the HWND's of the desktop with EnumWindows and then EnumChildWindows , then I go on each one and with GetWindowText compares my wanted text to the window text and if there is a match - I return it.

just to make things clear - I can catch the underlying HWND. if I print its text and the class name it is the winform checkbox wanted.

now, the checkbox I want to check has WindowsForm.10.BUTTON.app.0.33c0d9d5 class name. with this function I ask it if its a valid checkbox:

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;
}

now, the function does work (I checked it on many native checkboxes and also winform checkboxes) and it can validate if it's a valid checkbox or not (including the checkbox I want to check)

then , I try to see if the winform checkbox is checked or not with this function:

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;
}

but I fail miserably. can someone see what's wrong with my idea / code or suggest a different solution?

Upvotes: 2

Views: 1818

Answers (1)

Loathing
Loathing

Reputation: 5266

Is using IAccessibility an option?

e.g.

(taken from 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;
}

Upvotes: 2

Related Questions