ツールバー


コモンコントロール

前回までは、何らかの作業を肩代わりしてくれるコモンダイアログボックスを紹介しました
Windows は、この他に、標準のユーザーインターフェイスを提供する
コモンコントロール と呼ばれる標準コントロールを用意しています

このコントロールは CreateWindow() で生成できるコントロールに加え
グラフィカルな、ユーザーが直感的に理解しやすいアプリケーションの作成を手助けしてくれます

コモンコントロールを用いるには COMMCTRL.H ヘッダファイルをインクルードします
このヘッダファイルで、コモンコントロール関数が用いる定数などが宣言されています
また、COMCTL32.LIB インポートライブラリもリンクさせる必要があります
そうでなければ、DLL の関数を呼び出す時にリンカがエラーを吐きます

これらの準備ができたら、コモンコントロール関数を用いる前に初期化作業を行います
全てのコモンコントロールを用いる前に InitCommonControls() を呼び出します

void InitCommonControls(VOID);

この関数を呼び出せば、コモンコントロールの準備は完了です


ツールバーとボタンの作成

ツールバーは、一般的にメニューの下部に配置されるインターフェイスで
頻繁に用いられるであろうコマンドを、メニューに代わって発行するボタンを列挙したバーです
マウス操作が中心のユーザーにとっては、ツールバーは直感的で使用しやすく感じるでしょう

ツールバーを用いるには CreateToolbarEx() 関数を用います
あるいは、CreateWindowEx() 関数でウィンドウクラス TOOLBARCLASSNAME を用い
同様にツールバーを作れますが、この場合、ボタンはメッセージで作成しなければいけません
HWND CreateToolbarEx(
	HWND hwnd , DWORD ws ,
	UINT wID ,
	int nBitmaps, 	
	HINSTANCE hBMInst ,
	UINT wBMID ,
	LPCTBBUTTON lpButtons ,
	int iNumButtons ,
	int dxButton , int dyButton ,
	int dxBitmap , int dyBitmap ,
	UINT uStructSize
);
hwnd には、ツールバーの親ウィンドウを指定します
ws には、ツールバーのウィンドウスタイルを指定します
ここには、CreateWindowEx() 関数で用いるウィンドウスタイルを指定することができます
最低でも WM_CHILD スタイルを指定しなければいけません
また、それに加えて、次の定数を組み合わせて指定することができます

定数解説
CCS_ADJUSTABLE 組み込みカスタマイズ機能を有効にする
ボタンの位置をドラッグで移動させたり、ボタンの削除が行える
TBSTYLE_ALTDRAG ALt キーを押しながら、ツールバーボタンをドラッグし
ボタンの位置の移動を有効にすることを示す
CCS_ADJUSTABLE スタイルを設定しなければならない
TBSTYLE_TOOLTIPS ツールバー内のボタンに対する説明的なテキストの表示に用いる
ツールバーヒントコントロールの作成を有効にする
TBSTYLE_WRAPABLE 複数行のボタンを持つことができるツールバーを作成する

wID には、ツールバーのコントロール識別子を指定します

nBitmaps は、ビットマップに格納されているボタンイメージの数を指定します
hBMInst は、ビットマップリソースが格納されている
モジュールのインスタンスハンドルを指定します
あらかじめ、ツールバーで用いるビットマップを用意しておく必要があります
ビットマップハンドルをすでに取得している場合は、NULL を指定してもかまいません

wBMID には、ビットマップリソースのリソース識別子を指定します
hBMInst が NULL の場合は、ここに有効なビットマップのハンドルを指定します

lpButtons には、ツールバーに追加するボタンの情報を格納した
TBBUTTON 構造体へのポインタを指定します
この構造体には、ボタンのスタイルや ID 等を指定します

iNumButtons には、ツールバーに追加するボタンの数を指定します
dxButton と dyButton には、ツールバーのボタンのサイズを指定しますが
0 を指定すれば、最適なサイズになるので、一般的に 0 を指定します

dxBitmap には、1つのボタンのビットマップの横幅を
dyBitmap には、ボタンの高さを指定します
uStructSize は、TBBUTTON 構造体のサイズを指定します
関数が成功すれば、ツールバーのウィンドウハンドルが、失敗すれば NULL が返ります

