エディタのGUI化
 
 
[ index | 前のドキュメント | 次のドキュメント | このドキュメントのソース ]
■ GUI
今日では一般的なアプリケーションのほとんどはGUI化されてしまった。CUIに比べGUIは初期学習コストが低く初心者向けであるが、エキスパートにとっては非効率である場合もある。そしてなによりプログラムの作成工数が大幅に増加する。とは言っても、非GUIなエディタではユーザを獲得できそうもないので、エディタをGUI化する方法について述べないわけにはいかない。
メジャーなGUI環境としては、MS-Windows, Mac OS, X-Window などがある。通常、それぞれの環境でGUIのための実装方法は異なる。本稿では、MS-Windows 環境下で VC++6.0 を使い、MFC を利用し、ファイルオープン、表示が可能なエディタ(ビューワと呼んだ方がいいかも知れない)の実装方法を示す。MFC は Microsoft Foundation Class ライブラリの略で、Windows API の軽いラッパークラス、アプリケーション、ウィンドウなどを抽象化したクラス、文字列などのユーティリティクラス群を含むクラスライブラリである。必ずしも出来がいいとは言えないが、(プロによる)多くのアプリケーション開発で利用されているデファクトスタンダード的なものである。
■ AppWizard によるプログラム作成
VC++ で AppWizard を利用し、プログラムのスケルトン(骨子)を作成する。
MFC AppWizrad (exe)、
プロジェクト名は ge とする
MDI を選ぶ
■ エディットエンジンの組み込み
CEditEngine クラスの宣言、実装ファイルを作成し、プロジェクトに加える。
CDocument の派生クラスのメンバ変数に CEditEngine m_ee; を加える。
CGeDoc::OnNewDocument() で、m_ee の初期化を行う。

BOOL CGeDoc::OnNewDocument()
{
    if (!CDocument::OnNewDocument())
        return FALSE;

    m_ee.removeAll();       //  エディットバッファをクリア

    return TRUE;
}
■ ファイルオープン
一般的な形式のファイルを取り扱うのだから、シリアライズは使用しない。
クラスウィザードで CGeDoc::OnOpenDocument() をオーバライドする。以下のようなコードが自動生成される。

BOOL CGeDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
    .....
    return TRUE;
}
lpszPathName にはオープンするファイルのフルパス名が入っているので、その名前のファイルを読み込み、エディットバッファに格納すればよい。
ファイルの読み込みには、(1) 古典的な fopen(), fgets() 系統の関数群、(2) iostream クラス、(3) MFC のファイル操作クラス、のそれぞれを使用する3種類の方法がある。他のプラットフォームへの移植性を考えれば MFC のファイルクラスは使用しない方がいいかもしれない。
ここでは、古典的なファイルI/O関数を使用してみることにする。

BOOL CGeDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
    FILE *fp = fopen(lpszPathName, "r");
    if( !fp )
        return FALSE;
    char buf[4096];
    while( fgets(buf, sizeof(buf), fp) != NULL )
        m_ee.addText(buf);
    fclose(fp);

    return TRUE;
}
これで、ファイルオープンダイアログによるファイルオープンが可能になる。
オープンしたファイル情報はMFCが勝手に保存してくれる。[ファイル] メニューの最近のファイルも自動的に更新される(MFC さんに感謝)。
■ テキスト表示
テキストは CView の派生クラス CGeView の OnDraw() で描画しなくてはいけない。
とりあえず以下のようなコードを書けば、エディットバッファの内容を画面に表示できる。
実行画面を ここ に置く。

#define     VW_LINE_HEIGHT      20

void CGeView::OnDraw(CDC* pDC)
{
    CGeDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    CEditEngine *ee = pDoc->getEditEngine();
    int py = 0;
    for(int line=0; linegetLineCount(); ++line, py += VW_LINE_HEIGHT) {
        CString text;
        if( !ee->getText(line, text) )
            break;
        pDC->TextOut(0, py, text);
    }
}
■ まとめ
エディットエンジンを AppWizard で生成されたスケルトンに組み込むことで、簡単なテキストビューワがとりあえず実装できることを示した。
しかし、ここに示したコードでは、フォントサイズが固定になっている、背景色が白で無い場合に文字背景色とビュー背景色が異なり見苦しい、改行コードが■で表示され見苦しい、タブが■で表示され見苦しい、スクロールしない、フレームウィンドウをリサイズしたときに画面がちらつく、などの問題がある。次以降のドキュメントでそれらの解決方法を提示していく。
■ 演習問題
[1] 本稿で示した CGeDoc::OnOpenDocument() の実装では行バッファのサイズを 4096 としているが、オープンするファイルに含まれる行の行長が 4096 より大きい場合でも大丈夫か?もし問題があれば、問題が無いように書き換えなさい。
[2] iostream, MFC の CStdioFile それぞれを用いて、CGeDoc::OnOpenDocument() を実装しなさい。
[ index | 前のドキュメント | 次のドキュメント | このドキュメントのソース ]