はじめまして。
現在Windows XP + Excel 2003(VBA)で開発を行っていて、ユーザーフォーム上のコントロールのaccValueやaccNameを取得したり、accDoDefaultActionでボタンを押したりしています。
ふと疑問に思ったのですが、Valueプロパティは下記のようなコードで書き換えることができたのですが、
Sub test()
Dim myAcc As IAccessible
Set myAcc = UserForm1
Set myAcc = myAcc.accChild(1&) 'テキストボックス
myAcc.accValue(CHILDID_SELF) = "123456"
Set myAcc = Nothing
End Sub
Stateプロパティを変更しようと下記のようなコードを実行しても、「オブジェクトが必要です」とのエラーメッセージが表示され、変更することができませんでした。
Public Const STATE_SYSTEM_INVISIBLE = &H8000
Sub test2()
Dim myAcc As IAccessible
Set myAcc = UserForm1
Set myAcc = myAcc.accChild(1&)
myAcc.accState(CHILDID_SELF) = STATE_SYSTEM_INVISIBLE
Set myAcc = Nothing
End Sub
IAccessibleのStateプロパティは変更できないのでしょうか?
もちろんコントロールのEnabledやVisibleプロパティを変更した方が早いとは思うのですが、気になったので質問させていただきました。
IAccessible.accState プロパティ (Accessibility)
http://msdn.microsoft.com/ja-jp/library/accessibility.iaccessible.accstate(VS.80).aspx
上のページで、下のように「ReadOnly」となっているので読み取り専用のようです。
Visual Basic (宣言)
ReadOnly Property accState ( _
<InAttribute> <OptionalAttribute> varChild As Object _
) As Object
上のページは.NET でしたねぇ;;
ExcelのVBAなら、オブジェクトブラウザでライブラリに「Office」を指定して、「非表示のメンバを表示」にチェックを入れて、「accState」を検索すれば下の方に、
Property accState([varChild])
読み取り専用
Office.IAccessible のメンバ
と出るので、「読み取り専用」だということが分ります。
> ceさん
レスありがとうございます。
オブジェクトブラウザで確認したところ、確かに「accState」は読み取り専用になっていました。
情報ありがとうございました。
# 他言語の話題で何ですが。
VC++だと、
pacc->
とアロー演算子を打ち込んだ時点でインテリセンスが効いて、
メンバにput_accStateなんてメソッドが、無いのが分かります。
---
#include <windows.h>
#include <oleacc.h>
#include <comdef.h>
#pragma comment( lib, "oleacc.lib" )
int main(){
HRESULT hr = ::CoInitialize( NULL );
if ( FAILED ( hr ) ) return -1;
HWND hWnd = ::FindWindow( L"ThunderDFrame", NULL);
if ( hWnd ){
hWnd = ::GetTopWindow( hWnd );
IAccessible* pacc;
hr = ::AccessibleObjectFromWindow( hWnd, OBJID_CLIENT, __uuidof( IAccessible ), (void**)&pacc);
if ( SUCCEEDED ( hr ) ) {
_variant_t varChild;
varChild.vt = VT_I4;
varChild.lVal = 1;
IDispatch* pDisp;
hr = pacc->get_accChild( varChild, &pDisp );
pacc->Release();
if ( SUCCEEDED ( hr ) ) {
hr = pDisp->QueryInterface( __uuidof( IAccessible ), (void**)&pacc );
pDisp->Release();
if ( SUCCEEDED ( hr ) ) {
//テキストボックスに設定。
varChild.vt = VT_I4;
varChild.lVal = CHILDID_SELF;
pacc->put_accValue( varChild, ::SysAllocString( L"テスト" ) );
pacc->Release();
}
}
}
}
::CoUninitialize();
}
# インデントが崩れたので。
---
#include <windows.h>
#include <oleacc.h>
#include <comdef.h>
#pragma comment( lib, "oleacc.lib" )
int main(){
HRESULT hr = ::CoInitialize( NULL );
if ( FAILED ( hr ) ) return -1;
HWND hWnd = ::FindWindow( L"ThunderDFrame", NULL);
if ( hWnd ){
hWnd = ::GetTopWindow( hWnd );
IAccessible* pacc;
hr = ::AccessibleObjectFromWindow( hWnd, OBJID_CLIENT, __uuidof( IAccessible ), (void**)&pacc);
if ( SUCCEEDED ( hr ) ) {
_variant_t varChild;
varChild.vt = VT_I4;
varChild.lVal = 1;
IDispatch* pDisp;
hr = pacc->get_accChild( varChild, &pDisp );
pacc->Release();
if ( SUCCEEDED ( hr ) ) {
hr = pDisp->QueryInterface( __uuidof( IAccessible ), (void**)&pacc );
pDisp->Release();
if ( SUCCEEDED ( hr ) ) {
//テキストボックスに設定。
varChild.vt = VT_I4;
varChild.lVal = CHILDID_SELF;
pacc->put_accValue( varChild, ::SysAllocString( L"テスト" ) );
pacc->Release();
}
}
}
}
::CoUninitialize();
}