日記緑ログ

2006/07/03 ~ 2006/07/30

目次

戻る

Blog

impress.tv

[Create: 2006/07/03 20:29] [LastUpdate: 2006/07/03 20:30]

impress.tvで落語配信が始まっている。結構面白いぜ。

更新停滞の言い訳

[Create: 2006/07/09 21:34] [LastUpdate: 2006/07/09 21:46]

最近なにも書いていないのだがまあそりゃ書くことも無いからなのだがDoblogがUPしてからFirefoxあたりじゃ書き込みできないのが少し効いている気がする。

Firefox が軽いかというとIEのほうが軽い気がしてならないのだが(読み込み中のレンダリング時にはIEは固まるような動きをするのでそのあたりはFirefox のほうが軽く感じるかもしれない)、Firefoxを使って書き込みをしていたのだ。IEがセキュリティーホールが多いというよりもIEのセキュリティー ホールねらいのやつが多いのが決め手である。

IEはセキュリティーを高にしてCookieも全てさようなら状態なのでどうやったらログインできるねん。という形なのであんまり使えないのだ。あまり変なブラウザを使うと問題がありそうなのでFirefoxかなにかを使おうというわけだ。

要 するに少しユーザーが少ないやつのほうが安心(しきっては駄目なのだが)だろうという観点なのだ。じゃあOperaでも使ったらどうなのか。最近フリーに なったぜ。ということなのだがOperaは入れているのだ。ただ昔のこざっぱりしたインターフェイスから変化して実に鬱陶しい。むしろFirefoxより は軽いのだがIEと逆転しそうな勢いである。

FirefoxですらJavaScriptを切っているような私なのでDoblogは困る気がするのだがいちいち切り替えて頑張っていた。ところがFirefoxで書き込めないとなると話は別でじゃあずっと切りっぱなしでいいやとなって楽になった気がする。

た だしブックマーク等はFirefoxに集めておいたので(htmlになるので管理も楽チンだしOperaが完全フリーじゃない時代から両方つまみ食いして みたけどOperaの広告が画面解像度が狭い私にはきつく感じであきらめたりした経緯もあってとにかくしばらくはFirefoxだったのだ)どうしても Firefoxを起動してざっと眺めるという形になる。するとOperaとは疎遠になってしまって……という流れなのだ。

どうしたものなんだろうか。

IStream

[Create: 2006/07/28 20:28] [LastUpdate: 2006/07/28 20:44]

Win32のCOMにはIStreamというインターフェイスがある(言い回しが変かもしれないがともかくある)。

interfaces は抽象化できるように作られているのでkernel的なファイルハンドルとは違う(とはいってもNT系ではsocketをファイルハンドルとして ReadFileで利用できたりするが)。要するにメモリ上のデータだろうがファイルだろうが同様のストリームとして扱うことができるわけだ。

この考え方だと

Load(HANDLE hFile);

Load(LPCTSTR filename);

Load(LPVOID data, SIZE_T size);

のようにオーバーロード(的)関数を複数用意してやって~ということをせずに

Load(IStream* stream);

とするだけで済ませちまおうというようなことができるということになる。その分呼び出し側では一手間かかってしまうが。

COMはクラスというかオブジェクト指向というか伴った抽象化をDLLというなかなかあれなもので実現する奴なので癖はあるがなかなかいい奴である。Windows APIを見るとGDIやらkernelやらのC的な関数群のほうが資料も豊富で直感的に分かりやすい。

ただCOMはあちこちで(DirectXだとかShellだとかで)しばしば出てくるわけで(考えないようにして回避も可能だが)結構便利なんだと覚えておくといいかもしれないな。

と いう思いの裏にはSusie plug-inがあるのですね。あっちはファイルハンドル、こっちはメモリであっちはファイル名だとか仕様が混乱しています。IStreamで一発解決と いうわけにはいかないのかと思ったのですがそもそもそういう用途にはハンドルを用意してロードだけ手間をかければいいだけの話だったのだ。