これだけの説明では、いまいちの引数の意味がつかめませんね
初期化時に生成するボタンの数は iNumButtons メンバに指定しますが
ビットマップは1つしか指定できません
一体どうやって、複数のボタンにそれぞれのビットマップを指定するのでしょうか

実は、1つのビットマップとして、ボタンの絵を横一列に列挙します
すると、関数は1つのボタンのビットマップの横幅 dxBitmap メンバを参考に
nBitmap 分だけ分割して、それぞれのボタンに割り当てるのです



この画像は、今回のサンプルコード専用に作成したビットマップを4倍にしたものです
横幅40ピクセルで、1つのボタンごとに20ピクセルずつ割り当てるようにプログラムします
高さは 17 ピクセルになっています
黒く塗りつぶされている部分は、コントロールの背景色であると仮定してください

TBBUTTON 構造体というものがありましたが
この構造体は次のように定義されています
typedef struct _TBBUTTON {
    int iBitmap; 
    int idCommand; 
    BYTE fsState; 
    BYTE fsStyle; 
    DWORD dwData; 
    int iString; 
} TBBUTTON, NEAR* PTBBUTTON, FAR* LPTBBUTTON;
iBitmap には、ボタンイメージの 0 から数えるインデックスを指定します
このインデックスは、生成されるボタンとビットマップを関連付けるもので
ツールバーは、内部でビットマップにインデックスをつけて画像保有しています

idCommand は、ボタンに関連付けられるコマンド識別値を指定します
これは、ボタンが押された時に WM_COMMAND メッセージに送信されます

fsState には、ボタンの初期化フラグを指定します
このメンバには、次の定数のいずれか、または組み合わせを指定できます

定数解説
TBSTATE_CHECKED TBSTYLE_CHECK ボタンの場合
押された状態になっている
TBSTATE_ENABLED ボタンは使用可能である
TBSTATE_HIDDEN ボタンは非表示である
TBSTATE_INDETERMINATE ボタンは淡色表示になっている
TBSTATE_PRESSED ボタンは押されている
TBSTATE_WRAP このボタンの後で改行が発生する
TBSTATE_ENABLED も指定されていなければならない

fsStyle には、ボタンのスタイルを指定します
このメンバには、以下の定数を組み合わせて指定することができます

定数解説
TBSTYLE_BUTTON 標準プッシュボタン
TBSTYLE_CHECK チェックボックス型のボタン
ボタンの押すたびに、押された状態と押されていない状態が入れ替わる
TBSTYLE_CHECKGROUP ラジオボタン型のボタン
グループ内の他のボタンが押されるまで、押した状態を保つ
TBSTYLE_GROUP グループ内の別のボタンが押されるまで
押された状態を保つ標準ボタン
TBSTYLE_SEP ボタングループの間に隙間をあけ、区切り線の役割をする

bReserved は予約済みのメンバで、常に 0 を指定します
dwData は、ボタンに関連付けるアプリケーション定義の値です

iString は、ボタン文字列の 0 から数えるインデックス値です
この値は、メッセージの戻り値などで用いられることがあります

CreateToolbarEx() 関数で、いくつかのボタンを作成するには
この TBBUTTON 構造体の配列をあらかじめ作成しておき
lpButtons 引数に構造体の先頭アドレスを渡せば、後は関数が作成してくれます
/*resource.h*/
#define IDW_TOOL 100
#define IDB_TOOL 101
/*リソーススクリプト*/
#include "resource.h"

IDB_TOOL BITMAP DISCARDABLE "test.bmp"
#include <windows.h>
#include <commctrl.h>
#include "resource.h"
#define TITLE TEXT("Kitty on your lap")

TBBUTTON tbButton[] = {
	{ 0 , 1 , TBSTATE_ENABLED , TBSTYLE_BUTTON , 0 , 0 , 0} ,
	{ 1 , 2 , TBSTATE_ENABLED , TBSTYLE_BUTTON , 0 , 0 , 0}
};

