創建可訪問的UI組件的問題這個問題是指給定的解決方案 Creating Accessible UI components in Delphi與德爾福
我試圖使用從上面的問題解決的最後一個問題(here)解決說明我的問題。在如圖所示實現了IAccessible接口之後,我進行了調試並很高興,當我嘗試通過外部程序(在這種情況下,Visual Studio的Coded UI測試記錄工具)讀取WinForm屬性時,看到接口被訪問。
可訪問的名稱被設置爲我想要的,但它以某種方式丟失了,因爲該名稱仍未在WinForm屬性中定義。
下面的代碼:
聲明:
TXControlEigenschaften = class (TInterfacedObject, IAccessible)
strict private
FControl: IXControl;
FAccessibleName: string;
FAccessibleDescription: string;
// 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;
property AccessibleName: string read FAccessibleName write FAccessibleName;
property AccessibleDescription: string read FAccessibleDescription write FAccessibleDescription;
end;
了重要的實施情況:
procedure TXControlEigenschaften.WMGetMSAAObject(var Message: TMessage);
begin
Message.Result := LresultFromObject(IID_IAccessible, Message.WParam, Self);
end;
function TXControlEigenschaften.Get_accName(varChild: OleVariant; out pszName: WideString): HResult;
begin
pszName := '';
Result := S_FALSE;
if varChild = CHILDID_SELF then
begin
if AccessibleName <> '' then
pszName := AccessibleName
else
pszName := FControl.Name;
result := S_OK;
end;
end;
創建的使用TEDIT的推導界面,這裏關於c頌:
TXCustomEdit = class(TCustomMaskEdit, IAccessible, IXControl, IXCtrlInterface, ITBXValidate, IXReadOnly, IXChange,
IXDelete, IXCut, IXPaste, IXSelectAll, IXVisible, IComboEdit
{$IFNDEF PACKAGE}, IXDPISkalierung, IExtrafeldControl{$ENDIF PACKAGE})
strict private
procedure WMGetMSAAObject(var Message : TMessage); message WM_GETOBJECT;
FAccessible: IAccessible;
...
implementation
constructor TXCustomEdit.Create(AOwner: TComponent);
var
ce: TXControlEigenschaften;
begin
...
FSkalierungsZustand := TSkalierungsZustand.Create(Self);
end;
...
procedure TXCustomEdit.WMGetMSAAObject(var Message: TMessage);
begin
(FAccessible as TXControlEigenschaften).WMGetMSAAObject(Message);
end;
順便說一句,這只是一個調試解決方案,所以我會改變的東西,如消息後處理。
有人有一個想法,爲什麼我仍然在WinForms-Properties中得到一個空的名稱?
是否執行了「TXCustomEdit.WMGetMSAAObject」? –
是的,它也可以,並且我也可以調試到TXControlEigenschaften的get_accname並且名稱設置爲 –
剛剛發生了一些奇怪的事情:當我嘗試讀取Objects屬性後,通過對每個TXControlEigenschaften.WMGetMSAAObject調用進行調試時,名稱出現在我的財產清單。當我禁用斷點時,它不顯示名稱。 現在它變得荒謬...... –