MSAA获取QQ聊天界面群聊按钮位置

废话不多说直接上源码

以下是MSAA的核心操作源码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using Accessibility;

namespace QQSenders
{
    class MSAASupport
    {
        public const uint OBJID_WINDOW = 0x00000000;
        public const uint OBJID_SYSMENU = 0xFFFFFFFF;
        public const uint OBJID_TITLEBAR = 0xFFFFFFFE;
        public const uint OBJID_MENU = 0xFFFFFFFD;
        public const uint OBJID_CLIENT = 0xFFFFFFFC;
        public const uint OBJID_VSCROLL = 0xFFFFFFFB;
        public const uint OBJID_HSCROLL = 0xFFFFFFFA;
        public const uint OBJID_SIZEGRIP = 0xFFFFFFF9;
        public const uint OBJID_CARET = 0xFFFFFFF8;
        public const uint OBJID_CURSOR = 0xFFFFFFF7;
        public const uint OBJID_ALERT = 0xFFFFFFF6;
        public const uint OBJID_SOUND = 0xFFFFFFF5;

        private IAccessible accessible;
        private MSAAProperties properties;
        //构造函数
        public MSAASupport(IntPtr handle, uint OBJID)
        {
            object ppvObject = null;
            Guid guidCOM = new Guid("618736E0-3C3D-11CF-810C-00AA00389B71");
            AccessibleObjectFromWindow(handle, OBJID, ref guidCOM, ref ppvObject);
            this.accessible = ppvObject as IAccessible;
            if (this.accessible == null)
                throw new ArgumentException("当前句柄无效");
            this.properties = new MSAAProperties(this.accessible);
        }
        //构造函数
        public MSAASupport(IntPtr handle) : this(handle, OBJID_CLIENT) { }
        //构造函数
        public MSAASupport(IAccessible accessible)
        {
            this.accessible = accessible;
            if (this.accessible == null)
                throw new ArgumentException("当前句柄无效");
            this.properties = new MSAAProperties(this.accessible);
        }
        //构造函数
        public MSAASupport(IAccessible accessible, int childId)
        {
            if (accessible == null)
                throw new ArgumentException("当前句柄无效");
            if (childId < 0)
                throw new ArgumentException("子代元素ID不能为负值");
            if (childId == 0)
                this.accessible = accessible;
            this.properties = new MSAAProperties(accessible, childId);
        }
        //Accessible 接口
        public IAccessible Accessible { get { return this.accessible; } }
        //获取 MSAA 属性
        public MSAAProperties Properties { get { return this.properties; } }
        public static List<MSAASupport> GetAccessibleChildren(IAccessible accessible)
        {
            int childCount = 0;
            try { childCount = accessible.accChildCount; }
            catch { }
            object[] array = new object[childCount];
            int pcObtained = 0;
            if (childCount != 0)
                AccessibleChildren(accessible, 0, childCount, array, ref pcObtained);
            List<MSAASupport> result = new List<MSAASupport>();
            for (int i = 0; i < pcObtained; i++)
            {
                IAccessible child = array[i] as IAccessible;
                if (child == null)
                    result.Add(new MSAASupport(accessible, Convert.ToInt32(array[i])));
                else
                    result.Add(new MSAASupport(child));
            }
            return result;
        }
        public List<MSAASupport> GetAccessibleChildren()
        {
            return GetAccessibleChildren(this.accessible);
        }
        public static MSAASupport GetAccessibleChild(IAccessible accessible, int[] indexs)
        {
            if (indexs.Length != 0)
            {
                List<MSAASupport> children = GetAccessibleChildren(accessible);
                MSAASupport child = children[indexs[0]];
                if (child.Properties.ChildCount == 0)
                    return null;
                return GetAccessibleChild(child.accessible, indexs.Skip(1).ToArray());
            }
            else
                return new MSAASupport(accessible);
        }
        public MSAASupport GetAccessibleChild(int[] indexs)
        {
            return GetAccessibleChild(this.accessible, indexs);
        }
        #region API
        [DllImport("oleacc.dll")]
        internal static extern int AccessibleObjectFromWindow(
             IntPtr hwnd,
             uint dwObjectID,
             ref Guid riid,
             [In, Out, MarshalAs(UnmanagedType.IUnknown)]
             ref object ppvObject
            );

