gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 15:58:10 25 4
gpt4 key购买 nike

我目前正在尝试在我的自定义控件中实现 IAccessible 接口(interface),以便能够自动测试我的 GUI。我能够实现该接口(interface)并创建和使用 StdAccessibleObject 作为我不想更改的所有属性/函数的代理。但是,它并没有真正按照我想要的方式工作。

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

enter image description here

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

预先感谢您的宝贵时间。

在我的代码下面。

<小时/>

我创建了一个自己的类,其中包含 IAccessible 的功能,该类的实例是在创建句柄后在我的编辑中创建的。

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;

我的类(class)声明:

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;

重要实现:

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;

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

function TXControlEigenschaften.Get_accParent(out ppdispParent: IDispatch): HResult;
begin
Result := FAccessible.Get_accParent(ppdispParent);
end;

最佳答案

刚刚发现,仅在窗口控件中具有名称没有问题,因为 UI 测试生成器始终在两个 MSAA 对象中搜索以识别该控件。这就是为什么这个问题有点不必要。

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

关于winforms - IAccessible 实现 - 仅在控制窗口中可访问名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22043582/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com