<Previous>   <Next>   <SDK Top>   <Top>


章.1節.ツールバーを作ってみよう

今回はツールバーを作ってみましょう.
ボタン1つ,中に絵がなくテキストだけという,シンプルすぎるツールバーを作ります.

それでは,まず
ツールバーのボタンのIDを決めてやりましょう.
IDの作り方を知らない方は,「別章.2節.ストリングテーブルを編集してみよう」を先に読んでください.
ここで,IDは

ID キャプション
IDC_BUTTON1 ボタン1

としときましょう.

今回のポイントは,
@どうやってツールバーを作る?
Aどうやってツールバーにボタンを挿入する?
というところですね.

では,プログラムを見ましょう.


#include "stdafx.h"
#include <commctrl.h>
#include "resource.h"

#pragma comment(lib, "comctl32.lib")

#define MAX_LOADSTRING 100
#define IDC_RICHEDIT (101)

#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 );

HWND		ToolBarCreate(HWND hWnd);
void		ToolBarAddButtons(int nBotton, TBBUTTON* tbb);

HWND		hToolBar;

TBBUTTON tbb[1] =
{
	{0, IDC_BUTTON1, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0},
};

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;

	switch( message ) 
	{
		case WM_CREATE:
			//ツールバーを作る
			hToolBar = ToolBarCreate( hWnd );
			//ツールバーにボタンを追加する
			ToolBarAddButtons( 1, tbb );

			break;
		case WM_SIZE:
			MoveWindow(hToolBar, 0, 0, LOWORD(lParam), TOOL_HEIGHT, TRUE);
			break;
		case WM_DESTROY:
			PostQuitMessage( 0 );
			break;
		default:
			return DefWindowProc( hWnd, message, wParam, lParam );
   }
   return 0;
}

HWND ToolBarCreate(HWND hWnd)
{
	HWND hTool;

	InitCommonControls();

	hTool = CreateWindowEx(
			WS_EX_TOOLWINDOW, 
			TOOLBARCLASSNAME,
             	NULL,
             	WS_CHILD | WS_VISIBLE |
			CCS_ADJUSTABLE | CCS_NORESIZE,
			0,0,0,0,
             	hWnd,
             	NULL,
             	hInst,
             	NULL);


	SendMessage(hTool, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);

	return hTool;
}


void ToolBarAddButtons(int nBotton, TBBUTTON* tbb)
{
	int i;
	char szBuf[256];
	int nAddBotton[20];


	for( i=0; i<nBotton; i++ )
	{
		LoadString(hInst, tbb[i].idCommand, (LPSTR)&szBuf, sizeof(szBuf));
		nAddBotton[i] = (int)SendMessage(hToolBar, TB_ADDSTRING, 0, (LPARAM)(LPSTR)szBuf);
		tbb[i].iString = nAddBotton[i];
	}

	SendMessage(hToolBar, TB_ADDBUTTONS, (WPARAM)nBotton, (LPARAM)tbb);
}

☆プログラムの解説☆

@どうやってツールバーを作る?

ツールバーを使うために,ヘッダー及びライブラリを読み込みましょう.

#include <commctrl.h>

#pragma comment(lib, "comctl32.lib")

そして,次にツールバーのための定数(高さとか),関数,グローバル変数を宣言します.
TOOL_HEIGHTはツールバーの高さを表しています!

#define TOOL_HEIGHT (40)

HWND		ToolBarCreate(HWND hWnd);
void		ToolBarAddButtons(int nBotton, TBBUTTON* tbb);

HWND		hToolBar;

次に,ツールバーのボタンを宣言してやらないといけません.

TBBUTTON tbb[1] =
{
	{0, IDC_BUTTON1, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0},
};

TBBUTTON(ツールバーボタン)型の配列です.
配列の要素が1つであるので,1つのボタンの要素をここで決めています.
IDC_BUTTON1は始めに作ったIDですね!ここでボタンのIDを登録しています.
残りの引数は,ボタンのスタイルを決めたり,ボタンの初期状態を決めたりしています.

次に,ツールバーを作っていくところです.

case WM_CREATE:
	//ツールバーを作る
	hToolBar = ToolBarCreate( hWnd );
	//ツールバーにボタンを追加する
	ToolBarAddButtons( 1, tbb );

	break;

ツールバーを作ってボタンを挿入しています.
ToolBarCreate関数については,ただ中でツールバーを作るAPIを使用している関数と言う説明で終えときましょう.
ToolBarAddButtons関数については,次のようになっています.

Aどうやってツールバーにボタンを挿入する?

void ToolBarAddButtons(int nBotton, TBBUTTON* tbb)
{
	int i;
	char szBuf[256];
	int nAddBotton[20];


	for( i=0; i<nBotton; i++ )
	{
		LoadString(hInst, tbb[i].idCommand, (LPSTR)&szBuf, sizeof(szBuf));
		nAddBotton[i] = (int)SendMessage(hToolBar, TB_ADDSTRING, 0, (LPARAM)(LPSTR)szBuf);
		tbb[i].iString = nAddBotton[i];
	}

	SendMessage(hToolBar, TB_ADDBUTTONS, (WPARAM)nBotton, (LPARAM)tbb);
}

この関数はツールバーにボタンを挿入しています.
関数の第1引数はボタン数,第2引数はツールバーボタン型へのポインタです.
中を覗くと,for分になっていて,ボタン数分だけ繰り返しています.
順番に説明すると
LoadString関数は,IDからキャプションを抜き出す関数(別章2節参照)でしたね.
SendMessage関数は,ツールバーが保持する文字列のリストに新しい文字列を追加しています.
nAddBotton[i]は,追加された文字列のリスト中でのインデックスをもらい,
そのインデクスをtbb構造体の要素として,
最後のSendMessage関数で,ボタンを挿入するという流れです.
まぁ,深刻に考えずにこんな感じにやるんだなぁぐらいに思っておけばいいんじゃないでしょうか.


case WM_SIZE:
	MoveWindow(hToolBar, 0, 0, LOWORD(lParam), TOOL_HEIGHT, TRUE);
	break;

ツールバーの大きさを決めるためのコードがここにありますね.

MoveWindow(hToolBar, 0, 0, LOWORD(lParam), TOOL_HEIGHT, TRUE);

は,クライアントウィンドウ(=メニューバーの下のウィンドウ)の座標(0,0)(=左上)から
横幅はLOWORD(lParam)(=ウィンドウの幅)で,縦幅はTOOL_HEIGHT(=プログラムの始めで決めた定数)
の大きさのツールバーにしろという関数です.


ツールバーを作るのは,ごちゃごちゃしてややこしいですね..
今回のプログラムはツールバーを作っただけで,ボタンを押しても何も起こりません.


          

 

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

当ページの一部または全部を転載、複写、複製することを禁じます。
また,当サイトを利用した結果に関するトラブル等は、一切関与いたしませんのでご容赦下さい。
Update 04/02/29 By 松本義弘

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

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