2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

IUIAutomationElement::GetCurrentPatternで返されるpatternObject(IUnknown)が、QueryInterfaceをまともに実装していなかったせいでハマった

Posted at

こんなことにはまったのは自分だけかもしれないが、忘備録代わりに残しておく

##忙しい人に
結論から言うと、QueryInterfaceなんて律儀に呼ばずにキャストしてしまえばいい。

##長々としたハマった経緯
とある他プロセスが生成したウィンドウ内にある、エディットコントロールを外部から操作するためにUIAutomationを利用して操作しようとUI Spyを使って、そのエディットコントロールをいろいろ調べたところ。
エディットコントロールはControl Patternとして、IValueProviderを実装しており、IValueProviderのSetValueを使えば文字列を書き換えられると分かったので、さっそく自分のプログラムに実装してみた。
問題のエディットコントロールのIUIAutomationElementを取得して、GetCurrentPatternを呼び出すところまでは大丈夫だったのだが、

CComPtr<IUIAutomationElement> editElm = 何とか見つけた;
CComPtr<IUnknown> spUnk;
editElm->GetCurrentPattern(UIA_ValuePatternId, &spUnk);
CComQIPter<IValueProvider> spValueProvider = spUnk;

spUnkに値は入っていて、GetCurrentPatternの呼び出しは成功していたのだが、
spValueProvider へ代入(代入時にQueryInterfaceが呼ぶようになっている)時に、spValueProviderがNULL になってしまうのだ。
UI Spyでの操作は問題ないのにどうしてこうなったのか1時間ほど悩み
いろいろ試行錯誤した結果、簡単に言ってしまえば、

CComPtr<IValueProvider> spValueProvider;
editElm->GetCurrentPattern(UIA_ValuePatternId, (IUnknown**)&spValueProvider);

律儀にQueryInterfaceなんて呼ばずに、無理やりキャストしてしまえばよいだけの話だった…。

その後は無事
spValueProvider->SetValue("書き換えたい文字列");
することができて
めでたしめでたし。

C++からUIAutomationなんてものをわざわざ使う人が少ないのか、情報が少なくて困った
この情報が、もし誰かの役に立てば幸いである。

2
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?