#pragma twice

KAB-studio > プログラミング > #pragma twice > 097 Version 5.32 コンボボックスのリストに追加!

#pragma twice 097 Version 5.32 コンボボックスのリストに追加!

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

 Version 5.32
コンボボックスのリストに追加!

前回はコンボボックスに文字列を入れてみました
 SetWindowText() でできたのよねー、知っちゃえば簡単ね
で、わざわざコンボボックスにしたんだから、コンボボックスのリストに
パスを追加してみましょう
追加って、いつするのがいいのかな
その辺はどういう使い勝手にするかって部分だね。とりあえずは【参照】
ボタンを押したとき、ってことにしようか
はーい
じゃ、どういうふうにすればいい、っていうのイメージしてみて
えええっ!? えーっとねぇ……そういえば、リストボックスの時には 
CListBox::AddString() ってメンバ関数呼んだら追加できたんだから、コン
ボボックスでもそういうのできそう
では調べてみましょう
 MSDN 開いて CComboBox のメンバ関数一覧……あ、まんま AddString() 
ってのがある
じゃ、それ使ってみましょう!
使ってみるって言っても……
こういう、この関数でいいのかなーって時には、簡単にテストしてみると

簡単にテスト、ねぇ…… CFileTestDlg::OnBtnBrowse() の最後ででもし
てみようかな

void CFileTestDlg::OnBtnBrowse() 
{
// 略。
    m_cFileCmbBox.SetWindowText( cFileDlg.GetPathName() );

// この下を追加。
    m_cFileCmbBox.AddString( cFileDlg.GetPathName() );
}

んーと、コンボボックスのメンバ変数 m_cFileCmbBox から AddString() 
を呼び出して、それに、ファイルのフルパスを取得する 
cFileDlg.GetPathName() の戻り値を渡せば……ビルドして実行! ちゃん
と下のリストに追加されてく!!
うん、うまくいってるね。このメンバ関数で追加できるってことは分かっ
たね
……あれ? でも追加した順番と並び方が違う……
前にもそういうことあったね
あった! リストボックスの時! あのときソートされてたんだ
 Ver 5.19 ( No.084 ) の時だね
あのときは、プロパティでソートになってたんだよね。あ! ってことは
コンボボックスのプロパティにも!?  IDC_CMB_FILE のプロパティ……
あった!
これもソートがデフォルトなんだなぁ……
そういえば他にもいろんなスタイルがあるね
さて問題。こうやってプロパティで決めるの以外では、ウィンドウのスタ
イルはいつ決められる?
え!? えーっと……そう、 CreateWindow() 呼んだとき! 前にウィン
ドウやボタン作ったときに WS_CHILD とか BS_PUSHBUTTON 渡したんだもん

そうでした。ってことは、スタイルの情報についてはそういうページを見
ればいいってこと
なるほど! ってことは…… CComboBox::Create() とかにもあったりす
るのかな……あ、〈コンボボックススタイル〉ってのがある! おおっスタ
イルがいっぱい!
あとは、プロパティのスタイルがどれに当たるのか分かれば
見ればだいたい分かるね。 CBS_SORT っていまのソートするってのだよね
だからこれを見れば
……見てもわかんねぇ……
ま、そういうもんだね。こういうのは遊びがてら実際に試してみて、どう
いう機能を持ってるのかとか憶えていく方がいいかも
面倒な方法……
とりあえず、【ソート】は外して、【水平オートスクロール】はチェック
した方がいいかな
水平オートスクロール?
これしないで、長い文字列をコンボボックスに入れてみて
んじゃ深いフォルダにあるファイルを参照っと。あれ? なんかえらい使
いづらい……
普通、右の方にドラッグすると自動的にスクロールするんだけど
しない〜
で、【水平オートスクロール】をチェックすると
おおっ、ちゃんとなる!!
こういうふうに色々試して憶えていかないとね
っつーかさ、他のアプリだとできてるのにうちはできない! じゃあどう
いうスタイルか Spy++ で見てみよう、 CBS_AUTOHSCROLL がないじゃない、
それじゃそれを追加しよう、って方法じゃダメ?
OK。その方が普通かもね。あ、でも前に行ったけど、単にスタイルだけ
が原因とは限らないから
タイトルバーがどうのこうのとか前に言ってたね
たとえば、こういうスタイルで実現できるって知らなくて、プログラムの
力業で実現させてたりとか
うわぁ……
ま、スタイルはその辺にしといて、今の段階だとあとふたつ問題がありま

