Code:
CustomBMPInfo.bmiColors = Palette;
This should not compile. The BITMAPINFO structure has the following definition:
Code:
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO, *PBITMAPINFO;
The bmiColors member is an array, and therefore can not be assigned to. BITMAPINFO consists of an BITMAPINFOHEADER followed by a variable sized array of palette entries. It is not a BITMAPINFOHEADER followed by a pointer to an array of palette entries, which your code attempts to create. Because the array may be of various sizes, it is defined with the placeholder size of 1, and the programmer is expected to allocate appropriate memory. This pattern is not uncommon in the Windows API.
I have modified your code to demonstrate:
Code:
#include <windows.h>
#include <stdio.h>
#if defined(_MSC_VER)
#pragma comment(lib, "gdi32.lib")
#endif
int main(void)
{
BITMAP CustomBMP;
HBITMAP hCustomBMP;
BYTE BitmapData[16];
BITMAPINFO* CustomBMPInfo;
RGBQUAD* Palette;
/* Allocate space for a BITMAPINFO structure followed by an array of RGBQUADs */
CustomBMPInfo = (BITMAPINFO*) malloc(sizeof(BITMAPINFO) + (sizeof(RGBQUAD) * 16));
/* TODO: check malloc. */
/* Convenience variable. We could use CustomBMPInfo->bmiColors directly. */
Palette = CustomBMPInfo->bmiColors;
Palette[0].rgbRed = 0;
Palette[0].rgbGreen = 0;
Palette[0].rgbBlue = 0;
Palette[1].rgbRed = 255;
Palette[1].rgbGreen = 0;
Palette[1].rgbBlue = 0;
Palette[2].rgbRed = 0;
Palette[2].rgbGreen = 255;
Palette[2].rgbBlue = 0;
Palette[3].rgbRed = 0;
Palette[3].rgbGreen = 0;
Palette[3].rgbBlue = 255;
Palette[4].rgbRed = 255;
Palette[4].rgbGreen = 255;
Palette[4].rgbBlue = 0;
Palette[5].rgbRed = 255;
Palette[5].rgbGreen = 0;
Palette[5].rgbBlue = 255;
Palette[6].rgbRed = 0;
Palette[6].rgbGreen = 255;
Palette[6].rgbBlue = 255;
Palette[7].rgbRed = 128;
Palette[7].rgbGreen = 0;
Palette[7].rgbBlue = 0;
Palette[8].rgbRed = 0;
Palette[8].rgbGreen = 128;
Palette[8].rgbBlue = 0;
Palette[9].rgbRed = 0;
Palette[9].rgbGreen = 0;
Palette[9].rgbBlue = 128;
Palette[10].rgbRed = 128;
Palette[10].rgbGreen = 128;
Palette[10].rgbBlue = 0;
Palette[11].rgbRed = 128;
Palette[11].rgbGreen = 0;
Palette[11].rgbBlue = 128;
Palette[12].rgbRed = 0;
Palette[12].rgbGreen = 128;
Palette[12].rgbBlue = 128;
Palette[13].rgbRed = 128;
Palette[13].rgbGreen = 128;
Palette[13].rgbBlue = 128;
Palette[14].rgbRed = 255;
Palette[14].rgbGreen = 255;
Palette[14].rgbBlue = 255;
Palette[15].rgbRed = 0;
Palette[15].rgbGreen = 0;
Palette[15].rgbBlue = 0;
BitmapData[0] = 0x01;
BitmapData[1] = 0x23;
BitmapData[2] = 0x45;
BitmapData[3] = 0x67;
BitmapData[4] = 0x89;
BitmapData[5] = 0xAB;
BitmapData[6] = 0xCD;
BitmapData[7] = 0xEF;
BitmapData[8] = 0x01;
BitmapData[9] = 0x23;
BitmapData[10] = 0x45;
BitmapData[11] = 0x67;
BitmapData[12] = 0x89;
BitmapData[13] = 0xAB;
BitmapData[14] = 0xCD;
BitmapData[15] = 0xEF;
CustomBMPInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
CustomBMPInfo->bmiHeader.biWidth = 16;
CustomBMPInfo->bmiHeader.biHeight = 2;
CustomBMPInfo->bmiHeader.biPlanes = 1;
CustomBMPInfo->bmiHeader.biBitCount = 4;
CustomBMPInfo->bmiHeader.biCompression = BI_RGB;
CustomBMPInfo->bmiHeader.biSizeImage = 0;
CustomBMPInfo->bmiHeader.biXPelsPerMeter = 0;
CustomBMPInfo->bmiHeader.biYPelsPerMeter = 0;
CustomBMPInfo->bmiHeader.biClrUsed = 16;
CustomBMPInfo->bmiHeader.biClrImportant = 0;
HDC hdc = GetDC(NULL);
hCustomBMP = CreateCompatibleBitmap(hdc,
CustomBMPInfo->bmiHeader.biWidth,
CustomBMPInfo->bmiHeader.biHeight);
GetObject(hCustomBMP, sizeof(CustomBMP), &CustomBMP);
SetDIBits(hdc, hCustomBMP, 0, CustomBMP.bmHeight, BitmapData, CustomBMPInfo, DIB_RGB_COLORS);
HDC hdcMem = CreateCompatibleDC(hdc);
HBITMAP hbmOld = (HBITMAP) SelectObject(hdcMem, hCustomBMP);
BitBlt(hdc, 0, 0, CustomBMP.bmWidth, CustomBMP.bmHeight, hdcMem, 0, 0, SRCCOPY);
SelectObject(hdcMem, hbmOld);
DeleteDC(hdcMem);
DeleteObject(hCustomBMP);
ReleaseDC(NULL, hdc);
getchar();
return 0;
}