#pragma twice

KAB-studio > プログラミング > #pragma twice > 096 Version 5.31 コンボボックスとエディットボックス

#pragma twice 096 Version 5.31 コンボボックスとエディットボックス

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

 Version 5.31
コンボボックスとエディットボックス

前回はファイルダイアログを使ってみました
 CFileDialog ってクラスで簡単にできたよねー。で、その開いたファイ
ルを読み込むんだよね
そう。 CFileTestDlg::OnBtnShow() の中で……

void CFileTestDlg::OnBtnShow() 
{
    m_cDataLstBox.ResetContent();

    std::ifstream cIFStrm;
    cIFStrm.open( "Data.txt" );   // ここ!
// 以下略

この "Data.txt" をその開いたファイルのフルパス文字列に置き換えれば
うまくいきます
でもどーやって渡すの? メンバ関数違うじゃん
そこで〈コンボボックス〉を使います
こんぼぼっくす?
 IDC_CMB_FILE って ID を付けたコントロール。 Ver 5.01 ( No.066 ) 
を見といてね
あ、[ファイル]の右隣のだね。コンボって、チキンとフライドポテトとか
が一緒のセットをコンボとかゆーよね
それと同じ。コンボボックスは、エディットボックスとリストボックスが
組み合わさってるんです。 Spy++ 起動してからテスト実行してみて
はんこみたいなボタン!
普通に Spy++ の照準を重ねると ComboBox って出るでしょ
うんそーゆーウィンドウクラスだね
その内側に照準を持ってくると……
 Edit になった!!
つまりこの普通に見えるところはエディットボックス
おー
で、その横の [▼] を押すと出てくるのを〈ドロップダウンリスト〉って
言うんだけど、これがリストボックスで作られてます
リストボックス……むむむ、 Spy++ じゃ調べらんないね
そうだね
……じゃーなんでリストボックスだってわかるの?
あー、書いてあるんだよそう。 MSDN の Combo Boxes Overview ってペー
ジを見てみて
英語ページね。へー、クラス名は COMBOBOX だとか、 list box と edit 
control の組み合わせだとか書いてあるんだね
【次へ】を押してくと、どんどん見られるよ
色々細かい解説書いてあるんだね……あ、メッセージっぽいのが出てきた。
コンボボックスのメッセージは CB_ なんだね
左上の【同期】ってボタン押してみて
目次見るボタンだね。結構深いところにあるページだね
上の方に Platform SDK ってあるでしょ
うんある
ここ以下に書いてあるのが、ウィンドウズそのものの仕様
仕様……って、これ文章かなり多くない?
多いよー。コンボボックスだけでも50ページ以上あるみたいだし
50ページ以上!? あ、そーか、メッセージとか API の分も入れてね。
でも解説もかなり分量あるね。はっ、もしかして
そう、他のコントロールも同じくらいあるから
すごい量……
この Platform SDK には重要なことが書いてあること多いから、まめに見
るようにね
それって最初に言うべきことじゃない?
いや、ある程度勉強しとかないと見ても理解できないから
う~。質問! ぷらっとふぉーむえすでぃーけーってどーゆーいみ?
プラットフォームっていうのは OS のこと
つまりウィンドウズ?
そゆこと。 SDK は Software Development Kit の略。つまりソフトを作
るためのもののこと
ソフトを作るためのもの?
つまり API のこと
ああ!
 API はウィンドウズアプリを作るためのキットってことだね。ま、基本
的には SDK と API は同じに考えていいかな
違うことってある?
 API ってゆーと関数のこと指すことが多いかな。だから、前回使った
MAX_PATH みたいな整数値は API とは呼ばないことが多いみたいだけど
これは SDK のものってことなのね。ってことは SDK の中に API が入っ
てるってことなのかな
そういう考え方もできるかな。と、話がそれちゃったね
コンボボックスだよね。よーするにエディットボックスとリストボックス
がくっついてコンボボックスになってるんだね
そゆこと。ま、その辺が混乱の元なんだけどね
どゆこと?
それは……そうだね、メンバ変数作ってみれば分かるかな。リストボック
スの時みたいに、 IDC_CMB_FILE を操作するメンバ変数を作りましょう
リストボックスの m_cDataLstBox みたいなのってことね
まず ClassWizard ダイアログを表示させて【クラス名】が CFileTestDlg
になってるのを確認してから【コントロール ID 】の IDC_CMB_FILE をダブ
ルクリック
【メンバ変数の追加】ダイアログが出たよ。【変数のタイプ】が CString
なんだね
コンボボックスはエディットボックスとしても機能するから、その部分を
CString とくっつける方法も採れるんだけど、今回はパス。【カテゴリ】を
〈コントロール〉にして
【変数のタイプ】が CComboBox になった!
こっちなら CComboBox クラスを使ってコンボボックスを操作できるから
 CString の方だとそういう操作ができない?
そゆこと。計算機作ったときにやったでしょ、 UpdateData( FALSE ) を
呼ぶと、メンバ変数の値がコントロールに書き込まれるってやつ
やった! そっか、エディットの部分を CString 型のメンバ変数と結び
付けて、書き込み読み込みができるようにすることができるんだね
詳しくは Ver 3.11 ( No.036 ) 参照。でも、コンボボックスはリストボッ
クスとしての操作も必要でしょ
そっちは CComboBox 型のメンバ変数でってことになるんだ。ってことは
ふたつメンバ変数を作るってこと?
それもできるんだけどね
って? あんましない方がいいってこと?
まーね。コンボボックスを操作するメンバ変数がふたつもあったら混乱の
元だからね
……なんか煮え切らない言い方ね
でもふたつ作っちゃった方が楽って場合もあるからね。今回は CComboBox 
だけにするけど
ま、確かに混乱の元ってのは分からなくもないけどね。えーっと、メンバ
変数の名前は m_cFileCmbBox でいい?
うんOK
んじゃ【カテゴリ】をコントロール、【変数のタイプ】を CComboBox に
して OK っと。ほいメンバ変数できたよ
さて、じゃあこのコンボボックスに文字列を表示しましょう。 CComboBox 
のリファレンス見て
メンバ関数一覧~。…………ねー、エディットボックスのとこにどーたら
って感じのメンバ関数がみつかんないんだけど
そう、ないんです
えええっ!!
なんでねぇ、さっきの CString 使うっててもあるってことだね
うー、じゃー面倒な方法必要なんだ
あ、別にそういうわけじゃないんだけどね。えーっと、さっき見た MSDN 
の Combo Boxes Overview のページ開いて
ほい
【次へ】ボタンを何度も押して Edit Control Selection Fields って
ページを表示させて読んでみて
ほい出た。えーっとなになに……あ、 WM_SETTEXT ってある! これって
ウィンドウのタイトルとか、ボタンの文字列変えるときに使うのだよね
そうそう。これを見れば分かるとおり、コンボボックスにこのメッセージ
を直接送れば、エディットボックスに送られて、エディットボックスの文字
列を書き換えることができるんです
思い出した!  WM_SETTEXT って SetWindowText() と同じなんだよね。
ってことはこの API 使えばいいんだ!
 API じゃなくても大丈夫でしょ
え? えーっと、 SetWindowText() は…… CWnd のメンバ関数にもなっ
てるね。そっか、コントロールのクラスは CWnd から継承してるから!
そういうこと!  CComboBox は CWnd のメンバ関数も使えるんです。と
いうわけで、前回の CFileTestDlg::OnBtnBrowse() の中身をこう書き換え
てみましょう

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() );
}

