#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のトップページをご覧ください。