サイトマップ
-
Contents
-
Information
FileMaker プラグインインの作り方(2) - FileMaker で ZIP の圧縮解凍プラグインの作成
- FileMaker のプラグインを作ってみる
- FileMaker で ZIP の圧縮解凍プラグインの作成
MSのAccessと並んで人気のあるお手軽データベース「FileMaker」でプラグインを作る方法について紹介しています。2回目の今回は、ZIP形式での圧縮解凍を行うプラグインを作ってみます。
前回の復習
前回から、FileMaker のプラグインを作る方法を紹介しています。前回は、サンプルを少し改良して、簡単な自作関数を追加してみました。そして、プラグインのインストール方法、テストの方法も紹介しました。
今回作るプラグインについて
今回は、もう少し、実用的なものとして、ZIPファイルの圧縮・解凍を行うプラグインを作ってみます。圧縮解凍を行うライブラリには、「7-zip32.dll」を使います。つまり、ZIPファイルの圧縮解凍処理については、DLLに任せてしまって、今回は、FileMaker から、DLLを呼び出すためのインターフェイスを作るということです。
完成したプラグインと使い方
FileMakerのユーザーの方のために、コンパイルしなくても使えるWindowsバイナリを用意しました。必要な方は、以下からダウンロードしてお使いください。
- コンパイル済みFMXファイル
- http://aoikujira.com/demo/hakkaku/rc/2008053..
【インストールの方法】
プラグインを、FileMaker の extensions フォルダにコピーし、7-zip32.dll をWindows フォルダか、FileMaker のフォルダにコピーしておきます。
【追加される関数】
ZIP_Compress(対象ファイルパス;ZIPファイル名)
圧縮を行います。
ZIP_Expand(ZIPファイル名;展開ファイルパス)
解凍を行います。
ZIP_Command(コマンドライン)
各種コマンドラインを実行します。詳細は、7-zip32.dll のヘルプを見てください。
7-zip32.dll の使い方
プラグインを作る前に、7-zip32.dll をロードする簡単なサンプルを示します。以下のプログラムが、7-zip32.dll にある関数「SevenZip()」を実行する例です。
// 関数の戻り値
#define SEVENZIP_OK 0
#define SEVENZIP_NG 1
// 使いやすいように関数の型を定義
typedef int (WINAPI *SevenZipFunc_)(const HWND _hwnd, LPCSTR _szCmdLine, LPSTR _szOutput, const DWORD _dwSize);
// 7-zip32.dll でコマンドを実行する
int SeventZipDL(char* cmd)
{
HMODULE hModule = ::LoadLibrary("7-zip32.dll");
if (hModule == NULL) return SEVENZIP_NG;
SevenZipFunc_ SevenZipFunc = (SevenZipFunc_)::GetProcAddress(hModule, "SevenZip");
char output[65536];
int result = SevenZipFunc(0, cmd, output, 65535);
if (result != 0) {
MessageBox(0, output, "7-zip ERROR", MB_OK | MB_ICONERROR);
return SEVENZIP_NG;
}
::FreeLibrary(hModule);
return SEVENZIP_OK;
}
Windows でDLLをロードするには、Windows APIの「LoadLibrary()」を使います。そして、ロードしたDLLにある関数のポインタを取得するのが「GetProcAddress()」です。
7-zip32.dll の関数「SevenZip()」は引数に、圧縮や解凍のコマンドを指定します。圧縮なら「u (ZIPファイル) (圧縮するパス)」のように指定します。このままだとちょっと使いづらいので、コマンドを生成する関数も作りました。
// 圧縮をする
int SevenZipCompress(char* src, char* des)
{
char cmd[4096];
sprintf_s(cmd, 4096, "u -tzip \"%s\" \"%s\"", des, src);
return SeventZipDL(cmd);
}
// 解凍をする
int SevenZipExpand(char* src, char* des)
{
char cmd[4096];
sprintf_s(cmd, 4096, "x \"%s\" -o\"%s\"", src, des);
return SeventZipDL(cmd);
}
ご覧の通り、やっていることは非常に簡単です。sprintf() でコマンドラインを生成し、先ほど作った関数「SevenZipDL()」を呼び出しています。
FileMakerのプラグインとして登録する
それでは、これらの関数を、FileMaker のプラグインとして利用できるようにしてみましょう。前回と同じ要領で、FileMaker のサンプルを改良しながら作ってみます。
まず、手順を再確認しておきます。
- 文字列テーブルへの登録(FileMakerのメニューに表示するため)
- 文字列IDを決める
- 実際のリソースを定義
- 関数の定義を登録(FileMakerに関数を登録するため)
- 関数IDを決める
- 実際の関数を定義(ヘッダファイルと定義ファイルに)
- FileMakerに関数を登録する
(1)文字列テーブルへの登録
リソースファイル「FMPluginExample.rc」を編集
VS2008のExpress Editionを使っている場合は、エラーを回避するため「FMPluginExample.rc」を開いて、「#include "afxres.h"」の行を「#include "windows.h"」と書き換えます。
それから、「// String Table」以下を書き換えます。まず、文字列テーブルの1番を次のようにします。この11文字には意味があります。
STRINGTABLE
BEGIN
1 "XMpl1nnYYnn"
END
この文字列のはじめの4文字は、プラグインのIDを表します。各プラグインに固有のIDを割り当てます。マニュアルの開発ガイドによれば、このIDは、「F」「FM」「Web」以外からはじめなくてはなりません。IDに指定できるのは「0-9A-Za-z」です。(固有のIDを確実に割り当てるために、Apple Developer SupportのWebサイトでIDを登録するようにと勧めています。)ここではサンプルの通り「XMpl」を使っています。
5文字目は、常に「1」で、6文字目は、プラグインの「環境設定」ダイアログを使うかどうかを指定します。ここでは利用しないので「n」を指定します。7文字目は「n」を8文字目は、常に「n」、9文字目は、kFMXT_Idle メッセージが必要な場合「Y」を指定します。10、11文字目は常に「n」です。
これに引き続き、命令とその使い方を示す文字列を登録します。また、この名前で関数が登録されます。関数テーブルの番号は、後で関数を登録する箇所で指定します。
STRINGTABLE BEGIN 102 "ZIP_Command(コマンドライン)" 103 "ZIP_Compress(対象ファイルパス;ZIPファイル名)" 104 "ZIP_Expand(ZIPファイル名;展開ファイルパス)" END
それから、プラグインの説明を示す文字列テーブルを指定します。この文字列IDは固定となっています。
STRINGTABLE
BEGIN
128 "7-ZIP圧縮解凍プラグイン"
129 "このプラグインは ZIP形式のファイルを圧縮・解凍します。"
END
メインファイルは「FMPlugInExample.cpp」を編集
関数のIDをリソースの中で指定しましたが、使いやすいようにここで、IDを定数に登録します。
// General String IDs
enum {
ZIP_CommandID = 102,
ZIP_CompressID = 103,
ZIP_ExpandID = 104
};
(2)プラグイン関数を登録する
関数を識別するIDを設定する
次にプラグインの中で、関数を管理できるように、関数にIDをつけます。ファイル「FMPluginFunctions.h」を開いて、冒頭にある「Function IDs」に関数を識別する名前を追加します。
// Function IDs
enum
{
ZIP_Command,
ZIP_Compress,
ZIP_Expand
};
関数の定義をヘッダファイルで宣言
同じくファイル「FMPluginFunctions.h」を開いて、宣言する関数のプロトタイプ宣言を行います。これは、Do_XMpl_Version のプロトタイプ宣言をコピーして、関数名だけを書き換えたものです。
FMX_PROC(fmx::errcode) Do_ZIP_Command(short funcId, const fmx::ExprEnv& environment, const fmx::DataVect& dataVect, fmx::Data& results); FMX_PROC(fmx::errcode) Do_ZIP_Compress(short funcId, const fmx::ExprEnv& environment, const fmx::DataVect& dataVect, fmx::Data& results); FMX_PROC(fmx::errcode) Do_ZIP_Expand(short funcId, const fmx::ExprEnv& environment, const fmx::DataVect& dataVect, fmx::Data& results);
関数の定義(実体)を追加
次に、プラグインの関数を定義した「FMPluginFunctions.cpp」へ関数の実体を追加します。ここでは3つの関数を定義しています。
FMX_PROC(fmx::errcode) Do_ZIP_Compress(
short funcId,
const fmx::ExprEnv& environment,
const fmx::DataVect& dataVect,
fmx::Data& results)
{
fmx::errcode errorResult = 0;
char src[4096];
char des[4096];
// 引数を2つ取得する
fmx::TextAutoPtr param1;
fmx::TextAutoPtr param2;
param1->SetText( dataVect.AtAsText(0), 0, dataVect.AtAsText(0).GetSize() );
param1->GetBytes(src, 4096);
param2->SetText( dataVect.AtAsText(1), 0, dataVect.AtAsText(1).GetSize() );
param2->GetBytes(des, 4096);
// ZIPコマンドを実行
int res = SevenZipCompress(src, des);
// 戻り値をセット
fmx::FixPtAutoPtr num;
num->AssignInt(res);
results.SetAsNumber(*num);
return(errorResult);
}
FMX_PROC(fmx::errcode) Do_ZIP_Expand(
short funcId,
const fmx::ExprEnv& environment,
const fmx::DataVect& dataVect,
fmx::Data& results)
{
fmx::errcode errorResult = 0;
char src[4096];
char des[4096];
// 引数を2つ取得する
fmx::TextAutoPtr param1;
fmx::TextAutoPtr param2;
param1->SetText( dataVect.AtAsText(0), 0, dataVect.AtAsText(0).GetSize() );
param1->GetBytes(src, 4096);
param2->SetText( dataVect.AtAsText(1), 0, dataVect.AtAsText(1).GetSize() );
param2->GetBytes(des, 4096);
// ZIPコマンドを実行
int res = SevenZipExpand(src, des);
// 戻り値をセット
fmx::FixPtAutoPtr num;
num->AssignInt(res);
results.SetAsNumber(*num);
return(errorResult);
}
FMX_PROC(fmx::errcode) Do_ZIP_Command(
short funcId,
const fmx::ExprEnv& environment,
const fmx::DataVect& dataVect,
fmx::Data& results)
{
fmx::errcode errorResult = 0;
char buf[4096];
// 先頭にある引数を取得する
fmx::TextAutoPtr param;
param->SetText( dataVect.AtAsText(0), 0, dataVect.AtAsText(0).GetSize() );
param->GetBytes(buf, 4096);
// ZIPコマンドを実行
int res = SeventZipDL(buf);
// 戻り値をセット
fmx::FixPtAutoPtr num;
num->AssignInt(res);
results.SetAsNumber(*num);
return(errorResult);
}
関数をFileMakerに追加するコードを記述
関数を定義しただけでは、FileMakerから作った関数を認識させることはできません。最後に、FileMakerに関数を登録します。
メインファイルの「FMPlugInExample.cpp」を開いて、関数「Do_PluginInit()」を探してください。ここで、関数をFileMakerに登録する処理が記述されています。ここに以下を追加します。
// 今回、以下を追加 // ZIP_Command Do_GetString(ZIP_CommandID, name, true); Do_GetString(ZIP_CommandID, prototype); err = fmx::ExprEnv::RegisterExternalFunction(*pluginID, ZIP_Command, *name, *prototype, 1, 1, regFunctionFlags, Do_ZIP_Command); // ZIP_Compress Do_GetString(ZIP_CompressID, name, true); Do_GetString(ZIP_CompressID, prototype); err = fmx::ExprEnv::RegisterExternalFunction(*pluginID, ZIP_Compress, *name, *prototype, 2, 2, regFunctionFlags, Do_ZIP_Compress); // ZIP_Expand Do_GetString(ZIP_ExpandID, name, true); Do_GetString(ZIP_ExpandID, prototype); err = fmx::ExprEnv::RegisterExternalFunction(*pluginID, ZIP_Expand, *name, *prototype, 2, 2, regFunctionFlags, Do_ZIP_Expand);
また、関数を登録したら、登録を削除する処理も記述しましょう。同じく「FMPlugInExample.cpp」で、関数「Do_PluginShutdown()」に以下を追記します。
err = fmx::ExprEnv::UnRegisterExternalFunction(*pluginID, ZIP_Command ); err = fmx::ExprEnv::UnRegisterExternalFunction(*pluginID, ZIP_Compress ); err = fmx::ExprEnv::UnRegisterExternalFunction(*pluginID, ZIP_Expand );
これで、プラグインは完成です。コンパイルして、FileMakerのExtensionsフォルダにコピーして動作確認を行ってください。
まとめ
以上、手順に沿ってプラグインを作る方法を紹介しました。前回と今回で基本をしっかり押さえてしまえば、FileMaker 用だからと言って面倒なコードが必要ではないことが分かったと思います。サンプルや、プラグイン用のライブラリなどを読みながら作っていけば、案外手軽に作ることができるのではないでしょうか。特に、今回のような外部DLLを呼び出すだけのものでしたら、1日あればなんとかなると思いますので、本稿を参考に、ぜひ、挑戦してみてください。
プラグイン作成の参考になるもの
- FileMaker本家のプラグイン作成ガイド(PDF)
- http://www.filemaker.co.jp/downloads/pdf/FMP..
- 5章 サードパーティ FileMaker プラグインの開発
- CodeZine~FileMaker Proの機能を拡張するプラグインの作成
このサイトについて
TrackBack URL :