なるほど、 m_cFileCmbBox からそのまま SetWindowText() 呼んじゃえば
いいんだ
で、前回使った CFileDialog::GetPathName() と組み合わせれば
ビルドして実行! ファイルダイアログでファイル選んで【開く】っと。
おおっ選んだファイルのフルパスがコンボボックスに!!
じゃ、ついでに CFileTestDlg::OnBtnShow() の方も書き換えちゃいましょ
う。 SetWindowText() の逆に文字列を取得するのは
 GetWindowText() !!  MSDN のリファレンス~っと、2番目のよく分
かんないから1番目のでいーや。 LPTSTR だから文字配列用意して、サイズ
は……
前回やったでしょ、フルパスは最大
 MAX_PATH まで! だから、こんな感じかな?

void CFileTestDlg::OnBtnShow() 
{
    m_cDataLstBox.ResetContent();

    char chPath[MAX_PATH];
    m_cFileCmbBox.GetWindowText( chPath, MAX_PATH - 1 );
    std::ifstream cIFStrm;  
    cIFStrm.open( chPath );
// 以下そのまま。

ビルドして実行、【参照】ボタンでファイルダイアログで Data.txt を選
んで開いて、んで【表示】ボタン押して……おおおっ、前みたくリストボッ
クスに表示された!!
ここまでできると、なんかちゃんとしたアプリっぽいよね
アプリっぽい!! なんかすご~い!!
ま、ようするにコンボボックスも SetWindowText() とかでエディットの
操作ができるってことだね
なんだ、やっぱし CString は要らないんだね
でももし1人でやってとしたら、こーゆーことわかったと思う?
思わない。 CComboBox のメンバ変数から SetWindowText() を呼ぶって発
想出てこないし、そこまでたどり着かせるのも大変だし
だから CString の方法があるってことかも。 MFC は元々簡単にこういう
ことができるようにしてくれてるからね
確かにねー

/*
    Preview Next Story!
*/
コンボボックスひとつでも奥が深いのねぇ
作ってみる側から考えればそれも当然だよ
げ! 作る!?
そりゃコンボボックスだってプログラムとして作れるわけだから
そりゃそうだけど
操作ひとつひとつが、どういう仕様にするべきか熟考されてるんだから
というわけで次回
< Version 5.32 コンボボックスのリストに追加! >
につづく!
……ホントに熟考されてると思う?
う”
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。