喫茶XRAYトップページ

[スレッド全体
]

[6271] IAccessible返信 削除
2012/8/13 (月) 11:13:04 Taki
Mr.XRAYさん、みなさん
ご無沙汰しています。Takiです。

IAccessibleの仕組みについて教えてください。

基本的な「アクセシブル オブジェクト」と「単純要素」の関係です。

例えばのイメージですが、
Form1にPanel1を配置します。
Panel1にButton1とPanel2を配置します。
さらにPanel2にButton2を配置します。
※Panelはコンテナという意味で使っています。
「アクセシブル オブジェクト」はFormとPanel1、Panel2であり、
「単純要素」はButton1、Button2と考えて良いのでしょうか。

Form1
  Panel1 - ID1

Panel1
  Button1 - ID1
  Panel2  - ID2

Panel2
  Button2 - ID1

また、IDの割り当てもこれで良いでしょうか。
例えば、Panel2のサイズを得たいときはPanel1オブジェクトのID2で
アクセスすると考えて良いでしょうか。

よろしくお願いします。

[6272] Re:IAccessible返信 削除
2012/8/14 (火) 19:48:16 Taki
再び、Takiです。

やりたいことはButton2の座標位置からPanel2→Panel1→Form1の
情報を得たいのです。

SDKに付いてくるInspedt.exeのAncestorsのような情報が欲しいのです。

AccessibleObjectFromPointとAcc.get_accParentを組み合わせれば
できそうなので、マスターのサンプルプログラムのEnumAccTreeItemsを
参考にして親の情報を得るプログラムを書いてみました。

QueryInterfaceとかのコードの意味は全く理解できていません。
見よう見まねで書いたコードです。

手続きtestをTimerで3秒おきに呼び出して、その都度一覧を得ています。


function getOya(ko:IAccessible;oyalist:TMemo):IAccessible;
var
  varChild : OleVariant;
  AccDisp : IDispatch;
  rAcc :IAccessible;
  s : wideString;
begin
  result := nil;
  if (ko = nil) then exit;

  if ko.Get_accParent(AccDisp) = S_OK then  // koの親をAccDispで受け取る
  begin

    if Assigned(AccDisp) then       // AccDispが有効なら
    begin
      AccDisp.QueryInterface(IID_IAccessible,rAcc);   // rAccへ

    // 親のNameプロパティ 確認用
      TVariantArg(varChild).vt := VT_I4;
      TVariantArg(varChild).lVal := CHILDID_SELF;  // これでいいのか?
      if rAcc.Get_accName(varChild,s) = S_OK then
      begin
        oyalist.Lines.Append(s);
        result := rAcc;
      end;
    end else begin
      oyalist.Lines.Append('AccDisp 無効');
    end;
  end else begin
    oyalist.Lines.Append('Get_acc 失敗');
  end;
end;

procedure test;   // これをTimerで呼び出す
var
  pAcc : IAccessible;
  varChild : OleVariant;
  AccNext : IAccessible;   // 親のオブジェクト
  s : wideString;
  i : integer;
  mPos : TPoint;

begin
  GetCursorPos(mPos);
  if AccessibleObjectFromPoint(mPos,pAcc,varChild) = S_OK then
  begin
    FormMain.Memo1.Clear;
    // マウスの位置のNameプロパティ
    if pAcc.Get_accName(varChild,s) = S_OK then
    begin
      FormMain.Memo1.Lines.Append(s);
    end;

    // マウス位置のAccオブジェクトのNameプロパティ
    TVariantArg(varChild).vt := VT_I4;          // OleVariant型にセット
    TVariantArg(varChild).lVal := CHILDID_SELF;
    if pAcc.Get_accName(varChild,s) = S_OK then
    begin
      FormMain.Memo1.Lines.Append(s);
    end;

    accNext := pAcc;

    for i := 0 to 10 do   // 無限ループを回避するため
    begin
      accNext := getOya(accNext,FormMain.Memo1);
      if (accNext = nil) then break;
    end;

  end;
end;

ワードとかはリボンまでしかさかのぼれません。
Get_accParentを使う方法では限界があるのでしょうか。

忘れていました。私の環境です。
Windows7Pro(32Bit)+DelphiXE(Starter)
uses plEnumAccInfos.pas

