2003-07-01 [長年日記]

[Q3] HTMLビューで外部リソースを表示しない (3)

というわけでフックしたところうまく動いているようです。

まず、IAxWinAmbientDispatchと同じvtblの構造を持ったクラスを作ります。これは素直にIAxWinAmbientDispatchから派生させればOKです。AtlAxGetHostで取得したIUnknownにQueryInterfaceしてIAxWinAmbientDispatchのインターフェイスポインタを取得します。このインターフェイスポインタのvtblを無理やり自分で作ったクラスのvtblに置き換えます。

これでブラウザコントロールがこのIDispatchを呼び出してくると自分のクラスのメソッドが呼ばれるようになります。必要のないメソッドに関しては元のvtblを保存しておいてそこから関数ポインタ経由で呼び出しておきます。Invokeが呼ばれたときにDISPIDがDISPID_AMBIENT_DLCONTROLの場合だけフラグを返すようにしてやればOKです。

自分のクラスのメソッドが呼び出されるときにはthisポインタが元々のオブジェクトを指していますので、static変数にマップを用意しておいて、本来の自分のオブジェクトを取得しないとメンバ変数などにアクセスできません。

本来はそのオブジェクトが実装する全てのインターフェイスのIUnknownのメソッドの呼び出しをフックしないと参照カウンタの管理がちゃんとできなくなってしまいますが(それをやってもクラス内部で参照カウンタをいじっているとどうしようもないのですけど)、今回の件に関してはブラウザコントロール側が作成されたときにQueryInterfaceして、破棄されたときにReeaseするだけのようなので、最初にReleaseが呼ばれたときにフックを解除してしまうようにしておきました。

フックしたクラスの実装によっては元のメソッドを呼び出すときにthisのオフセットを調節してやる必要があるかもしれませんが、今回はIDispatchImplが単一継承なので調節する必要はありませんでした。

[Q3] 並列同期

parallelモードで巡回すると複数の同期を並列に行えますが、巡回を使わなくても同期中に別の同期を始めるとそれもパラレルで実行されます。IMAP4で使っていると他のフォルダを同期中でも自分の見たいフォルダを同時に同期できるので結構便利です。

フォルダごとにToを指定

私はやっていないのですが、フォルダごとにToを指定しておきたいという話は結構あるようです。もちろんそれぞれのフォルダ用にテンプレートを用意すれば出来るのですが、文面などを指定しないでToを指定するだけならちょっと大げさです。

で、ちょっと思いついたのですが、.accountに<FolderName>_Toみたいなエントリを用意しておいて、テンプレートから@Profile('.account', @Folder(), 'To')のように呼び出すとよい感じです。qsというフォルダならqs_Toというエントリを用意しておくわけですね。

そう考えると、@Profileを使うと超簡易データベースが使えるということですから、他にも応用が利きそうです。


トップ «前の日記(2003-06-30) 最新 次の日記(2003-07-02)»