2009年11月25日水曜日

ウィンドウハンドル

なんだかいきなりプログラミングの話。

別のアプリケーションのテキストボックスにテキストを入力する必要があって、
同僚に相談したところ、ウィンドウハンドルを取得すればできるって話だったんで、
実際にやってみたら、はまっちゃったって話です。

まず、何で組むってことからやったんだけど、
(軟派な?)使い慣れたVB6で組むことに。

それで、まず、Visual Basic 中学校の記事を参考に、やろうとしたところ、
自アプリケーションのForm外をクリックした時の座標を取得する方法がわからなくて(しょぼい)
とりあえず、対象のテキストボックスに自アプリケーションのFormの角を合わせて
ボタンか何かを押したときにその座標を取得するつもりで作り始めた。
が、Form.Left、Form.Top、は、WindowFromPointで指定する座標と違うってことで、
この案はボツ。


それで、再びくだんの同僚に相談したところ、
対象のテキストボックスが固定的なら、FindWindowで親のウィンドウハンドルを取得して、
EnumChildWindowで対象のテキストボックスを特定したらどうかとアドバイス。

子ウィンドウを列挙…(A)を参考にして作ってみたら、VBレスキュー(花ちゃん)で、
出ている通り(おそらく前出(A)の内容を改変したソースで質問されているらしい、私目も同様にコピペして改変していることは言うまでも無い)「DLL が正しく呼び出せません。」と出る。
結局、これはコールバック関数の引数の数が問題だったみたいで、LPARAM lParamを、
ひとつ仮引数として増やしてみると通った。

更に、ウィンドウハンドルが取得できれば、setWindowTextで、テキストが渡せると
思っていたが、甘くて、これは所謂キャプションを書き換えるだけで、
セットしたテキストは表示されない。Spy++なんかでみるとキャプションが
変わっている様はよくわかる。
結局SendMessageでWM_SETTEXTを第2引数で、
VB 「メモ帳」に書き込むで、されている様にして一件落着。