首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >IAccessible实现-仅在控制窗口中可访问的名称?

IAccessible实现-仅在控制窗口中可访问的名称?
EN

Stack Overflow用户
提问于 2014-02-26 13:57:55
回答 1查看 841关注 0票数 4

我目前正尝试在我的自定义控件中实现IAccessible接口,以便能够自动测试我的GUI。我能够实现接口,并创建并使用StdAccessibleObject作为我不想更改的所有属性/函数的代理。但是,它并不像我想要的那样起作用。

MSAA访问的每个控件都有自己的Window- control,其中包含控件本身。在我的例子中,只有这个窗口获得我应用的name属性,真正的控件(在我的例子中是TCustomEdit的派生)具有标准值。

有人知道如何将可访问的名称附加到控件和控件窗口,甚至只是控件本身吗?

提前谢谢你的时间。

在我的代码下面。

我创建了一个包含IAccessible函数的类,它是在创建句柄后在编辑中创建的这个类ist的实例。

代码语言:javascript
复制
TXCustomEdit = class(TCustomMaskEdit, IXControl, ... , IAccessible)

...

strict private
  FAccessible: IAccessible;
  ...
  procedure WMGetMSAAObject(var Message : TMessage); message WM_GETOBJECT;
  ...
private
  procedure CreateHandle(); override;
  ...
protected
  property Accessible: IAccessible read FAccessible implements IAccessible;
  ...
end;

implementation
...

procedure TXCustomEdit.CreateHandle;
begin
  inherited CreateHandle;
  FAccessible := TXControlEigenschaften.Create(Self);
end;

procedure TXCustomEdit.WMGetMSAAObject(var Message: TMessage);
begin
  if Assigned(FAccessible) then
    (FAccessible as TXControlEigenschaften).WMGetMSAAObject(Message);
end;

我们班的宣言:

代码语言:javascript
复制
TXControlEigenschaften = class (TInterfacedObject, IAccessible)
strict private
  FControl: IXControl;
  FAccessible: IAccessible;

  // IAccessible
  function Get_accParent(out ppdispParent: IDispatch): HResult; stdcall;
  function Get_accChildCount(out pcountChildren: Integer): HResult; stdcall;
  function Get_accChild(varChild: OleVariant; out ppdispChild: IDispatch): HResult; stdcall;
  function Get_accName(varChild: OleVariant; out pszName: WideString): HResult; stdcall;
  function Get_accValue(varChild: OleVariant; out pszValue: WideString): HResult; stdcall;
  function Get_accDescription(varChild: OleVariant; out pszDescription: WideString): HResult; stdcall;
  function Get_accRole(varChild: OleVariant; out pvarRole: OleVariant): HResult; stdcall;
  function Get_accState(varChild: OleVariant; out pvarState: OleVariant): HResult; stdcall;
  function Get_accHelp(varChild: OleVariant; out pszHelp: WideString): HResult; stdcall;
  function Get_accHelpTopic(out pszHelpFile: WideString; varChild: OleVariant;
                                                      out pidTopic: Integer): HResult; stdcall;
  function Get_accKeyboardShortcut(varChild: OleVariant; out pszKeyboardShortcut: WideString): HResult; stdcall;
  function Get_accFocus(out pvarChild: OleVariant): HResult; stdcall;
  function Get_accSelection(out pvarChildren: OleVariant): HResult; stdcall;
  function Get_accDefaultAction(varChild: OleVariant; out pszDefaultAction: WideString): HResult; stdcall;
  function accSelect(flagsSelect: Integer; varChild: OleVariant): HResult; stdcall;
  function accLocation(out pxLeft: Integer; out pyTop: Integer; out pcxWidth: Integer;
                                           out pcyHeight: Integer; varChild: OleVariant): HResult; stdcall;
  function accNavigate(navDir: Integer; varStart: OleVariant; out pvarEndUpAt: OleVariant): HResult; stdcall;
  function accHitTest(xLeft: Integer; yTop: Integer; out pvarChild: OleVariant): HResult; stdcall;
  function accDoDefaultAction(varChild: OleVariant): HResult; stdcall;
  function Set_accName(varChild: OleVariant; const pszName: WideString): HResult; stdcall;
  function Set_accValue(varChild: OleVariant; const pszValue: WideString): HResult; stdcall;

  function GetIDsOfNames(const IID: TGUID; Names: Pointer;
    NameCount, LocaleID: Integer; DispIDs: Pointer): HResult; stdcall;
  function GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult; stdcall;
  function GetTypeInfoCount(out Count: Integer): HResult; stdcall;
  function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;
    Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult; stdcall;

public
  constructor Create(aControl: IXControl);

  procedure WMGetMSAAObject(var Message : TMessage); message WM_GETOBJECT;
end;

重要实现:

代码语言:javascript
复制
constructor TXControlEigenschaften.Create(aControl: IXControl);
var
  p: Pointer;
begin
  inherited Create();
  FControl := aControl;
  CreateStdAccessibleObject((FControl.GetOwnControl as TWinControl).Handle, OBJID_CLIENT, IID_IAccessible, p);
  FAccessible := IAccessible(p);
end;

procedure TXControlEigenschaften.WMGetMSAAObject(var Message: TMessage);
begin
  if (Message.Msg = WM_GETOBJECT) then
    Message.Result := LresultFromObject(IID_IAccessible, Message.WParam, Self)
  else
    Message.Result := DefWindowProc((FControl.GetOwnControl as TWinControl).Handle, Message.Msg, Message.WParam, Message.LParam);
end;

function TXControlEigenschaften.Get_accName(varChild: OleVariant; out pszName: WideString): HResult;
begin
  pszName := FControl.Name;
  Result := S_OK;
end;

接口的所有其他功能都是通过我的“代理”实现的,例如:

代码语言:javascript
复制
function TXControlEigenschaften.Get_accParent(out ppdispParent: IDispatch): HResult;
begin
  Result := FAccessible.Get_accParent(ppdispParent);
end;
EN

回答 1

Stack Overflow用户

发布于 2014-02-27 07:51:11

刚刚发现,只在窗口控件中使用名称是没有问题的,因为UI测试生成器总是在两个MSAA对象中搜索以标识控件。这就是为什么这个问题有点不必要。

如果有人知道这个问题的真正答案,我会接受的,但是没有必要解决这个问题,因为这对我的用例来说没有问题。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22043582

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档