Click here to Skip to main content
15,891,529 members
Articles / Desktop Programming / WTL

Fun with Common Controls Bitmaps and Toolbars

Rate me:
Please Sign up or sign in to vote.
4.45/5 (10 votes)
29 May 2004CPOL5 min read 110.1K   2.1K   23  
A WTL mix-in class for creating toolbar controls using common controls bitmaps instead of local resources.
// SysToolbarCtrl.h: Toolbar helper class CSysToolbarCtrl.
// Should compile only when used as a mix-in class for a
// WTL::CFrameWindowImpl<T> based class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_SYSTOOLBARCTRL_H__ABD82C39_37E1_4A9B_903A_14C1DFADA70F__INCLUDED_)
#define AFX_SYSTOOLBARCTRL_H__ABD82C39_37E1_4A9B_903A_14C1DFADA70F__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000


// padding for TBBUTTON alignment:
#ifdef _WIN64
#define TBBPADDING 0, 0, 0, 0, 0, 0,
#elif defined(_WIN32)
#define TBBPADDING 0, 0,
#else
#define TBBPADDING
#endif

// Generic button:
#define STBB(Img, Cmd, Bmp) {Img, Cmd, TBSTATE_ENABLED, TBSTYLE_BUTTON, TBBPADDING Bmp, 0}

// Separator:
#define STBB_SEPARATOR {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, TBBPADDING 0L, 0}

// History buttons (all without standard command IDs):
#define STBB_HIST_ADDTOFAVORITES(Cmd)	STBB(HIST_ADDTOFAVORITES, Cmd, IDB_HIST_SMALL_COLOR)
#define STBB_HIST_BACK(Cmd)				STBB(HIST_BACK, Cmd, IDB_HIST_SMALL_COLOR)
#define STBB_HIST_FAVORITES(Cmd)		STBB(HIST_FAVORITES, Cmd, IDB_HIST_SMALL_COLOR)
#define STBB_HIST_FORWARD(Cmd)			STBB(HIST_FORWARD, Cmd, IDB_HIST_SMALL_COLOR)
#define STBB_HIST_VIEWTREE(Cmd)			STBB(HIST_VIEWTREE, Cmd, IDB_HIST_SMALL_COLOR)

// Standard buttons (based on command IDs in <atlres.h>):
#define STBB_STD_COPY				STBB(STD_COPY, ID_EDIT_COPY, IDB_STD_SMALL_COLOR)
#define STBB_STD_CUT				STBB(STD_CUT, ID_EDIT_CUT, IDB_STD_SMALL_COLOR)
// (No standard Delete command in <atlres.h>)
#define STBB_STD_DELETE(Cmd)		STBB(STD_DELETE, Cmd, IDB_STD_SMALL_COLOR)
#define STBB_STD_FILENEW			STBB(STD_FILENEW, ID_FILE_NEW, IDB_STD_SMALL_COLOR)
#define STBB_STD_FILEOPEN			STBB(STD_FILEOPEN, ID_FILE_OPEN, IDB_STD_SMALL_COLOR)
#define STBB_STD_FILESAVE			STBB(STD_FILESAVE, ID_FILE_SAVE, IDB_STD_SMALL_COLOR)
#define STBB_STD_FIND				STBB(STD_FIND, ID_EDIT_FIND, IDB_STD_SMALL_COLOR)
#define STBB_STD_HELP				STBB(STD_HELP, ID_CONTEXT_HELP, IDB_STD_SMALL_COLOR)
#define STBB_STD_PASTE				STBB(STD_PASTE, ID_EDIT_PASTE, IDB_STD_SMALL_COLOR)
#define STBB_STD_PRINT				STBB(STD_PRINT, ID_FILE_PRINT, IDB_STD_SMALL_COLOR)
#define STBB_STD_PRINTPRE			STBB(STD_PRINTPRE, ID_FILE_PRINT_PREVIEW, IDB_STD_SMALL_COLOR)
// (No standard Properties command in <atlres.h>)
#define STBB_STD_PROPERTIES(Cmd)	STBB(STD_PROPERTIES, Cmd, IDB_STD_SMALL_COLOR)
#define STBB_STD_REDOW				STBB(STD_REDOW, ID_EDIT_REDO, IDB_STD_SMALL_COLOR)
#define STBB_STD_REPLACE			STBB(STD_REPLACE, ID_EDIT_REPLACE, IDB_STD_SMALL_COLOR)
#define STBB_STD_UNDO				STBB(STD_UNDO, ID_EDIT_UNDO, IDB_STD_SMALL_COLOR)

