|
|
#include "ctlspriv.h"
//
// include HEX forms of some standard bitmaps
//
#include "toolbar.hex"
#include "thumb.hex"
// these are the default colors used to map the dib colors
// to the current system colors
#define RGB_BUTTONTEXT (RGB(000,000,000)) // black
#define RGB_BUTTONSHADOW (RGB(128,128,128)) // dark grey
#define RGB_BUTTONFACE (RGB(192,192,192)) // bright grey
#define RGB_BUTTONHILIGHT (RGB(255,255,255)) // white
#define RGB_BACKGROUNDSEL (RGB(000,000,255)) // blue
#define RGB_BACKGROUND (RGB(255,000,255)) // magenta
#define FlipColor(rgb) (RGB(GetBValue(rgb), GetGValue(rgb), GetRValue(rgb)))
#define MAX_COLOR_MAPS 16
HBITMAP WINAPI CreateMappedDib(LPBITMAPINFOHEADER lpBitmapInfo, WORD wFlags, LPCOLORMAP lpColorMap, int iNumMaps) { HDC hdc, hdcMem = NULL; DWORD FAR *p; DWORD FAR *lpTable; LPBYTE lpBits; HBITMAP hbm = NULL, hbmOld; int numcolors, i; int wid, hgt; DWORD rgbMaskTable[16]; DWORD rgbSave[16]; DWORD rgbBackground; static const COLORMAP SysColorMap[] = { {RGB_BUTTONTEXT, COLOR_BTNTEXT}, // black
{RGB_BUTTONSHADOW, COLOR_BTNSHADOW}, // dark grey
{RGB_BUTTONFACE, COLOR_BTNFACE}, // bright grey
{RGB_BUTTONHILIGHT, COLOR_BTNHIGHLIGHT},// white
{RGB_BACKGROUNDSEL, COLOR_HIGHLIGHT}, // blue
{RGB_BACKGROUND, COLOR_WINDOW} // magenta
}; #define NUM_DEFAULT_MAPS (sizeof(SysColorMap)/sizeof(COLORMAP))
COLORMAP DefaultColorMap[NUM_DEFAULT_MAPS]; COLORMAP DIBColorMap[MAX_COLOR_MAPS];
if (!lpBitmapInfo) return NULL;
hmemcpy(rgbSave, lpBitmapInfo+1, 16 * sizeof(RGBQUAD));
/* Get system colors for the default color map */ if (!lpColorMap) { lpColorMap = DefaultColorMap; iNumMaps = NUM_DEFAULT_MAPS; for (i=0; i < iNumMaps; i++) { lpColorMap[i].from = SysColorMap[i].from; lpColorMap[i].to = GetSysColor((int)SysColorMap[i].to); } }
/* Transform RGB color map to a BGR DIB format color map */ if (iNumMaps > MAX_COLOR_MAPS) iNumMaps = MAX_COLOR_MAPS; for (i=0; i < iNumMaps; i++) { DIBColorMap[i].to = FlipColor(lpColorMap[i].to); DIBColorMap[i].from = FlipColor(lpColorMap[i].from); }
lpTable = p = (DWORD FAR *)((LPBYTE)lpBitmapInfo + (int)lpBitmapInfo->biSize);
/* Replace button-face and button-shadow colors with the current values
*/ numcolors = 16;
// if we are creating a mask, build a color table with white
// marking the transparent section (where it used to be background)
// and black marking the opaque section (everything else). this
// table is used below to build the mask using the original DIB bits.
if (wFlags & CMB_MASKED) { rgbBackground = FlipColor(RGB_BACKGROUND); for (i = 0; i < 16; i++) { if (p[i] == rgbBackground) rgbMaskTable[i] = 0xFFFFFF; // transparent section
else rgbMaskTable[i] = 0x000000; // opaque section
} }
while (numcolors-- > 0) { for (i = 0; i < iNumMaps; i++) { if (*p == DIBColorMap[i].from) { *p = DIBColorMap[i].to; break; } } p++; }
/* First skip over the header structure */ lpBits = (LPVOID)((LPBYTE)lpBitmapInfo + (int)lpBitmapInfo->biSize);
/* Skip the color table entries, if any */ lpBits += (1 << (lpBitmapInfo->biBitCount)) * sizeof(RGBQUAD);
/* Create a color bitmap compatible with the display device */ i = wid = (int)lpBitmapInfo->biWidth; hgt = (int)lpBitmapInfo->biHeight; hdc = GetDC(NULL); hdcMem = CreateCompatibleDC(hdc); if (!hdcMem) goto cleanup; // if creating a mask, the bitmap needs to be twice as wide.
if (wFlags & CMB_MASKED) i = wid*2;
if (wFlags & CMB_DISCARDABLE) hbm = CreateDiscardableBitmap(hdc, i, hgt); else hbm = CreateCompatibleBitmap(hdc, i, hgt); if (hbm) { hbmOld = SelectObject(hdcMem, hbm);
// set the main image
StretchDIBits(hdcMem, 0, 0, wid, hgt, 0, 0, wid, hgt, lpBits, (LPBITMAPINFO)lpBitmapInfo, DIB_RGB_COLORS, SRCCOPY);
// if building a mask, replace the DIB's color table with the
// mask's black/white table and set the bits. in order to
// complete the masked effect, the actual image needs to be
// modified so that it has the color black in all sections
// that are to be transparent.
if (wFlags & CMB_MASKED) { hmemcpy(lpTable, (DWORD FAR *)rgbMaskTable, 16 * sizeof(RGBQUAD)); StretchDIBits(hdcMem, wid, 0, wid, hgt, 0, 0, wid, hgt, lpBits, (LPBITMAPINFO)lpBitmapInfo, DIB_RGB_COLORS, SRCCOPY); BitBlt(hdcMem, 0, 0, wid, hgt, hdcMem, wid, 0, 0x00220326); // DSna
} SelectObject(hdcMem, hbmOld); }
cleanup: if (hdcMem) DeleteObject(hdcMem); ReleaseDC(NULL, hdc);
hmemcpy(lpBitmapInfo+1, rgbSave, 16 * sizeof(RGBQUAD)); return hbm; }
HBITMAP WINAPI CreateMappedBitmap(HINSTANCE hInstance, int idBitmap, WORD wFlags, LPCOLORMAP lpColorMap, int iNumMaps) { HANDLE h; HANDLE hRes; HBITMAP hbm; LPBITMAPINFOHEADER lpbi;
h = FindResource(hInstance, MAKEINTRESOURCE(idBitmap), RT_BITMAP);
if (!h) { if (idBitmap == IDB_THUMB) lpbi = (LPVOID)Bitmap_Thumb; else lpbi = (LPVOID)Bitmap_Toolbar;
return CreateMappedDib(lpbi, wFlags, lpColorMap, iNumMaps); }
hRes = LoadResource(hInstance, h);
/* Lock the bitmap and get a pointer to the color table. */ lpbi = (LPBITMAPINFOHEADER)LockResource(hRes); if (!lpbi) return NULL;
hbm = CreateMappedDib(lpbi, wFlags, lpColorMap, iNumMaps);
UnlockResource(hRes); FreeResource(hRes);
return hbm; }
|