⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xtruecolortoolbar.cpp

📁 VC++写的仿Windows系统的写字板程序
💻 CPP
字号:
// XTrueColorToolBar.cpp  Version 1.0 - article available at www.codeproject.com
//
// Author:  Hans Dietrich
//          hdietrich@gmail.com
//
// Description:
//     XTrueColorToolBar is an MFC class derived from CToolBar that provides 
//     support for true-color bitmaps, with optional support for an 
//     Office-style color picker button.  It is based on Peter Lee's
//     article "Full-Featured 24-bit Color Toolbar", which you can find
//     at http://www.codeguru.com/Cpp/controls/toolbar/article.php/c2537.
//
// History
//     Version 1.0 - 2007 December 17
//     - Initial public release
//
// License:
//     This software is released into the public domain.  You are free to use
//     it in any way you like, except that you may not sell this source code.
//
//     This software is provided "as is" with no expressed or implied warranty.
//     I accept no liability for any damage or loss of business that this 
//     software may cause.
//
///////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "XTrueColorToolBar.h"

#pragma warning(disable : 4996)	// disable bogus deprecation warning


//=============================================================================
CXTrueColorToolBar::CXTrueColorToolBar()
//=============================================================================
{
	m_nNumImages        = 0;
	m_nImageWidth       = 16;
	m_nImageHeight      = 16;
	m_nToolBarBitDepth  = ILC_COLOR24;
	m_crCurrentColor    = RGB(0,0,0);
	m_crMaskColor       = RGB(0,0,1);
	m_crBackgroundColor = RGB(192,192,192);
}

//=============================================================================
// Create copy of toolbar image list
BOOL CXTrueColorToolBar::CreateTemplate(COLORREF rgb)
//=============================================================================
{
	BOOL rc = FALSE;

	SetMaskColor(rgb);

	if (m_ImageTemplate.GetSafeHandle() != NULL)
		m_ImageTemplate.DeleteImageList();

	CToolBarCtrl& ctrl = GetToolBarCtrl();
	CImageList *pList = ctrl.GetImageList();

	if (pList)
	{
		// create copy of toolbar image list
		rc =  m_ImageTemplate.Create(pList);

		if (!rc)
		{
			TRACE(_T("ERROR - failed to create image template\n"));
			ASSERT(FALSE);
		}
	}
	else
	{
		TRACE(_T("ERROR - failed to get toolbar image list\n"));
		ASSERT(pList);
	}

	return rc;
}

//=============================================================================
// Find every pixel of the default background color in the specified
// bitmap and set each one to the user's button color.
void CXTrueColorToolBar::ReplaceBackgroundColor(CBitmap& bm, 
												COLORREF OldColor, 
												COLORREF NewColor)
//=============================================================================
{
	// figure out how many pixels there are in the bitmap
	BITMAP bmInfo;
	VERIFY(bm.GetBitmap(&bmInfo));
	
	// add support for additional bit depths here if you choose
	VERIFY(bmInfo.bmBitsPixel == 24);
	VERIFY(bmInfo.bmWidthBytes == (bmInfo.bmWidth * 3));

	UINT nPixels = bmInfo.bmHeight * bmInfo.bmWidth;

	// get a pointer to the pixels
    DIBSECTION ds;

    VERIFY(bm.GetObject(sizeof(DIBSECTION), &ds) == sizeof(DIBSECTION));

	RGBTRIPLE *pixels = reinterpret_cast<RGBTRIPLE*>(ds.dsBm.bmBits);
	VERIFY(pixels);

	RGBTRIPLE NewBackgroundColor = {
		GetBValue(NewColor), GetGValue(NewColor), GetRValue(NewColor) };

	RGBTRIPLE OldBackgroundColor = {
		GetBValue(OldColor), GetGValue(OldColor), GetRValue(OldColor) };

	// search through the pixels, substituting the new background
	// color for any pixel that has the old background color

	int nCount = 0;
	for (UINT i = 0; i < nPixels; ++i)
	{
		if (pixels[i].rgbtBlue  == OldBackgroundColor.rgbtBlue &&
			pixels[i].rgbtGreen == OldBackgroundColor.rgbtGreen &&
			pixels[i].rgbtRed   == OldBackgroundColor.rgbtRed)
		{
			pixels[i] = NewBackgroundColor;
			nCount++;
		}
	}
	TRACE(_T("ReplaceColor: replaced %d pixels\n"), nCount);
}

