234 lines
6 KiB
C++
234 lines
6 KiB
C++
|
/*++
|
||
|
|
||
|
Copyright (C) 1997-2001 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
History:
|
||
|
|
||
|
--*/
|
||
|
|
||
|
// ToolBarEx.cpp : implementation file
|
||
|
//
|
||
|
|
||
|
#include "stdafx.h"
|
||
|
#include "wmitest.h"
|
||
|
#include "ToolBarEx.h"
|
||
|
#include <AFXISAPI.H>
|
||
|
|
||
|
#ifdef _DEBUG
|
||
|
#define new DEBUG_NEW
|
||
|
#undef THIS_FILE
|
||
|
static char THIS_FILE[] = __FILE__;
|
||
|
#endif
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// CToolBarEx
|
||
|
|
||
|
CToolBarEx::CToolBarEx()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
CToolBarEx::~CToolBarEx()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
|
||
|
BEGIN_MESSAGE_MAP(CToolBarEx, CToolBar)
|
||
|
//{{AFX_MSG_MAP(CToolBarEx)
|
||
|
// NOTE - the ClassWizard will add and remove mapping macros here.
|
||
|
//}}AFX_MSG_MAP
|
||
|
END_MESSAGE_MAP()
|
||
|
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
// Lifted from Bartool.cpp.
|
||
|
#define RGB_TO_RGBQUAD(r,g,b) (RGB(b,g,r))
|
||
|
#define CLR_TO_RGBQUAD(clr) (RGB(GetBValue(clr), GetGValue(clr), GetRValue(clr)))
|
||
|
|
||
|
struct AFX_COLORMAP
|
||
|
{
|
||
|
// use DWORD instead of RGBQUAD so we can compare two RGBQUADs easily
|
||
|
DWORD rgbqFrom;
|
||
|
int iSysColorTo;
|
||
|
};
|
||
|
|
||
|
const AFX_COLORMAP _afxSysColorMap[] =
|
||
|
{
|
||
|
// mapping from color in DIB to system color
|
||
|
//{ RGB_TO_RGBQUAD(0x00, 0x00, 0x00), COLOR_BTNTEXT }, // black
|
||
|
//{ RGB_TO_RGBQUAD(0x80, 0x80, 0x80), COLOR_BTNSHADOW }, // dark gray
|
||
|
{ RGB_TO_RGBQUAD(0xC0, 0xC0, 0xC0), COLOR_BTNFACE }, // bright gray
|
||
|
//{ RGB_TO_RGBQUAD(0xFF, 0xFF, 0xFF), COLOR_BTNHIGHLIGHT } // white
|
||
|
};
|
||
|
|
||
|
HBITMAP AFXAPI AfxLoadSysColorBitmapEx(HINSTANCE hInst, HRSRC hRsrc, BOOL bMono = FALSE);
|
||
|
|
||
|
#ifndef _countof
|
||
|
#define _countof(x) (sizeof(x)/sizeof(x[0]))
|
||
|
#endif
|
||
|
|
||
|
HBITMAP AFXAPI
|
||
|
AfxLoadSysColorBitmapEx(HINSTANCE hInst, HRSRC hRsrc, BOOL bMono)
|
||
|
{
|
||
|
HGLOBAL hglb;
|
||
|
if ((hglb = LoadResource(hInst, hRsrc)) == NULL)
|
||
|
return NULL;
|
||
|
|
||
|
LPBITMAPINFOHEADER lpBitmap = (LPBITMAPINFOHEADER)LockResource(hglb);
|
||
|
if (lpBitmap == NULL)
|
||
|
return NULL;
|
||
|
|
||
|
// make copy of BITMAPINFOHEADER so we can modify the color table
|
||
|
const int nColorTableSize = 16;
|
||
|
UINT nSize = lpBitmap->biSize + nColorTableSize * sizeof(RGBQUAD);
|
||
|
LPBITMAPINFOHEADER lpBitmapInfo = (LPBITMAPINFOHEADER)::malloc(nSize);
|
||
|
if (lpBitmapInfo == NULL)
|
||
|
return NULL;
|
||
|
memcpy(lpBitmapInfo, lpBitmap, nSize);
|
||
|
|
||
|
// color table is in RGBQUAD DIB format
|
||
|
DWORD* pColorTable =
|
||
|
(DWORD*)(((LPBYTE)lpBitmapInfo) + (UINT)lpBitmapInfo->biSize);
|
||
|
|
||
|
for (int iColor = 0; iColor < nColorTableSize; iColor++)
|
||
|
{
|
||
|
// look for matching RGBQUAD color in original
|
||
|
for (int i = 0; i < _countof(_afxSysColorMap); i++)
|
||
|
{
|
||
|
if (pColorTable[iColor] == _afxSysColorMap[i].rgbqFrom)
|
||
|
{
|
||
|
if (bMono)
|
||
|
{
|
||
|
// all colors except text become white
|
||
|
if (_afxSysColorMap[i].iSysColorTo != COLOR_BTNTEXT)
|
||
|
pColorTable[iColor] = RGB_TO_RGBQUAD(255, 255, 255);
|
||
|
}
|
||
|
else
|
||
|
pColorTable[iColor] =
|
||
|
CLR_TO_RGBQUAD(::GetSysColor(_afxSysColorMap[i].iSysColorTo));
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int nWidth = (int)lpBitmapInfo->biWidth;
|
||
|
int nHeight = (int)lpBitmapInfo->biHeight;
|
||
|
HDC hDCScreen = ::GetDC(NULL);
|
||
|
HBITMAP hbm = ::CreateCompatibleBitmap(hDCScreen, nWidth, nHeight);
|
||
|
|
||
|
if (hbm != NULL)
|
||
|
{
|
||
|
HDC hDCGlyphs = ::CreateCompatibleDC(hDCScreen);
|
||
|
HBITMAP hbmOld = (HBITMAP)::SelectObject(hDCGlyphs, hbm);
|
||
|
|
||
|
LPBYTE lpBits;
|
||
|
lpBits = (LPBYTE)(lpBitmap + 1);
|
||
|
lpBits += (1 << (lpBitmapInfo->biBitCount)) * sizeof(RGBQUAD);
|
||
|
|
||
|
StretchDIBits(hDCGlyphs, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight,
|
||
|
lpBits, (LPBITMAPINFO)lpBitmapInfo, DIB_RGB_COLORS, SRCCOPY);
|
||
|
SelectObject(hDCGlyphs, hbmOld);
|
||
|
::DeleteDC(hDCGlyphs);
|
||
|
}
|
||
|
::ReleaseDC(NULL, hDCScreen);
|
||
|
|
||
|
// free copy of bitmap info struct and resource itself
|
||
|
::free(lpBitmapInfo);
|
||
|
::FreeResource(hglb);
|
||
|
|
||
|
return hbm;
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
// Lifted from Bartool.cpp. The only thing we changed was LoadBitmap to
|
||
|
// LoadBitmapEx.
|
||
|
struct CToolBarData
|
||
|
{
|
||
|
WORD wVersion;
|
||
|
WORD wWidth;
|
||
|
WORD wHeight;
|
||
|
WORD wItemCount;
|
||
|
//WORD aItems[wItemCount]
|
||
|
|
||
|
WORD* items()
|
||
|
{ return (WORD*)(this+1); }
|
||
|
};
|
||
|
|
||
|
BOOL CToolBarEx::LoadToolBarEx(LPCTSTR lpszResourceName)
|
||
|
{
|
||
|
ASSERT_VALID(this);
|
||
|
ASSERT(lpszResourceName != NULL);
|
||
|
|
||
|
// determine location of the bitmap in resource fork
|
||
|
HINSTANCE hInst = AfxFindResourceHandle(lpszResourceName, RT_TOOLBAR);
|
||
|
HRSRC hRsrc = ::FindResource(hInst, lpszResourceName, RT_TOOLBAR);
|
||
|
if (hRsrc == NULL)
|
||
|
return FALSE;
|
||
|
|
||
|
HGLOBAL hGlobal = LoadResource(hInst, hRsrc);
|
||
|
if (hGlobal == NULL)
|
||
|
return FALSE;
|
||
|
|
||
|
CToolBarData* pData = (CToolBarData*)LockResource(hGlobal);
|
||
|
if (pData == NULL)
|
||
|
return FALSE;
|
||
|
ASSERT(pData->wVersion == 1);
|
||
|
|
||
|
UINT* pItems = new UINT[pData->wItemCount];
|
||
|
for (int i = 0; i < pData->wItemCount; i++)
|
||
|
pItems[i] = pData->items()[i];
|
||
|
BOOL bResult = SetButtons(pItems, pData->wItemCount);
|
||
|
delete[] pItems;
|
||
|
|
||
|
if (bResult)
|
||
|
{
|
||
|
// set new sizes of the buttons
|
||
|
CSize sizeImage(pData->wWidth, pData->wHeight);
|
||
|
CSize sizeButton(pData->wWidth + 7, pData->wHeight + 7);
|
||
|
SetSizes(sizeButton, sizeImage);
|
||
|
|
||
|
// load bitmap now that sizes are known by the toolbar control
|
||
|
bResult = LoadBitmapEx(lpszResourceName);
|
||
|
}
|
||
|
|
||
|
UnlockResource(hGlobal);
|
||
|
FreeResource(hGlobal);
|
||
|
|
||
|
return bResult;
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
// Lifted from Bartool.cpp. The only thing we changed was AfxLoadSysColorBitmap to
|
||
|
// AfxLoadSysColorBitmapEx.
|
||
|
BOOL CToolBarEx::LoadBitmapEx(LPCTSTR lpszResourceName)
|
||
|
{
|
||
|
ASSERT_VALID(this);
|
||
|
ASSERT(lpszResourceName != NULL);
|
||
|
|
||
|
// determine location of the bitmap in resource fork
|
||
|
HINSTANCE hInstImageWell = AfxFindResourceHandle(lpszResourceName, RT_BITMAP);
|
||
|
HRSRC hRsrcImageWell = ::FindResource(hInstImageWell, lpszResourceName, RT_BITMAP);
|
||
|
if (hRsrcImageWell == NULL)
|
||
|
return FALSE;
|
||
|
|
||
|
// load the bitmap
|
||
|
HBITMAP hbmImageWell;
|
||
|
hbmImageWell = AfxLoadSysColorBitmapEx(hInstImageWell, hRsrcImageWell);
|
||
|
|
||
|
// tell common control toolbar about the new bitmap
|
||
|
if (!AddReplaceBitmap(hbmImageWell))
|
||
|
return FALSE;
|
||
|
|
||
|
// remember the resource handles so the bitmap can be recolored if necessary
|
||
|
m_hInstImageWell = hInstImageWell;
|
||
|
m_hRsrcImageWell = hRsrcImageWell;
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// CToolBarEx message handlers
|
||
|
|