Version 5.33
仕様を考えてさらに使いやすく!
「まとめがてら、ここまでのコードを見ておきましょう」
void CFileTestDlg::OnBtnBrowse()
{
CFileDialog cFileDlg( TRUE );
char chPath[MAX_PATH];
GetModuleFileName
( AfxGetInstanceHandle(), chPath, MAX_PATH - 1 );
cFileDlg.m_ofn.lpstrInitialDir = chPath;
int iRes
= cFileDlg.DoModal();
if( iRes == IDCANCEL )
{
return;
}
m_cFileCmbBox.SetWindowText( cFileDlg.GetPathName() );
int iNo
= m_cFileCmbBox.FindString( -1, cFileDlg.GetPathName() );
if( iNo != CB_ERR )
{
m_cFileCmbBox.DeleteString( iNo );
}
m_cFileCmbBox.InsertString( 0, cFileDlg.GetPathName() );
}
『これが【参照】ボタンを押したときのね。でもホントはこれじゃない方が
いいんだよね』
「そう、前回決めた仕様じゃ【表示】ボタンを押したときってことにしてた
からね。その【表示】ボタンを押したときのメンバ関数は……」
void CFileTestDlg::OnBtnShow()
{
m_cDataLstBox.ResetContent();
char chPath[MAX_PATH];
m_cFileCmbBox.GetWindowText( chPath, MAX_PATH - 1 );
std::ifstream cIFStrm;
cIFStrm.open( chPath );
if( cIFStrm.fail() )
{
MessageError( IDS_E_NOFILE );
return;
}
// 以下略。
『あれ、そういえばファイル名って CWnd::GetWindowText() でコンボボッ
クスから取ってるんだね。ってことは今のままでも動くの?』
「動くよ、ちゃんと」
『んじゃ【参照】で色々ファイル集めて、【表示】すると……エラー。んで
Data.txt をリストから選んで【表示】……おおっちゃんと出た!!』
「基本的な機能はこれで大丈夫だね」
『……ねー、リストへの追加って【参照】ボタン押したとき、でいいんじゃ
ない?』
「横着しないの。このコンボボックス、普通にパスを打ち込めるでしょ」
『あ、そういうのがリストに追加されなくなっちゃうね』
「それに、その打ち込んだパスが間違ってたらリストに載せない方がいいで
しょ」
『ってことは、 if( cIFStrm.fail() ) が通ってから追加した方が良さそう
だね』
「それじゃ早速」
『 CFileTestDlg::OnBtnBrowse() の中でコンボボックスに追加してるのは
CComboBox::FindString() 呼んでるとこからだから、それをカット&ペース
トっと』
void CFileTestDlg::OnBtnShow()
{
// 略。
return;
}
int iNo
= m_cFileCmbBox.FindString( -1, cFileDlg.GetPathName() );
if( iNo != CB_ERR )
{
m_cFileCmbBox.DeleteString( iNo );
}
m_cFileCmbBox.InsertString( 0, cFileDlg.GetPathName() );
// 以下略。
『ビルドして……あれ? エラーになっちゃった cFileDlg がないって言わ
れてるのかな』
「実際にないでしょうが」
『あ、そっか、 cFileDlg は CFileTestDlg::OnBtnBrowse() の中の変数だ
もんね。あれ、でもこの変数からファイルパス取得してたんだよね、じゃあ
どうすればいいの??』
「混乱しないの! 今の状態だと、 CFileTestDlg::OnBtnBrowse() の最後
でしてるのは?」
『 CWnd::SetWindowText() でコンボボックスに貼り付けてる……あ、そっ
か、そのコンボボックスからもらえばいいんだ』
「そゆこと。で、それをもう CFileTestDlg::OnBtnShow() の最初の方でし
てるでしょ」
『ホントだ! ってことは chPath に入ってるんだね。だから……』
void CFileTestDlg::OnBtnShow()
{
// 略。
int iNo
= m_cFileCmbBox.FindString( -1, chPath );
if( iNo != CB_ERR )
{
m_cFileCmbBox.DeleteString( iNo );
}
m_cFileCmbBox.InsertString( 0, chPath );
// 以下略。
『ビルド!! おおっ通った!! んで実行っと。うん、【表示】ボタンを
押したときに追加される!』
「これでかなりしっかりした感じになったね」
『あれ……なんか?』
「どしたの?」
『んー、全然関係ないファイルを開くと【整数値が含まれていません】にな
るけど、こういう時に追加するのっていいのかな』
「この辺は微妙なとこだね。理想は設定で変えられるようにすることかな」
『もひとつ、リストの中から選んで【表示】させると、コンボボックスが空
欄になっちゃうんだけど』
「あ、ホントだ。これはほら、リストにすでにある場合にはリストから削除
して挿入してたでしょ、あれでたぶん」
『なんかちょっと見栄え悪いよね』
「なら追加しちゃうとか」
void CFileTestDlg::OnBtnShow()
{
// 略。
m_cFileCmbBox.InsertString( 0, chPath );
m_cFileCmbBox.SetWindowText( chPath ); // ここだけ追加。
// 以下略。
『あ、そういうのアリなんだ!』
「もちろん。あーでも、他の方法もあるのかもなー」
『なんか適当……』
「あと……もうふたつほど。まず履歴の数」
『そういえば、普通10個くらいだよね。じゃあ10個超えたら一番最後の
を削除しちゃうとか』
「うん、それしてみて」
『リストの中の数を調べるのは…… GetCount() っぽいから、これを if し
て 11 の時に DeleteString() で 11 番目を』
「 0 から始まるから……」
『 DeleteString() には 10 を渡せばいいんでしょ? そのくらい分かって
るよー』
void CFileTestDlg::OnBtnShow()
{
// 略。
m_cFileCmbBox.InsertString( 0, chPath );
m_cFileCmbBox.SetWindowText( chPath );
if( m_cFileCmbBox.GetCount() == 11 )
{
m_cFileCmbBox.DeleteString( 10 );
}
// 以下略。
『ううっ、テストがめんどい……』
「テストするときは少ない数字の方がいいかも」
『そういうことは早く言ってよ!』
「あと整数値は……」
『そうだ! const int しなきゃね。あとで 11 を 21 に変えたりするの
大変だもの』
「ま、それは今回はいいや。火美ちゃんは分かってるんだし。あともうひと
つの問題点は【参照】のフォルダかな」
『そういえば、今はアプリのフォルダなんだよね』
「でもそれじゃ不親切でしょ」
『不親切! 全然違うとこのファイルを開いたら、やっぱ次もそのフォルダ
開きたいよね』
「どうすればいいと思う?」
『えーっと……最初に開くフォルダは cFileDlg.m_ofn.lpstrInitialDir で
決まるんだよね』
「そう、そこに GetModuleFileName() で取得したパスを使ってたから」
『アプリのフォルダが開いてたんだよね』
「で、前回開いたファイルのパスはどこに書き込まれてる?」
『……コンボボックス! ってことは CWnd::GetWindowText() でコンボボッ
クスから拾って……』
「たぶんこんな感じになると思うよ」
void CFileTestDlg::OnBtnBrowse()
{
CFileDialog cFileDlg( TRUE );
char chPath[MAX_PATH];
// ここから下を改変。
m_cFileCmbBox.GetWindowText( chPath, MAX_PATH - 1 );
if( chPath[0] == '\0' )
{
GetModuleFileName
( AfxGetInstanceHandle(), chPath, MAX_PATH - 1 );
}
// ここまで改変。
cFileDlg.m_ofn.lpstrInitialDir = chPath;
int iRes
= cFileDlg.DoModal();
if( iRes == IDCANCEL )
{
return;
}
m_cFileCmbBox.SetWindowText( cFileDlg.GetPathName() );
}
『 GetWindowText() のはいつものヤツね』
「元々 chPath っていうのがあるんだから、それを利用してってことで」
『 if( chPath[0] == '\0' ) は……文字列が空かどうかってこと?』
「そ。一番最初の時とか、コンボボックスに何も書き込まれてないならアプ
リのフォルダを開くように。こういうふうに、最初に終端文字が来てるか調
べる方法もあるし、文字列の長さを調べる方法もあるかな」
『ランタイムの strlen() 使ってとか?』
「そゆこと。その戻り値が 0 なら、って感じにね」
『で……あんま変わってないよね』
「うん」
『……私がちょっと考えたのだと、結構膨らんじゃうなー』
「僕は chPath を使い回したからね。でも重要なのは分かり易さ。使い回し
て分かりにくくなるなら意味がないから」
『分かりやすさって?』
「変数の意味が変わらない、ってことかな」
『そっか、ファイルのパスってことは変わんないんだもんね』
「データの一時保存に利用しちゃうとかしないように心がけていれば、こう
いう使い回しはいいと思うよ」
/*
Preview Next Story!
*/
『もうそろそろ完成じゃない?』
「あとレジストリまわり作れば完成だよ」
『レジストリ! 前やったね』
「この段階になると、いかに昔のこと憶えてるかが鍵かも」
『というわけで次回』
< Version 5.34 閉じる前にレジストリに >
「につづく!」
『あたしがメールで送られてきたとかも?』
「そういう設定、もう生かせないかも……」