MSAAのIAccessibleを使うには

解決


Atchoum  URL  2012-05-08 15:35:47  No: 42143  IP: 192.*.*.*

リンク先で.NETで作成されたアプリケーションのツールバー(ToolStrip)のボタンを押下したかったのですが
できなくて困っていたところ
IAccessible インターフェイスの accDoDefaultAction メソッドを試してみては?との情報をいただいたので
座標を指定してクリックという逃げ道を残しつつ、チャレンジすることにしました。
力尽きたので、どなたかinterfaceにお詳しい方のアドバイスいただければと思います。

-----------------------
・MSAAの準備
-----------------------
Microsoft Active Accessibility(MSAA)をつかうために
プロンプトで下記を実行します。
tlibimp -Hs- -Hr- -Ftoleacc -Ps- -O- %systemroot%\SYSTEM32\OLEACC.DLL
oleacc.pas,dcrが作成されます。
これをプロジェクトと、Usesに追加します。

【参考リンク】
http://www.stevetrefethen.com/blog/UsingtheMSAAIAccessibleinterfacewithinaDelphiApplication.aspx#comment

---------------------------------
・必須のサポートライブラリを作成
---------------------------------
ここのリンクのInterfaceUtilsUnitをコピーしてInterfaceUtilsUnit.pasを作成
http://tobysoft.net/wiki/index.php?Delphi%2Finterface%A4%F2%BB%C8%A4%AA%A4%A6%2F%C9%AC%BF%DC%A4%CE%A5%B5%A5%DD%A1%BC%A5%C8%A5%E9%A5%A4%A5%D6%A5%E9%A5%EA


---------------------------------
・テスト用プログラム作成
---------------------------------
usesに oleacc,  interfaceUtilsUnitを追加する。

実装するのは面倒なので参考リンク先を参考にしてMyInterfaceを宣言。

  TAccClass = class(TInterfacedBase, IAccessible)
    FMyInterface: IAccessible;
    property MyInterface: IAccessible read FMyInterface implements IAccessible;
    function accDoDefaultAction(varChild: OleVariant): HResult; stdcall;
  end;

【参考リンク】
http://delwiki.info/?%E8%B3%87%E6%96%99%2F%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%95%E3%82%A7%E3%82%A4%E3%82%B9



問題点1  どのようにaccDoDefaultActionを実装したらよいかわからない。
問題点2  ツールバーのボタンをクリックさせるためにどのようにしてaccDoDefaultActionを使ったらよいのかわからない。
    clsAcc := TAccClass.Create;
    try
      AccIfc := clsAcc;
      //AccIfc.accDoDefaultAction();
    finally
      clsAcc.Free;
    end;

よろしくお願いいたします。

編集 削除
Mr.XRAY  2012-05-08 19:04:36  No: 42144  IP: 192.*.*.*

こんちには.

>IAccessible インターフェイスの accDoDefaultAction メソッドを試して

ええっと,ちょっと待ってください.前のレッドに確かDelhiのバージョンが...
あっ,書いてあった.Delphi 2007でしたよね.でしたら,
IAccessibleインターフェイスは実装されています.

accDoDefaultActionですが,例えば,エクセルなんかですと,ツールバー,
コマンドバーに,あることを実行するコマンドが決まっています.
これを実行するやつですね.

accDoDefaultActionではないですが,IAccessible インターフェイスの簡単な使用例です.
前のスレッドでの,ツールバーのボタンの数を調べます.
usesにoleaccが必要です

const //* Reserved IDs for system objects
  OBJID_WINDOW            = $00000000;
  OBJID_SYSMENU           = $FFFFFFFF;
  OBJID_TITLEBAR          = $FFFFFFFE;
  OBJID_MENU              = $FFFFFFFD;
  OBJID_CLIENT            = $FFFFFFFC;
  OBJID_VSCROLL           = $FFFFFFFB;
  OBJID_HSCROLL           = $FFFFFFFA;
  OBJID_SIZEGRIP          = $FFFFFFF9;
  OBJID_CARET             = $FFFFFFF8;
  OBJID_CURSOR            = $FFFFFFF7;
  OBJID_ALERT             = $FFFFFFF6;
  OBJID_SOUND             = $FFFFFFF5;
  OBJID_QUERYCLASSNAMEIDX = $FFFFFFF4;
  OBJID_NATIVEOM          = $FFFFFFF0;

procedure TForm1.Button1Click(Sender: TObject);
var
  hTargetWnd  : HWND;
  hToolBar    : HWND;
  oAccessible : IAccessible;
  Ret         : HRESULT;
  vValue      : Integer;
begin


  //hToolBarはツールバーのハンドルとする
  Ret := AccessibleObjectFromWindow(hToolBar, OBJID_WINDOW, IID_IAccessible, oAccessible);
  if Ret = S_OK then begin
    oAccessible.Get_accChildCount(vValue);
    ShowMessage(IntToStr(vValue));
  end;
end;

編集 削除
Mr.XRAY  2012-05-08 19:11:51  No: 42145  IP: 192.*.*.*

