Visual Studio (VC++) 入門 (その3)

− ダイヤログを用いたパラメータ入力 −


信州大学工学部 井澤裕司

(H18.1.30)


課  題 3

Microsoft Visual Studio2005 の Visual C++ を用いて、以下の機能をもつプログラムを作成しなさい.

MFCアプリケーションのメニュー「 設定 」の,サブメニュー「 パラメータ入力 」 を起動すると,画面上に 入力用ダイヤログ が表示される.
その入力欄に2つの数値を入力して 「
OKボタン 」 を押すと,ダイヤログが消え,その数値に対応する リサージュ図形 が画面上に表示される.


このコンテンツの中で,Visual C++ の使用法を詳細に説明することは困難です. Visual C++については、以下のような書籍が出版されていますので,参考にして下さい.
   ・Visual C++ 2005 ビギナー編
         林 晴彦 Softbank Creative
 
WEB上には 以下のようなサイトがあります.
 
   ・[ Visual C++ の使い方 ]
          http://www.nitoyon.com/vc/
   ・[ Visual C++ の勉強部屋 ]
          http://homepage3.nifty.com/ishidate/vcpp.htmvc/
   ・[ Area of VC++ Tips ]
          http://rararahp.cool.ne.jp/vc/vctips/tipindex.htm
 
