エンタープライズ:特集 2003/07/04 17:20:00 更新
C Magazine

C MAGAZINE 2002年8月号より転載
プログラムのレシピ――プログラミングの考え方・作り方 (6/13)

グラフィックエディタの製作(2)
基本機能の作成−画像ファイルの読み書き

 それではいよいよ制作にとりかかりましょう。いちばん初めにどこから作るかはお好みしだいですが、お勧めなのは「グラフィックエディタとして最低限の基本機能」から作ることです。そこでまずは、

  • 画像ファイルを読み込む
  • ウィンドウに画像を表示する

というところまでを作ってみましょう。

画像ファイルの読み書き

 ビットマップファイルを読み込む機能はたいていのライブラリにあるので、既存の機能を使うのがいちばんです。Win32 APIの場合はLoadBitmap関数、VCLの場合にはTBitmapクラスのLoadFromFileメソッドを使います。一方、ファイルを保存する機能については、残念ながらWin32 APIにはありません(自作することはできます)。VCLではTBitmapクラスのSaveToFileメソッドが使えます。

 ユーザの操作手順も確認しておきましょう。ファイルを読み込むときの手順は、

  • [ファイル]→[開く]メニューを選択
  • ファイルダイアログでファイルを選択
  • 選択したファイルを開く

です。逆に保存のときには、

  • [ファイル]→[名前をつけて保存]メニューを選択
  • ファイルダイアログでファイルを選択
  • 選択したファイル名で保存

となります。

 SDI(Single Document Interface)アプリケーションにするか、MDI(Multi Document Interface)アプリケーションにするかも決めておきましょう。SDIは、ファイルごとにべつべつのアプリケーションウィンドウが開く方式です。一方MDIは、1つのアプリケーションウィンドウの中に複数の内部ウィンドウを表示して、各内部ウィンドウごとにべつべつのファイルを開く方式です。

 SDIとMDIにはそれぞれよさがありますが、一般にプログラミングが簡単なのはSDIアプリケーションです。そこで今回はSDIを採用しましょう。C++Builderの場合は、SDIをあとからMDIに変えたくなったときにも比較的簡単に変更できます。

●プログラム例

 C++Builderの場合には、まずプロジェクトとメインフォームを作成します。そしてフォームにメインメニューを配置し、[ファイル]→[開く]や[ファイル]→[名前をつけて保存]といったメニュー項目を追加します。続いてメニュー項目に対してイベントを設定して、ファイルの読み書き処理を書きます。

 Fig. 2はフォームの作成例です。ファイルの読み書きにファイルダイアログを使うので、読み込み用のOpenDialogコンポーネントと保存用のSaveDialogコンポーネントを配置します。またメインメニューには、Fig. 3のようにメニュー項目を追加しておきます。

Fig2

Fig. 2 メインフォーム


Fig3

Fig. 3 メインメニュー


 次にイベント処理を記述します。List 1はファイルの読み込み処理、List 2は保存処理です。

List 1 ファイルを開く処理(UGEditorForm.cpp)
// ファイルを開く
void TGEditorForm::OpenFile() {
    //========================================================= (1)
    // ファイルダイアログを開く
    if (OpenDialog-> Execute()) {
        try {
            // ビットマップを読み込む
            Bitmap-> LoadFromFile(OpenDialog-> FileName);
        } catch(...) {
            // エラー時にメッセージを表示
            Application-> MessageBox(
                ("ファイル"+
                    OpenDialog-> FileName+
                    "は読み込めません").c_str(),
                "ファイルの読み込みエラー",
                MB_OK
            );
        }
    }
}

List 2 ファイルを保存する処理(UGEditorForm.cpp)
// 名前を付けて保存
void TGEditorForm::SaveFileAs() {
    //========================================================= (1)
    // ファイルダイアログを開く
    if (SaveDialog-> Execute()) {
        try {
            // ビットマップファイルを保存
            Bitmap-> SaveToFile(SaveDialog-> FileName);
        } catch(...) {
            // エラーの場合はメッセージを表示
            Application-> MessageBox(
                "ファイルが書き込めません",
                "ファイルの書き込みエラー",
                MB_OK
            );
        }
    }
}

 ファイルダイアログ(OpenDialog、SaveDialog)はExecuteメソッドで開きます(List 1-(1)、List 2-(1))。ファイル名はFileNameプロパティで得られるので、これをLoadFromFileメソッドもしくはSaveToFileメソッドの引数とします。

 エラーが発生したときは、TApplicationクラスのMessageBoxメソッドを使ってメッセージボックスを表示します。MessageBoxメソッドはデバッグメッセージなどを表示するのにも便利なので、覚えておくといいでしょう。

 それからビットマップデータを保持するために、フォームのクラスにTBitmap型のメンバ変数(ここではBitmap)を追加する必要があります。List 3のように、変数Bitmapの宣言はクラス宣言のprivate部分に追加します。またこの変数は、メインフォームのコンストラクタの中でList 4のように初期化する必要があります。

List 3 ビットマップを保持する変数の宣言(UGEditorForm.h)
class TGEditorForm : public TForm
{
__published:    // IDE 管理のコンポーネント
    // ... 中略 ...
private:    // ユーザー宣言
    // ビットマップ
    Graphics::TBitmap *Bitmap;
    // ... 中略 ...
public:     // ユーザー宣言
    // ... 中略 ...
};

List 4 メインフォームのコンストラクタ(UGEditorForm.cpp)
__fastcall TGEditorForm::TGEditorForm(TComponent* Owner) 
    : TForm(Owner) {
    // メモリ確保
    Bitmap=new Graphics::TBitmap();
}

 変数やメソッドの宣言はヘッダファイル(拡張子.h、.hpp)、コンストラクタやメソッドの定義はソースファイル(拡張子.c、.cpp)に書く必要があります。ファイル間を行き来しなければならないので少々めんどうですが、C++Builderの場合はエディタのタブを右クリックすると、対応するファイルが簡単に開けます(Fig. 4)。あるいは[Ctrl]+[F6]キーを使っても同じです。

Fig4

Fig. 4 対応するヘッダファイルやソースファイルを開くためのポップアップメニュー


前のページ | 1 2 3 4 5 6 7 8 9 10 11 12 13 | 次のページ

[松浦健一郎(ひぐぺん工房),C MAGAZINE]

Copyright © ITmedia, Inc. All Rights Reserved.