// View buttons (all without standard command IDs):
#define STBB_VIEW_DETAILS(Cmd)			STBB(VIEW_DETAILS, Cmd, IDB_VIEW_SMALL_COLOR)
#define STBB_VIEW_LARGEICONS(Cmd)		STBB(VIEW_LARGEICONS, Cmd, IDB_VIEW_SMALL_COLOR)
#define STBB_VIEW_LIST(Cmd)				STBB(VIEW_LIST, Cmd, IDB_VIEW_SMALL_COLOR)
#define STBB_VIEW_NETCONNECT(Cmd)		STBB(VIEW_NETCONNECT, Cmd, IDB_VIEW_SMALL_COLOR)
#define STBB_VIEW_NETDISCONNECT(Cmd)	STBB(VIEW_NETDISCONNECT, Cmd, IDB_VIEW_SMALL_COLOR)
#define STBB_VIEW_NEWFOLDER(Cmd)		STBB(VIEW_NEWFOLDER, Cmd, IDB_VIEW_SMALL_COLOR)
#define STBB_VIEW_PARENTFOLDER(Cmd)		STBB(VIEW_PARENTFOLDER, Cmd, IDB_VIEW_SMALL_COLOR)
#define STBB_VIEW_SMALLICONS(Cmd)		STBB(VIEW_SMALLICONS, Cmd, IDB_VIEW_SMALL_COLOR)
#define STBB_VIEW_SORTDATE(Cmd)			STBB(VIEW_SORTDATE, Cmd, IDB_VIEW_SMALL_COLOR)
#define STBB_VIEW_SORTNAME(Cmd)			STBB(VIEW_SORTNAME, Cmd, IDB_VIEW_SMALL_COLOR)
#define STBB_VIEW_SORTSIZE(Cmd)			STBB(VIEW_SORTSIZE, Cmd, IDB_VIEW_SMALL_COLOR)
#define STBB_VIEW_SORTTYPE(Cmd)			STBB(VIEW_SORTTYPE, Cmd, IDB_VIEW_SMALL_COLOR)
#if (_WIN32_IE >= 0x0400)
#define STBB_VIEW_VIEWMENU(Cmd)			STBB(VIEW_VIEWMENU, Cmd, IDB_VIEW_SMALL_COLOR)
#endif

// yeah, yeah, I know, this is a cheap shot, but it works
#pragma warning(push)
#pragma warning(disable:4189)   // pFrameWnd: variable not referenced, it's just a compile-time sanity check
#pragma warning(disable:4211)   // BMPSIZES:  nonstandard redefine extern to static

