Files
FC1/Editor/Controls/HiColorToolBar.cpp
romkazvo 34d6c5d489 123
2023-08-07 19:29:24 +08:00

286 lines
8.3 KiB
C++

// HiColorToolBar.cpp : implementation file
//
#include "stdafx.h"
#include "HiColorToolBar.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CHiColorToolBar
CHiColorToolBar::CHiColorToolBar()
{
}
CHiColorToolBar::~CHiColorToolBar()
{
}
BEGIN_MESSAGE_MAP(CHiColorToolBar, CToolBar)
//{{AFX_MSG_MAP(CHiColorToolBar)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CHiColorToolBar message handlers
void CHiColorToolBar::AttachToolbarImages(UINT inNormalImageID)
{
////////////////////////////////////////////////////////////////////////
// Load the high color toolbar images and attach them to the toolbar
////////////////////////////////////////////////////////////////////////
// Make high-color image lists for each of the bitmaps
MakeToolbarImageList(inNormalImageID, m_ToolbarImages, LTNormal);
MakeToolbarImageList(inNormalImageID, m_ToolbarImagesDisabled, LTDisabled);
MakeToolbarImageList(inNormalImageID, m_ToolbarImagesHot, LTHot);
// Get the toolbar control associated with the CToolbar object
CToolBarCtrl& barCtrl = GetToolBarCtrl();
// Attach the image lists to the toolbar control
barCtrl.SetImageList(&m_ToolbarImages);
barCtrl.SetDisabledImageList(&m_ToolbarImagesDisabled);
barCtrl.SetHotImageList(&m_ToolbarImagesHot);
}
void CHiColorToolBar::ReplaceBackgroundColor(CBitmap& ioBM)
{
////////////////////////////////////////////////////////////////////////
// Find every pixel of the default background color in the specified
// bitmap and set each one to the user's button color
////////////////////////////////////////////////////////////////////////
// Figure out how many pixels there are in the bitmap
BITMAP bmInfo;
VERIFY (ioBM.GetBitmap (&bmInfo));
// Add support for additional bit depths if you choose
VERIFY (bmInfo.bmBitsPixel == 24);
VERIFY (bmInfo.bmWidthBytes == (bmInfo.bmWidth * 3));
const UINT numPixels (bmInfo.bmHeight * bmInfo.bmWidth);
// Get a pointer to the pixels
DIBSECTION ds;
VERIFY (ioBM.GetObject (sizeof (DIBSECTION), &ds) == sizeof (DIBSECTION));
RGBTRIPLE* pixels = reinterpret_cast<RGBTRIPLE *> (ds.dsBm.bmBits);
VERIFY (pixels != NULL);
// Get the user's preferred button color from the system
const COLORREF buttonColor (::GetSysColor (COLOR_BTNFACE));
const RGBTRIPLE userBackgroundColor = {
GetBValue (buttonColor), GetGValue (buttonColor), GetRValue (buttonColor)};
// Search through the pixels, substituting the user's button
// color for any pixel that has the magic background color
for (UINT i = 0; i < numPixels; ++i)
{
if (pixels[i].rgbtBlue == kBackgroundColor.rgbtBlue
&& pixels[i].rgbtGreen == kBackgroundColor.rgbtGreen
&& pixels[i].rgbtRed == kBackgroundColor.rgbtRed)
{
pixels [i] = userBackgroundColor;
}
}
}
void CHiColorToolBar::MakeDisabled(CBitmap &ioBM)
{
////////////////////////////////////////////////////////////////////////
// Give the bitmap a disabled look
////////////////////////////////////////////////////////////////////////
// Figure out how many pixels there are in the bitmap
BITMAP bmInfo;
VERIFY (ioBM.GetBitmap (&bmInfo));
// Add support for additional bit depths if you choose
VERIFY (bmInfo.bmBitsPixel == 24);
VERIFY (bmInfo.bmWidthBytes == (bmInfo.bmWidth * 3));
const UINT numPixels (bmInfo.bmHeight * bmInfo.bmWidth);
// Get a pointer to the pixels
DIBSECTION ds;
VERIFY (ioBM.GetObject (sizeof (DIBSECTION), &ds) == sizeof (DIBSECTION));
RGBTRIPLE* pixels = reinterpret_cast<RGBTRIPLE *> (ds.dsBm.bmBits);
VERIFY (pixels != NULL);
// Get the user's preferred button color from the system
const COLORREF buttonColor (::GetSysColor (COLOR_BTNFACE));
const RGBTRIPLE userBackgroundColor = {
GetBValue (buttonColor), GetGValue (buttonColor), GetRValue (buttonColor)};
// Loop trough all pixels
for (UINT i = 0; i < numPixels; ++i)
{
if (pixels[i].rgbtBlue == userBackgroundColor.rgbtBlue
&& pixels[i].rgbtGreen == userBackgroundColor.rgbtGreen
&& pixels[i].rgbtRed == userBackgroundColor.rgbtRed)
{
// Skip pixels that have the background color
continue;
}
// Average out the BGR channels
pixels[i].rgbtBlue = (pixels[i].rgbtBlue + pixels[i].rgbtGreen + pixels[i].rgbtRed) / 3;
pixels[i].rgbtRed = pixels[i].rgbtGreen = pixels[i].rgbtBlue;
}
}
void CHiColorToolBar::MakeToolbarImageList(UINT inBitmapID, CImageList& outImageList, LoadType lt)
{
////////////////////////////////////////////////////////////////////////
// Create an image list for the specified BMP resource
////////////////////////////////////////////////////////////////////////
CBitmap bm;
DWORD dwStyleParam = 0;
// 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) | dwStyleParam)));
// Replace the specified color in the bitmap with the user's
// button color
ReplaceBackgroundColor(bm);
// Disable it when requested
if (lt == LTDisabled)
MakeDisabled(bm);
// Create a 24 bit image list with the same dimensions and number
// of buttons as the toolbar
VERIFY(outImageList.Create (
kImageWidth, kImageHeight, kToolBarBitDepth, kNumImages, 0));
// Attach the bitmap to the image list
VERIFY(outImageList.Add (&bm, RGB (0, 0, 0)) != -1);
}
void CHiColorToolBar::AddTextStrings()
{
////////////////////////////////////////////////////////////////////////
// Add text descriptions to a tool bar
////////////////////////////////////////////////////////////////////////
// Set the text for each button
CToolBarCtrl& bar = GetToolBarCtrl();
// Remove the string map in case we are loading another toolbar into this control
if (m_pStringMap)
{
delete m_pStringMap;
m_pStringMap = NULL;
}
int nIndex = 0;
TBBUTTON tb;
for (nIndex = bar.GetButtonCount() - 1; nIndex >= 0; nIndex--)
{
ZeroMemory(&tb, sizeof(TBBUTTON));
bar.GetButton(nIndex, &tb);
// Do we have a separator?
if ((tb.fsStyle & TBSTYLE_SEP) == TBSTYLE_SEP)
continue;
// Have we got a valid command id?
if (tb.idCommand == 0)
continue;
// Get the resource string if there is one.
CString strText;
LPCTSTR lpszButtonText = NULL;
CString strButtonText(_T(""));
_TCHAR seps[] = _T("\n");
strText.LoadString(tb.idCommand);
if (!strText.IsEmpty())
{
lpszButtonText = _tcstok((LPTSTR) (LPCTSTR) strText, seps);
while(lpszButtonText)
{
strButtonText = lpszButtonText;
lpszButtonText = _tcstok(NULL, seps);
}
}
if (!strButtonText.IsEmpty())
SetButtonText(nIndex, strButtonText);
}
// Resize the buttons so that the text will fit.
CRect rc(0, 0, 0, 0);
CSize sizeMax(0, 0);
for (nIndex = bar.GetButtonCount() - 1; nIndex >= 0; nIndex--)
{
bar.GetItemRect(nIndex, rc);
rc.NormalizeRect();
sizeMax.cx = __max(rc.Size().cx, sizeMax.cx);
sizeMax.cy = __max(rc.Size().cy, sizeMax.cy);
}
SetSizes(sizeMax, CSize(32, 32));
// Set the minimum button size
SendMessage(TB_SETBUTTONWIDTH, 0, (LPARAM) (DWORD) MAKELONG(85, 128));
}
bool CHiColorToolBar::CreateAll(UINT nIDRessource, UINT inNormalImageID, CWnd *pwndParent)
{
////////////////////////////////////////////////////////////////////////
// Load all data required for the full toolbar functionality
////////////////////////////////////////////////////////////////////////
CLogFile::WriteLine("Creating new high color toolbar...");
// Create the toolbar itself
if (!CreateEx(pwndParent, TBSTYLE_FLAT | TBSTYLE_WRAPABLE, WS_CHILD | CBRS_TOP
| CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC))
{
return false;
}
// Load the buttons
if (!LoadToolBar(nIDRessource))
return false;
// Attach the 24bpp images
AttachToolbarImages(inNormalImageID);
// Read the text strings out of the ressource and set them
AddTextStrings();
// Set maximum number of rows
GetToolBarCtrl().SetRows(99, TRUE, NULL);
// Indent the first button a few pixels so that the toolbar is centered
GetToolBarCtrl().SetIndent(4);
return true;
}