IAccessibleのStateプロパティを設定するには?

解決


ナナセ  2008-12-27 23:22:23  No: 101429  IP: 192.*.*.*

はじめまして。
現在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プロパティを変更した方が早いとは思うのですが、気になったので質問させていただきました。

編集 削除
ce  2008-12-28 22:25:09  No: 101430  IP: 192.*.*.*

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

編集 削除
ce  2008-12-29 00:49:49  No: 101431  IP: 192.*.*.*

上のページは.NET でしたねぇ;;

ExcelのVBAなら、オブジェクトブラウザでライブラリに「Office」を指定して、「非表示のメンバを表示」にチェックを入れて、「accState」を検索すれば下の方に、

Property accState([varChild])
    読み取り専用
    Office.IAccessible のメンバ

と出るので、「読み取り専用」だということが分ります。

編集 削除
ナナセ  2008-12-29 01:48:28  No: 101432  IP: 192.*.*.*

> ceさん

レスありがとうございます。
オブジェクトブラウザで確認したところ、確かに「accState」は読み取り専用になっていました。
情報ありがとうございました。

編集 削除
熊谷隆史  2008-12-29 12:21:01  No: 101433  IP: 192.*.*.*

# 他言語の話題で何ですが。
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();
}

編集 削除
熊谷隆史  2008-12-29 12:27:36  No: 101434  IP: 192.*.*.*

# インデントが崩れたので。

---
#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();
}

編集 削除