//=============================================================================
// Find every pixel set to old color in mask bitmap and set corresponding
// pixel in toolbar bitmap to new color.
void CXTrueColorToolBar::ReplaceMaskColor(CBitmap& bm1,		// toolbar bitmap
										  CBitmap& bm2,		// mask bitmap
										  COLORREF OldColor, 
										  COLORREF NewColor)
//=============================================================================
{
	// figure out how many pixels there are in the bitmap
	BITMAP bmInfo1, bmInfo2;
	VERIFY(bm1.GetBitmap(&bmInfo1));
	VERIFY(bm2.GetBitmap(&bmInfo2));
	
	// add support for additional bit depths here if you choose
	VERIFY(bmInfo1.bmBitsPixel == 24);
	VERIFY(bmInfo1.bmWidthBytes == (bmInfo1.bmWidth * 3));
	VERIFY(bmInfo2.bmBitsPixel == 24);
	VERIFY(bmInfo2.bmWidthBytes == (bmInfo2.bmWidth * 3));

	UINT nPixels1 = bmInfo1.bmHeight * bmInfo1.bmWidth;
	UINT nPixels2 = bmInfo2.bmHeight * bmInfo2.bmWidth;
	//TRACE(_T("bmInfo1.bmHeight=%d  bmInfo1.bmWidth=%d\n"), bmInfo1.bmHeight, bmInfo1.bmWidth);
	//TRACE(_T("bmInfo2.bmHeight=%d  bmInfo2.bmWidth=%d\n"), bmInfo2.bmHeight, bmInfo2.bmWidth);
	//TRACE(_T("nPixels1=%d  nPixels2=%d\n"), nPixels1, nPixels2);
	ASSERT(nPixels1 == nPixels2);

	// get a pointer to the pixels
    DIBSECTION ds1, ds2;

    VERIFY(bm1.GetObject(sizeof(DIBSECTION), &ds1) == sizeof(DIBSECTION));
    VERIFY(bm2.GetObject(sizeof(DIBSECTION), &ds2) == sizeof(DIBSECTION));

	RGBTRIPLE *pixels1 = reinterpret_cast<RGBTRIPLE*>(ds1.dsBm.bmBits);
	VERIFY(pixels1 != NULL);
	RGBTRIPLE *pixels2 = reinterpret_cast<RGBTRIPLE*>(ds2.dsBm.bmBits);
	VERIFY(pixels2 != NULL);

	RGBTRIPLE NewMaskColor = {
		GetBValue(NewColor), GetGValue(NewColor), GetRValue(NewColor) };

	RGBTRIPLE OldMaskColor = {
		GetBValue(OldColor), GetGValue(OldColor), GetRValue(OldColor) };

	// search through the pixels, substituting the new mask
	// color for any pixel that has the old mask color

	int nCount = 0;
	for (UINT i = 0; i < nPixels1; ++i)
	{
		if (pixels2[i].rgbtBlue  == OldMaskColor.rgbtBlue &&
			pixels2[i].rgbtGreen == OldMaskColor.rgbtGreen &&
			pixels2[i].rgbtRed   == OldMaskColor.rgbtRed)
		{
			pixels1[i] = NewMaskColor;
			nCount++;
		}
	}
	TRACE(_T("ReplaceMaskColor: replaced %d pixels\n"), nCount);
}

//=============================================================================
// create an image list for the specified BMP resource
void CXTrueColorToolBar::MakeToolbarImageList(UINT inBitmapID, 
											  CImageList& outImageList)
