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