パラメータ等を設定するダイヤログを利用するためには ,ダイヤログクラスを継承する新しいクラスを生成する必要があります.
これをスケルトンで作成したViewクラスの中から呼び出し,ダイヤログで入力したパラメータを受け取った後,入門(その2)で説明した手法により,リサージュ図形を描画します.
なお,パラメータ値の受け渡しは,ダイヤログクラスのメンバ変数により処理されます.
手順の概略を以下に示します.
なお手順の (3)が新たに付け加わった部分で,それ以外は, 基本的に資料 「VC++入門(その2)」と同じです.
(1) プロジェクト( Lisj_dia )の新規作成
・新規プロジェクト 「 Lisj_dia 」 をシングルダイヤログ形式( SDI で作成する.

・手順は
入門(その2) のステップ1〜3と同じ.
(2) メニューの作成
メニューの「 表示 」,「 リソースビュー 」をクリックし,「 Menu 」の IDR_MAINFRAME を編集する.

・新しいメニュー名として,例えば 「
設定 」 を,その下の サブメニュー名 として例えば 「 パラメータ入力 」 を入力する.

・作成したサブメニュー「
パラメータ入力 」 を左ダブルクリックするか,メニューの右上にあるアイコンの 「 プロパティ ウィンドウ 」 を左クリックして, メニューエディタ を起動し,リストの項目 ID を例えば 「 ID_PARAM_IN 」 のように設定する. 

・再度リソースのサブメニュー「
パラメータ入力 」 にマウスのカーソルを合わせ,マウスを ”右” クリックして,「 イベント ハンドラの追加 」 を起動する.

・メッセージの種類を 「
COMMAND 」,クラスの一覧の中から 「 CLisj_diaView 」 を選択し,「 追加して編集 」 のボタンをクリックする.

イベントハンドラ ウィザード により View クラスの中に新たなクラス(メッセージハンドラ) 「 OnParamIn() 」 が自動生成され,自動的にエディタのモードに移行する.
(3) ダイヤログの作成
メニューの 「 表示 」,「 リソースビュー 」 をクリックし, 「 Dialog 」 を右クリック,「 リソースの追加 」 を指定して,新しいダイヤログを新規作成する.

・新しく作成したダイヤログを,
ダイヤログエディタ を用いて編集する.
ツールボックス から必要な部品 (数値入力の窓など) を選択し,適切な位置に レイアウト する.この課題では,整数値を代入する2つの 「 Edit Control 」 と,その入力窓の役割を表示するための 「 Static Text 」 を2つ選択して,ダイヤログ内の適切な位置に配置する.

・ダイヤログ内にマウスのカーソルを置き,右クリックにより,ダイヤログの「
プロパティ 」 を開く.縦スクロールバーを操作し,「 Caption 」 欄の 「 Dialog 」 という文字列を,例えば「 パラメータ入力 」 に書き換える.

・プロパティを閉じた後,再度ダイヤログにカーソルを置き,右クリックにより 「
クラスの追加 」 を起動し, MFCクラスウィザード を立ち上げ,クラス名として,例えば「 CParamDlg 」 と入力する.

・「
完了 」 により MFCクラスウィザード を閉じた後,ダイヤログの2つの 「 Edit Control 」 を右クリックして 「 変数の追加 」 を選択する.メンバ変数のカテゴリを 「 value 」 ,変数の種類を 「 int 」 (整数)型に選び,変数名を例えば m_fx 」,「 m_fy 」 のように入力する.

(4)  Viewクラスのコード 「 Lisj_diaView.cpp 」 の最初に,作成したダイヤログを呼び出すための ヘッダーファイル ( ParamDlg.h ) 等をインクルードする.
‥(略)‥
#include   "Lisj_diaView.h"

#include    "ParamDlg.h"   ← 追加行
#include    "math.h"      ← 追加行
#define    PI    3.1415926 ← 追加行
(5)  Viewクラス 「 CLisj_diaView.cpp 」 の編集 (1)
Viewクラスの中に生成された 「 OnParamIn() 」 の内部に,ダイヤログを表示し,パラメータの2つの値をメンバー変数として受け取るコードを追加する.

CParamDlg  dlg;

dlg.m_fx = fx;

dlg.m_fy = fy;

if ( dlg.DoModal( ) == IDOK ) {;
    fx_old = dlg.m_fx;
    fy_old = dlg.m_fy;
}
   ‥(略)‥
(6)   Viewクラス「 *CLisj_diaView.cpp 」 の編集 (2)
自動生成された「 OnParamIn() 」 の内部に,描画用のコードを追加する.

‥(略)‥

CClientDC  dc(this);
int        i;
double      x;
double      y;

‥(略)‥
ダイヤログの表示と,パラメータの受け渡し
‥(略)‥


dc.FillSolidRect( 0,0,400, 400, RGB(255, 255, 255));
dc.TextOutW( 0,0,(CString)“Lissajous Curves”);
dc.MoveTo( 200, 200 );
for( i = 0; i < 1000; i++){
    x = 100.0 * sin( PI * (double)i * (double)fx_old) / 100.0;
    y = 100.0 * sin( PI * (double)i * (double)fy_old) / 100.0;
    LineTo( 200 + (int) x, 200 + (int) y);
}

(7) コンパイル , デバッグ および 実行
入門(その2) のステップ5〜7に同じ.


ステップ1. Microsoft Visual Studio2005 を起動する

メニューの 「 ファイル 」 から 「 新規作成 」 の 「 プロジェクト 」 を指定します.
  


ステップ2. Visual C++ のMFC アプリケーションを立ち上げる

プロジェクトの種類から「 Visual C++ 」 の 「 MFC 」 (Microsoft Foundation Class Library) を選択し,右側のテンプレートから 「 MFCアプリケーション 」 を指定します.
下の欄のプロジェクト名として,例えば 「 Lisj_dia 」 と入力します.


ステップ3. MFC アプリケーション ウィザードに従ってスケルトン(雛形)を生成する

MFCアプリケーション ウィザード に従って,スケルトンを生成します.
なお,「
アプリケーションの種類 」 はこれまで通り,「 シングル ドキュメント 」とし,「 高度な機能 」については,すべての チェックをはずし て下さい.
以上の手順により,下に示す MFC アプリケーション の雛形ができ上がります.
  



ステップ4. メニューのリソースを追加し,イベントハンドラを起動して,新規メニューに対応するクラスを生成する.

4-[a]

メニューの「 表示 」から 「 リソースビュー 」 を指定し,「 Lisj_dia 」 プロジェクトの リソース一覧を表示します.
次に,「 Lisj_dia.rc 」 の「 Menu 」 をクリックし,ファイル一覧を表示します.

なお,一覧が表示されない場合は,上位のフォルダをダブルクリックすると,その下の階層が表示されます.




4-[b]

    リソース一覧の中から 「
IDR_MAINFRAME 」 をダブルクリックして,MFC アプリケーションのメニュー画面を表示します.




4-[c]

「 ここへ入力 」 の欄の下端にマウスのカーソルを合わせ,左ダブルクリックして,「 設定 」 と入力します.
次に,「
設定 」 の下の 「 ここへ入力 」 の下端にマウスのカーソルを合わせ,左ダブルクリックして 「 パラメータ入力 」 と入力します.




4-[d]

パラメータ入力 」 の ”右側” にマウスのカーソルを合わせ,左ダブルクリックして,「 メニューエディタ 」 を起動します.
なお,メニュー欄の右端にあるアイコン 「
プロパティ ウィンドウ 」 を左クリックしても,この メニューエディタ」 が開きます.
次に,画面左の「 メニューエディタ 」 の「 ID 」 の欄に,ユニークな名前,例えば,「 ID_PARAM_IN 」 を入力します.




4-[e]


メニューエディタ 」 を閉じた後,再びサブメニューの 「 パラメータ入力 」 にマウスのカーソルを合わせ,今度は ”右” クリックして, 「 イベントハンドラの追加 」 を起動します.




4-[f]

イベント ハンドラ ウィザード 」 のクラス一覧から Viewクラス ,すなわち 「CLisj_diaView 」 を選択して,「 追加して編集 」 を起動します.
なお,「
メッセージの種類 」 の欄は 「 COMMAND 」 とします.




4-[g]
    「 イベント ハンドラ ウィザード 」 により, Viewクラス の中に,新規メニューに対応する新しいクラス 「 OnParamIn() 」 が自動的に生成されます




ステップ5. リソースエディタを用いてダイアログを新規作成・編集し,新しいクラスを生成して,メンバー変数を追加する.

5-[a]

メニューの「 表示 」から 「 リソースビュー 」 を指定し,「 Lisj_dia 」 プロジェクトの リソース一覧を表示します.
次に,「 Lisj_dia.rc 」 の「 Dialog 」 をクリックし,ファイル一覧を表示します.

なお,一覧が表示されない場合は,上位のフォルダをダブルクリックすると,その下の階層が表示されます.




5-[b]
    ダイヤログを ”
”クリックして,「 リソースの追加 」から,「 新規ダイヤログ 」 を選択します.




5-[c]

新規ダイヤログ 」 が生成されました.
次に,このダイヤログを,リソースエディタを用いて編集します.




5-[d]

メニューの 「 表示 」 から 「 ツールボックス 」を選択します.




5-[e]

ツールボックス 」 の ”Edit Control” をマウスで選択し,ダイヤログ画面内の適切な位置にドラッグします


5-[f]

Edit Contol 」 は数値や文字列を入力するための窓のことです.
ダイヤログ内の適切な位置に,この「
Edit control 」を2つ,レイアウトします.


5-[g]

ツールボックス 」 から,「 Static Text 」を選択します.


5-[h]

ツールボックス 」 から選択した「 Static Text 」を,ダイヤログの適切な位置にドラッグします.
この「
Static Text 」 は,上で使用した 「 Edit Control 」 等の内容を文字表示するために使用します.



5-[i]

ダイヤログ上部のキャプションは,デフォルト値で,「 Dialog 」 となっています.
この内容を変更するため,ダイヤログにマウスのカーソルを置き,右クリックにより,「
プロパティ 」を選択します.



5-[j]

画面の左側に,ダイヤログの「 プロパティ 」 の詳細がリスト形式で表示されます.
新たに追加したダイヤログを識別するため,「
ID 」の欄に,例えば 「 IDD_PARAM_DLG 」 と入力します.



5-[k]

プロパティの「 Caption 」 の欄にパラメータ入力 」という文字を入力します.
同様に,2つの 「
Static Text 」 についても,右クリックで 「 プロパティ 」 を開き,それぞれ「 X軸周波数 」 および,「 Y軸周波数 」 と入力します.
さらに,「 OKボタン 」や「 キャンセルボタン 」についても,マウス操作により,バランスのよい位置に再配置します.



5-[l]

このようにして,デザインとレイアウトを完了した「 ダイヤログ 」 を,実際のプログラムに相当する 「 クラス 」に変換します.
マウスのカーソルを「
ダイヤログ 」本体に合わせ,右クリックにより,「 クラスの追加 」 を選択します.


5-[m]

MFC クラス ウィザード 」が起動しますので, 「 クラス名 」に,”C”から始まる名称,例えば「 CParamDlg 」 を入力して,「 完了 」をクリックします.
なお,新しく生成されるクラスは, 「
CDialog 」 というダイヤログの基本クラスを継承したものとなっています.



5-[n]

次に,2つの「 Edit Control 」 に対応する「 メンバ変数 」を定義します.
X軸周波数 」 に対応する Edit Control 」 にマウスのカーソルを合わせ,右クリックにより,「 変数の追加 」 を選択します.



5-[o]

メンバ変数の追加ウィザード 」 が起動しますので,「 カテゴリ  」から「 Value 」, 「 変数の種類 」 から 「 double 」を選択し , 変数名  」には,例えば「 m_fx 」と入力します.
入力を終えたら「 完了 」をクリックして,「 ウィザード 」を終了します.


5-[p]

Y軸周波数 」 に対応する「 Edit Control 」も同様に処理します.
変数名 」 は,例えば 「 m_fy 」 とします.



以上で,「 新規ダイヤログ 」の設定は完了です.

次は,最終的な「 CLisj_diaViewクラス 」 のコーディングに入ります.

ステップ6. ソースファイルの編集(1)  (ダイヤログの表示とパラメータの受け渡し)

6-[a]

ステップ5で作成した「 ダイヤログ 」 を,ステップ4で生成した「 メニューに対応するクラス 」から呼び出して表示し,2つの「 Edit Control 」 に相当する変数の受け渡しを行います.
はじめに, 「
ソリューション エクスプローラ 」 を表示し,ソースファイルからViewクラスの 「 Lisj_diaView.cpp 」 を選択します.
その最も下にあるメッセージハンドラ「
OnParamI() 」を表示します.



6-[b]

ダイヤログを表示して,データの受け渡しを行います.
新しく生成したクラス 「
OnParamIn() 」 の中に以下のソースコードを追加します.
ただし, // スラント 以下のコメント行は不要です.

CParamDlg     dlg;        // ダイヤログクラスのオブジェクト「dlg」

dlg.m_fx = fx_old;           // 一度入力した値を再入力する手間を省くため
dlg.m_fy = fy_old;           //    上に同じ

if (dlg.DoModal() == IDOK ) {;   // ダイヤログを表示し,「OK」が押されたら以下の処理を行う

     fx_old = dlg.m_fx;      // 入力データ (X軸) の読み込み
     fy_old = dlg.m_fy;      // 入力データ (Y軸) の読み込み

}

ここで,bouble型の変数 「 fx_old 」と 「 fy_old 」は,このVeiwクラスの先頭で定義します.
これらの初期値は
0 です.

以下にその編集画面を示します.




6-[c]

ダイヤログを表示して,データの受け渡しを行います.
Viewクラス 」 の先頭に,以下の変数の定義を追加します.
ただし, // スラント 以下のコメント行は不要です.


doublel    fx_old;           // X軸の周波数 (入力値保存用)
doublel    fy_old;           // Y軸の周波数 (入力値保存用)

ここで,bouble型の変数 「 fx_old 」と 「 fy_old 」は,このVeiwクラスの先頭で定義します.
なお,これらの初期値は「
0 」になりますが,明確に初期値を与える場合は,コンストラクタ「 CLisj_diaVeiw::CLisj_diaVeiw() 」の中でそれらを代入します.

以下にその編集画面を示します.


ステップ7. ソースファイルの編集(2)  (リサージュ図形の表示)

7-[a]

新しく作成したダイヤログをViewクラスの中から呼び出すため, 「 Viewクラス 」 の先頭に,以下の2つのインクルード文と定数(円周率)の定義を追加します.
なお,「
茶色 」 で示した部分が,新たに追加するコードです.

#Include       "ParamDlg.h"
#Include       "math.h"

#define  PI     3.1415926

double        fx_old;
double        fy_old;



以下にその編集画面を示します.





7-[b]

リサージュ図形を表示するソースコードを編集します.
ステップ6で修正したクラス 「
OnParamIn() 」 に,以下のソースコードを追加して下さい.
なお,「
茶色 」 で示した部分が,新たに追加するコードです.

CParamDlg     dlg;

CClientDC      dc(this);
int           i;
double        x, y;


dlg.m_fx = fx_old;
dlg.m_fy = fy_old;

if (dlg.DoModal() == IDOK) {
   fx_old = dlg.m_fx;
   fy_old = dlg.m_fy;
}

dc.FillSolidRect( 0, 0, 400, 400, RGB(255, 255, 255) ); // 画面のクリア (白の矩形で塗りつぶす)

dc.TextOutW ( 0, 0, (CString) "Lissajous Curves" );
dc.MoveTo( 200, 200 );

for (i = 0; i < 1000; i++){
      x = 100.0 * sin( PI * (double) i * fx_old / 100.0);
      y = 100.0 * sin( PI * (double) i * fy_old / 100.0);
      dc.LineTo(200 + (int) x, 200 + (int) y);
}

なお,「LineTo() 」等の描画処理では,基本的に画面がクリアされず,上書きされます.
このため,新しく再描画する場合は,画面をクリアする必要があり,

      dc.FillSolidRect( 0, 0, 400, 400, RGB (255, 255, 255) );

を用いて,白い矩形を上書きしています.

その他の内容は,課題2で説明しましたので,ここでは省きます.


以下にその編集画面を示します.



ステップ8. ソースコードのコンパイル(ビルド ・ リビルド)

    VC++のメニュー 「 ビルド 」,「 ソリューションのビルド 」 をクリックして ビルド (コンパイル)します.





    エラーが表示されたら,該当する箇所を修正します.


ステップ9. 作成したプログラムの実行結果

VC++ の メニュー「 デバッグ 」 の 「 デバッグなしで開始 」 をクリックして,作成したプログラムを実行します.
作成した MFCアプリケーション のメニュー「 設定 」のサブメニュー「 パラメータ入力 」 を起動します.



パラメータ入力 」というキャプションのダイヤログが表示されますので,「 X軸周波数 」 および「 Y軸周波数 」の欄に,例えば,「 7 」,「 11 」 という数字を入力し,「 OKボタン 」をクリックします.




Lissajous Curves 」という文字が左上に表示され,入力した数値に対応する「 リサージュ図形 」 が表示されます.




まとめ
VC++を用いて,ダイヤログからパラメータを入力して,リサージュ図形を表示する方法を紹介しました.
波形や色等を変えて,その実行結果を確認して下さい.


便利なツールとして活用することを目標において,とにかく慣れるよう努力して下さい.