#pragma twice

KAB-studio > プログラミング > #pragma twice > 098 Version 5.33 仕様を考えてさらに使いやすく!

#pragma twice 098 Version 5.33 仕様を考えてさらに使いやすく!

前のページへ 表紙・目次へ 次のページへ

 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 閉じる前にレジストリに >
「につづく!」
『あたしがメールで送られてきたとかも?』
「そういう設定、もう生かせないかも……」
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。