LRESULT CALLBACK WndProc(HWND hWnd , UINT msg , WPARAM wp , LPARAM lp) {
	static HWND hToolbar;

	switch (msg) {
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	case WM_CREATE:
		InitCommonControls();
		hToolbar = CreateToolbarEx(
			hWnd , WS_CHILD | WS_VISIBLE , IDW_TOOL , 2 , 
			((LPCREATESTRUCT)(lp))->hInstance , IDB_TOOL ,
			tbButton , 2 , 0 , 0 , 20 , 17 , sizeof (TBBUTTON)
		);
		return 0;
	case WM_SIZE:
		SendMessage(hToolbar , WM_SIZE , wp , lp);
		return 0;
	}
	return DefWindowProc(hWnd , msg , wp , lp);
}

int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance ,
			PSTR lpCmdLine , int nCmdShow ) {
	HWND hWnd;
	MSG msg;
	WNDCLASS winc;

	winc.style		= CS_HREDRAW | CS_VREDRAW;
	winc.lpfnWndProc	= WndProc;
	winc.cbClsExtra	= winc.cbWndExtra	= 0;
	winc.hInstance		= hInstance;
	winc.hIcon		= LoadIcon(NULL , IDI_APPLICATION);
	winc.hCursor		= LoadCursor(NULL , IDC_ARROW);
	winc.hbrBackground	= (HBRUSH)GetStockObject(WHITE_BRUSH);
	winc.lpszMenuName	= NULL;
	winc.lpszClassName	= TEXT("KITTY");

	if (!RegisterClass(&winc)) return -1;

	hWnd = CreateWindow(
			TEXT("KITTY") , TITLE ,
			WS_OVERLAPPEDWINDOW | WS_VISIBLE ,
			CW_USEDEFAULT , CW_USEDEFAULT ,
			CW_USEDEFAULT , CW_USEDEFAULT ,
			NULL , NULL , hInstance , NULL
	);
	if (hWnd == NULL) return -1;

	while(GetMessage(&msg , NULL , 0 , 0)) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return msg.wParam;
}


これが、先ほどのビットマップを使った独自のツールバーとボタンです
ビットマップが二つのボタンに分割されていることが確認できますね
ボタンは TBBUTTON 構造体の配列の情報をもとに初期化されます

ボタンが押されると、親ウィンドウに WM_COMMAND が送信されます
一般的に、ツールバーのボタンはメニューアイテムと同一の処理をすることが多いので
その場合、ボタンにはメニューアイテムと同じ ID を割り当てれば良いでしょう


標準のツールボタンを使う

ツールバーのボタンには、標準のボタンがいくつか用意されています
これを用いれば、基本的なファイルを開くなどのボタンを他のアプリケーションと共有でき
ユーザーはボタンを見ただけで、それが「ファイルを開く」ボタンであることを認識できます

標準のツールバーボタンを使うには、CreateToolbarEx() 関数の
hBMInst 引数に HINST_COMMCTRL を指定しなければいけません
これが指定されれば、関数は標準のボタンを使うことを認識します

wBMID 引数に渡すビットマップリソースには、次のいずれかを指定します
リソースには、標準ビットマップと、ビュービットマップの2種類が用意されています

リソース
IDB_STD_LARGE_COLOR 大きいカラー標準ビットマップ
IDB_STD_SMALL_COLOR 小さいカラー標準ビットマップ
IDB_VIEW_LARGE_COLOR 大きいカラービュービットマップ
IDB_VIEW_SMALL_COLOR 小さいカラービュービットマップ

標準ビットマップボタンは、インデックスに STD というプリフィクスを持ち
ビュービットマップボタンは VIEW というプリフィックスを持っています
あとは、TBBUTTON の iBitmap メンバに、用いたいボタンのインデックス値を指定します

定数解説
STD_COPY コピー
STD_CUT カット
STD_DELETE 削除
STD_FILENEW 新規作成
STD_FILEOPEN ファイルを開く
STD_FILESAVE 保存
STD_FIND 検索
STD_HELP ヘルプ
STD_PASTE 貼りつけ
STD_PRINT 印刷
STD_PRINTPRE 印刷プレビュー
STD_PROPERTIES プロパティ
STD_REDOW やり直し
STD_REPLACE 置換え
STD_UNDO 元に戻す
VIEW_DETAILS 詳細
VIEW_LARGEICONS 大きいアイコンとして表示
VIEW_LIST 一覧として表示
VIEW_SMALLICONS 小さいアイコンとして表示
VIEW_SORTDATE 一覧を日付順に表示
VIEW_SORTNAME 一覧を名前順に表示
VIEW_SORTSIZE 一覧をサイズ順に表示
VIEW_SORTTYPE 一覧をタイプ順に表示

