/*++ Copyright (C) 1997-2001 Microsoft Corporation Module Name: Abstract: History: --*/ // ToolBarEx.cpp : implementation file // #include "stdafx.h" #include "wmitest.h" #include "ToolBarEx.h" #include #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