■ MFC アプリケーションの作成 ■ ■ 初めに
此処では、Visual Studio 2017 を起動し、新しいプロジェクトで、MFC を選択し、MFC(Micorosft Foundation Class)アプリケーションを作成する。 ■ インストール時の注意 インストール時に、「ワークロード」で「C++によるデスクトップ開発」を選択した丈では、MFC アプ リケーションの開発を行う事が出来ない。右欄の「概要」で「x86 用と x64 用の Visual C++ MFC」に チェックを付ける必要が有る。亦、「個別のコンポーネント」で「x86 用と x64 用の Visual C++ MFC」 にチェックが入って居る事を確認する。 亦、CLR アプリケーションを開発する場合は、「概要」で「x86 用と x64 用の Visual C++ ATL」と「個 別のコンポーネント」で「C++/CLI サポート」にもチェックを入れて置く。 猶、此等は、「新しいプロジェクト」ダイアログで「Visual Studio インストーラを開く」から、何時で も追加する事が出来る。 ※ .NET Framework 登場に依り、現在では MFC を使っての新規開発は無いと思われるが、古いアプ リケーションの流用や保守の為に、一通りの使用法は憶えて置いた方が良いと思われる。
M
MF
FC
C
ア
アプ
プリ
リケ
ケー
ーシ
ショ
ョン
ン
■ シングルドキュメントの作成 ■ 新しいプロジェクトで MFC アプリケーションを選択すると、アプリケーションの種類のオプションの ダイアログが開くので、アプリケーションの種類にシングルドキュメントを選択して、次へボタンをク リックする(此処で完了ボタンをクリックしても構わないが、不要なフレームペインを取り除く為、次 へボタンをクリックしてウィザードを続ける)。 次のドキュメントテンプレートプロパティやユーザーインターフェース機能のダイアログでは何もせ ずに、次へをクリックする。 次の高度な機能オプションのダイアログの高度なフレームペインのチェックを総て外して、完了をクリ ックする。 ※ アップデートの種類に依り、ダイアログの出現順序が異なる場合が有る。 アプリケーションの種類 解説 シングルドキュメント メニューバー、ツールバー、ステータスバーを含む単一ウィンド ウのアプリケーション 複数のドキュメント メニューバー、ツールバー、ステータスバーを含むフレームウィ ンドウに複数の子ウィンドウを表示するのアプリケーション ダイアログベース 1個のダイアログを持つアプリケーション 複数のトップレベルドキュメント Visual Studio 風のアプリケーション
プロジェクトが作成されると、ソリューションエクスプローラに下図の様なツリーが表示される。 上図のファイルを観ると解る様に、プロジェクト名に Doc の付加されたファイルと View の付加された ファイルが存在する。此の様に、ドキュメント(データ)と画面(ビュー)を分けてアプリケーション を構築する方法を DOC/VIEW モデルと謂い、現在では一般的な手法で有る。 MFC ではドキュメントの基本クラスとして CDocument、ビューの基本クラスとして CView と謂うク ラスが用意されて居て、此等のクラスからアプリケーション独自のドキュメントとビュークラスを派生 させてプログラムを構築する。 猶、リソースビューに切り替えると、アイコン等の色々なリソースを観る事が出来る。 ※ ソリューションエクスプローラのペインにリソースビューのタブが表示されて居ない場合は、メニ ューの「表示」から「その他のウィンドウ」をポイントし「リソースビュー」をクリックすると表 示される様に成る。
実行(デバッグの開始 F5)すれば、下図の様な画面が表示される(高度なフレームペインのチェック を総て外して居ない場合は、更に色々なペインが装備されて居るので確認して欲しい)。 此処では、空気抵抗を受けるボールの運動形を描画するグラフィックアプリケーションを作成する事に する。 ■ ドキュメント ドキュメントクラスのヘッダーファイル(プロジェクト名 Doc.h)と実装(プロジェクト名 Doc.cpp) は、今回は何も変更を加えて居ない。 ■ ビュー ビュークラスのヘッダーファイル(プロジェクト名 View.h)は変更せずに其の儘使用する。 ビュークラスの実装(プロジェクト名 View.cpp)に下記のコードを追加する(赤字の部分)。 // MFCApplicationSDIView.cpp : CMFCApplicationSDIView クラスの実装 // #include "stdafx.h" // SHARED_HANDLERS は、プレビュー、縮小版、および検索フィルター ハンドラーを実装… // そのプロジェクトとのドキュメント コードの共有を可能にします。 #ifndef SHARED_HANDLERS #include "MFCApplicationSDI.h" #endif #include "MFCApplicationSDIDoc.h" #include "MFCApplicationSDIView.h" #include <math.h>
#ifdef _DEBUG
#define new DEBUG_NEW #endif // 変数の定義 #define g 9.8 //重力加速度 #define PI 3.14159 //円周率 #define d 0.072 //ボールの直径 #define dt 0.03 //計算時間間隔 //関数の宣言
double _sgn(double, int); //符号変化の関数 void timewait(int); //時間待 // CMFCApplicationSDIView IMPLEMENT_DYNCREATE(CMFCApplicationSDIView, CView) BEGIN_MESSAGE_MAP(CMFCApplicationSDIView, CView) // 標準印刷コマンド ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CMFCApplicationSDIView::OnFilePrintPreview) ON_WM_CONTEXTMENU() ON_WM_RBUTTONUP() END_MESSAGE_MAP() // CMFCApplicationSDIView コンストラクション/デストラクション CMFCApplicationSDIView::CMFCApplicationSDIView() { // TODO: 構築コードをここに追加します。 } CMFCApplicationSDIView::~CMFCApplicationSDIView() { } BOOL CMFCApplicationSDIView::PreCreateWindow(CREATESTRUCT& cs) {
// TODO: この位置で CREATESTRUCT cs を修正して Window クラスまたはスタイルを // 修正してください。 return CView::PreCreateWindow(cs); } // CMFCApplicationSDIView 描画 void CMFCApplicationSDIView::OnDraw(CDC* pDC) {
CMFCApplicationSDIDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc);
if (!pDoc) return; // TODO: この場所にネイティブ データ用の描画コードを追加します。 CPen pc1(PS_SOLID, 1, RGB(0, 125, 128)); //ペンの初期化 CPen pc3(PS_SOLID, 2, RGB(0, 0, 255));
CPen* oldp = pDC->SelectObject(&pc1); //ペンの変更
int x0 = 50, y0 = 380, xsp = 600, ysp = 300; //作図範囲 int xp, yp;
int ss = 0; CString str;
double xmax = 120, ymax = 50; //各変数 double a, cd, l;
double x, y, v0, vi0, t, th; double xd, yd, x2d, y2d, r, m;
cd = 0.4; //空気抵抗係数 l = 1.25 / g; //空気密度 m = 0.146 / g; //ボールの質量 x = y = t = 0; vi0 = 150; //初速度 th = 45; //打ち上げ角度 v0 = vi0 * 1000.0 / 3600.0; th = th * PI / 180.0; a = d * d*PI / 4.0; xd = v0 * cos(th); yd = v0 * sin(th); //軸の表示 pDC->SelectObject(&pc3);
pDC->MoveTo(x0, y0); pDC->LineTo(x0 + xsp, y0); pDC->MoveTo(x0, y0); pDC->LineTo(x0, y0 - ysp);
str = "空気抵抗を受けるボールの放物運動計算プログラム"; pDC->SetTextColor(RGB(0, 0, 255)); pDC->TextOut(60, 0,str); //文字出力 pDC->SelectObject(&pc1); while (y >= 0) { xp = (int)(x0 + x * xsp / xmax); yp = (int)(y0 - y * ysp / ymax);
pDC->Ellipse(xp - 3, yp - 3, xp + 3, yp + 3); //左上と右下に接する楕円 r = 0.5*l*a*cd; //運動方程式の解 ss = (int)_sgn(xd, ss); x2d = -r * (xd * xd) / m * ss; xd += x2d * dt; x += xd * dt;
ss = (int)_sgn(yd, ss); y2d = -r * yd*yd / m * ss - g; yd += y2d * dt; y += yd * dt; t += dt; timewait(1000); //時間待ち } pDC->SetTextColor(RGB(250, 52, 50)); str.Format(_T("到達距離 = %f"), x); pDC->TextOut(120, 40, str); //文字出力 pDC->SelectObject(oldp); //ペンを元に戻す } // CMFCApplicationSDIView の印刷 void CMFCApplicationSDIView::OnFilePrintPreview() { #ifndef SHARED_HANDLERS AFXPrintPreview(this); #endif }
BOOL CMFCApplicationSDIView::OnPreparePrinting(CPrintInfo* pInfo) {
// 既定の印刷準備
return DoPreparePrinting(pInfo); }
void CMFCApplicationSDIView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) {
// TODO: 印刷前の特別な初期化処理を追加してください。 }
void CMFCApplicationSDIView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) {
// TODO: 印刷後の後処理を追加してください。 }
void CMFCApplicationSDIView::OnRButtonUp(UINT /* nFlags */, CPoint point) {
ClientToScreen(&point); OnContextMenu(this, point); }
void CMFCApplicationSDIView::OnContextMenu(CWnd* /* pWnd */, CPoint point) {
#ifndef SHARED_HANDLERS
theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EDIT, point.x, point.y, this, TRUE);
#endif }
// CMFCApplicationSDIView の診断 #ifdef _DEBUG
void CMFCApplicationSDIView::AssertValid() const {
CView::AssertValid(); }
void CMFCApplicationSDIView::Dump(CDumpContext& dc) const {
CView::Dump(dc); }
CMFCApplicationSDIDoc* CMFCApplicationSDIView::GetDocument() const { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMFCApplicationSDIDoc))); return (CMFCApplicationSDIDoc*)m_pDocument; } #endif //_DEBUG // 記号変更
double _sgn(double dd, int s) { if (dd < 0) s = -1; else if (dd == 0) s = 0; else s = 1; return(s); } // 時間待 void timewait(int n) { int a, i, j, m = 1000; for (i = 0; i<n; i++) { for (j = 0; j<m; j++) { a = i; } } } // CMFCApplicationSDIView メッセージ ハンドラー