これらの値を用いることで、標準のツールボタンを表示させることができます
ファイルの保存や読み込みボタンは、これらの標準ボタンを使いましょう
#include <windows.h>
#include <commctrl.h>
#define TITLE TEXT("Kitty on your lap")

TBBUTTON tbButton[] = {
	{ STD_FILENEW , 1 , TBSTATE_ENABLED , TBSTYLE_BUTTON , 0 , 0 , 0 } ,
	{ STD_FILEOPEN , 2 , TBSTATE_ENABLED , TBSTYLE_BUTTON , 0 , 0 , 0 } ,
	{ STD_FILESAVE , 3 , TBSTATE_ENABLED , TBSTYLE_BUTTON , 0 , 0 , 0 } ,
	{ 0 , 0 , TBSTATE_ENABLED , TBSTYLE_SEP , 0 , 0 , 0 } ,
	{ STD_COPY , 4 , TBSTATE_ENABLED , TBSTYLE_BUTTON , 0 , 0 , 0 } ,
	{ STD_CUT , 5 , TBSTATE_ENABLED , TBSTYLE_BUTTON , 0 , 0 , 0 } ,
	{ STD_DELETE , 6 , TBSTATE_ENABLED , TBSTYLE_BUTTON , 0 , 0 , 0 }
};

LRESULT CALLBACK WndProc(HWND hWnd , UINT msg , WPARAM wp , LPARAM lp) {
	static HWND hToolbar;

	switch (msg) {
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	case WM_CREATE:
		InitCommonControls();
		hToolbar = CreateToolbarEx(
			hWnd , WS_CHILD | WS_VISIBLE , 0 , 6 , 
			(HINSTANCE)HINST_COMMCTRL ,
			IDB_STD_SMALL_COLOR ,
			tbButton , 7 , 0 , 0 , 0 , 0 , sizeof (TBBUTTON)
		);
		return 0;
	case WM_SIZE:
		SendMessage(hToolbar , WM_SIZE , wp , lp);
		return 0;
	}
	return DefWindowProc(hWnd , msg , wp , lp);
}

int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance ,
			PSTR lpCmdLine , int nCmdShow ) {
	HWND hWnd;
	MSG msg;
	WNDCLASS winc;

	winc.style		= CS_HREDRAW | CS_VREDRAW;
	winc.lpfnWndProc	= WndProc;
	winc.cbClsExtra	= winc.cbWndExtra	= 0;
	winc.hInstance		= hInstance;
	winc.hIcon		= LoadIcon(NULL , IDI_APPLICATION);
	winc.hCursor		= LoadCursor(NULL , IDC_ARROW);
	winc.hbrBackground	= (HBRUSH)GetStockObject(WHITE_BRUSH);
	winc.lpszMenuName	= NULL;
	winc.lpszClassName	= TEXT("KITTY");

	if (!RegisterClass(&winc)) return -1;

	hWnd = CreateWindow(
			TEXT("KITTY") , TITLE ,
			WS_OVERLAPPEDWINDOW | WS_VISIBLE ,
			CW_USEDEFAULT , CW_USEDEFAULT ,
			CW_USEDEFAULT , CW_USEDEFAULT ,
			NULL , NULL , hInstance , NULL
	);
	if (hWnd == NULL) return -1;

	while(GetMessage(&msg , NULL , 0 , 0)) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return msg.wParam;
}


見なれたボタンでしょう
ファイル関連のボタンと、クリップボード関連のボタンの間にセパレータを挿入しています


ツールバーを増やす

上のように、静的にボタンを作るだけで終わるのならば苦労はありませんが
プログラムによっては、動的にボタンを増やしたり、消したりしたいことがあるでしょう

ツールバーの操作は、従来のコントロール同様に、メッセージを用います
残念ながら、この場で全てのメッセージを紹介することはできませんが
ツールバーに関連したメッセージは TB_ というプリフィックスを持っています
メッセージを調べたい時は TB_ からはじまるメッセージを探せばよいでしょう

