2003-02-14 128060 [長年日記]

スレッドとWM_ACTIVATE

スクリプト中からMsgBoxを出していて気づいたのですが、WM_ACTIVATEのタイミングがおかしいことがあるようです。

Active Scriptingでスクリプトを走らせると専用のスレッドが作成されてそのスレッドでスクリプトが走ります。さて、スクリプトの中にMsgBoxがある場合には、メッセージボックスの親ウィンドウは、IActiveScriptSiteWindow::GetWindow()で返したウィンドウになります。当然このウィンドウは別のスレッドのものです。

MsgBoxをだすと、親ウィンドウは非アクティブになるので、WM_ACTIVATEを受け取ります。ここで、GetFocus()を呼び出すとなぜかメッセージボックスのOKボタンのウィンドウハンドルが返されます。普通にメインスレッドからメッセージボックスを出した場合には、メッセージボックスを出す直前にフォーカスを持っていたウィンドウのウィンドウハンドルが返されます。このため、アクティブになったときにフォーカスを復元することができません。

実はWM_ACTIVATEのプロシージャが直接別スレッドから呼び出されていて、そっちのスレッドのフォーカスのあるウィンドウを取得してしまっているのかと思いましたが、スクリプトのスレッド側からはSendMessage経由で呼び出されていて、プロシージャを実行しているのはちゃんとウィンドウの持ち主のスレッドでした。

確かに親ウィンドウと子ウィンドウの持ち主のスレッドが違うとWindowsはちゃんと動かないことが多いですが、これはどうやって回避しろというんでしょうね。。

IWebBrowser2::ExecWB

IWebBrowser2::ExecWBでOLECMDID_COPYが使えなくなってしまいました。この前まで動いていた気がするのですが、Windows Updateでセキュリティパッチをあてたからなのでしょうか。OLECMDID_SELECTALLは使えるので、ExecWB自体の使い方がおかしいということはないと思うのですが。。

Documentオブジェクト

Applicationオブジェクトに加えて、Documentオブジェクトのスケルトンも追加してみました。でもまだ出来るのは、

document.offline = true

くらいだったり。。

スレッド生成

スレッド生成のルーチンをちょっと見直しました。ちょっと遅いのでデータの持ち方をメモリ消費量優先から速度優先に変更。だいぶ早くなった気がします。メモリ消費量もそれほど変わらないですし。