レバーコントロール(クールバー、リバーコントロール)上にツールバーをのせます。
レバーコントロール2:背景 - インコのWindowsSDK で作成したソースを修正します。
ツールバー4: 既成のボタンを使う - インコのWindowsSDK で作成したソースを流用します。今回追加した箇所は、ほとんど、ここから流用しています。
流れ
1.ツールバーを使うのでINITCOMMONCONTROLSEX構造体にICC_BAR_CLASSESを追加
2.フラットツールバー:
親ウィンドウ(メインウィンドウ)の子ウィンドウとして、フラットツールバーを作る場合は、
CreateWindowEx()でTBSTYLE_FLATを指定しても、うまくいきませんでした。
レバーコントロールの子ウィンドウとして、フラットツールバーを作る場合は、
CreateWindowEx()でTBSTYLE_FLATを指定しても問題ありません。
今回は、この方法を使います。
3.ツールバーのコモンコントロールスタイルに、CCS_NORESIZEを追加
これがないと、うまく表示しません。
これ以外の追加点は、 ツールバー4: 既成のボタンを使う - インコのWindowsSDK をご覧ください。
ソースコードの入力
ソースコードは下記のように入れてください。
#define _WIN32_WINNT 0x0501 #include <windows.h> #include <commctrl.h> #include "resource.h" #pragma comment(lib, "comctl32.lib") // レバーコントロールの作成に必要 // グローバル変数: HWND hCombo1; // コンボボックスのハンドル HWND hToolBar; // ツールバーのウィンドウハンドル WNDPROC defProc; // TBBUTTON(ツールバーボタン)型の配列 TBBUTTON tbButton[] = { { STD_FILEOPEN, ID_BUTTON1, TBSTATE_ENABLED, TBSTYLE_BUTTON | BTNS_AUTOSIZE, 0, 0, 0}, { STD_FILESAVE, ID_BUTTON2, TBSTATE_ENABLED, TBSTYLE_BUTTON | BTNS_AUTOSIZE, 0, 0, 0}, { STD_COPY, ID_BUTTON3, TBSTATE_ENABLED, TBSTYLE_BUTTON | BTNS_AUTOSIZE, 0, 0, 0}, { STD_CUT, ID_BUTTON4, TBSTATE_ENABLED, TBSTYLE_BUTTON | BTNS_AUTOSIZE, 0, 0, 0}, { STD_DELETE, ID_BUTTON5, TBSTATE_ENABLED, TBSTYLE_BUTTON | BTNS_AUTOSIZE, 0, 0, 0}, { STD_PASTE, ID_BUTTON6, TBSTATE_ENABLED, TBSTYLE_BUTTON | BTNS_AUTOSIZE, 0, 0, 0}, { STD_REDOW, ID_BUTTON7, TBSTATE_ENABLED, TBSTYLE_BUTTON | BTNS_AUTOSIZE, 0, 0, 0}, { STD_UNDO, ID_BUTTON8, TBSTATE_ENABLED, TBSTYLE_BUTTON | BTNS_AUTOSIZE, 0, 0, 0} }; TBBUTTON tbSPACE = {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0L}; // このコード モジュールに含まれる関数の宣言を転送します: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK ToolbarProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM 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") }; UINT i; UINT index; UINT com_no; TBADDBITMAP tb; switch (message) { case WM_CREATE: //コモンコントロールの初期化 ic.dwICC = ICC_COOL_CLASSES | ICC_BAR_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); // レバーコントロールにツールバーを挿入 hToolBar = CreateWindowEx( 0, // 拡張スタイルなし TOOLBARCLASSNAME, // クラスネーム NULL, // ウィンドウタイトル WS_CHILD | WS_VISIBLE | CCS_NODIVIDER | CCS_NORESIZE | TBSTYLE_FLAT, //ウィンドウスタイル 0, 0, // ウィンドウ位置 0, 40, // ウィンドウ幅、高さ hRebar, // 親ウィンドウ (HMENU)IDW_TOOL, // コントロール識別子 (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), //インスタンスハンドル NULL); tb.hInst = HINST_COMMCTRL; // ボタンをシステム定義のビットマップ tb.nID = IDB_STD_SMALL_COLOR; // システム標準ビットマップ(小) SendMessage(hToolBar, TB_ADDBITMAP, 0, (LPARAM)&tb); SendMessage(hToolBar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0); /* ツールバーにボタンを挿入 */ SendMessage(hToolBar, TB_ADDBUTTONS, (WPARAM)(sizeof(tbButton) / sizeof(TBBUTTON)), (LPARAM)(LPTBBUTTON)&tbButton); // ボタンの区切りを挿入 SendMessage(hToolBar, TB_INSERTBUTTON, 2, (LPARAM)&tbSPACE); /* ツールバーサブクラス化 */ defProc = (WNDPROC)GetWindowLong(hToolBar, GWL_WNDPROC); SetWindowLong(hToolBar, GWL_WNDPROC, (LONG)ToolbarProc); SetWindowLong(hToolBar, GWL_USERDATA, (LONG)defProc); rbBand.hwndChild = hToolBar; 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 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; } /* ツールバーサブクラス */ LRESULT CALLBACK ToolbarProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_RBUTTONDOWN: case WM_RBUTTONUP: if (SendMessage(hWnd, TB_GETHOTITEM, 0, 0) >= 0){ ReleaseCapture(); } return 0; } return CallWindowProc(defProc, hWnd, msg, wParam, lParam); }
上記の太線で示している箇所のみ追加です。
#define IDM_ABOUT 104 #define IDM_EXIT 105 #define IDC_HP 109 #define IDW_TOOL 149 #define ID_COOL 150 #define IDB_BITMAP1 131 #define ID_COMBO1 165 #define ID_COMBO2 166 #define IDC_COMBO1 161 #define IDC_COMBO2 162 #define ID_BUTTON1 151 #define ID_BUTTON2 152 #define ID_BUTTON3 153 #define ID_BUTTON4 154 #define ID_BUTTON5 155 #define ID_BUTTON6 156 #define ID_BUTTON7 157 #define ID_BUTTON8 158
上記の太線で示している箇所のみ追加です。
#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"