ボタンを CreateToolbarEx() 関数以外の場所で作る理由としては
複数のビットマップリソースからツールバーのボタンを作成したいときでしょう
このような場合、CreateToolbarEx() 以外の場所でボタンを作らなければいけません

ボタンを増やすには、まず、ボタンに用いるビットマップを登録します
ビットマップを登録するには TB_ADDBITMAP メッセージを送信します
WPARAM には、ビットマップ内のボタンイメージの数を
LPARAM には、TBADDBITMAP 構造体のポインタを指定します

TBADDBITMAP 構造体は次のように定義されています
typedef struct {
    HINSTANCE hInst; 
    UINT nID; 
} TBADDBITMAP, *LPTBADDBITMAP;
hInst は、ビットマップリソースを格納するモジュールのインスタンスハンドルを
nID は、ビットマップリソースの識別 ID を指定します

SendMessage() 関数は、TB_ADDBITMAP によるイメージの登録が成功すれば
登録したイメージの先頭のインデックスを、失敗した場合は -1 を返します

追加するボタンを表す TBBUTTON 構造体の iBitmap メンバは
SendMessage() 関数が返した値を先頭にしなければいけません
CreateToolbarEx() で登録する時と異なり、従来の iBitmap の値は
SendMessage() 関数が返した値のオフセットとなるのです

ビットマップの登録と、TBBUTTON 構造体の iBitmap メンバの再設定が終われば
あとは TB_ADDBUTTONS メッセージでボタンを追加します
WPARAM には追加するボタンの数を、LPARAM には追加するボタンの情報を格納した
TBBUTTON 構造体配列の先頭へのポインタを指定します
成功した場合は 0 以外、失敗した時は 0 が返ります
#include <windows.h>
#include <commctrl.h>
#define TITLE TEXT("Kitty on your lap")

TBBUTTON tbButton[] = {
	{ STD_FILENEW , 1 , TBSTATE_ENABLED , TBSTYLE_BUTTON , 0 , 0 , 0 } ,
	{ STD_FILEOPEN , 2 , TBSTATE_ENABLED , TBSTYLE_BUTTON , 0 , 0 , 0 } ,
	{ STD_FILESAVE , 3 , TBSTATE_ENABLED , TBSTYLE_BUTTON , 0 , 0 , 0 } ,
	{ 0 , 0 , TBSTATE_ENABLED , TBSTYLE_SEP , 0 , 0 , 0 } ,
	{ STD_COPY , 4 , TBSTATE_ENABLED , TBSTYLE_BUTTON , 0 , 0 , 0 } ,
	{ STD_CUT , 5 , TBSTATE_ENABLED , TBSTYLE_BUTTON , 0 , 0 , 0 } ,
	{ STD_DELETE , 6 , TBSTATE_ENABLED , TBSTYLE_BUTTON , 0 , 0 , 0 } ,
	{ 0 , 0 , TBSTATE_ENABLED , TBSTYLE_SEP , 0 , 0 , 0 } ,
	{ VIEW_NEWFOLDER , 7 , TBSTATE_ENABLED , TBSTYLE_BUTTON , 0 , 0 , 0 } ,
	{ VIEW_PARENTFOLDER , 8 , TBSTATE_ENABLED , TBSTYLE_BUTTON , 0 , 0 , 0 } ,
	
};

LRESULT CALLBACK WndProc(HWND hWnd , UINT msg , WPARAM wp , LPARAM lp) {
	static HWND hToolbar;
	TBADDBITMAP tb;
	int iIndex;

	switch (msg) {
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	case WM_CREATE:
		InitCommonControls();
		hToolbar = CreateToolbarEx(
			hWnd , WS_CHILD | WS_VISIBLE , 0 , 6 , 
			(HINSTANCE)HINST_COMMCTRL ,
			IDB_STD_SMALL_COLOR ,
			tbButton , 7 , 0 , 0 , 0 , 0 , sizeof (TBBUTTON)
		);

		tb.hInst = HINST_COMMCTRL;
		tb.nID = IDB_VIEW_SMALL_COLOR;
		iIndex = SendMessage(hToolbar , TB_ADDBITMAP , 2 , (LPARAM)&tb);
		tbButton[8].iBitmap += iIndex;
		tbButton[9].iBitmap += iIndex;
		SendMessage(hToolbar , TB_ADDBUTTONS , 3 , (LPARAM) &tbButton[7]);

		return 0;
	case WM_SIZE:
		SendMessage(hToolbar , WM_SIZE , wp , lp);
		return 0;
	}
	return DefWindowProc(hWnd , msg , wp , lp);
}

