Button 如何通过UIAutomation确定按钮是否按下?

Button 如何通过UIAutomation确定按钮是否按下?,button,automation,pressed,getstate,Button,Automation,Pressed,Getstate,我想知道按钮是否按下了。这似乎不是按钮的官方属性(不是按钮样式的复选框!),但似乎可以访问,例如BM_GETSTATE消息应该可以获得所需的结果 问题是,我经常得不到按钮的窗口句柄(它们只是另一个工具栏的一部分,尽管它们可以通过AutomationElement进行区分)。对于SendMessage函数,我需要这样一个句柄 所以。。有没有办法让我进入那家酒店?我知道它是可访问的,因为我在其他自动化程序中见过它,我只是不知道如何获得它 我打算使用C#,但任何C代码都可以 非常感谢(编辑:所以我终于

我想知道按钮是否按下了。这似乎不是按钮的官方属性(不是按钮样式的复选框!),但似乎可以访问,例如BM_GETSTATE消息应该可以获得所需的结果

问题是,我经常得不到按钮的窗口句柄(它们只是另一个工具栏的一部分,尽管它们可以通过AutomationElement进行区分)。对于SendMessage函数,我需要这样一个句柄

所以。。有没有办法让我进入那家酒店?我知道它是可访问的,因为我在其他自动化程序中见过它,我只是不知道如何获得它

我打算使用C#,但任何C代码都可以

非常感谢

(编辑:所以我终于在这里正确地设置了代码格式-只需在开头插入4个空格。)

好好享受吧,我花了很长时间才把它修好。。但现在我感觉自己达到了一个新的水平

(请告诉我如何使其格式正确-报价和代码对我都失败)

编辑: 这里有可读的代码和解释,用一种奇怪的外语。。不过,代码注释是英文的。希望你觉得有用。 此外,如果没有这里的信息,我也无法解决这个问题。

(编辑:因此我最终设法在这里正确地设置了代码格式-只需在开头插入4个空格。)

好好享受吧,我花了很长时间才把它修好。。但现在我感觉自己达到了一个新的水平

(请告诉我如何使其格式正确-报价和代码对我都失败)

编辑: 这里有可读的代码和解释,用一种奇怪的外语。。不过,代码注释是英文的。希望你觉得有用。 此外,如果没有这里的信息,我也无法解决这个问题

int res;
#region direct method
int hwnd = ae.Current.NativeWindowHandle;
if (hwnd != 0)
{
    const UInt32 BM_GETSTATE = 0x00F2;
    res = SendMessage(hwnd, BM_GETSTATE, 0, 0);
}
#endregion
else
#region method via toolbar
{
    AutomationElement parent = TreeWalker.RawViewWalker.GetParent(ae);
    while ((parent != null) && (parent.Current.ControlType != ControlType.ToolBar))
        parent = TreeWalker.RawViewWalker.GetParent(ae);
    if (parent != null)
    {
        int toolBarHandle = parent.Current.NativeWindowHandle;
        #region defines
        const int WM_USER = 0x400;
        const int TB_GETSTATE = (WM_USER + 18);
        const int TB_GETBUTTON = (WM_USER + 23);
        const int TB_BUTTONCOUNT = (WM_USER + 24);
        #endregion

        #region get correct child number
        int numButtons = SendMessage(toolBarHandle, TB_BUTTONCOUNT, 0, 0);
        AutomationElement sibling = ae;
        int cnt = -1;
        while (sibling != null)
        {
            sibling = TreeWalker.RawViewWalker.GetPreviousSibling(sibling);
            ++cnt;
        }
        if (cnt >= numButtons)
            cnt = 0; // nonsense value, but pass a valid one
        #endregion

        #region get command id
        TBBUTTON butInfo = new TBBUTTON();
        butInfo.idCommand = 1234;
        uint pid;
        GetWindowThreadProcessId((IntPtr)toolBarHandle, out pid);
        IntPtr process = OpenProcess(ProcessAccessFlags.VMOperation | ProcessAccessFlags.VMRead |
        ProcessAccessFlags.VMWrite | ProcessAccessFlags.QueryInformation, false, pid);

        IntPtr p = VirtualAllocEx(process, IntPtr.Zero, (uint)Marshal.SizeOf(typeof(TBBUTTON)), AllocationType.Commit
                                     , MemoryProtection.ReadWrite);

        int _res = SendMessage(toolBarHandle, TB_GETBUTTON, cnt, p.ToInt32());

        #region getresult
        int read;
        IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(TBBUTTON)));
        Marshal.StructureToPtr(butInfo, ptr, true);
        bool __res = ReadProcessMemory(process, p, ptr, Marshal.SizeOf(typeof(TBBUTTON)), out read);
        System.Diagnostics.Debug.Assert(read == Marshal.SizeOf(typeof(TBBUTTON)));
        butInfo = (TBBUTTON)Marshal.PtrToStructure(ptr, typeof(TBBUTTON));
        #endregion

        int commandId = butInfo.idCommand;
        VirtualFreeEx(process, p, 0, FreeType.Release);

        #endregion

        //!define BST_UNCHECKED      0
        //!define BST_CHECKED        1
        //!define BST_INDETERMINATE  2
        //!define BST_PUSHED         4
        //!define BST_FOCUS          8

        #region get state
        res = SendMessage(toolBarHandle, TB_GETSTATE, commandId, 0);
        #endregion
    }
}
#endregion