ただし依然としてファイルとメモリ上のイメージの差を吸収するというメリットはある。そのメリットの重要性は数あるSusie plug-inたちの仕様の準拠度がいまいち(Susie本体で動けばいいやというつくり)なためであるのだった。

GDI+なんかでは実際IStream読み出しOKだったりするのが結構使える気がするのだが。

IStreamの利用

[Create: 2006/07/30 13:14] [LastUpdate: 2006/08/26 08:52]

Win32のCOMオブジェクトであるところのIStream(オブジェクトではなくIStream自体はinterfacesだが)の利点は抽象化だよという話で収めた。またしてもSusie plug-inのご登場だが単に普及している規格だからである。

'00AM'系のアーカイブ用のプラグインにはGetFileというExport関数が用意されている。宣言は

int _export PASCAL GetFile (LPSTR src, long len, LPSTR dest, unsigned int flag, FARPROC prgressCallback, long lData);

のようになっているのだが入力と出力はそれぞれflagによってファイル名ととったりメモリーブロックへのポインタととったりするので、ファイル入力ファイル出力、ファイル入力メモリ出力、メモリ入力ファイル出力、メモリ入力メモリ出力という4つのパターンが存在する。

残 念ながらSusie本体で動作すればよいという考えのプラグインが多くファイル出力がサポートされていないものが結構ある。そもそも4パターンも似たよう な処理ができるわけでどうすればいいのか悩むところである。メモリに出力するとなるとテンポラリファイルを用意するのは無駄でパフォーマンスが劣化する し、ファイル出力時にメモリを一旦確保すると大きめのファイルの場合に無駄が大きいと感じるだろう。

要するにそれを抽象化すればひとつの処理で済むのだ。内部でそのようにしてもいいが外部インターフェイス自体がそのようになっているほうが自由度が膨らむというわけだ。

さ てその話は前回もしたわけで実際IStreamを使うにはどうすればいいのだろうか。世の中はファイルハンドル渡しのような抽象度の低いものがわかりやす くとっつきやすいということか例があまりない気がする。使うとなると使える人が使うわけで資料はあえて放出されない気がするのだ。

一番簡単なのはSHCreateStreamOnFileを使うことだ。IE5以降に付属しているshlwapi.dllで使える関数でファイル名とオープンモードにLPSTREAM変数へのポインタを渡してやればファイルを開いてIStreamにできる。

メモリ上に作成する場合にはSHCreateMemStreamを 使えるがこれは元隠しAPIかなにかなのだろう。MSDNも"Import library None"だし、GetProcAddressで取得するときにも関数名ではなく順序値で指定しなければならない(はず。ちなみに12番らしい)。とは いってもCreateStreamOnHGlobalでも使えということかもしれない。

IE5が入っていないNT4や9xでこれらと同様の操作をしたい場合には自分で同様の関数を作成すればよい。

株式会社ワックドットコムのページには

ファイルからストリーム(IStream)を作成

http://www.wac-jp.com/programmers/win32/StreamHelper_Emulete_SHCreateMemStream.html

という実装例が掲示されているので参考にさせていただこう。

さて今までが前置きでこれからが本番である。ただし分量は少ない。

パス情報はShellでは文字列ではなくITEMIDLISTで扱う。IShellFolderなんかの例でよく見かけるのだがファイルはCreateFileで開くというような構造が多い気がする。

LPSTREAM stream;

shellFolder->BindToStorage(itemID NULL, IID_IStream, (void**)&stream);

としてやれば簡単にIStreamオブジェクトが得られるのだ。SHGetPathFromIDListでITEMIDLISTをパス文字列に変換云々は必要ない。いやこれがIStreamを使わないという場合には変換する必要があるのだが。

と もあれ作成は簡単である(ファイルについては)。DLLのインターフェイスでIStreamを使うのを推し進めたいという気持ちはあるのだがやっぱり普及 しないかもしれない。そもそもVistaの時代は.NET時代なのでCOMはCOMでもこんな部分は気にしないですむのだろう。済んでほしい。