トップ回答者
MFCにおけるMDI(マルチ)エディタの作成

質問
-
MFCを用いたエディタの作成についてどなたかアドバイスをお願いします.現在VC++2010 (Premium)でMFCを用いたアプリケーションを開発中です.以前Win32でアプリケーションを作成していました.Windowsアプリの基本的なことはわかっているつもりです.今回,MFCを利用すると様々なアプリケーションを容易に作れると聞いたので,現在勉強中です.ここでクラスウィザードを利用し,-------------------プロジェクトの新規作成->MFCアプリケーション->アプリケーションの種類の画面 で「マルチドキュメント(タブ付き)」にチェック,スタイルと色で「Visual Studio 2008」を選択->複合ドキュメントサポート で初期設定のまま->ドキュメントテンプレートプロパティ で初期設定のまま->データベースサポート で初期設定のまま->ユーザインタフェース機能 で初期設定のまま->高度な機能 で初期設定のまま->生成されたクラス で「基本クラス」にCEditViewを選択-------------------でプロジェクトを作成した結果次のようなVisual Studioに似た,アプリケーションが作成されました.左にはツリービューが表示され,中央には,エディタがあり,メニューからファイル選択のダイアログを開くと,任意のファイルを開くことができるというものです.これを私は,左のツリービューからファイルを選択しダブルクリックや,ドラッグをすることで選択ファイルを,エディタで開くように実装したいのですが,何分始めたばかりで,何をどこに書いていいのかわかりません.現在わかっているのは,「ツリーの表示」,「ウィンドウズメッセージの取得方法」ぐらいです.どなたかアドバイスをお願いします.
回答
-
MFCを使ってプログラミングを行う場合にMFCのフレームワークを理解して組まないと
恩恵も受けられませんし、かえって枷になりかねないのでフレームワークに関する学習を
された方が良いと思います。ピンポイントにつまみ食いをしても全体像がつかめないのでは
とも思いますし。SDIやMDIのプログラムを作成する場合、MFCではドキュメント-ビュウ アーキテクチャと
呼ばれる考え方を使っています。ファイルの読み込み等のインターフェイスはメインフレームの
メニューにある「ファイル」から行なうようになっており、ここで出てきたダイアログでファイルを選択すると
そのファイルを読み込む為のドキュメントと対になるビュウが生成されて関連付けられます。
この当たりの動作はフレームワークが行なうのでウインドウズの一般的なインターフェイスを採用するのであれば、
そのまま利用できる事になります。プログラマが記述するのはドキュメントクラスのシリアライズ関数の中身とかある程度決まった部分です。
フレームワークの既定の動きで問題ない場合はコードを追記する部分はある程度限定されます。これはビュウに関しても同じ事でフレームワークの流れに載って必要な部分だけをコーディングする事に
なります。この辺のフレームワークの仕組みとかドキュメント-ビュウ アーキテクチャ等の話は
MFCを使ったウインドウズアプリケーションの作成方法をレクチャする書籍に解説があると思います。そういった書籍を使ってフレームワークの把握をされた方が効率は良いと思いますよ。
Web上で情報を拾って勉強する方法もありますが、Web上の情報はS/N比が悪いので
自分で情報をより分ける必要があります。学習効率を考えるなら書籍の方が良いと思います。
解決した時は、参考になったレスポンスの所にある[回答としてマーク]ボタンをクリックしてスレッドを締めましょう。
すべての返信
-
まず、C++言語の文法に関しては大丈夫でしょうか?
Win32APIで組まれていたのであれば、C言語の範疇でもプログラミングできていたと思うので
もしC++言語の知識が足り無いのであれば、そちらの勉強をまずされる事をお勧めします。特にMFCを使ってプログラミングするのであれば、C++言語のクラスに関する知識は必須ですし、
派生とか仮想関数とかは当たり前に使用します。
少なくともC++言語のコードを書くのに迷わない程度の知識は必要だと思ってください。
自分で自作のクラスが設計、作成可能であるくらいが望ましいと思います。
願わくば、いきなりGUIアプリで勉強するのではなくてコンソールアプリで勉強される事をお勧めします。
いきなりC++言語の文法とMFCの使い方をいっぺんに勉強するのは無理があると思います。あと、MFCを使った場合、メッセージのハンドリング等はフレームワークのほうで受け持つので
特殊な事をし無いのであれば、基本的にはメッセージハンドラを追加してそこに処理を記述するのが
基本的なスタイルになります。この辺の基本的な方法論に関しては入門書なりで勉強されてください。
Web上の情報源だけで勉強するのはいささか無理があると思います。
解決した時は、参考になったレスポンスの所にある[回答としてマーク]ボタンをクリックしてスレッドを締めましょう。- 編集済み PATIO 2011年11月28日 11:01
-
C++も,Win32も一通り学んでいるつもりです.
しかし,正直MFCのプログラムを見たときに,何をどこに書けばいいのかわからないというのが現状です.
今回のエディタの件で具体的にわからないのは,
まず,現在のマウスのクリック位置とクリックしたときのイベントの関連づけ.
そして,ファイルを読み込んだ時に自動で生成されるエディタダイアログのウィンドウハンドルの取得の仕方です.
これがわからないため,どのようにして,作成されたダイアログに対して処理を行うような記述を書くことができません.
わかっている人から見たら,検討違いな質問かもしれませんが,よろしければアドバイスをお願いします.
-
おそらくはウィンドウプロシジャーとメッセージポンプ部分が存在しない為、混乱されているのだと思いますが。
MFC ではウィンドウプロシジャーは、MFC のフレームワーク内に隠蔽?されており、メッセージポンプは CWinApp::Run にカプセル化されています。
クラスビューで CEditView 派生クラスを選択した状態で、右クリック、またはメニューのプロジェクト→クラスウィーザードで、クラスウィザードを起動して下さい。
マウスのクリックですから、MFC Class Wizard よりメッセージタブを選択。
WM_LBUTTONDOWN、または WM_LBUTTONUP を選択して、ハンドラの追加ボタンを押すと、選択したメッセージに対応したハンドラ関数が作成されます。
後は MSDN のヘルプを見るなりして、MFC の OnLButtonDown 等のハンドラにアプリケーション独自のハンドラを追加していって下さい。
そもそもウィンドウプロシジャーで switch 文を書く手間などを省略したのが、MFC 等のライブラリです。
いきなり、MFC から Win32 プログラムを始めると混乱しますが、Win32 でのプログラム経験がおありとの事ですので、MFC にカプセル化された該当 API を探す感じでやっていけばいいのではないでしょうか? -
MFCをこれから学ぶというのであれば、いろいろ余計なものが付いたものをいきなり作るより、シンプルなMFCのアプリケーション(VC1.0から連綿と続くもっとも基本的なタイプ)から始めるのが良いと思いますよ。
具体的には、新規作成時のウィザードの2ページ目にあたる「アプリケーションの種類」のページの右側にある、プロジェクトの種類ラジオでMFC標準(32bit版Visual C++が対象になっていればどの時代の書籍でも参考になる形式)か、Windows エクスプローラー(VC6か7から増えている形式。具体的にはツールバースタイルが異なるだけ)を選んで、そこから始めるのが良いと思います。
それ以外の2種類は、Visual Studio 2008 SP1 から導入されたMFC Feature Pack(以下MFC-FP) の機能を使っています。これから学習するのであればひとまず知らないまま(名前だけ聞いたことがある程度のレベル)で進めてしまっても問題ないと思います。
あと、Vista以降のOSを相手とする場合、MDIで作成すると一部のウィンドウがOSの恩恵を受けられないという欠点がありますので、個人的にはMDIではなく、SDIで作成することをお勧めします。
必須ではありませんが...
わんくま同盟,Microsoft MVP for Visual C++(Oct 2005-) http://blogs.wankuma.com/tocchann/ -
回答ありがとうございます.
ご意見を元にソースを組んでみました.
ツリーについての処理を ViewTree.cppに 以下のように追加しました.
// マウスのLボタンがダブルクリックされた時の処理
void CViewTree::OnLButtonDblClk(UINT nFlags, CPoint point)
{
// TODO: ここにメッセージ ハンドラー コードを追加するか、既定の処理を呼び出します。
CTreeCtrl::OnLButtonDblClk(nFlags, point);
AfxMessageBox(_T("ダブルクリックされました"));
// ドキュメントの呼び出しテスト
CFile f("test1.txt", CFile::modeCreate | CFile::modeWrite);
CArchive ar(&f, CArchive::store);
CIDEDoc* test= new CIDEDoc();
test->Serialize(ar);
}
----------------------
CIDEDoc.cppファイル
すべてテンプレートの記述です.
void CIDEDoc::Serialize(CArchive& ar)
{
// CEditView は、すべてのシリアル化を処理するエディット コントロールを含んでいます。
//ここのm_viewListのCObjectが0になるため処理が通らない.
if (!m_viewList.IsEmpty())
{
reinterpret_cast<CEditView*>(m_viewList.GetHead())->SerializeRaw(ar);
}
#ifdef SHARED_HANDLERS
if (m_viewList.IsEmpty() && ar.IsLoading())
{
CFile* pFile = ar.GetFile();
pFile->Seek(0, FILE_BEGIN);
ULONGLONG nFileSizeBytes = pFile->GetLength();
ULONGLONG nFileSizeChars = nFileSizeBytes/sizeof(TCHAR);
LPTSTR lpszText = (LPTSTR)malloc(((size_t)nFileSizeChars + 1) * sizeof(TCHAR));
if (lpszText != NULL)
{
ar.Read(lpszText, (UINT)nFileSizeBytes);
lpszText[nFileSizeChars] = '\0';
m_strThumbnailContent = lpszText;
m_strSearchContent = lpszText;
}
}
#endif
}
----------------------
CIDEDocクラスのSerializeで新たなエディタを開くのだということは見当が付きました.
しかし,ダブルクリックのイベント時に,Serializeを呼び出すと,m_viewListのがm_nCountが0になっているために,エディタの作成ができないようです.
CIDEDocは,Documentを継承しているため,afxwin.hのDocumentクラス内で定義している CPtrList m_viewList を使えるようですが,
現在,m_viewList内にどこで値を代入しているのかわからない状態です.
-
MFCを使ってプログラミングを行う場合にMFCのフレームワークを理解して組まないと
恩恵も受けられませんし、かえって枷になりかねないのでフレームワークに関する学習を
された方が良いと思います。ピンポイントにつまみ食いをしても全体像がつかめないのでは
とも思いますし。SDIやMDIのプログラムを作成する場合、MFCではドキュメント-ビュウ アーキテクチャと
呼ばれる考え方を使っています。ファイルの読み込み等のインターフェイスはメインフレームの
メニューにある「ファイル」から行なうようになっており、ここで出てきたダイアログでファイルを選択すると
そのファイルを読み込む為のドキュメントと対になるビュウが生成されて関連付けられます。
この当たりの動作はフレームワークが行なうのでウインドウズの一般的なインターフェイスを採用するのであれば、
そのまま利用できる事になります。プログラマが記述するのはドキュメントクラスのシリアライズ関数の中身とかある程度決まった部分です。
フレームワークの既定の動きで問題ない場合はコードを追記する部分はある程度限定されます。これはビュウに関しても同じ事でフレームワークの流れに載って必要な部分だけをコーディングする事に
なります。この辺のフレームワークの仕組みとかドキュメント-ビュウ アーキテクチャ等の話は
MFCを使ったウインドウズアプリケーションの作成方法をレクチャする書籍に解説があると思います。そういった書籍を使ってフレームワークの把握をされた方が効率は良いと思いますよ。
Web上で情報を拾って勉強する方法もありますが、Web上の情報はS/N比が悪いので
自分で情報をより分ける必要があります。学習効率を考えるなら書籍の方が良いと思います。
解決した時は、参考になったレスポンスの所にある[回答としてマーク]ボタンをクリックしてスレッドを締めましょう。