int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance ,
			PSTR lpCmdLine , int nCmdShow ) {
	HWND hWnd;
	MSG msg;
	WNDCLASS winc;

	winc.style		= CS_HREDRAW | CS_VREDRAW;
	winc.lpfnWndProc	= WndProc;
	winc.cbClsExtra	= winc.cbWndExtra	= 0;
	winc.hInstance		= hInstance;
	winc.hIcon		= LoadIcon(NULL , IDI_APPLICATION);
	winc.hCursor		= LoadCursor(NULL , IDC_ARROW);
	winc.hbrBackground	= (HBRUSH)GetStockObject(WHITE_BRUSH);
	winc.lpszMenuName	= NULL;
	winc.lpszClassName	= TEXT("KITTY");

	if (!RegisterClass(&winc)) return -1;

	hWnd = CreateWindow(
			TEXT("KITTY") , TITLE ,
			WS_OVERLAPPEDWINDOW | WS_VISIBLE ,
			CW_USEDEFAULT , CW_USEDEFAULT ,
			CW_USEDEFAULT , CW_USEDEFAULT ,
			NULL , NULL , hInstance , NULL
	);
	if (hWnd == NULL) return -1;

	while(GetMessage(&msg , NULL , 0 , 0)) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return msg.wParam;
}


このプログラムは、先ほどの標準ボタンを使ったプログラムに
新たにビューボタンを、動的にツールバーに追加したものです


InitCommonControls()

void InitCommonControls(VOID);

コモンコントロールに関連した初期化処理を行います
コモンコントロール を使用する前に、必ず呼び出します

CreateToolbarEx()

HWND CreateToolbarEx(
	HWND hwnd , DWORD ws ,
	UINT wID ,
	int nBitmaps, 	
	HINSTANCE hBMInst ,
	UINT wBMID ,
	LPCTBBUTTON lpButtons ,
	int iNumButtons ,
	int dxButton , int dyButton ,
	int dxBitmap , int dyBitmap ,
	UINT uStructSize
);
ツールバーを指定ウィンドウに表示します

hwnd - ツールバーの親ウィンドウを指定します
ws - ツールバーのウィンドウスタイルを指定します
wID - ツールバーのコントロール識別子を指定します
nBitmaps - ビットマップに格納されているボタンイメージの数を指定します
hBMInst - リソースが格納されているモジュールのインスタンスを指定します
wBMID - ビットマップリソースのリソース識別子を指定します
lpButtons - ボタンの情報を格納した TBBUTTON 構造体へのポインタを指定します
iNumButtons - ツールバーに追加するボタンの数を指定します
dxButton - ツールバーのボタンの幅を指定します
dyButton - ツールバーのボタンの高さを指定します
dxBitmap - ボタンのビットマップの横幅を指定します
dyBitmap - ボタンのビットマップの高さを指定します
uStructSize - TBBUTTON 構造体のサイズを指定します

戻り値 - ツールバーのウィンドウハンドル、失敗すれば NULL

ws には、CreateWindowEx() で指定するウィンドウスタイルを指定できます
また、次のいずれかの定数を組み合わせて指定することもできます
ただし、最低でも WS_CHILD を含まなければいけません

定数解説
CCS_ADJUSTABLE 組み込みカスタマイズ機能を有効にする
ボタンの位置をドラッグで移動させたり、ボタンの削除が行える
TBSTYLE_ALTDRAG ALt キーを押しながら、ツールバーボタンをドラッグし
ボタンの位置の移動を有効にすることを示す
CCS_ADJUSTABLE スタイルを設定しなければならない
TBSTYLE_TOOLTIPS ツールバー内のボタンに対する説明的なテキストの表示に用いる
ツールバーヒントコントロールの作成を有効にする
TBSTYLE_WRAPABLE 複数行のボタンを持つことができるツールバーを作成する



前のページへ戻る次のページへ