【问题标题】:How to determine via UIAutomation, whether a button is pressed or not?如何通过 UIAutomation 确定按钮是否被按下?
【发布时间】:2011-09-14 21:22:32
【问题描述】:

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

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

那么.. 有没有办法让我访问该属性?我知道它是可以访问的,因为我在其他自动化程序中看到过它,我只是不知道如何获得它。

我将使用 C#,但任何 C 代码都可以。

非常感谢

【问题讨论】:

    标签: button automation pressed getstate


    【解决方案1】:

    (编辑:所以我终于设法在这里正确地制作代码格式 - 只需在开头插入 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
    

    编辑: 这里http://www.andreas-reiff.de/2011/06/c-speicher-anderen-prozess-befullen-lassen-checken-ob-ein-button-gedruckt/ 带有可读的代码和一种奇怪的外语解释......不过,代码 cmets 是英文的。希望你觉得它有用。 另外,如果没有How come some controls don't have a windows handle? 此处的信息,我将无法解决此问题。

    【讨论】:

      猜你喜欢
      • 2020-01-02
      • 2017-06-11
      • 1970-01-01
      • 2013-10-17
      • 1970-01-01
      • 1970-01-01
      • 2016-12-15
      • 2010-11-13
      • 1970-01-01
      相关资源
      最近更新 更多