<Previous> <Next> <SDK Top> <Top>
5章.1節.クールバー(レバーコントロール)を作ってみよう
クールバー(レバーコントロール)とは,上図のように自由に動かすことのできるバーのことです.
今回はボタンを2つにし,そのボタンのIDを決めてやりましょう.
(IDの作り方を知らない方は,「別章.2節.ストリングテーブルを編集してみよう」を先に読んでください.)
ID | キャプション |
IDC_BUTTON1 | ボタン1 |
IDC_BUTTON2 | ボタン2 |
今回のポイントは,
@クールバーをどうやって作るか?
Aクールバーにどうやってボタンを加えるのか?
というところですね.
では,プログラムを見ましょう.
#include "stdafx.h" #include <commctrl.h> #include "resource.h" #pragma comment(lib, "comctl32.lib") #define MAX_LOADSTRING 100 #define TOOL_HEIGHT (40) // グローバル変数: HINSTANCE hInst; // 現在のインスタンス TCHAR szTitle[MAX_LOADSTRING]; // タイトル バー テキスト TCHAR szWindowClass[MAX_LOADSTRING]; // タイトル バー テキスト // このコード モジュールに含まれる関数の前宣言: ATOM MyRegisterClass( HINSTANCE hInstance ); BOOL InitInstance( HINSTANCE, int ); LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM ); void DispText(HWND hWnd, char* pszBuf); HWND ButtonCreate(char *pszName, HWND hParent, int id); HWND CoolBarCreate(HWND hWnd); void CoolBarInitialize(void); void CoolBarInsert(char *pszName, HWND hWnd, int cx); HWND hCool, hBut1, hBut2; RECT rtCoolBar; HDC hdc; REBARBANDINFO rbBand; int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { MSG msg; HACCEL hAccelTable; // グローバル ストリングを初期化します LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_SAMPLE, szWindowClass, MAX_LOADSTRING); MyRegisterClass( hInstance ); // アプリケーションの初期化を行います: if( !InitInstance( hInstance, nCmdShow ) ) { return FALSE; } hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_SAMPLE); // メイン メッセージ ループ: while( GetMessage(&msg, NULL, 0, 0) ) { if( !TranslateAccelerator (msg.hwnd, hAccelTable, &msg) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } } return msg.wParam; } ATOM MyRegisterClass( HINSTANCE hInstance ) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = (WNDPROC)WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_SAMPLE); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = (LPCSTR)IDC_SAMPLE; wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL); return RegisterClassEx( &wcex ); } BOOL InitInstance( HINSTANCE hInstance, int nCmdShow ) { HWND hWnd; hInst = hInstance; // グローバル変数にインスタンス ハンドルを保存します hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if( !hWnd ) { return FALSE; } ShowWindow( hWnd, nCmdShow ); UpdateWindow( hWnd ); return TRUE; } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; static char szBuf[256]=""; switch( message ) { case WM_CREATE: //クールバーを生成 hCool = CoolBarCreate(hWnd); //クールバーに必要な変数の初期設定 CoolBarInitialize(); //ボタン1の作成 hBut1 = ButtonCreate("ボタン1", hCool, IDC_BUTTON1 ); //クールバーにボタン1を挿入 CoolBarInsert("ボタン1", hBut1, 150); //ボタン2の作成 hBut2 = ButtonCreate("ボタン2", hCool, IDC_BUTTON2 ); GetWindowRect(hCool, &rtCoolBar); //クールバーにボタン2を挿入 CoolBarInsert( "ボタン2", hBut2, rtCoolBar.right - rtCoolBar.left - 150 ); break; case WM_PAINT: DispText( hWnd, szBuf ); break; case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); switch( wmId ) { case IDC_BUTTON1: lstrcpy( szBuf, "ボタン1が押されました"); break; case IDC_BUTTON2: lstrcpy( szBuf, "ボタン2が押されました"); break; default: return DefWindowProc( hWnd, message, wParam, lParam ); } InvalidateRect(hWnd, NULL, FALSE);//クライアント全体を再描画する命令 break; case WM_SIZE: MoveWindow(hCool, 0, 0, LOWORD(lParam), TOOL_HEIGHT, TRUE); break; case WM_DESTROY: PostQuitMessage( 0 ); break; default: return DefWindowProc( hWnd, message, wParam, lParam ); } return 0; } void DispText(HWND hWnd, char* pszBuf) { HDC hdc; PAINTSTRUCT ps; hdc = BeginPaint ( hWnd, &ps ); TextOut( hdc, 30, 60, (LPSTR)pszBuf, lstrlen(pszBuf) ); EndPaint( hWnd, &ps ); } HWND ButtonCreate(char *pszName, HWND hParent, int id) { return CreateWindow("BUTTON", pszName, WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 0, 0, 0, 0, hParent, (HMENU)id, hInst ,NULL); } HWND CoolBarCreate(HWND hWnd) { HWND hCool; REBARINFO rbi; INITCOMMONCONTROLSEX ic; ic.dwSize = sizeof(INITCOMMONCONTROLSEX); ic.dwICC = ICC_COOL_CLASSES; InitCommonControlsEx(&ic); //クールバーの設定 hCool = CreateWindowEx(WS_EX_TOOLWINDOW, REBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | RBS_BANDBORDERS | CCS_NODIVIDER , 0, 0, 0, 0, hWnd, NULL, hInst, NULL); ZeroMemory(&rbi, sizeof(REBARINFO)); rbi.cbSize = sizeof(REBARINFO); SendMessage(hCool, RB_SETBARINFO, 0, (LPARAM)&rbi); return hCool; } void CoolBarInitialize(void) { ZeroMemory(&rbBand, sizeof(REBARBANDINFO)); rbBand.cbSize = sizeof(REBARBANDINFO); rbBand.fMask = RBBIM_TEXT | RBBIM_STYLE | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE; rbBand.fStyle = RBBS_CHILDEDGE; rbBand.cxMinChild = 0; rbBand.cyMinChild = 25; } void CoolBarInsert(char *pszName, HWND hWnd, int cx) { rbBand.lpText = pszName; rbBand.hwndChild = hWnd; rbBand.cx = cx; SendMessage(hCool, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbBand); }
☆プログラムの解説☆ @クールバーをどうやって作るか? //クールバーを生成 hCool = CoolBarCreate(hWnd); この関数で,クールバーの作成を行ってます. //クールバーに必要な変数の初期設定 CoolBarInitialize(); では,次に説明するクールバーへのボタンの追加のための初期設定を行っています. クールバーの大きさやスタイルもここで決めてるんですね. Aクールバーにどうやってボタンを加えるのか? //ボタン1の作成 hBut1 = ButtonCreate("ボタン1", hCool, IDC_BUTTON1 ); //クールバーにボタン1を挿入 CoolBarInsert("ボタン1", hBut1, 150); //ボタン2の作成 hBut2 = ButtonCreate("ボタン2", hCool, IDC_BUTTON2 ); GetWindowRect(hCool, &rtCoolBar); //クールバーにボタン2を挿入 CoolBarInsert( "ボタン2", hBut2, rtCoolBar.right - rtCoolBar.left - 150 ); ButtonCreate関数を自作しました.(中身はCreateWindow関数(API)一つだけです) そして,そのボタンをクールバーに追加するために,CoolBarInsert関数を呼んでいます. 第1引数はクールバーに表示するテキスト, 第2引数はさっき作ったボタンのハンドル, 第3引数はそのクールバーの幅,を指定しています. ボタン2の方もだいたい同じですが,GetWindowRect関数(API)を呼んでいます. この関数でウィンドウに表示するクールバーの座標情報を取得しています. その座標情報より,rtCoolBar.right - rtCoolBar.leftで横幅を取得し, さらに150(ボタン1の方のクールバーの横幅)を引いて,ボタン2のクールバーの横幅を指定しています.![]()
![]()
![]()
------------------------------------------------------------------------------------------------
当ページの一部または全部を転載、複写、複製することを禁じます。
また,当サイトを利用した結果に関するトラブル等は、一切関与いたしませんのでご容赦下さい。
Update 04/03/05 By 松本義弘
------------------------------------------------------------------------------------------------