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


章.5節.ツールバーに既存のビットマップを挿入してみよう

  

今回はツールバーに既存のビットマップを挿入してみます.
さらに,押されたボタンをウィンドウに文字列として表示させてみましょう.

今回はボタンが8つなので,8つもIDを作らないと..だるいですね.
(IDの作り方を知らない方は,「別章.2節.ストリングテーブルを編集してみよう」を先に読んでください.)

ID キャプション
IDC_BUTTON1 コピー
IDC_BUTTON2 カット
IDC_BUTTON3 削除
IDC_BUTTON4 ヘルプ
IDC_BUTTON5 詳細
IDC_BUTTON6 リスト
IDC_BUTTON7 新作
IDC_BUTTON8 ソート

今回のポイントは,
@ツールバーに既存のビットマップをどうやって表示するか?
というところですね.

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


#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		ToolBarAddBitmap(int nBotton, TBBUTTON* tbb, HINSTANCE hInst, UINT nID);
void		ToolBarAddButtons(int nBotton, TBBUTTON* tbb);
void		ToolBarAddButtonSpace(void);

void		DispText(HWND hWnd, char* pszBuf);

HWND		hToolBar;

#define NUMTBB1 (4)
#define NUMTBB2 (4)

TBBUTTON tbb1[NUMTBB1] =
{
	{STD_COPY, IDC_BUTTON1, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0},
	{STD_CUT, IDC_BUTTON2, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0},
	{STD_DELETE, IDC_BUTTON3, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0},
	{STD_HELP, IDC_BUTTON4, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0},
};

