Win32apiでツールバーでbmpを読み込んでくれません

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
リポD

Win32apiでツールバーでbmpを読み込んでくれません

#1

投稿記事 by リポD » 6年前

VC++2017でwin32apiライブラリを使ってツールバーのボタンのイメージを
左から[標準のイメージ]→[自作のイメージ]の順で表示させたいと思っています。
自作イメージの追加はリソースファイルに取り込んだ画像を呼び出す方法でしています。

標準のイメージは表示してくれたのですが、自作のイメージが表示されないので今回質問させていただきました。
理想としては、左から3つが標準のイメージ、続けて3つが自作のイメージとなるようにしたいです。
原因と解決策を教えていただけますでしょうか。

TBBUTTON構造体の宣言部分です。

コード:

TBBUTTON tbb[] =
{
	{ STD_CUT         , ID_CUT , TBSTATE_ENABLED , BTNS_BUTTON , 0 , 0 },
	{ STD_COPY        , ID_COPY , TBSTATE_ENABLED , BTNS_BUTTON , 0 , 0 },
	{ STD_PASTE       , ID_PASTE , TBSTATE_ENABLED , BTNS_BUTTON , 0 , 0 },
	{ 100             , ID_CREATE_DIALOG  , TBSTATE_ENABLED , BTNS_BUTTON , 0 , 0 },
	{ 101             , ID_RECTSTART , TBSTATE_ENABLED , BTNS_BUTTON , 0 , 0 },
	{ 102             , ID_GRABCUT  , TBSTATE_ENABLED , BTNS_BUTTON , 0 , 0 },
};
イメージとボタンの追加部分です

