戻る 第10章 コントロールの使用
(コンボボックス)
次へ

ソース 実行ファイル
sdk10.cpp sdk10.exe

今回はコンボボックスです。
これもかなり使う機会が多いと思われるコントロールです。
しかし今回も結構できる事が多い分複雑です。

ここではその中でも最低限必要な部分を説明します。
それは追加・削除・選択です。
メッセージ 効果
CB_ADDSTRING
wParam = 0;/* 使われません。0でなければなりません*/
lParam = (LPARAM) (LPCSTR) lpsz;/* 追加される文字列のアドレス*/
項目の追加
CB_DELETESTRING
wParam = (WPARAM) index;/* 削除する項目*/
lParam = 0;/* 使われません。0でなければなりません*/
項目の削除
CB_GETCURSEL
wParam = 0;/* 使われません。0でなければなりません*/
lParam = 0;/* 使われません。0でなければなりません*/
選択の取得
CB_SETCURSEL
wParam = (WPARAM) index;/*項目インデックス*/
lParam = 0;/* 使われません。0でなければなりません*/
項目の選択
CB_GETLBTEXT
wParam = (WPARAM) index;/*項目インデックス*/
lParam = (LPARAM) (LPCSTR) lpszBuffer;/* バッファのアドレス*/
文字列の取得
CB_GETLBTEXTLEN
wParam = (WPARAM) index;/*項目インデックス*/
lParam = 0;/* 使われません。0でなければなりません */
文字数の取得
これだけならかなり簡単に出来そうですね。 前回とにてるなぁと思った人がいると思います(^^; 実はリストボックスとコンボボックスはかなり似てるんです(^^) 注意して頂きたい点はコンボボックスのサイズはリストを開いたサイズになるということです。 サイズのYの範囲に32とかしていると中身は見えないです(^^; #include <windows.h> LRESULT CALLBACK WinProc(HWND hwnd, UINT msg,WPARAM wP, LPARAM lP) { HDC hdc; PAINTSTRUCT ps; char str[40]; switch(msg){ case WM_CREATE: combo=CreateWindowEx(0, "COMBOBOX", //コンボボックスクラスを指定 "",//空白にする WS_CHILD|WS_BORDER|WS_VSCROLL|LBS_NOTIFY,//子Window指定・メッセージ取得指定 24, 8,128, 96,//コンボボックスのサイズ hwnd, NULL,//IDはいらない (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), NULL);//プロシージャ ShowWindow(list,SW_SHOW);//コンボボックスを表示 //リストボックスに項目を追加する SendMessage(combo, CB_ADDSTRING, 0L, (LPARAM)"いちご"); SendMessage(combo, CB_ADDSTRING, 0L, (LPARAM)"バナナ"); SendMessage(combo, CB_ADDSTRING, 0L, (LPARAM)"みかん"); SendMessage(combo, CB_ADDSTRING, 0L, (LPARAM)"りんご"); SendMessage(combo, CB_ADDSTRING, 0L, (LPARAM)"ゆず"); SendMessage(combo, CB_ADDSTRING, 0L, (LPARAM)"桃"); SendMessage(combo, CB_SETCURSEL, 0, 0L);//最初の項目を選択しておく //追加・削除・選択のボタンを描画 btn[0]=CreateWindowEx(0,"BUTTON","追加",WS_CHILD, 164, 8,64, 32,hwnd,(HMENU)ID_BTN1, (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE),NULL); ShowWindow(btn[0],SW_SHOW); btn[1]=CreateWindowEx(0,"BUTTON","削除",WS_CHILD, 164, 40,64, 32,hwnd,(HMENU)ID_BTN2, (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE),NULL); ShowWindow(btn[1],SW_SHOW); btn[2]=CreateWindowEx(0,"BUTTON","選択",WS_CHILD, 164, 72,64, 32,hwnd,(HMENU)ID_BTN3, (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE),NULL); ShowWindow(btn[2],SW_SHOW); break; case WM_COMMAND: switch ( LOWORD ( wP ) ) { case ID_BTN1://「追加」と言う項目を入れる SendMessage(combo, CB_ADDSTRING, 0L, (LPARAM)"追加"); break; case ID_BTN2://最後の項目を削除する。 SendMessage(combo, CB_DELETESTRING, SendMessage(combo, CB_GETCOUNT, 0L, 0L)-1, 0L); SendMessage(combo, CB_SETCURSEL, 0, 0L);//最初の項目を選択しておく break; case ID_BTN3://現在選択している番号を取得 i=SendMessage(combo, CB_GETCURSEL, 0L, 0L); if(i!=LB_ERR){ wsprintf(str,"%dが選択されました。",i); MessageBox(hwnd,str,"BUTTON",MB_OK); } else{ MessageBox(hwnd,"項目を選択してください","BUTTON",MB_OK); } break; } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, msg, wP, lP); } return 0; } これでコンボボックスの操作はとりあえず出来ます。 ボタンと違って応答はハンドルとメッセージですると言うことを注意してください。
追記(2003/6/19) 文字列の取得について i=SendMessage(combo, CB_GETCURSEL, 0L, 0L); ではインデックス番号が帰ってきます。 実際には文字列が欲しい場合があると思いますがその場合は こうします。 SendMessage(combo, CB_GETLBTEXT, SendMessage(combo, CB_GETCURSEL, 0L, 0L), (LPARAM)str); これでstrに選択したインデックスの文字列が格納されます。 バッファはあふれないように取っておいてください。 動的にバッファを生成したい場合は strlen=SendMessage(combo, CB_GETLBTEXTLEN, SendMessage(combo, CB_GETCURSEL, 0L, 0L), 0L); とする事により戻り値strlenに文字数が格納されます。 これを元にバッファを確保してから文字列を格納する方が確実です。