このページも作成が全然進んでいません。 実際のところどうなんだって気になる人がいるかもしれないですが、 Mint Plug-inでよければ一応ソースを置いています。使う方のサンプルも付けてみました。
長らく注意書を忘れていましたがこのページで扱うPlug-inは00IN Plug-in(画像展開用)です。 00AM Plug-in(アーカイブPlug-in)は作ったことがないので割愛します。
以下の記述は経験的に得られたもので必ずしも正確であるとは限らないし、
間違っていることも多いと思うし、将来にわたってそうとは限りません。
と、一応逃げを打っておきます。
またSusie以外のSusie Plug-inを使うアプリケーションでは利用の仕方が違っている
可能性が大きいです。
例えばPlug-inと拡張子の関連付けをハードコーディングしているアプリケーションもあります。
私の壁紙チェンジャーではPlug-inのサポートしているファイルタイプを見ているので、
"JPEG"とか"JPE"となっているJPEGファイルは壁紙の対象にはなりません。
Susieと各画像ファイル用のPlug-inとの間のインタフェース(SPI)を簡単に説明します。
サポートしているPlug-inの種類(Import/Export/Archive)や対応している 代表的なファイルタイプ(*.JPGとか*.GIFとか)などの情報を取得します。 使用する事になっているPlug-inに対して、 Susieは起動時にこの関数をコールします。 [ファイル]-[開く]ダイアログのファイルタイプとフィルター、 [設定]ダイアログの拡張子関連付けで利用します。
Susieは指定されたファイルに対してIsSupportedを呼び出します。
GetPluginInfoのファイルタイプは(多分)利用されません。
つまりJpeg Plug-inに対して"Sample.pic"というファイルが渡される事もあり得るということです。
どれか一つのPlug-inが成功を返却すると他のPlug-inは呼び出されません。
またその後GetPictureInfoが失敗しても再度他のPlug-inに対してIsSupportedを呼び出すことはありません。
ですからこの関数の返す値は重要です。
表示対象となっている画像がファイルの場合には、 メモリーインタフェースで呼び出されます。 この関数が実際にファイルインタフェースで呼び出されることがあるかどうかは調査していません。
SusieではIsSupportedで成功を返却するとその直後に呼び出されますが、 Susie Plug-inを使用するアプリケーションの中でIsSupportedを呼び出さないで GetPictureInfoを呼び出すものがあります。 このためGetPictureInfoは必ずしもサポートしている画像形式がbufに指定されると 考えてはいけません。
bufで指定された画像に内蔵ドキュメントがない時にはlpInfoのhInfoはNULLにします。
Susie(Ver0.41)ではIsSupportedが成功を返すがGetPictureInfoが失敗を返すという状況があってもGetPictureを呼び出します。 おそらくGetPictureInfoの戻り値のチェックをしていないか、 またはGetPictureInfoが失敗を返した場合には単にコメントがないという風に扱っているのだと思われます。
pHBInfoはBITMAPINFO構造体を格納した領域へのハンドルです。 またこの領域にはパレットも含みます。 pHBmはピクセルデータ(と言って分かります?)が格納された領域へのハンドルです。
bufで指定された画像ファイルのアスペクト比が1:1でない時にはpHBInfoのBITMAPINFO 構造体中のbmiHeaderのbiXPelsPerMeterとbiYPelsPerMeterを使ってアスペクト比を 指定します。 これによりpHBmのデータを実際に編集せずに済みます。 アスペクト比の補正はSusieが表示の際に行ないます。
カタログ表示の時に呼び出されます。それ以外はGetPictureと同じ。
この関数が存在しないか、サポートされていない場合には、 GetPictureが使用されます。
Plug-in自身によるaboutダイアログ表示、設定ダイアログの表示を行ないます。 Susie Ver0.40以降よりサポートされています。 この関数は最新のPlug-in仕様のrev4には含まれておらず、 ドキュメントは今のところSusieの掲示板に書かれたものだけです。
parentは親ウィンドウのHWNDです。 fncは機能コードであり現在定義されているコードは次のものです。
機能コード | 意味 |
---|---|
0 | Plug-inのaboutダイアログ表示(必要であれば) |
1 | 設定ダイアログ表示 |
2以上 | 予約 |
戻り値 | 意味 |
---|---|
0 | 正常終了 |
-1 | インプリメントしていない |
>0(正の値) | エラー |
Plug-inのaboutダイアログを実装していなければ、SusieはGetPluginInfoで返却する Plug-in名を表示します。
以下、続かないかもしれない。
SUSIE配布ファイルの中にあるSPI_API.TXTからPlug-inのヘッダファイルを作成します。 これは機械的(手動で)に変換可能なのでがんばって書き換えます。
注意点としては構造体のアライメントの問題があります。 PictureInfo構造体のメンバはshortのメンバがあり、 VC++などのデフォルトのアライメントが8バイトのコンパイラで使用するとhInfoの オフセットがSusieが期待しているものとずれてしまいます。 これは内蔵DOCが表示されないという現象となってあらわれるので 分かりやすいです。
typedef struct SpiPictureInfo { long left,top; /* 画像を展開する位置 */ long width; /* 画像の幅(pixel) */ long height; /* 画像の高さ(pixel) */ WORD x_density; /* 画素の水平方向密度 */ WORD y_density; /* 画素の垂直方向密度 */ short colorDepth; /* 画素当たりのbit数 */ HLOCAL hInfo; /* 画像内のテキスト情報 */ } SpiPictureInfo;
コンパイルオプションで対策を打つのは美しくないのでヘッダファイルで処理します。 といいつつ、この対策はコンパイラに依存するので美しくないです。 実際にはヘッダファイルを参考していただくと分かるでしょう。
Plug-in制作中で私がはまった点について書いておきます。 他にも解決方法があるかもしれませんが、私の場合の解決法を書いておきます。 ちなみに以下の項目はおぼろげな記憶とバグ修正履歴から再構成してお送りしてます。
Plug-inの各APIはWin3.1で言うところのPASCAL呼び出し、
Win32で言うところの__stdcallです。
Win32でもWindows.hでは
#define PASCAL __stdcall
Mint Plug-inでの例
LIBRARY IFMINT.SPI
DESCRIPTION 'Susie Plugin. support mint title[HoshihanaKyoko-III] format'
EXPORTS
GetPluginInfo
IsSupported
GetPictureInfo
GetPicture
GetPreview
ConfigurationDlg
これはヘッダファイルのところでも書いたことです。 api_spi.txtからヘッダファイルを作った時にPictureInfo構造体メンバのオフセットがアライメントの関係で本来の位置とずれてしまったからです。
対策はPictureInfo構造体の前後を次のようにします。
VC++の場合
#include <pshpack1.h>
struct PictureInfo ......
#include <poppack.h>
BC++の場合(未確認)
#pragma option -a-
struct PictureInfo ......
#pragma option -a.
メモリインタフェースとファイルインタフェースのどちらも実装しましたか?。
GetPictureInfo/GetPicture/GetPreviewの各関数で ファイルインタフェースであった場合にファイルオフセットを きちんと扱っていますか?。
こんなのはまるの私だけ・・・だよね。
Susieではメニューなどの言語設定ができます(設定ダイアログの[ウィンドウ]の画面)。
この設定の結果は以下のレジストリに反映されます。
HKEY_CURRENT_USER:Software/takechin/Susie/Resource
Japanese : REG_DWORD : 英語(0) / 日本語(1)
この値が存在しない時は1(日本語)とする
ダイアログは日本語と英語をそれぞれ用意しておいて上記レジストリの値を読んで切り替えてあげます。
J6I Plug-in Ver 0.03ではこのことに気がついてなくて英語のリソースが存在しません。
もしかしてSusie起動時に以下のようなメッセージが表示されませんか?。
MSVCRT40.DLL for Win32
Error: This version of MSVCRT40.DLL is not compatible
with Win32s
これはMSVCRT40.DLLがWin32sとWin95/WinNTで違うものだからです。
Win32s用のMSVCRT40.DLLをVC++4.xのCDROMからコピーしなおすか、
VC++ Pro以上であれば使用するライブラリをスタティックリンクする事で
回避できます。
しかしWin32s用のMSVCRT40.DLLはWin32s 1.30cの配布パッケージには含まれていないのでスタティックリンクする方がよいでしょう。
その他の原因としてPlug-inがWin32sでサポートされていないWin32 APIを使っていませんか?。 例えばTLS(Thread Local Storage)やMutexなどはWin32sではサポートされていません。
またVC++4.2以上では正式にはWin32sはサポートされない事になっています。 しかしライブラリをDLLを使った時には上記のようなメッセージボックスを表示しますが、 スタティックリンクした場合にはWin32sかどうかを意識していません。 よってVC++4.2以上でもスタティックリンクする事で動作の可能性があります。 ちなみにMint Plug-in程度であればVC++4.2でもWin32sで動作していました。
Plug-in制作よりは利用の時にはまるかもしれません。
spi_api.txtのGetPictureの説明のところと関数ヘッダの定義のところで、
pHBInfoとpHBmの並び順が違うのでついプログラムを書く時に間違ってしまいます。
私が使っているヘッダではこの点は普通の順に並び変えています。
壁紙チェンジャーを作った時にはまって3時間ぐらい悩んだのは内緒です(^^;)。
デバッグ中に見知らぬコードの中でINT 3Hで止まってしまう事があります。 具体的には各Plug-in->LocalFree->RtlFreeHeap->.....->DbgBreakPoint のような呼び出しです。
私が少し追いかけたところでは、LocalFreeの中で呼ばれるルーチンのチェックコードに引っ掛かっているのは確認できました。 LocalFreeはSetLastError(ERROR_INVALID_HANDLE)を呼んでエラーコードを設定していることと、この現象が発生しないPlug-inがあることから、 該当のPlug-inかPlug-inが使っているライブラリの問題のような気がします。 lhasad.spi/ifgif.spi/ifpi.spi/ifpic.spiなどで発生します。
私はどうしようもないので(VC++で)"SPACE"と"F5"を連打してきりぬけています。
Plug-inを使うサンプルコードを公開します。 詳しい使い方をここに書いた方が良いのですが、 取り合えず同梱のドキュメントを参考にしてください。 メールを出すまでもないような質問であれば 掲示板 の方にでも書いてもらってもよいです。
一応断っておくと奇麗なソースじゃありません。 それとOCXとかいう高級なものでもありません。 単なるwrapperです。
以下の点を修正しています(1997/10/31)