For a monochrome bitmap, the format of the bits is relatively simple and can almost be derived directly from the image you want to create. For instance, suppose you want to create a bitmap that looks like this:
You can write down a series of bits (0 for black and 1 for white) that directly corresponds to this grid. Reading these bits from left to right, you can then assign each group of 8 bits a hexadecimal byte. If the width of the bitmap is not a multiple of 16, pad the bytes to the right with zeros to get an even number of bytes:
0 1 0 1 0 0 0 1 0 1 1 1 0 1 1 1 0 0 0 1 = 51 77 10 00
0 1 0 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 0 1 = 57 77 50 00
0 0 0 1 0 0 0 1 0 1 1 1 0 1 1 1 0 1 0 1 = 11 77 50 00
0 1 0 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 0 1 = 57 77 50 00
0 1 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 = 51 11 10 00
The width in pixels is 20, the height in scan lines is 5, and the width in bytes is 4. You can set up a BITMAP structure for this bitmap with the following statement:
static BITMAP bitmap = { 0, 20, 5, 4, 1, 1 } ;
and you can store the bits in a BYTE array:
static BYTE byBits [] = { 0x51, 0x77, 0x10, 0x00,
0x57, 0x77, 0x50, 0x00,
0x11, 0x77, 0x50, 0x00,
0x57, 0x77, 0x50, 0x00,
0x51, 0x11, 0x10, 0x00 } ;
Creating the bitmap with CreateBitmapIndirect requires two statements:
bitmap.bmBits = (LPSTR) byBits ;
hBitmap = CreateBitmapIndirect (&bitmap) ;
Be careful when working with the pointer to byBits. It's OK to call CreateBitmapIndirect right after you assign the far address to the bmBits field, but this field can become invalid if Windows moves your local data segment.
You may prefer the following statements, which avoid this problem
hBitmap = CreateBitmapIndirect (&bitmap) ;
SetBitmapBits (hBitmap, (DWORD) sizeof byBits, byBits) ;
You can also avoid using the bitmap structure entirely and create the bitmap in one statement:
hBitmap = CreateBitmap (20, 5, 1, 1, byBits) ;