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