基于MSAA的QQ界面信息获取的实现

时间:2021-11-17 00:08:58

主要技术(Microsoft Active Accessibility)讲解:

以下是微软对于此技术的说明

Microsoft Active Accessibility

Version 2.0

Purpose

Microsoft® Active Accessibility® 2.0 is a COM-based technology that improves the way accessibility aids work with applications running on Microsoft Windows®. It provides dynamic-link libraries that are incorporated into the operating system as well as a COM interface and application programming elements that provide reliable methods for exposing information about user interface elements.

For a copy of the Active Accessibility SDK documentation formatted in Microsoft Word or WinHelp, see theAccessibility home page on MSDN.

Where Applicable

By using Active Accessibility and following accessible design practices, developers can make applications running on Windows more accessible to many people with vision, hearing, or motion disabilities.

Developer Audience

Active Accessibility is designed primarily for C, C++, and Microsoft Visual Basic® developers. In general, developers need a moderate level of understanding about COM objects and interfaces as well as about Unicode.

Run-Time Requirements

Full support for Active Accessibility 2.0 is built into the Windows XP and Windows Server 2003 operating systems. Active Accessibility 2.0 also supports Microsoft Windows NT® 4.0 with Service Pack 6 and Windows 98.

MSAA的全称是Microsoft Active Accessibility。这是类似DCOM技术。技术模型是这样的,UI程序可以暴露出一个Interface,方便另一个程序对其进行控制。 MSAA技术的初衷是为了方便残疾人使用Windows 程序。比如盲人看不到窗口,但是盲人可以通过一个USB读屏器连接到电脑上, 读屏器通过UI程序暴露出来的这个Interface,就可以获取程序信息,通过盲文或者其它形式传递给盲人。MSAA提供了如此方便的功能, UI自动化测试自然可以借用这项技术。MSAA暴露出来的Interface叫做IAccessible。测试程序和目标UI程序互操作流程如下:

  1. 测试程序调用Windows API: AccessibleObjectFromWindow,传入目标UI程序HWND。

  2. AccessibleObjectFromWindow函数向UI程序发送WM_GETOBJECT消息。

  3. UI程序创建实现了IAccessible的内部类,然后通过LresultFromObject API把IAccessible 接口返回给测试程序。

  4. 测试程序拿到IAccessible接口,开始调用IAccessible接口函数操作测试目标。

  IAccessible接口里面的几个关键函数是:

  IAccessible.get_accChild/ IAccessible.get_accParent通过这两个函数,调用者可以浏览目标程序的窗口关系树,定位到UI元素。

  IAccessible.accLocation/I Accessible.accHitTest读取和分辨目标元素的屏幕位置。

  IAccessible.accName/ I Accessible.accSelect读取元素的名字,对UI元素进行指定的操作,比如选取Listbox里面的某一项等等。

  IAccessible.accValue 开发人员可以自定义value属性的实现。比如针对折线图控件,开发人员可以在accValue中返回折线的坐标数列。

  MSAA的理念 类似于test hook。 通过主动让UI程序暴露一个接口来让调用者控制。 在具体使用中,测试人员往往是结合MSAA和Win32 API操作,取长补短。一方面对于UI元素丰富的属性,比如style,钩选状态,是否最大化和模拟用户输入等,继续采用Win32 API。 另一方面用MSAA的优势来弥补Win32 API的一些不足,比如:

  由于MSAA有自己的get_accChild方法,使其控件树关系并不一定要和Win32 HWNDd关系对应一致。对于自绘窗口,虽然说只有一个HWND, 但是开发人员可以通过实现IAccessible接口来实现逻辑上的层次关系。比如Excel中就可以通过IAccessible把多个cell的子 IAccessible接口暴露给调用者。

  IAccessible的实现是由开发者提供, 开发者可以灵活地根据实际情况决定方法的实现。比如前面提到了折线图控件可以返回坐标数列。对于.NET WinForm, 微软在Framework中就提供了IAccessible的默认实现,这样在具体实现中,就可以处理.NET动态维护HWND的细节。

可见这个接口主要是用于软件测试和实现特殊的UI需求所用的 , 了解到这个技术之后我就想QQ会不会也使用了这个技术实现软件的测试呢 ?

结果是肯定的 , QQ的GUI也使用了这个接口 , 所以我们可以通过这个接口获取QQ窗口内部的信息 , 而且信息很全面 , 好在.NET中已经封装好了这一接口使得这一编程过程变得比较容易 , IAccessible接口在Accessibility命名空间下

实现窗口信息的获取需要配合oleacc.dll中提供的API来进行操作 , 下面是使用到的主要的API函数名

  1. public static extern int AccessibleChildren(
  2. IAccessible paccContainer,
  3. int iChildStart,
  4. int cChildren,
  5. [Out()] [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] object[] rgvarChildren,
  6. ref int pcObtained);
  7. internal static extern int AccessibleObjectFromWindow(
  8. IntPtr hwnd,
  9. uint id,
  10. ref Guid iid,
  11. [In, Out, MarshalAs(UnmanagedType.IUnknown)] ref object ppvObject);
  12. public static extern uint WindowFromAccessibleObject(IAccessible pacc, ref IntPtr phwnd);

转载请注明出处 : 文章来自CSDN  SadlyCodes的博客

希望大家可以通过这篇文章了解到更多的关于IAccessible接口的知识

最后附一张我的测试DEMO图:

基于MSAA的QQ界面信息获取的实现

为了防止盗图我加上了我自己的水印  如果违规请通知我  我会立即更改  谢谢