コード:

	HINSTANCE hInst;
	HWND hTool;
	TBADDBITMAP tb;
	int stdid, i;

	hInst = (HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE);

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

	//標準
	SendMessage(hTool, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
	tb.hInst = HINST_COMMCTRL;
	tb.nID = IDB_STD_SMALL_COLOR;
	stdid = SendMessage(hTool, TB_ADDBITMAP, (WPARAM)0, (LPARAM)&tb);
	tbb[0].iBitmap += stdid;
	tbb[1].iBitmap += stdid;
	tbb[2].iBitmap += stdid;
	SendMessage(hTool, TB_ADDBUTTONS, (WPARAM)3,(LPARAM)&tbb[0]);

	//自作
	tb.hInst = NULL;
	tb.nID = (int)LoadBitmap(hInst,"BMP_TOOLBAR");
	SendMessage(hTool, TB_ADDBITMAP, (WPARAM)3, (LPARAM)&tb);
	SendMessage(hTool, TB_ADDBUTTONS, (WPARAM)3, (LPARAM)&tbb[3]);

	return hTool;
リソース部分です

コード:

BMP_TOOLBAR BITMAP "toolbar1.bmp"

たいちう
記事: 418
登録日時: 13年前

Re: Win32apiでツールバーでbmpを読み込んでくれません

#2

投稿記事 by たいちう » 6年前

猫でもわかるプログラミング
Windows SDK編 第1部
第61章 ツールバーを作る その1
http://www.kumei.ne.jp/c_lang/sdk/sdk_61.htm

第62章 ツールバーを作る その2
http://www.kumei.ne.jp/c_lang/sdk/sdk_62.htm

この辺りが参考になりませんか?
ただ書かれているコードはかなり古いので、
リンクエラー等が発生するかもしれません。
私の場合、VC++2008では解決しているので、
エラーの種類によってはお助けできるかもしれません。
オフトピック
Win32APIは最近よく質問を見かけるけど流行っているのかな?たまたま?もしかして殆どが同一人物?

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: Win32apiでツールバーでbmpを読み込んでくれません

#3

投稿記事 by ISLe » 6年前

2つ目のコードの32行目で代入すべきは、ビットマップハンドルじゃなくて、ビットマップのリソースIDなのでは?

リポD

Re: Win32apiでツールバーでbmpを読み込んでくれません

#4

投稿記事 by リポD » 6年前

たいちうさん、参考サイトを張っていただいてありがとうございます。

参考サイトのやりかたも考えましたが、
参考サイトでは
CreateToolBarExでビットマップのイメージをボタンに追加し、
SendMessageで標準のイメージを追加しています。

ですが、Sendmessageの引数にCreateToolBarExの戻り値のHWNDを使用しているので
先に標準イメージを追加したい自分の理想ができないと思いました。

なので、自分のコードではCreateWindowExでHWNDを取得し、
SendMessageで標準イメージとBMPイメージを追加しようとしました。

リポD

Re: Win32apiでツールバーでbmpを読み込んでくれません

#5

投稿記事 by リポD » 6年前

ISLe さんが書きました:2つ目のコードの32行目で代入すべきは、ビットマップハンドルじゃなくて、ビットマップのリソースIDなのでは?
確認しましたが、リソース名でした。
https://msdn.microsoft.com/ja-jp/library/cc410429.aspx

たいちう
記事: 418
登録日時: 13年前

Re: Win32apiでツールバーでbmpを読み込んでくれません

#6

投稿記事 by たいちう » 6年前

以前書いたコードの一部ですが、左に3つの標準ボタン、
右に4つのオリジナルのボタンを持ったツールバーを作っています。
参考になるでしょうか。

コード:

HWND MainWindow::createToolBar() {
	static TBBUTTON tbb[] = {
		{ STD_FILENEW,  IDM_NEW,  TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0 },
		{ STD_FILEOPEN, IDM_OPEN, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0 },
		{ STD_FILESAVE, IDM_SAVE, 0,               TBSTYLE_BUTTON, 0, 0 },

		{ 0, IDM_EDIT,    0, TBSTYLE_BUTTON, 0, 0 },
		{ 1, IDM_ADD,     0, TBSTYLE_BUTTON, 0, 0 },

		{ 2, IDM_AUTO,    0, TBSTYLE_BUTTON, 0, 0 },
		{ 3, IDM_TESTALL, 0, TBSTYLE_BUTTON, 0, 0 },

		{ 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0 } // セパレータ
	};

	// ツールバー本体
	::InitCommonControls();
	HINSTANCE instance = getInstance();
	HWND toolbar =
		::CreateWindowEx(0, TOOLBARCLASSNAME, NULL,
		                 WS_CHILD | WS_VISIBLE | TBSTYLE_TOOLTIPS,
						 0, 0, 0, 0, hWnd_,
						 reinterpret_cast<HMENU>(ID_TOOLBAR), instance, NULL);
	::SendMessage(toolbar, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);

	// 標準のボタン
	TBADDBITMAP tb;
	tb.hInst = HINST_COMMCTRL;
	tb.nID = IDB_STD_SMALL_COLOR;
	int stdid = 
		static_cast<int>(::SendMessage(toolbar, TB_ADDBITMAP, 3, (LPARAM)&tb));
	tbb[0].iBitmap += stdid;
	tbb[1].iBitmap += stdid;
	tbb[2].iBitmap += stdid;
	::SendMessage(toolbar, TB_ADDBUTTONS, 3, reinterpret_cast<LPARAM>(&tbb[0]));

	// オリジナルのボタン
	tb.hInst = NULL;
	tb.nID = reinterpret_cast<UINT_PTR>(getTransparentBitmap());
	stdid = static_cast<int>(::SendMessage(toolbar, TB_ADDBITMAP, 4, (LPARAM)&tb));
	tbb[3].iBitmap += stdid;
	tbb[4].iBitmap += stdid;
	tbb[5].iBitmap += stdid;
	tbb[6].iBitmap += stdid;
	::SendMessage(toolbar, TB_ADDBUTTONS, (WPARAM)4, (LPARAM)(&tbb[3]));

	::SendMessage(toolbar, TB_INSERTBUTTON, 3, (LPARAM)(&tbb[7])); 
	::SendMessage(toolbar, TB_INSERTBUTTON, 6, (LPARAM)(&tbb[7])); 
	return toolbar;
}

HBITMAP MainWindow::getTransparentBitmap() {
	// 元のビットマップ
	HBITMAP bitmap = ::LoadBitmap(getInstance(), TEXT("TOOLBAR_BITMAP"));

	// サイズ・背景色の取得
	BITMAP bmp;
	::GetObject(bitmap, sizeof(bmp), &bmp);
	int cx = bmp.bmWidth;
	int cy = bmp.bmHeight;
	HDC hdc = ::GetDC(hWnd_);
	HDC hdc2 = ::CreateCompatibleDC(hdc);
	HBITMAP bitmap0 = static_cast<HBITMAP>(::SelectObject(hdc2, bitmap));
	COLORREF back = ::GetPixel(hdc2, 0, 0);
	HBITMAP bitmap2 = ::CreateCompatibleBitmap(hdc, cx, cy);
	::SelectObject(hdc2, bitmap2);

	// ビットマップを作成
	::SelectObject(hdc2, ::GetStockObject(NULL_PEN));
	::SelectObject(hdc2, ::GetSysColorBrush(COLOR_BTNFACE));
	::Rectangle(hdc2, 0, 0, cx + 1, cy + 1);

	HIMAGELIST imageList = ::ImageList_Create(cx, cy, ILC_COLOR | ILC_MASK, 1, 0);
	::ImageList_AddMasked(imageList, bitmap, back);
	::ImageList_Draw(imageList, 0, hdc2, 0, 0, ILD_NORMAL); 

	// 後片付け
	::SelectObject(hdc2, bitmap0);
	::DeleteDC(hdc2);
	::ReleaseDC(hWnd_, hdc);
	::ImageList_Destroy(imageList);
	::DeleteObject(bitmap);

	return bitmap2;
}

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: Win32apiでツールバーでbmpを読み込んでくれません

#7

投稿記事 by ISLe » 6年前

CreateToolBarExはビットマップの背景色の処理をやってくれるので利用しましょう。

1番目のパラメータはビットマップ内のボタンイメージのインデックス
自前部分は0から振る

コード:

TBBUTTON tbb[] =
{
	{ STD_CUT,   ID_CUT,           TBSTATE_ENABLED, BTNS_BUTTON, 0, 0 },
	{ STD_COPY,  ID_COPY,          TBSTATE_ENABLED, BTNS_BUTTON, 0, 0 },
	{ STD_PASTE, ID_PASTE,         TBSTATE_ENABLED, BTNS_BUTTON, 0, 0 },
	{ 0,         ID_CREATE_DIALOG, TBSTATE_ENABLED, BTNS_BUTTON, 0, 0 },
	{ 1,         ID_RECTSTART,     TBSTATE_ENABLED, BTNS_BUTTON, 0, 0 },
	{ 2,         ID_GRABCUT,       TBSTATE_ENABLED, BTNS_BUTTON, 0, 0 },
};
CreateToolbarExで自前のビットマップを読み込むだけでボタンは追加せず
既成のビットマップを読み込んで対象のインデックスの差分を更新
まとめてボタン追加

コード:

	HINSTANCE hInst;
	HWND hTool;
	TBADDBITMAP tb;
	int stdid, i;

	hInst = (HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE);

	hTool = CreateToolbarEx(
		hWnd,
		WS_CHILD | WS_VISIBLE,
		ID_TOOLBAR,
		3,
		hInst,
		BMP_TOOLBAR,
		0, 0, 0, 0, 0, 0,
		sizeof(TBBUTTON));

	tb.hInst = HINST_COMMCTRL;
	tb.nID = IDB_STD_SMALL_COLOR;
	stdid = SendMessage(hTool, TB_ADDBITMAP, (WPARAM)0, (LPARAM)&tb);
	tbb[0].iBitmap += stdid;
	tbb[1].iBitmap += stdid;
	tbb[2].iBitmap += stdid;

	SendMessage(hTool, TB_ADDBUTTONS, (WPARAM)6,(LPARAM)tbb);

	return hTool;

リポD

Re: Win32apiでツールバーでbmpを読み込んでくれません

#8

投稿記事 by リポD » 6年前

たいちうさん、ISLeさん回答ありがとうございます。
お二人の方法で描画されました!ありがとうございます。

返信

“C言語何でも質問掲示板” へ戻る