え? そなの?
同じファイルを3回立て続けに参照すると
みっつ全部追加されるね
それって変じゃない?
うん、変。これってようするにファイルの履歴でしょ、そしたら同じファ
イルがいっぱいあってもしょうがないじゃん
というわけでこれを何とかしましょう
……そういうのを何とかするスタイルとかあるの?
ありません
……ってことは、自分でなんとかしなきゃダメ?
そゆこと
難しそう〜
順を追って考えれば大丈夫。まず、ファイルの履歴がリストにずらっと並
んでます
ずらっと
ここに新しいファイルのフルパスが追加されます。でも同じものがリスト
にもありました。普通のアプリだとどうなる?
んーと、普通、リストにあったのが一番上に来るんだよね
ってことは、手順としては、まずリストに同じものがあるか調べて、あれ
ばそれを先頭まで移動、ってすればいいわけ
あ、そっか!
この辺はパズルみたいなものかも
じゃ、そうと分かればそういう機能があるメンバ関数を探せばいいんだね。
えーっと、見つけだすのは CComboBox::FindString() で良さそう。あ、で
も移動させるのはなさそう
うん、移動させるのはないみたいだね。そういう場合はどうする?
そーねぇ…… DeleteString() で削除して AddString() で追加するって
いうのは?
んじゃそれを試してみましょう。あ、まず CComboBox::FindString() か
ら試した方がいいかも
そなの?
いやね、僕がいるんだからホントは必要ないんだけど、実際に自分で調べ
てくときには、あまりいっぺんにしない方がいいから
さっき言ってた簡単なテスト、ってヤツね
そゆこと。あ、でも、今みたく〈どのメンバ関数使えばいいのかな〉って
調べるときには、片っ端からテストせずに、まずどんな方法があるのか良く
調べてからの方がいいよ
どして?
1発で簡単にできちゃう関数があるかもしれないでしょ
あ、そっか
それに、どの関数を使うかによってメリットデメリットがあるってことも
あるから、必要なら使い比べることも必要だしね
片っ端から使ってたら、最初に使ったのが良かったら他の方法見ないもん

じゃ、まずは CComboBox::FindString() から
んーと、第1引数は調べる場所……あ、でも -1 でいいんだね
そだね、 -1 だと全体を検索するみたいだね
あのさ、ここに書いてある〈 0 から始まるインデックス〉って、つまり
配列みたいに 0 から始まるのって意味だよね
そうだよ。他の言語だと 1 から始まるのとかあるし、もちろん関数に
よっては
 2 とか 3 とかから始まる?
作れなくはないけど……
で、第2引数が探す文字列、戻り値に、何番目に同じのがあったのかって
いうのが返ってくるのね。見つからなかったら CB_ERR っと
んじゃ使ってみましょう
テストだから、戻り値を TRACE() で出してみればいいかな

void CFileTestDlg::OnBtnBrowse() 
{
// 略。
    m_cFileCmbBox.SetWindowText( cFileDlg.GetPathName() );

// この下を追加。
    int iNo
        = m_cFileCmbBox.FindString( -1,  cFileDlg.GetPathName() );
    TRACE( "%d\n", iNo );
// この下のはさっきの。
    m_cFileCmbBox.AddString( cFileDlg.GetPathName() );
}

うん、同じのを選ぶとそのインデックスナンバーが返ってくる!
じゃ、次はそれを削除しましょう
 CComboBox::DeleteString() でたぶん削除できると思うから、これの引
数に CComboBox::FindString() の戻り値を渡してっと
 CB_ERR が返ってきたときは削除しないようにすること、忘れないで
おおっとそうだった

void CFileTestDlg::OnBtnBrowse() 
{
// 略。
    m_cFileCmbBox.SetWindowText( cFileDlg.GetPathName() );

    int iNo
        = m_cFileCmbBox.FindString( -1,  cFileDlg.GetPathName() );
    if( iNo != CB_ERR )
    {
        m_cFileCmbBox.DeleteString( iNo );
    }
    m_cFileCmbBox.AddString( cFileDlg.GetPathName() );
}

ビルドして実行! おおっ、ちゃんと削除されてる! そしてちゃんと追
加……あれ?
そ、もうひとつの問題点。最後に追加じゃなく
履歴っぽくするんならやっぱ一番上じゃないとね。でもだとしたらどう
するんだろう
どうすればいいと思う?
 AddString() は最後にしか追加できないから……他の位置に追加できる
メンバ関数を探せばいいんだ! えーっと、 CComboBox::InsertString() 
なんかそれっぽいね
うん、それで大丈夫でしょ
えっと、第1引数は……この〈挿入〉って、どこに入んのかいまいち分か
んないんだけど
そうなんだよね、2番目を指定したときに2番目の上にはいるのか下に入
るのか、っていうのがあるから。ま、これはよく読めば分かるだろうけど
分かる?
理論上、〈上に挿入〉なら一番最後に追加できないし、〈下に挿入〉なら
一番最初に追加できないでしょ
あ、だから〈 -1 で最後に追加〉ってあるんだ! ってことは〈上に挿入〉

そゆこと。ってことは一番最初に追加するには?
インデックスナンバーを 0 にする! だからこんな感じ?

void CFileTestDlg::OnBtnBrowse() 
{
// 略。
    int iNo
        = m_cFileCmbBox.FindString( -1,  cFileDlg.GetPathName() );
    if( iNo != CB_ERR )
    {
        m_cFileCmbBox.DeleteString( iNo );
    }
    m_cFileCmbBox.InsertString( 0, cFileDlg.GetPathName() ); // ここ。
}

ビルドして実行! おおっちゃんとした履歴みたい!


/*
    Preview Next Story!
*/
少しずつできてくって楽しいね!
ま、ホントはこういうのはいけないんだけどね
どゆこと?
仕様とかを最初にしっかり決めてから作り始めないと
そんなの遠い先の話だと思ってた……
いや実際遠い話かも
なにそれ!
というわけで次回
< Version 5.33 仕様を考えてさらに使いやすく! >
につづく!
ま、そういうのはも少し先ってことで
行き当たりばったりばかりの水希ちゃんに、仕様なんて作れるのぉ?
う”
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。