<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 松本義弘

------------------------------------------------------------------------------------------------

デル4_120x60富士通ショッピングサイト WEB MART   NEC得選街   sotecロゴ88x31b   バナー 10000035