template <class T>
class ATL_NO_VTABLE CSysToolbarCtrl
{
	typedef CFrameWindowImpl<T> frameWndClass;
	typedef frameWndClass::_AtlToolBarData toolbarData;

protected:
	static const SIZE BMPSIZES[2];
	enum {BMP_SMALL, BMP_LARGE};

public:
	HWND CreateSysToolbarCtrl(HWND hWndParent,			// Parent window handle
	  TBBUTTON* pItems,									// An array of toolbar items
	  int nItems,										// Number of array items
	  CCommandBarCtrl* pCmdBar = NULL,					// Optional command bar pointer
	  int bmpSize = BMP_SMALL,							// Bitmap size
	  DWORD dwStyle = ATL_SIMPLE_TOOLBAR_PANE_STYLE,	// Toolbar style
	  UINT nID = ATL_IDW_TOOLBAR)						// Control ID
	{
		// compile only if this is a CFrameWindowImpl
		T* pThis = static_cast<T*>(this);
		frameWndClass* pFrameWnd = pThis;	// disable warning 4189

		// create toolbar control
		AtlInitCommonControls(ICC_BAR_CLASSES);			// (just making sure)
		HWND hWnd = ::CreateWindowEx(0, TOOLBARCLASSNAME, NULL, dwStyle, 0, 0,
				100, 100, hWndParent, (HMENU)LongToHandle(nID),
				_Module.GetResourceInstance(), NULL);
		if (hWnd == NULL)
			return NULL;
		CToolBarCtrl wndToolbar = hWnd;
		wndToolbar.SetButtonStructSize();

		// Set initial button size
		wndToolbar.SetBitmapSize(BMPSIZES[bmpSize].cx, BMPSIZES[bmpSize].cy);
		wndToolbar.SetButtonSize(BMPSIZES[bmpSize].cx + 7,
			BMPSIZES[bmpSize].cy + 7);

		// build toolbar buttons
		int iImgListOffsets[3] = {-1, -2, -3},		// Offsets to std bitmaps in toolbar's image list
			iStdImgList;							// selector for iImgListOffsets
		for (int i = 0; i < nItems; i++){
			if (pItems[i].idCommand != 0){
				// Select large or small bitmap using bmpSize
				pItems[i].dwData &= ~1;
				pItems[i].dwData |= bmpSize;

				// Determine which image list offset to use (modulo 3 just in case...)
				iStdImgList = (pItems[i].dwData >> 2) % 3;

				// if the standard bitmap isn't loaded yet, load it
				// TO DO: Does toolbar control release bitmaps when destroyed?
				if (iImgListOffsets[iStdImgList] < 0)
					iImgListOffsets[iStdImgList] =
						wndToolbar.LoadStdImages(pItems[i].dwData);

				// button image index = standard bitmap index + image index
				pItems[i].iBitmap += iImgListOffsets[iStdImgList];

				// Add the current bitmap to the command bar
				if (pCmdBar && pCmdBar->m_hWnd){
					HDC hdc = GetDC(pCmdBar->m_hWnd);
					HBITMAP hBitmap = CreateCompatibleBitmap(hdc,
						BMPSIZES[bmpSize].cx, BMPSIZES[bmpSize].cy);
					HDC hdcMem = CreateCompatibleDC(hdc);
					HANDLE hOld = SelectObject(hdcMem, hBitmap);
					CImageList cImgList = wndToolbar.GetImageList();
					cImgList.SetBkColor(pCmdBar->GetImageMaskColor());
					cImgList.Draw(hdcMem, pItems[i].iBitmap, 0, 0, 0);
					SelectObject(hdcMem, hOld);
					DeleteDC(hdcMem);
					pCmdBar->SetImageSize(BMPSIZES[bmpSize].cx,
						BMPSIZES[bmpSize].cy);
					pCmdBar->AddBitmap(hBitmap, pItems[i].idCommand);
					DeleteObject(hBitmap);
					ReleaseDC(pCmdBar->m_hWnd,hdc);
				}
			}
		}
		wndToolbar.AddButtons(nItems, pItems);

		// check if font is taller than our bitmaps
		CFontHandle font = (HFONT)::SendMessage(hWnd, WM_GETFONT, 0, 0L);
		if(font.IsNull())
			font = AtlGetDefaultGuiFont();
		LOGFONT lf;
		font.GetLogFont(lf);
		WORD cyFontHeight = (WORD)abs(lf.lfHeight);
		int cyBmp = max(BMPSIZES[bmpSize].cy, cyFontHeight);

		// Size the buttons
		wndToolbar.SetBitmapSize(BMPSIZES[bmpSize].cx, cyBmp);
		wndToolbar.SetButtonSize(BMPSIZES[bmpSize].cx + 7, cyBmp + 7);

		return hWnd;
	}
};

// disable warning 4211: redefine extern to static
template <class T>
const SIZE CSysToolbarCtrl<T>::BMPSIZES[2] = {
	{16, 15},
	{24, 23}
};
#pragma warning(pop)


#endif // !defined(AFX_SYSTOOLBARCTRL_H__ABD82C39_37E1_4A9B_903A_14C1DFADA70F__INCLUDED_)

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
United States United States
A geek-of-all-trades who's masqueraded as a software engineer, metrologist, production engineer, BB stacker, and translator, just to name a few.

Comments and Discussions