こんなことにはまったのは自分だけかもしれないが、忘備録代わりに残しておく
##忙しい人に
結論から言うと、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なんてものをわざわざ使う人が少ないのか、情報が少なくて困った
この情報が、もし誰かの役に立てば幸いである。