TBBUTTON tbb2[NUMTBB2] =
{
	{VIEW_DETAILS, IDC_BUTTON5, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0},
	{VIEW_LIST, IDC_BUTTON6, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0},
	{VIEW_NEWFOLDER, IDC_BUTTON7, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0},
	{VIEW_SORTNAME, IDC_BUTTON8, 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;
	static char		szBuf[256]="";

	switch( message ) 
	{
		case WM_CREATE:
			// ツールバーを作る
			hToolBar = ToolBarCreate( hWnd );
			// ツールバーにグラフィックの挿入準備
			ToolBarAddBitmap( NUMTBB1, tbb1, HINST_COMMCTRL, IDB_STD_SMALL_COLOR );
			// ツールバーにボタンを挿入する
			ToolBarAddButtons( NUMTBB1, tbb1 );
			// ツールバーにスペース
			ToolBarAddButtonSpace();
			// ツールバーにグラフィックの挿入準備
			ToolBarAddBitmap( NUMTBB2, tbb2, HINST_COMMCTRL, IDB_VIEW_SMALL_COLOR );
			// ツールバーにボタンを挿入する
			ToolBarAddButtons( NUMTBB2, tbb2 );
			
			break;
		case WM_PAINT:
			DispText( hWnd, szBuf );
			break;
		case WM_COMMAND:
			wmId = LOWORD(wParam);
			wmEvent = HIWORD(wParam);

			switch( wmId )
			{
				// 今回は,IDから文字列を取得しています
				case IDC_BUTTON1: LoadString(hInst, IDC_BUTTON1, (LPSTR)&szBuf, sizeof(szBuf)); break;
				case IDC_BUTTON2: LoadString(hInst, IDC_BUTTON2, (LPSTR)&szBuf, sizeof(szBuf)); break;
				case IDC_BUTTON3: LoadString(hInst, IDC_BUTTON3, (LPSTR)&szBuf, sizeof(szBuf)); break;
				case IDC_BUTTON4: LoadString(hInst, IDC_BUTTON4, (LPSTR)&szBuf, sizeof(szBuf)); break;
				case IDC_BUTTON5: LoadString(hInst, IDC_BUTTON5, (LPSTR)&szBuf, sizeof(szBuf)); break;
				case IDC_BUTTON6: LoadString(hInst, IDC_BUTTON6, (LPSTR)&szBuf, sizeof(szBuf)); break;
				case IDC_BUTTON7: LoadString(hInst, IDC_BUTTON7, (LPSTR)&szBuf, sizeof(szBuf)); break;
				case IDC_BUTTON8: LoadString(hInst, IDC_BUTTON8, (LPSTR)&szBuf, sizeof(szBuf)); break;
				default:
					return DefWindowProc( hWnd, message, wParam, lParam );
			}
			InvalidateRect(hWnd, NULL, TRUE);//クライアント全体を再描画する命令

			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	ToolBarAddBitmap(int nBotton, TBBUTTON* tbb, HINSTANCE hInst, UINT nID)
{
	int i, index;
	TBADDBITMAP tbAddBmp;

	tbAddBmp.hInst = hInst;
	tbAddBmp.nID = nID;
	
	index = SendMessage(hToolBar, TB_ADDBITMAP, 0, (LPARAM)&tbAddBmp);
	
	for( i=0; i<nBotton; i++ )		tbb[i].iBitmap += index;
}

void	ToolBarAddButtons(int nBotton, TBBUTTON* tbb)
{
	int i, index;
	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);
}

void	ToolBarAddButtonSpace(void)
{
	TBBUTTON tbSpace = {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0};

	SendMessage(hToolBar, TB_ADDBUTTONS, 1, (LPARAM)&tbSpace);
}

void	DispText(HWND hWnd, char* pszBuf)
{
	HDC hdc;
	PAINTSTRUCT ps;

	hdc = BeginPaint ( hWnd, &ps );
	TextOut( hdc, 130, 60, (LPSTR)pszBuf, lstrlen(pszBuf) );
	EndPaint( hWnd, &ps );
}

☆プログラムの解説☆

@ツールバーに既存のビットマップをどうやって表示するか?

とりあえず,一つ一つのボタンに既存のビットマップってどんなものがあるか見てみましょう.
探してみると,

 

などがありました.こういうボタンのビットマップが使えちゃうわけですね.
それぞれのビットマップには名前があります.上の図の一番左端の図は「カット」のボタンですね.
このボタンの名前は,STD_CUTという名前です.
コピーのボタンはSTD_COPY,上書き保存はSTD_FILESAVEです.
STD_??以外には,VIEW_??(ビューに関するボタン)などがあります.
そこで,ボタン構造体の各先頭要素にその使いたいビットマップの名前を下のように入れていきましょう.

TBBUTTON tbb1[NUMTBB1] =
{
	{STD_COPY, IDC_BUTTON1, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0},
	{STD_CUT, IDC_BUTTON2, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0},
	{STD_DELETE, IDC_BUTTON3, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0},
	{STD_HELP, IDC_BUTTON4, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0},
};

TBBUTTON tbb2[NUMTBB2] =
{
	{VIEW_DETAILS, IDC_BUTTON5, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0},
	{VIEW_LIST, IDC_BUTTON6, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0},
	{VIEW_NEWFOLDER, IDC_BUTTON7, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0},
	{VIEW_SORTNAME, IDC_BUTTON8, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0},
};

前回同様.ツールバーをToolBarCreate関数を用いて作ります.
そして,ツールバーにビットマップを挿入する準備をします.その関数を作ります.

// ツールバーにグラフィックの挿入準備
ToolBarAddBitmap( NUMTBB1, tbb1, HINST_COMMCTRL, IDB_STD_SMALL_COLOR );
第1引数 ボタンの数
第2引数 ツールバーボタン構造体へのポインタ
第3引数 既存か未存かどっちのビットマップを使う?(HINST_COMMCTRL:既存)
第4引数 STD_??かVIEW_??かどっちのビットマップを使うか
(IDB_STD_SMALL_COLOR:STD,IDB_VIEW_SMALL_COLOR:VIEW)
こんな感じです.関数の中身を見ましょう.

void	ToolBarAddBitmap(int nBotton, TBBUTTON* tbb, HINSTANCE hInst, UINT nID)
{
	int i, index;
	TBADDBITMAP tbAddBmp;

	tbAddBmp.hInst = hInst;
	tbAddBmp.nID = nID;
	
	index = SendMessage(hToolBar, TB_ADDBITMAP, 0, (LPARAM)&tbAddBmp);
	
	for( i=0; i<nBotton; i++ )		tbb[i].iBitmap += index;
}

これが,ツールバーにビットマップを挿入する仕組みです.
ビットマップを挿入するために,TBADDBITMAPという構造体が必要です.
その構造体変数にhInst(既存か未存か)とnID(STD_??かVIEW_??か)をつめて,SendMessageを起こします.
これで,ツールバーにビットマップがいきますから!ってことを伝えました.
すると,ツールバーはこれをボタン構造体のiBitmapに加算しろという値を返してきます.
それが,indexという変数です.これを各々のボタン構造体のiBitmap変数に加算していってるのがわかりますね.

これで,ビットマップの挿入準備が完了しました.
しかし,これは準備が終わっただけなので,最後にいつものToolBarAddButtonsでボタンを挿入しましょう.
それで完了です!!


              

 

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

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

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

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