トップ » 技術記事 » FileMaker プラグインインの作り方(2) - FileMaker で ZIP の圧縮解凍プラグインの作成

FileMaker プラグインインの作り方(2) - FileMaker で ZIP の圧縮解凍プラグインの作成 はてなブックマーク数 このエントリーをブックマークに追加

MSのAccessと並んで人気のあるお手軽データベース「FileMaker」でプラグインを作る方法について紹介しています。2回目の今回は、ZIP形式での圧縮解凍を行うプラグインを作ってみます。

前回の復習

前回から、FileMaker のプラグインを作る方法を紹介しています。前回は、サンプルを少し改良して、簡単な自作関数を追加してみました。そして、プラグインのインストール方法、テストの方法も紹介しました。

今回作るプラグインについて

今回は、もう少し、実用的なものとして、ZIPファイルの圧縮・解凍を行うプラグインを作ってみます。圧縮解凍を行うライブラリには、「7-zip32.dll」を使います。つまり、ZIPファイルの圧縮解凍処理については、DLLに任せてしまって、今回は、FileMaker から、DLLを呼び出すためのインターフェイスを作るということです。

完成したプラグインと使い方

FileMakerのユーザーの方のために、コンパイルしなくても使えるWindowsバイナリを用意しました。必要な方は、以下からダウンロードしてお使いください。

【インストールの方法】

プラグインを、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日あればなんとかなると思いますので、本稿を参考に、ぜひ、挑戦してみてください。

プラグイン作成の参考になるもの

Series Navigation«FileMaker のプラグインを作ってみる

このサイトについて

八角研究所
株式会社八角研究所のWEBサイトですよー。 いろんなものを創り出すことのできる環境をコツコツ構築中。 いったい、いつになったらできるのか。 この技術情報サイトもそのための活動の一環のつもり。

執筆者紹介

クジラ飛行机

クジラ飛行机

くじらはんど(http://kujirahand/)にて、日本語プログラミング言語「なでしこ」(IPA未踏ユース採択)、テキスト音楽「サクラ」(OSPオンラインソフト大賞入賞)など多くのオンラインソフトを開発。著書に「Flexプロフェッショナルガイド」「なでしこ公式バイブル」、「一週間でマスターするActionScript3.0」など。

TrackBack URL :