[6274] Re2:IAccessible返信 削除
2012/8/16 (木) 00:18:05 Mr.XRAY
▼ Takiさん,どうも,レスが遅くなり,スミマセン.

[ 678_他のアプリの操作と IAccessible インターフェイス]
のIAccesible関係ですよね.
この記事は,少し説明が不足しています.
ただ,説明を追加するつもりも,実はないのですが(苦笑)
ちょっと説明が必要と思われます.
スミマセンが,明日(あっ,もう今日になっていますが)以降ということで,
ご容赦を.

提示のコードは,まだよく見ていませんが,
おそらく,希望の動作の実現はできないと思われます.
もちろん,IAccessibleを使用してでは,という意味です.

とりあえず,

>例えば、Panel2のサイズを得たいときはPanel1オブジェクトのID2で
>アクセスすると考えて良いでしょうか。


これが,おそらく,Takiさんの意図することとは,多分違うかも知れません.
スミマセンね.苦労されているところに水を差していまい.m(_ _)m

[6277] Re3:IAccessible返信 削除
2012/8/16 (木) 10:15:50 Mr.XRAY
分かりやすく説明できるか,自信はありません.

例えばActiveXというのがあります.
当サイトには,このActiveX,OCXなどの作成のサンプルなどの記事は
ありません.
一方,ActiveXの取り込み等の記事はあります.
つまり,利用側(クライアント)の使用方法となっています.

 IAccessible インターフェイスのサンプルは,クライアント側,つまり
利用する側のサンプルとなっています.
この IAccessible (MSAA)を実装する記事はありません.
Mozilla であれば,この実装の解説記事があります.
[MSAA サーバーを実装する]
http://www.mozilla-japan.org/access/windows/msaa-server.html

Delphi XE2までには,この{MSAAサーバ]の実装するための機能は
ないようです.
したがって,MSAA(IAccessible)は,既にそれを実装したアプリに
対しての操作ということになります.

>Form1
>  Panel1 - ID1


このIDですが,Windows API を使用すると

  SetWindowLong(Edit1.Handle, GWL_ID, 1000);
  SetWindowLong(Memo1.Handle, GWL_ID, 1100);

のように,各コントロールにID値を設定することができます.
しかし,このID値は,MSAA(IAccessible)のID値とは,全く別のものです.
残念ですが.また,

>ワードとかはリボンまでしかさかのぼれません。

のようです.これはいたし方ありません (^^;
展開して,例えば以下のように[貼り付け]であれば,ChildIDではなく,
nameプロパティの[貼り付け]で区別するしかないようです.
(図は,Windows XP(SP3) + Excel 2007)

で,肝心の

>Button2の座標位置からPanel2→Panel1→Form1の情報を

ですが,う〜ん.どんな方法がいいのか.考えてみます.


[6279] Re4:IAccessible返信 削除
2012/8/16 (木) 12:51:55 Taki
▼ Mr.XRAYさん

マスターありがとうございます。

>  IAccessible インターフェイスのサンプルは,クライアント側,つまり
> 利用する側のサンプルとなっています.


> Delphi XE2までには,この{MSAAサーバ]の実装するための機能は
> ないようです.
> したがって,MSAA(IAccessible)は,既にそれを実装したアプリに
> 対しての操作ということになります.


最初のパネルとボタンの例が悪く誤解を招いてしまいました。
WordやExcel、メモ帳といったアプリケーションのボタンやメニューからの
情報を得たいので、クライアント側での使用?になると思います。
panelに実装するつもりはありません。すみません。

> で,肝心の
>
> >Button2の座標位置からPanel2→Panel1→Form1の情報を
>
> ですが,う〜ん.どんな方法がいいのか.考えてみます.


Wordの「貼り付け」ボタンをクリックするとWordがForgroundWindowになるので
WindowFromAccessibleObjectからEnumAccObjectTreeで展開してLocationと
マウスの座標を比較して「貼り付け」ボタンをみつけ、
そこから逆に親の情報を得ていくという方法が確実なのかもしれません。

しかし、あまりにも遠回りなやり方なので…。

[▼次のスレッド]
INCM/CMT
Cyclamen v3.82