ゴメンなさい.これ間違いです.

>    oAccessible.Get_accChildCount(vValue);
>    ShowMessage(IntToStr(vValue));

編集 削除
Atchoum  2012-05-09 10:20:04  No: 42146  IP: 192.*.*.*

XRayさん

こんにちわ。
前回記載したいろいろな準備は不要なようでした。
oleaccはdelphiインストールフォルダ配下\win32\rtl\win\oleacc.pasがありました。
しかも上の方法で作成したものにAccessibleObjectFromWindowが宣言されておらず、XRAYさんのサンプルが動きませんでした。ドンマイ自分。

思いがけず簡単に動かせるみたいですね。

サンプルでいただいたコードを試しましたが、
正しいツールボタンの数はかえってこなかったので間違いとおっしゃっていたのはそういうことかな。
でもエラーなく動くのがわかったので糸口が見つかりました。
ありがとうございました。

編集 削除
Atchoum  2012-05-09 14:02:31  No: 42147  IP: 192.*.*.*

フランス語のページですが、
ここにIAccessibleを使ったサンプルがありました。
ダウンロードしてみたらカーソル位置のコントロールの情報が取れました。
こちらのソースのoleacc.pasは、サンプル作成者によってかなり修正されていました。

※ダウンロードするにはサイトの登録が必要です。

http://files.codes-sources.com/fichier.aspx?id=28611&f=Unit1.pas

IAccessibleで困ったときは参考になるかと思います。

編集 削除
Atchoum  2012-05-09 14:51:26  No: 42148  IP: 192.*.*.*

OBJID_WINDOWをOBJID_CLIENTにしたら正しいカウント数が取得できました。

  Ret := AccessibleObjectFromWindow(hToolBar, OBJID_CLIENT, IID_IAccessible, oAccessible);
  if Ret = S_OK then begin
     oAccessible.Get_accChildCount(vValue);
     ShowMessage(IntToStr(vValue));
  end;

編集 削除
Atchoum  2012-05-09 15:03:24  No: 42149  IP: 192.*.*.*

できました。
ツールバー上の3番目のコントロールを押下してます。
ツールバーの動かす部分?(点が縦に並んでいる部分)も子のカウントに含まれるようで、それを1番目と数えて、3番目のボタンを押しています。
oleacc.pasはdelphiインストールフォルダ配下source\win32\rtl\win\oleacc.pasのものを使っています。

varChild:VARIANT;
pDisp:IDispatch;

  Ret := AccessibleObjectFromWindow(hToolBar, OBJID_CLIENT, IID_IAccessible, oAccessible);
  if Ret = S_OK then begin
     oAccessible.Get_accChildCount(vValue);
     ShowMessage(IntToStr(vValue));

     varChild := 3;
     oAccessible.get_accChild(varChild,pDisp);
     oAccessible.accDoDefaultAction(varChild);
  end;

編集 削除
Atchoum  2012-05-09 15:09:34  No: 42150  IP: 192.*.*.*

上ソース、oAccessible.get_accChild(varChild,pDisp);の部分は不要です。

varChild := 3;
oAccessible.accDoDefaultAction(varChild);

編集 削除
Mr.XRAY  2012-05-09 15:54:12  No: 42151  IP: 192.*.*.*

こんちには.

>できました。

うぉー,すごいですね.
OBJID_WINDOW こいつは失礼しました.
以前エクセルだか,ワードで試してやつなもんで.
IAccessibleインターフェイスが,自分で実装しなくてもいい.という意味のレスとして
ご容赦ください.    
確か,Delphi 2007からの実装だと.

是非,当サイトのサンプルプログラム集に掲載させてください.

編集 削除
Atchoum  2012-05-09 16:37:14  No: 42152  IP: 192.*.*.*

XRayさん

「こんちにわ」になってますよ!

XRayさんのおかげでできたようなものです。
サンプルにぜひ載せてください。

編集 削除
Mr.XRAY  2012-05-09 23:42:27  No: 42153  IP: 192.*.*.*

>「こんちにわ」になってますよ!

えっ? そう言いませんか?
ウソです.よく間違えるんです.

編集 削除
Mr.XRAY  2012-05-10 00:17:52  No: 42154  IP: 192.*.*.*

失礼しました.
先程,サイトに掲載する記事のために調べたら,OBJID_CLIENT等の定数は,
Winows.pas内で定義されていますね.
constの部分のコードは必要ありませんね.

編集 削除
Mr.XRAY  2012-05-15 16:59:35  No: 42155  IP: 192.*.*.*

こんにちは,Mr.XRAYです.

というわけで(どういうわけだ?),サンプル作成してみました.
toolStripだけじゃつまらないので,何かいいサンプルはないかと,考えていたら...
遅くなってしまいました.
結局考えついたのはこんもんです.

[678_他のアプリの操作と IAccessible インターフェイス]
http://mrxray.on.coocan.jp/Delphi/plSamples/678_IAccessibleInterface.htm

編集 削除