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
これはGetPictureInfoでも記述しています。 spi_api.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ではメニューなどの言語設定ができます(設定ダイアログの[ウィンドウ]の画面)。
この設定の結果はWin32(95/98/NT)環境では以下のレジストリに反映されます。
HKEY_CURRENT_USER:Software/takechin/Susie/Resource
Japanese : REG_DWORD : 英語(0) / 日本語(1)
この値が存在しない時は1(日本語)とする
またWin32s(Win3.1+Win32s 1.3C)環境ではWindowsディレクトリにあるファイルに以下のように保存されています。
ファイル名:Susie.ini
[Resource]
Japanese=英語(0) / 日本語(1)
この値が存在しない時は1(日本語)とする。このあたりはWin32と同じ
ダイアログは日本語と英語をそれぞれ用意しておいて上記レジストリの値を読んで切り替えてあげます。
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用とWin32(Win95/WinNT)用で違うものだからです。
Win32s用のMSVCRT40.DLLをVC++4.xのCDROMからコピーしなおすか、
VC++ Pro以上であれば使用するライブラリをスタティックリンクする事で
回避できます(Learning Editionでも統合環境からスタティックリンクのオプションが指定出来ないだけだそうです)。
しかしWin32s用のMSVCRT40.DLLはWin32s 1.30cの配布パッケージには含まれていないのでスタティックリンクする方がよいでしょう。
その他の原因としてPlug-inがWin32sでサポートされていないWin32 APIを使っていませんか?。 例えばTLS(Thread Local Storage)やMutexなどはWin32sではサポートされていません。 またWin32sでサポートされていないダイアログリソースのフラグもありますので注意しましょう(SpinコントロールやEditコントロールの右寄せなど;_;)。
また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時間ぐらい悩んだのは内緒です(^^;)。
補足:
spi_api.txtでは間違ったことは記述されていません。
単に読み手が引数の書かれている順に、説明も書かれていると暗に期待するために読み間違うだけです。
注意深く読めば間違うことはありません。
デバッグ中に見知らぬコードの中で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"を連打してきりぬけています。
SPIの仕様書においてフラグの説明はビットフラグ(2進数)として説明されています。 ですから、「SSS」が「1」とは「001(2進数)」のことです。
例:GetFileInfoで、メモリインタフェースかつファイル情報の大文字・小文字を同一視する場合。
この場合は「I」を1、「SSS」を1として呼び出します。
ですから、フラグは「xxxx xxxx 1xxx x001」を指定します。
このうちxには0を指定しますので「0000 0000 1000 0001(2進数)」となります。
つまり「0081(16進数)」となります。