| 日時指定コントロール |
CDateTimeCtrl m_DateDiary; |
| コンボボックス |
CComboBox m_Weather; |
| エディットボックス |
CEdit m_EditDiary; |
・ボタン
ボタンは,日記帳(MyDiary)では「保存」とか「終了」と書かれているもので,ユーザがアプリケーションに対して指示をするために使われます.つまり,これはダイアログに対しての入力インタフェースです.ボタンがクリックされたときにはボタンからメッセージが発生するので,ボタンがクリックされたことを検出するには,それに対応したメッセージハンドラ関数を用意すればいいのです.メッセージハンドラの作成はClass Wizardを使って行います.日記帳(MyDiary)で「保存」がクリックされたときに行なわれる処理を以下に示します.
![]()
・コンボボックス
コンボボックスは日記帳(MyDiary)では天気を選択するのに使っています.ボタンはユーザからの入力が大きな役割を持ちましたが,コンボボックスはボタンと違って,コンボボックスにいろいろな(「晴れ」とか「雨」などの)情報を載せなければなりません.これらの情報はリソース編集の場面で設定することも可能ですが,日記帳(MyDiary)ではプログラムソース内で情報を掲載するようにしています.具体的には,コンボボックスを取り扱うためのインスタンス(クラスの実体)をDDX変数で宣言しているのです.そのインスタンス名はm_Weatherで,コントロールであるコンボボックスの管理をm_Weatherオブジェクトで行えるようにしています.つまり,m_Weatherオブジェクトは天気を管理するコンボボックスを扱う専用オブジェクトなのです.
もちろん,上記のボタンの場合と同じように,コンボボックスをユーザが操作すれば,コンボボックスからメッセージが発生します.具体的にはCBN_SELCHNGE(選択内容が変化),CBN_SETFOCUS(コンボボックスがフォーカスを受けた)などのメッセージ(11種類)があります.ところが,コンボボックスがどうされようとかまわない場合はこれらのメッセージハンドラを作る必要はありません.実際,日記帳(MyDiary)では一つもハンドラ関数を設けていません.
・エディットボックス
日記帳(MyDiary)での本文を編集する部分にエディットボックスを使用しています.エディットボックスは,ユーザとアプリケーションとが相互に文字情報を交換する場(インタフェース)です.アプリケーションが文字をエディットボックスに送ったり読み込んだり,あるいはユーザがエディットボックスの文章を読んだり文字を打ち込んだりします.編集の機能を備え持ったのがエディットボックスですから,このコントロールを実装すれば,プログラマは簡単にアプリケーションとユーザの文字情報交換インタフェースを提供することができます.
日記帳(MyDiary)では,このコントロールを管理するために,DDX変数のm_EditDiary(CEdit型)インスタンスを設けました.m_EditDiary.SetWindowText(st);で文字列stをエディットボックスに送り,m_EditDiary.GetWindowText(st);でエディットボックスの文字列をstに格納することができます.
・ラジオボタン
一日の満足度はたいてい「最高」「満足」「普通」「不満」「最悪」の5つに分けられるでしょう.確かに,気分が「最高」であれば「満足」なわけですから,「最高」と「満足」が共存することはありえます.しかし,ここでは一日の満足度を5つに分割して,上から順に「最高」「満足」・・・「最悪」となると考えましょう.このような場合,ユーザにどれか一つを選択してもらうことになります.選択するならば,コンボボックスやリストボックスを使う手もあるのですが,このように項目数が少ない場合や順位(順番)があるような場合にはラジオボタンを使うほうがすっきりします.
ラジオボタンはグループボックスで区切られた中でどれか一つが選択されている状態になります.このような機能で使うばあい,ラジオボタンはDDX変数を使うことはできないため.直接コントロールIDを参照するプログラムを作らなければなりません.IDからそのコントロールを扱うためにはCWnd::GetDlgItem関数を使います.この関数はオブジェクトIDを指定するとそのオブジェクトへのハンドル(CWnd*型)を返すので,それを(CButton*)へキャストして使います(ラジオボタンを扱うクラスはCButtonクラス).
・日時指定コントロール
日記帳は日時の取り扱いを避けて通れません.日時情報を管理するプログラムを作ってもいいのですが,幸いWindowsには日時指定コントロールがあって,MFCにそれを扱うクラスとしてCDateTimeCtrlクラスがあるので,これを利用してみました.実行場面は次のようになります.
![]()
このコントロールの取り扱いもDDX変数(m_DateDiaryインスタンス:CDateTimeCtrl型)で行っています.なお日記帳(MyDiary)ではユーザによる日付の変更に対して,情報を新しく(選択した日の情報があればそれを表示,なければ初期化)するために,イベント検出を行っています.つまり,日時指定コントロールの日付が変更されると,DTN_DATETIMECHANGEメッセージが発生するので,そのメッセージハンドラを設けています.そのメッセージハンドラ内での動作は後ほど解説します.
| 2003年02月26日の日記 天気:晴れ 満足度:A 今日はこのプログラム(Ver1.0)を完成させることができて,最高の気分です. このプログラム開発を通して,さまざまなコントロールの取り扱い方を学びました. 具体的には, 日時指定コントロール・・・CDateTimeCtrlクラス コンボボックス・・・・・・・・・CComboBoxクラス ラジオボタン・・・・・・・・・・・CButtonクラス エディットボックス・・・・・・CEditクラス などの対応を理解しました. また,CTimeクラスを初めて使いました. なお今回のプログラム開発では,実際のプログラミングに入る前に,綿密な計画と実験を行っています. Windowsプログラミングでは,この手法が非常に有効であると思われます. |
| CFile fread; CString fName; fName=m_Date.Format("%Y_%m_%d.txt"); if(!fread.Open(fName,CFile::modeRead,NULL)){ : : : : }else{ CArchive arch(&fread,CArchive::load,4096,NULL); Serialize(arch); arch.Close(); fread.Close(); : : } |
・リソースの作成以上,新たなダイアログボックスをアプリケーションに実装する流れを見てきました.これはあくまで実装の流れですので,好みに合わせたリソースの編集やクラスの編集を行う必要はあります.
初めのほうで説明したようにダイアログはリソースの設計とクラスの設計とを別々に行います.そこで新たなダイアログボックスをアプリケーションに取り込みたいときはまずリソースの作成をします.具体的には,Visual C++メニューバーの「挿入」欄の「リソース」をクリックすることでプロジェクトに挿入したいリソースを選ぶことができます.リソースにはいろいろなタイプがありますが,今はダイアログボックスを作りたいのでダイアログリソースを作成します.
・クラスの作成
リソースを扱うためにはそれに対応するクラスが必要です.ダイアログボックスを作りたいのでCDialogクラスを継承させたクラスにリソースを埋め込む必要があります.これはClass Wizardを使えば実現可能です.以下のような感覚でクラスを作成することができます.
保存するか否かを確認する(confirm)ダイアログということで,派生クラスの名前をCSaveConfirmDlgクラスとしました.ダイアログIDというのはリソースに付けられた(Visual C++が付けた)名前です.このようにして,リソースを取り込んだクラスを作ることができるのです.![]()
・アプリケーションとの結合
さてここでは,作成したダイアログボックスをどのようにしてアプリケーションユーザに提供できるかを見ていきましょう.ダイアログボックスを表示したいのはユーザが「終了」をクリックしたときですから,そのイベントを処理するハンドラ関数内でCSaveConfirmDlgインスタンスを作成すればよいことになります.そこでは以下のような流れを組みます.ここでCSaveConfirmDlgのm_textメンバはCString型で,STATICコントロールに表示する文字列を管理しています.このプログラムで注目してもらいたいのはSCD.DoModal()です.この関数を実行すると,次のようなダイアログボックスが表示され,ユーザに応答を求めることになります.
CSaveConfirmDlg SCD;
SCD.m_text=m_Date.Format("「%Y年%m月%d日の日記」は修正されています.")+"\x0d\x0a保存しますか?";
if(SCD.DoModal()==IDOK){
OnSave();
}
この問いかけに対し,ユーザが「はい」や「いいえ」をクリックすると,このダイアログボックスは閉じられます.このときSCD.DoModal()はクリックされたものに応じた値を返すので,それを使って次の処理に移ることができます.具体的には「はい」がクリックされると,SCD.DoModal()は「IDOK」という値を返すので,上のプログラムではこれを検出して保存操作に入ることができるわけです.なお,「いいえ」がクリックされた場合には「IDCANCEL」が帰ってきます.![]()
さて,ここで「注意すべきこと」を述べておきましょう.CDiaryDlgに上のような記述を加えるわけですが,ただこれを記述しただけではいけません.これをコンパイル処理の観点から見てみましょう.CDiaryDlgクラスの本体が定義されているDiaryDlg.cppをコンパイルする場合,CSaveConfirmDlgクラスのプロトタイプが必要になります.つまり,CSaveConfirmDlgクラスが一体どのようなものなのかを,コンパイラに知らせなければなりません.コンパイル処理についてあまりよくわからない人は難しく聞こえるかもしれませんが,要するにDiaryDlg.cppの上のほうで「#include "SaveConfirmDlg.h"」と一行付け加えればいいのです."SaveConfirmDlg.h"にはクラスの定義が書かれていて,これをインクルードすることによってコンパイラにCSaveConfirmDlgとはどのようなものかを知らせることができるのです.
・初期化処理
コントロール類の初期化はCDiaryDlg::OnInitDialog関数内で行います.この関数はダイアログボックスの表示直前に呼び出されます.日記帳(MyDiary)では以下の処理をしています.(App Wizardで生成される処理は除いてある.)
![]()
NewDocument関数はCDiaryDlgクラスのメンバ関数で,独自に作成した関数です.後ほどこの関数のフローチャートを示します.
・イベント処理(日付の変更検出)・・・OnNewDiary関数
日時指定コントロール(ID:ON_IDC_DATETIMEPICKER1)が変更されると,DTN_DATETIMECHANGEメッセージが発生します.このメッセージハンドラとして,OnNewDiary関数を用意しました.このメッセージハンドラのおかげで,日付が変更されるとその日の日記を自動的に読み出すことができます.ただし,変更前の日記が保存されてない場合は,それを保存するかどうか確認するようになっています.フローチャートは以下の通りです.エディットボックスが変更されているかどうかはCEdit::GetModify関数を使って判別できます.
![]()
・イベント処理(「保存」ボタンがクリックされた)・・・OnSave関数
保存ボタンがクリックされたときに,OnSave関数が呼び出されるようにしました.OnSave関数内ではファイルのオープンやCArchiveオブジェクトの作成を行いSerialize関数を呼び出します.
・イベント処理(「終了」ボタンがクリックされた)・・・OnEnd関数
「終了」ボタンがクリックされれば,OnEnd関数が呼び出されます.OnEnd関数では次の処理を行います.
![]()
・NewDocument関数
新しい日記を見るときには,この関数を呼び出せばすべてが済むようになっています.以下にフローチャートを示します.
![]()
|
Copyright © 2004 Multisoft-lab All rights reserved. |