EternalWindows
ツールバー / 独自のボタンイメージ

これまで、ツールバーのボタンにはシステムの既定のボタンイメージを表示してきましたが、 今回はアプリケーションが用意した独自のボタンイメージを表示します。 次に、今回使用するビットマップを示します。


1つ目のビットマップはボタンが通常の状態の場合に表示され、 2つ目のビットマップはボタンがホット状態の場合に表示されます。 次に、今回のプログラムを示します。

#include <windows.h>
#include <commctrl.h>

#define ID_TOOLBAR 100
#define ID_BUTTON1 200
#define ID_BUTTON2 300

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

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hinstPrev, LPSTR lpszCmdLine, int nCmdShow)
{
	TCHAR      szAppName[] = TEXT("sample");
	HWND       hwnd;
	MSG        msg;
	WNDCLASSEX wc;

	wc.cbSize        = sizeof(WNDCLASSEX);
	wc.style         = 0;
	wc.lpfnWndProc   = WindowProc;
	wc.cbClsExtra    = 0;
	wc.cbWndExtra    = 0;
	wc.hInstance     = hinst;
	wc.hIcon         = (HICON)LoadImage(NULL, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_SHARED);
	wc.hCursor       = (HCURSOR)LoadImage(NULL, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_SHARED);
	wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	wc.lpszMenuName  = NULL;
	wc.lpszClassName = szAppName;
	wc.hIconSm       = (HICON)LoadImage(NULL, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_SHARED);
	
	if (RegisterClassEx(&wc) == 0)
		return 0;

	hwnd = CreateWindowEx(0, szAppName, szAppName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hinst, NULL);
	if (hwnd == NULL)
		return 0;

	ShowWindow(hwnd, nCmdShow);
	UpdateWindow(hwnd);
	
	while (GetMessage(&msg, NULL, 0, 0) > 0) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return (int)msg.wParam;
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	static HWND       hwndToolbar = NULL;
	static HIMAGELIST himl = NULL;
	static HIMAGELIST himlHot = NULL;
	
	switch (uMsg) {

	case WM_CREATE: {
		TBBUTTON tbButton[] = {
			{0, ID_BUTTON1, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0},
			{1, ID_BUTTON2, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0}
		};
		int                  nCount = sizeof(tbButton) / sizeof(tbButton[0]);
		DWORD                dwStyle;
		INITCOMMONCONTROLSEX ic;
		
		ic.dwSize = sizeof(INITCOMMONCONTROLSEX);
		ic.dwICC  = ICC_BAR_CLASSES;
		InitCommonControlsEx(&ic);
		
		hwndToolbar = CreateToolbarEx(hwnd, WS_CHILD | WS_VISIBLE, ID_TOOLBAR, 0, NULL, 0, tbButton, nCount, 0, 0, 0, 0, sizeof(TBBUTTON));

		himl = ImageList_LoadImage(NULL, TEXT("toolbar.bmp"), 16, CLR_NONE, RGB(255, 255, 255), IMAGE_BITMAP, LR_CREATEDIBSECTION | LR_LOADFROMFILE);
		if (himl == NULL)
			return -1;
		SendMessage(hwndToolbar, TB_SETIMAGELIST, 0, (LPARAM)himl);

		himlHot = ImageList_LoadImage(NULL, TEXT("toolbar_hot.bmp"), 16, CLR_NONE, RGB(255, 255, 255), IMAGE_BITMAP, LR_CREATEDIBSECTION | LR_LOADFROMFILE);
		if (himlHot == NULL)
			return -1;
		SendMessage(hwndToolbar, TB_SETHOTIMAGELIST, 0, (LPARAM)himlHot);

		dwStyle = (DWORD)SendMessage(hwndToolbar, TB_GETSTYLE, 0, 0) | TBSTYLE_FLAT;
		SendMessage(hwndToolbar, TB_SETSTYLE, 0, (LPARAM)dwStyle);

		return 0;
	}
	
	case WM_SIZE:
		MoveWindow(hwndToolbar, 0, 0, LOWORD(lParam), HIWORD(wParam), TRUE);
		return 0;

	case WM_DESTROY:
		if (himl != NULL)
			ImageList_Destroy(himl);
		if (himlHot != NULL)
			ImageList_Destroy(himlHot);

		PostQuitMessage(0);
		return 0;

	default:
		break;

	}

	return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

今回は独自のボタンイメージを表示するということで、TBBUTTON構造体の最初のメンバにはSTD_FILEOPENなどの定数を指定していません。 単純にビットマップ上におけるボタンイメージのインデックスを指定するだけで問題ありません。 また、CreateToolbarExの第5引数にHINST_COMMCTRLを指定したり、 第6引数にIDB_STD_SMALL_COLORを指定したりする必要もありません。 用意したビットマップはイメージリストとしてImageList_LoadImageでロードし、 TB_SETIMAGELISTでイメージリストをツールバーに指定します。

himl = ImageList_LoadImage(NULL, TEXT("toolbar.bmp"), 16, CLR_NONE, RGB(255, 255, 255), IMAGE_BITMAP, LR_CREATEDIBSECTION | LR_LOADFROMFILE);
if (himl == NULL)
	return -1;
SendMessage(hwndToolbar, TB_SETIMAGELIST, 0, (LPARAM)himl);

himlHot = ImageList_LoadImage(NULL, TEXT("toolbar_hot.bmp"), 16, CLR_NONE, RGB(255, 255, 255), IMAGE_BITMAP, LR_CREATEDIBSECTION | LR_LOADFROMFILE);
if (himlHot == NULL)
	return -1;
SendMessage(hwndToolbar, TB_SETHOTIMAGELIST, 0, (LPARAM)himlHot);

dwStyle = (DWORD)SendMessage(hwndToolbar, TB_GETSTYLE, 0, 0) | TBSTYLE_FLAT;
SendMessage(hwndToolbar, TB_SETSTYLE, 0, (LPARAM)dwStyle);

ImageList_LoadImageの第2引数には、ロードするビットマップを指定します。 第3引数は1つのボタンイメージのサイズであり、第4引数はCLR_NONEで問題ありません。 第5引数は透過したい色であり、使用するビットマップの背景色が白であることを仮定してRGB(255, 255, 255)を指定しています。 第6引数はIMAGE_BITMAPを指定し、第7引数はLR_CREATEDIBSECTIONとLR_LOADFROMFILEを指定します。 2つ目にロードしたイメージリストはホット状態の場合に使用するため、 TB_SETIMAGELISTではなくTB_SETHOTIMAGELISTを送ります。 ホット状態はツールバーがフラットでなければならないため、 その処理も行われています。

今回はビットマップをファイルとしてロードしていますが、 当然ながらEXEファイルに格納されているリソースとしてロードすることもできます。 この場合は、第1引数にインスタンスハンドルを指定し、 リソースIDをMAKEINTRESOURCEマクロに指定したものを第2引数に指定します。 また、第6引数にLR_LOADFROMFILEを指定しないようにします。


戻る