//=============================================================================
{
	CBitmap bm;

	// If we use CBitmap::LoadBitmap() to load the bitmap, the colors
	// will be reduced to the bit depth of the main screen and we won't
	// be able to access the pixels directly. To avoid those problems,
	// we'll load the bitmap as a DIBSection instead and attach the
	// DIBSection to the CBitmap.
	VERIFY(bm.Attach(::LoadImage(
		::AfxFindResourceHandle(MAKEINTRESOURCE(inBitmapID), RT_BITMAP),
								MAKEINTRESOURCE(inBitmapID), IMAGE_BITMAP, 0, 0,
								(LR_DEFAULTSIZE | LR_CREATEDIBSECTION))));

	// replace the background color in the toolbar bitmap with the 
	// current system toolbar background color
	ReplaceBackgroundColor(bm, m_crBackgroundColor, GetSysColor(COLOR_BTNFACE));

	// create a 24 bit image list with the same dimensions and number
	// of buttons as the toolbar
	VERIFY(outImageList.Create(m_nImageWidth, 
							   m_nImageHeight, 
							   m_nToolBarBitDepth, 
							   m_nNumImages, 
							   0));

	// attach the bitmap to the image list
	VERIFY(outImageList.Add(&bm, RGB(0,0,0)) != -1);
}

//=============================================================================
// load the high color toolbar images and attach them to toolbar
void CXTrueColorToolBar::AttachToolbarImages(UINT nBitmapId,
											 int nNumImages,
											 int nToolbar)	// 0 = normal, 1 = disabled, 2 = hot
//=============================================================================
{
	ASSERT(nNumImages > 0);

	m_nNumImages = nNumImages;

	if (m_TrueColorImages.GetSafeHandle())
		m_TrueColorImages.DeleteImageList();

	// make true-color image list for the bitmap
	MakeToolbarImageList(nBitmapId, m_TrueColorImages);
	ASSERT(m_TrueColorImages.GetSafeHandle());

	// get the toolbar control associated with the CToolbar object
	CToolBarCtrl& ctrl = GetToolBarCtrl();

	// attach the image list to the toolbar control
	switch (nToolbar)
	{
		default:
		case 0:
			ctrl.SetImageList(&m_TrueColorImages);
			break;
		case 1:
			ctrl.SetDisabledImageList(&m_TrueColorImages);
			break;
		case 2:
			ctrl.SetHotImageList(&m_TrueColorImages);
			break;
	}
}

//=============================================================================
// Get image list index from command ID
int CXTrueColorToolBar::GetImageIndex(UINT nCommandId)
//=============================================================================
{
	CToolBarCtrl& ctrl = GetToolBarCtrl();

	int nButtonIndex = ctrl.CommandToIndex(nCommandId);

	UINT nID = 0;
	UINT nStyle = 0;
	int iImage = 0;
	GetButtonInfo(nButtonIndex, nID, nStyle, iImage);

	return iImage;
}

//=============================================================================
// Get bitmap from image list
BOOL CXTrueColorToolBar::GetBitmapFromImageList(CBitmap& bm, CImageList* pList)
//=============================================================================
{
	BOOL rc = FALSE;

	ASSERT(pList && pList->GetSafeHandle());

	if (pList && pList->GetSafeHandle())
	{
		IMAGEINFO ImageInfo;
		rc = pList->GetImageInfo(0, &ImageInfo);

		if (rc)
		{
			rc = bm.Attach(ImageInfo.hbmImage);

			if (!rc)
			{
				TRACE(_T("ERROR - Attach failed\n"));
				ASSERT(FALSE);
			}
		}
		else
		{
			TRACE(_T("ERROR - GetImageInfo failed\n"));
			ASSERT(FALSE);
		}
	}

	return rc;
}

//=============================================================================
// Set color of color button 
void CXTrueColorToolBar::SetColorButton(UINT nCommandId, COLORREF rgb)
//=============================================================================
{
	CToolBarCtrl& ctrl = GetToolBarCtrl();
	CImageList *pList = ctrl.GetImageList();

	if (pList && pList->GetSafeHandle())
	{
		CBitmap bmTemplate;
		VERIFY(GetBitmapFromImageList(bmTemplate, &m_ImageTemplate));

		int iImage = GetImageIndex(nCommandId);

		// restore original toolbar image from saved image template
		VERIFY(pList->Replace(iImage, &bmTemplate, NULL));

		CBitmap bmToolbar;
		VERIFY(GetBitmapFromImageList(bmToolbar, pList));

		// replace mask color in toolbar image list with new color
		ReplaceMaskColor(bmToolbar, bmTemplate, m_crMaskColor, rgb);

		m_crCurrentColor = rgb;

		RedrawWindow();
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -