Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

185 lines
5.6 KiB

#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;
}