        [DllImport("oleacc.dll")]
        public static extern int AccessibleChildren(
            IAccessible paccContainer,
            int iChildStart,
            int cChildren,
            [Out()] [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)]
            object[] rgvarChildren, ref int pcObtained
            );
        #endregion
    }
}
以下为UI控件元素属性:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using Accessibility;

namespace QQSenders
{
    class MSAAProperties
    {
        private IAccessible accessible;

        private string _name;
        private string _role;
        private string _state;
        private string _value;
        private string _description;
        private int _childCount;
        private Rectangle _loaction;
        public string Name { get { return this._name; } }
        public string Role { get { return this._role; } }
        public string State { get { return this._state; } }
        public string Value { get { return this._value; } }
        public string Description { get { return this._description; } }
        public IAccessible Accessible { get { return this.accessible; } }
        public int ChildCount
        {
            get
            {
                try { this._childCount = this.accessible.accChildCount; }
                catch { this._childCount = 0; }
                return this._childCount;
            }
        }
        //构造函数
        public MSAAProperties(IAccessible accessible) : this(accessible, 0) { }
        //构造函数
        public MSAAProperties(IAccessible accessible, int childId)
        {
            if (accessible == null)
                throw new ArgumentNullException();
            if (accessible != null)
                this.accessible = accessible;
            this.GetProperties(childId);
        }
        //获取元素属性
        private void GetProperties(int childId)
        {
            try { this._name = this.accessible.get_accName(childId); }
            catch { }
            try { this._value = this.accessible.get_accValue(childId); }
            catch { }
            try { this._description = this.accessible.get_accDescription(childId); }
            catch { }
            try
            {
                uint role = Convert.ToUInt32(this.accessible.get_accRole(childId));
                this._role = GetRoleText(role);
            }
            catch { }
            try
            {
                uint state = Convert.ToUInt32(this.accessible.get_accState(childId));
                this._state = this._state = GetStateText(state);
            }
            catch { }
            try
            {
                int pxLeft, pyTop, pcxWidth, pcyHeight;
                this.accessible.accLocation(out pxLeft, out pyTop, out pcxWidth, out pcyHeight, childId);
                this._loaction = new Rectangle(pxLeft, pyTop, pcxWidth, pcyHeight);
            }
            catch { }
        }
        //获取控件名称
        private static string GetRoleText(uint role)
        {
            StringBuilder lpszRole = new StringBuilder(1024);
            GetRoleText(role, lpszRole, 1024);
            return lpszRole.ToString();
        }
        private const uint STATE_SYSTEM_ALERT_HIGH = 0x10000000;
        private const uint STATE_SYSTEM_ALERT_LOW = 0x04000000;
        private const uint STATE_SYSTEM_ALERT_MEDIUM = 0x08000000;
        private const uint STATE_SYSTEM_ANIMATED = 0x00004000;
        private const uint STATE_SYSTEM_BUSY = 0x00000800;
        private const uint STATE_SYSTEM_CHECKED = 0x00000010;
        private const uint STATE_SYSTEM_COLLAPSED = 0x00000400;
        private const uint STATE_SYSTEM_DEFAULT = 0x00000100;
        private const uint STATE_SYSTEM_EXPANDED = 0x00000200;
        private const uint STATE_SYSTEM_EXTSELECTABLE = 0x02000000;
        private const uint STATE_SYSTEM_FLOATING = 0x00001000;
        private const uint STATE_SYSTEM_FOCUSABLE = 0x00100000;
        private const uint STATE_SYSTEM_FOCUSED = 0x00000004;
        private const uint STATE_SYSTEM_HASPOPUP = 0x40000000;
        private const uint STATE_SYSTEM_HOTTRACKED = 0x00000080;
        private const uint STATE_SYSTEM_INVISIBLE = 0x00008000;
        private const uint STATE_SYSTEM_LINKED = 0x00400000;
        private const uint STATE_SYSTEM_MARQUEED = 0x00002000;
        private const uint STATE_SYSTEM_MIXED = 0x00000020;
        private const uint STATE_SYSTEM_MOVEABLE = 0x00040000;
        private const uint STATE_SYSTEM_MULTISELECTABLE = 0x01000000;
        private const uint STATE_SYSTEM_NORMAL = 0x00000000;
        private const uint STATE_SYSTEM_OFFSCREEN = 0x00010000;
        private const uint STATE_SYSTEM_PRESSED = 0x00000008;
        private const uint STATE_SYSTEM_READONLY = 0x00000040;
        private const uint STATE_SYSTEM_SELECTABLE = 0x00200000;
        private const uint STATE_SYSTEM_SELECTED = 0x00000002;
        private const uint STATE_SYSTEM_SELFVOICING = 0x00080000;
        private const uint STATE_SYSTEM_SIZEABLE = 0x00020000;
        private const uint STATE_SYSTEM_TRAVERSED = 0x00800000;
        private const uint STATE_SYSTEM_UNAVAILABLE = 0x00000001;
        private const uint STATE_SYSTEM_VALID = 0x1FFFFFFF;
        //获取状态文本
        private static string GetStateText(uint state)
        {
            StringBuilder focusableStateText = new StringBuilder(1024);
            StringBuilder sizeableStateText = new StringBuilder(1024);
            StringBuilder moveableStateText = new StringBuilder(1024);
            StringBuilder invisibleStateText = new StringBuilder(1024);
            StringBuilder unavailableStateText = new StringBuilder(1024);
            StringBuilder hasPopupStateText = new StringBuilder(1024);

            if (state == (STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_SIZEABLE | STATE_SYSTEM_MOVEABLE))
            {
                GetStateText(STATE_SYSTEM_FOCUSABLE, focusableStateText, 1024);
                GetStateText(STATE_SYSTEM_SIZEABLE, sizeableStateText, 1024);
                GetStateText(STATE_SYSTEM_MOVEABLE, moveableStateText, 1024);
                return focusableStateText + "," + sizeableStateText + "," + moveableStateText;
            }
            if (state == (STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_INVISIBLE))
            {
                GetStateText(STATE_SYSTEM_FOCUSABLE, focusableStateText, 1024);
                GetStateText(STATE_SYSTEM_INVISIBLE, invisibleStateText, 1024);
                return focusableStateText + "," + invisibleStateText;
            }
            if (state == (STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_UNAVAILABLE))
            {
                GetStateText(STATE_SYSTEM_FOCUSABLE, focusableStateText, 1024);
                GetStateText(STATE_SYSTEM_UNAVAILABLE, unavailableStateText, 1024);
                return focusableStateText + "," + unavailableStateText;
            }
            if (state == (STATE_SYSTEM_HASPOPUP | STATE_SYSTEM_UNAVAILABLE))
            {
                GetStateText(STATE_SYSTEM_HASPOPUP, hasPopupStateText, 1024);
                GetStateText(STATE_SYSTEM_UNAVAILABLE, unavailableStateText, 1024);
                return hasPopupStateText + "," + unavailableStateText;
            }
            var stateText = new StringBuilder((int)1024);
            GetStateText(state, stateText, 1024);
            return stateText.ToString();
        }

        #region API
        [DllImport("oleacc.dll")]
        private static extern uint GetRoleText(
            uint dwRole,
            StringBuilder lpszRole,
            uint cchRoleMax
        );
        [DllImport("oleacc.dll")]
        private static extern uint GetStateText(
            uint dwStateBit,
            StringBuilder lpszStateBit,
            uint cchStateBitMax
        );
        #endregion
    }
}

获取群组按钮位置:

            MSAASupport support = new MSAASupport(this.process.Handle);
            support = support.GetAccessibleChild(new int[] { 4, 1, 5, 0, 0, 0, 0, 0 });
            List<MSAASupport> children = support.GetAccessibleChildren();
            support = children.Find(i => i.Properties.Description == "群聊");


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值