2002-01-31 ストリームからロード [長年日記]

ストリームからロード

一時ファイルに書き出すのもかっこ悪いしパフォーマンスも悪そうだし、やっぱりストリームからロードしたい。と思ってちょっと調べたら、Loading HTML content from a Streamなんていうのを発見。

イベントをハンドリングしなくちゃいけないので、Connection Point関係を自前でやらなくちゃいけないのが面倒だけど、それほど手間ではなさそう。

でもそうすると、今度はmultipart/relatedで格納されているインラインイメージとかをロードするときのフックが必要(cid:....というURIからストリームにマップする)なんだけど、それはどうやるんだろうか?

メモリからロード

上に書いたやり方でHTMLをロードするとちょっと問題があることが発覚。

まともなHTMLならば問題なさそうなのだけれど、ちゃんとしていないHTMLをロードするとテキスト扱いになる。たとえば、いきなり<br>とかから始まるようなものとか。

で、色々と調べた結果、IWebBrowser2からget_DocumentしてIHTMLDocument2を取得して、そのインターフェイスに対して、open、write、closeを順番に呼び出していくことにした。これだと、MediaTypeを指定できるし(今のところtext/htmlしかサポートしていないみたいだけれど)、変なHTMLもそれなりに解釈してくれる。スクリプトからだったらよくつかったけど、こんなところで使うとは思わなかった。

ちなみに、2002/01/30に書いたセキュリティの制限は、多少ならばホストにIDispatchを実装して対応できるらしい(WebBrowser Customization)。今回の場合、ATL側のホストのIDispatchはいじれないのでダメだけど。

IInternetProtocol

上に書いたインラインイメージのハンドルは、IInternetProtocolを実装して、IServiceProviderのQueryServiceから返すことでできそう(ServiceIDがわからないけれど、IID_IInternetProtocolを要求してくる)。WebBrowserが"cid:..."というURLを見つけるとURLモニカがバインドするときに、IInternetProtocolを要求するようなので、このURLのIDと等しいContent-IDを持つパートのデータを用意して、IInternetProtocol::Readが呼ばれたときに返してやれば良さそう。

こんなことをしなくてもMHTML (Multipart HTML)を使えばよいじゃんという話もあるんだけれども、

1. 一度ファイルに落とさずにMHTMLをロードさせる方法がわからない

2. IE4(少なくともHPC2Kのやつ)はMHTMLをサポートしていない

というようなことによりメモリ中でぐりぐりやるのでした。


トップ «前の日記(2002-01-30) 最新 次の日記(2002-02-01)»