エディタの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 | 前のドキュメント | 次のドキュメント | このドキュメントのソース ]
|