ホーム
|
アプリケーション | Tips | ダウンロード | プログラム
| コラム

CBアプリ工房


アプリケーション > 解凍ソフトは難しい![ 1 | 2 ]

解凍ソフトは難しい! - 1/2

更新 : 2009/01/14

 



実行時の解凍ソフト 完成品

今回、コンピュータ対戦型リバーシゲームの解説をする予定だったのですが、要望の寄せられた、解凍ソフトを急きょ作成することにしました。

解凍(圧縮)ソフトというのは、私がアプリケーションを作り始めたとき、作ってみたかったソフトのひとつです。ファイルが圧縮されたり、元に戻ったり、とても不思議でした。「どうしたらあんなことができるのだろう? 自分でも作ってみたい」――そう思っていました。
今回は、そうしたこともあってなんだか解説が楽しみです。皆さんもファイルが解凍(圧縮)される楽しさ、それを自分で作ったときの喜びを味わってください。

解凍(圧縮)ソフトを作るには、UNLHA32.DLL というダイナミックリンクライブラリ(スタティックライブラリも参照しておいてください)ファイルが必要になります。これはインターネット(統合アーカイバ・プロジェクト)から入手できます(入手後、各種ドキュメントをよく見ておくことをお勧めします)。

解凍(圧縮)ソフト作成のポイント
●LoadLibrary/GetProcAddress などの API 関数の使い方。
●提供される DLL の情報・仕様の読解力。
以上ちょっと頑張れば(やっかいですが)作成できます。

例によって VCL 等については説明していませんので、分からないプロパティ/メソッドはヘルプで調べてください。

細かい部分は、その都度考えることにして、さっそくフォームの作成から行ってみましょう。



まず、新規にアプリケーションを作成し、以下のコンポーネントを適当に配置します。

Name プロパティを変え、Caption にはボタンの機能がわかるような文字列を入力しておきます。サイズや位置は適当でかまいません。今回 Memo1 への入力は必要ありませんので、 ReadOnly を true にしておきます。ポップアップメニューも必要ないので、PopupMenu プロパティにダミーの PopupMenu1 を設定しておきます。Form の BorderIcons の biMaximize を false に BorderStyle を bsSingle にしてサイズも制限しておきます。

解凍ソフト 解説

コンポーネント Name 説明
TMemo Memo1 解凍の結果を表示します。
TOpenDialog OpenDialog1 圧縮ファイルを指定します。
TPopupMenu PopupMenu1 ダミーとして使います。
TButton ExtractBtn, 
ExitBtn
Caption を各々 "書庫ファイル展開"、"終了" としてください。

ヘッダーファイル Unit1.h のコーディングから行きます。
今回使う変数とメンバ関数を宣言しておきます。

まず、インスタンスのハンドルを保持させるために、HINSTANCE hDll を宣言します。次に WinAPI で DLL の関数のアドレスを取得する必要があるので、呼び出したい関数(Unlha)と同じプロトタイプの関数へのポインタを typedef(既存の型に対して新しい名前を作成。分かりやすいコードが記述できる) しておきます(typedef の部分は、先ほど紹介したドキュメントの中に書かれています)。


最後に、関数ポインタ ProcUnlha Unlha を宣言しておきます。


private: // ユーザー宣言
    //DLLのロードのための変数宣言
    HINSTANCE hDll;

    //DLL呼び出し関数の宣言(Unlha32.dllのUnlha関数を呼び出す)
    typedef int WINAPI (*ProcUnlha)(const HWND _hwnd,
                                    LPCSTR _szCmdLine,
                                    LPSTR _szOutput,
                                    const DWORD _dwSize);

    //関数ポインタ
    ProcUnlha Unlha; 

C++Builder で DLLを使うには、静的リンクと動的リンクという方法があります。
今回は、動的リンクを採用してみます
静的リンクに関しては、時間のあるときにヘルプを読んでください)。

それでは、ソースファイル Unit1.cpp にインプリメントして行きます。

Form 起動時、UNLHA32.DLL が存在するかどうか LoadLibrary 関数の戻り値を使って調べます。LoadLibrary 関数は、正常に終了した場合、 インスタンスのハンドルを返しますが、それ以外(つまり UNLHA32.DLL が存在しない場合)は NULL を返します。

NULL が返ったら、見つからない旨のメッセージを表示させて、アプリケーションを終了します。
存在した場合は、GetProcAddress という API 関数を呼び出し、LoadLibrary で得られたハンドルと DLL 内の関数名(Unlha)を引数として、Unlha のアドレスを取得します("Unlha" という関数を探しているわけですね)。


void __fastcall TForm1::FormActivate(TObject *Sender)
{
    //DLLのロード
    hDll = LoadLibrary("UNLHA32.DLL");

    if (!hDll){
        //DLLが見つからなかった場合
        Application->MessageBox(
                            "UNLHA32.DLL が見つかりませんでした。",
                            "DLL エラー",
                             MB_ICONSTOP | MB_OK);
        Close();
    } else
        //DLLがあったら関数ポインタを取得する
        Unlha = (ProcUnlha)GetProcAddress(hDll, "Unlha");
} 

続く・・・。



[ ホーム | ページトップ | 次へ | ブック | リンク | サイトマップ ]
Copyright(c) 2003 Shibu All rights reserved.