ListBoxを使ってみる
ListBoxの使い方を勉強する.
ListBoxの項目を選択すると選択したものがStaticTextに反映されるっていうものを作る.
コード
typedef struct Window_ { int id; HWND handle; } Window; INT_PTR CALLBACK Dialog1Proc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); static Window selection, selected; BOOL inited = FALSE; switch (message) { case WM_INITDIALOG: if (inited != TRUE) { /* 初期化 */ TCHAR items[][16] = { TEXT("C"), TEXT("C++"), TEXT("Perl"), TEXT("Python"), TEXT("Ruby"), TEXT("Java"), TEXT("Javascript") }; int i, items_len = sizeof (items) / sizeof(items[0]); selection.id = IDC_SELECTIONS_LIST; selection.handle = GetDlgItem(hDlg, selection.id); selected.id = IDC_SELECTED_ITEM_LABEL; selected.handle = GetDlgItem(hDlg, IDC_SELECTED_ITEM_LABEL); for (i = 0; i < items_len; i++) { /* ListBoxの初期化 */ SendMessage(selection.handle, LB_ADDSTRING, 0, (LPARAM) items[i]); } /* デフォルトの選択としてListBoxの0番目を選択 */ SendMessage(selection.handle, LB_SETCURSEL, 0, 0); } return (INT_PTR)TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_SELECTIONS_LIST: /* ListBoxにメッセージがとんできた */ switch (HIWORD(wParam)) { case LBN_SELCHANGE: /* ListBoxの選択が変化したよ(>_<) */ LPTSTR t; int t_len, i; i = (int) SendMessage(selection.handle, LB_GETCURSEL, 0, 0); t_len = (int) SendMessage(selection.handle, LB_GETTEXTLEN, i, 0); t = (LPTSTR) calloc(sizeof(t[0]), t_len + 1); if (t == NULL) { return FALSE; } SendMessage(selection.handle, LB_GETTEXT, i, (LPARAM) t); SetWindowText(selected.handle, t); free(t); break; } break; case IDOK: case IDCANCEL: PostQuitMessage(0); // return (INT_PTR)TRUE; } break; case WM_DESTROY: PostQuitMessage(0); break; } return (INT_PTR)FALSE; }
"スタティック"のままの原因
デフォルト項目への選択時にLBN_SELCHANGEが送られていないのが原因.
LBS_NOTIFYを設定してあるListBoxだと,マウスとかキーボードでListBoxの項目を選択したときには親ウィンドウにWM_COMMANDでLBN_SELCHANGEが送られる.
でも,LB_SETSELCHANGEしたときには送ってくれないから自分で送らなきゃいけない.
ということで初期化部分を修正
case WM_INITDIALOG: if (inited != TRUE) { /* 初期化 */ TCHAR items[][16] = { TEXT("C"), TEXT("C++"), TEXT("Perl"), TEXT("Python"), TEXT("Ruby"), TEXT("Java"), TEXT("Javascript") }; int i, items_len = sizeof (items) / sizeof(items[0]); selection.id = IDC_SELECTIONS_LIST; selection.handle = GetDlgItem(hDlg, selection.id); selected.id = IDC_SELECTED_ITEM_LABEL; selected.handle = GetDlgItem(hDlg, IDC_SELECTED_ITEM_LABEL); for (i = 0; i < items_len; i++) { /* ListBoxの初期化 */ SendMessage(selection.handle, LB_ADDSTRING, 0, (LPARAM) items[i]); } /* デフォルトの選択としてListBoxの0番目を選択 */ SendMessage(selection.handle, LB_SETCURSEL, 0, 0); /* ここを追加だよ(>_<) */ SendMessage(hDlg, WM_COMMAND, MAKEWPARAM(selection.id, LBN_SELCHANGE), 0); } return (INT_PTR)TRUE;
まとめ
- LB_SELCHANGEしたときにはLBN_SELCHANGEを送ってくれない
- LBN_SELCHANGEの送り方は
SendMessage(parantDlg, WM_COMMAND, MAKEPARAM(LISTID, LBN_SELCHANGE), 0); - WPARAMは MAKEWPARAM(下位,上位); でつくる.