レバーコントロール(クールバー、リバーコントロール)に背景をつけます。
レバーコントロール上にコンボボックスをのせます。
コンボボックスからメニューを選択すれば、右のようなポップアップメニューが出ます。
レバーコントロール1 - インコのWindowsSDK で作成したソースを修正します。
流れ
WM_CREATE
WM_CREATEは、ウインドウが生成されたときに1回だけ実行されます。
1.REBARBANDINFO構造体のfMaskメンバに、hbmBackメンバを有効にするため、RBBIM_BACKGROUNDを追加。
2.REBARBANDINFO構造体のhbmBackメンバに、背景用ビットマップのハンドルをセット。
LoadBitmap()で、ビットマップリソースをロードする。
3.CreateFont()で、論理フォントを作成
4.CreateWindowEx()でコンボボックスを作成
lpClassName | 登録されているクラス名 コンボボックスの場合 |
|
TEXT("COMBOBOX") | コンボボックス | |
dwStyle | ウィンドウスタイル 共通のウィンドウスタイル、 コンボボックスのスタイルが使えます。 |
|
コンボボックスのスタイル ●以下は、lpClassNameでTEXT("COMBOBOX")を指定したときのみ有効 |
||
CBS_SIMPLE | 常時リストボックスが表示されるコンボボックスを作成 | |
CBS_DROPDOWN | ドロップダウンコンボボックスを作成 | |
CBS_DROPDOWNLIST |
ドロップダウンリストボックスを作成 テキストの編集は不可 |
|
CBS_OWNERDRAWFIXED | 各項目の高さがすべて同じ、オーナードローコンボボックスを作成 | |
CBS_OWNERDRAWVARIABLE | 各項目の高さが可変の、オーナードローコンボボックスを作成 | |
CBS_AUTOHSCROLL | ユーザーが行末に文字を入力すると、エディットコントロール内のテキストが自動的に右スクロール | |
CBS_SORT | リストボックスに追加されたテキストを自動的にソート | |
CBS_HASSTRINGS | オーナードローコンボボックスのアイテムがテキストであることを指定 | |
CBS_NOINTEGRALHEIGHT |
コンボボックスのサイズを指定 デフォルトでは、項目が途中で切れないように、Windows システムがコンボボックスのサイズを調整 |
|
CBS_DISABLENOSCROLL | スクロールするほどの項目数がない場合、リストボックスの垂直方向のスクロールバーが無効状態で表示 | |
CBS_UPPERCASE | コンボボックスのエディットコントロールに入力された小文字を、大文字に変換 | |
CBS_LOWERCASE | コンボボックスのエディットコントロールに入力された大文字を、小文字に変換 |
● 以下のコンボボックスについては、 コンボボックス - インコのWindowsSDK を参照してください。
5.WM_SETFONTメッセージをセットし、フォントを変更する。
6.CB_ADDSTRINGメッセージで、コンボボックスにデータを入れる。
7.CB_FINDSTRINGEXACTメッセージで、指定文字列にマッチする項目を選択。
8.CB_SETCURSELメッセージで、表示する項目を選択。
WM_COMMAND
コンボボックスのリストボックスを選択すると、CBN_SELCHANGEメッセージが 送られてくる。
1.CB_GETCURSELメッセージで、現在選択されているコンボボックスの インデックスを取得する。
ソースコードの入力
ソースコードは下記のように入れてください。
#define _WIN32_WINNT 0x0501 #include <windows.h> #include <commctrl.h> #include "resource.h" #pragma comment(lib, "comctl32.lib") // レバーコントロールの作成に必要 // グローバル変数: HWND hCombo1; // コンボボックスのハンドル HWND hCombo2; // コンボボックスのハンドル // このコード モジュールに含まれる関数の宣言を転送します: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG msg; MyRegisterClass(hInstance); // アプリケーションの初期化を実行します: if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } // メイン メッセージ ループ: while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (int) msg.wParam; } // // 関数: MyRegisterClass() // // 目的: ウィンドウ クラスを登録します。 // ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(NULL , IDI_APPLICATION); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = MAKEINTRESOURCE(IDC_HP); wcex.lpszClassName = TEXT("HP"); wcex.hIconSm = LoadIcon(NULL , IDI_APPLICATION); return RegisterClassEx(&wcex); } // // 関数: InitInstance(HINSTANCE, int) // // 目的: メイン ウィンドウを作成します。 // BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; hWnd = CreateWindow(TEXT("HP"), TEXT("HP"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } // // 関数: WndProc(HWND, UINT, WPARAM, LPARAM) // // 目的: メイン ウィンドウのメッセージを処理します。 // // WM_CREATE - ウインドウ作成時の処理 // WM_SIZE - ウインドウサイズ変更時の処理 // WM_COMMAND - アプリケーション メニューの処理 // WM_DESTROY - 中止メッセージを表示して戻る // // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; static HWND hRebar; // レバーコントロールのハンドル RECT Rect; // RECT構造体 INITCOMMONCONTROLSEX ic; // INITCOMMONCONTROLSEX構造体 REBARBANDINFO rbBand; // REBARBANDINFO構造体 HFONT hFont; // フォント LPCTSTR szBuf_edit1; LPCTSTR strItem1[] = { TEXT("COM1") , TEXT("COM2") , TEXT("COM3") }; LPCTSTR strItem2[] = { TEXT("COM11") , TEXT("COM12") , TEXT("COM13") }; UINT i; UINT index; UINT com_no; switch (message) { case WM_CREATE: //コモンコントロールの初期化 ic.dwICC = ICC_COOL_CLASSES; ic.dwSize = sizeof(INITCOMMONCONTROLSEX); InitCommonControlsEx(&ic); //レバーコントロールの作成 hRebar = CreateWindowEx(0,REBARCLASSNAME,TEXT(""), WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS |WS_CLIPCHILDREN | CCS_NODIVIDER, 0, 0, 0, 0, hWnd, (HMENU)ID_COOL, (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), NULL); // REBARBANDINFO構造体 ZeroMemory(&rbBand, sizeof(REBARBANDINFO)); // 構造体のサイズ rbBand.cbSize = sizeof(REBARBANDINFO); // マスクフラグ rbBand.fMask = RBBIM_STYLE | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE | RBBIM_BACKGROUND; // バンドの背景 rbBand.hbmBack = LoadBitmap((HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), MAKEINTRESOURCE(IDB_BITMAP1)); // バンドのスタイルフラグ rbBand.fStyle = RBBS_CHILDEDGE; // 最小値の高さ rbBand.cyMinChild = 21; // 最小値の幅 rbBand.cxMinChild = 100; // レバーコントロールにのせる対象の子ウインドウのハンドル hFont = CreateFont(12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, SHIFTJIS_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_MODERN, TEXT("MS Pゴシック")); hCombo1 = CreateWindowEx(0, TEXT("COMBOBOX"), TEXT(""), WS_CHILD | WS_VISIBLE | CBS_DROPDOWN, 0, 0, 0, 0, hRebar, (HMENU)ID_COMBO1, (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE) ,NULL); SendMessage(hCombo1, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(true, 0)); // コンボボックスにデータを詰めていく for (i = 0 ; i < 3 ; i++) { SendMessage(hCombo1 , CB_ADDSTRING , 0 , (LPARAM)strItem1[i]); } // ウインドウ生成時にはじめに表示するデータを指定 index = SendMessage(hCombo1, CB_FINDSTRINGEXACT, -1, (LPARAM)TEXT("COM1")); SendMessage(hCombo1, CB_SETCURSEL, index, 0); rbBand.hwndChild = hCombo1; // レバーコントロールにコンボボックス1を挿入 SendMessage(hRebar, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbBand); // レバーコントロールにコンボボックス2を挿入 hCombo2 = CreateWindowEx(0, TEXT("COMBOBOX"), TEXT(""), WS_CHILD | WS_VISIBLE | CBS_DROPDOWN, 0, 0, 0, 0, hRebar, (HMENU)ID_COMBO2, (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE) ,NULL); SendMessage(hCombo2, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(true, 0)); // コンボボックスにデータを詰めていく for (i = 0 ; i < 3 ; i++) { SendMessage(hCombo2 , CB_ADDSTRING , 0 , (LPARAM)strItem2[i]); } // ウインドウ生成時にはじめに表示するデータを指定 index = SendMessage(hCombo2, CB_FINDSTRINGEXACT, -1, (LPARAM)TEXT("COM11")); SendMessage(hCombo2, CB_SETCURSEL, index, 0); rbBand.hwndChild = hCombo2; GetClientRect(hRebar, &Rect); rbBand.cx = Rect.right - 100; SendMessage(hRebar, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbBand); break; case WM_SIZE: SendMessage(hRebar, WM_SIZE, wParam, lParam); break; case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // 選択されたメニューの解析: switch (wmId) { case ID_COMBO1: if (HIWORD(wParam) == CBN_SELCHANGE) { // 現在のコンボボックスのデータを取得 com_no = (UINT)SendMessage(hCombo1, CB_GETCURSEL, 0, 0); // テキストの表示 szBuf_edit1 = strItem1[com_no]; MessageBox(hWnd, szBuf_edit1, TEXT("メッセージ"), MB_OK); } break; case ID_COMBO2: if (HIWORD(wParam) == CBN_SELCHANGE) { // 現在のコンボボックスのデータを取得 com_no = (UINT)SendMessage(hCombo2, CB_GETCURSEL, 0, 0); // テキストの表示 szBuf_edit1 = strItem2[com_no]; MessageBox(hWnd, szBuf_edit1, TEXT("メッセージ"), MB_OK); } break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
上記の太線で示している箇所のみ追加です。
#define IDM_ABOUT 104
#define IDM_EXIT 105
#define IDC_HP 109
#define ID_COOL 150
#define IDB_BITMAP1 131
#define ID_COMBO1 151
#define ID_COMBO2 152
#define IDC_COMBO1 161
#define IDC_COMBO2 162
上記の太線で示している箇所のみ追加です。
#include "resource.h"
/////////////////////////////////////////////////////////////////////////////
//
// メニュー
//
IDC_HP MENU
BEGIN
POPUP "ファイル(&F)"
BEGIN
MENUITEM "アプリケーションの終了(&X)", IDM_EXIT
END
POPUP "ヘルプ(&H)"
BEGIN
MENUITEM "バージョン情報(&A)...", IDM_ABOUT
END
END
/////////////////////////////////////////////////////////////////////////////
//
// ビットマップ テーブル
//
IDB_BITMAP1 BITMAP "reber.bmp"
上記の太線で示している箇所のみ追加です。