2014-02-26 79 views
2

我目前正試圖在自定義控件中實現IAccessible接口,以便能夠自動測試我的GUI。 我能夠實現接口並創建並使用StdAccessibleObject作爲我不想更改的所有屬性/函數的代理。但是,這並不是我想要的。IAccessible實現 - 僅在控制窗口中可訪問的名稱?

MSAA訪問的每個控件都有自己的Window-Control,它包含控件本身。在我的情況下,只是這個窗口獲得我應用的名稱屬性,真正的控制(在我的情況下衍生TCustomEdit)具有標準值。

enter image description here

是否有人有一個想法如何追加訪問的名稱,用於控制和控制窗口,甚至只是控制自己?

提前感謝您的時間。

下面我的代碼。


我創建了一個自己的類,它包含的IAccessible,句柄創建之後在我的編輯創建此類IST的一個實例的功能。

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; 

我的類的聲明:

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; 

重要實現方式:

function TXControlEigenschaften.Get_accParent(out ppdispParent: IDispatch): HResult; 
begin 
    Result := FAccessible.Get_accParent(ppdispParent); 
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; 

接口的其他所有功能都可以通過我的 「代理」,如實施

+0

我迷路了。什麼是實際問題? –

+0

問題是,我在'get_accName'裏面添加的名字只在我選擇控件窗口時纔可見,而不是當我選擇控件本身時 –

回答

0

Just fo只有在窗口控件中才有名稱是沒有問題的,因爲UI測試生成器總是在兩個MSAA對象中搜索以識別控件。這就是爲什麼這個問題有點不必要。

如果有人知道這個問題的真正答案,我會接受它,但沒有必要解決這個問題,因爲這對我的使用案例沒有任何問題。