The DrawBitmap Function

BitBlt becomes most valuable in working with bitmaps that have been selected into a memory device context. When you perform a ”bit-block transfer“ from the memory device context to a device context for your client area, the bitmap selected in the memory device context is transferred to your client area.

Earlier I mentioned a hypothetical DrawBitmap function that would draw a bitmap on a display surface. Such a function would have the syntax:

DrawBitmap (hdc, hBitmap, xStart, yStart) ;

I promised we'd write a DrawBitmap function; here it is:

void DrawBitmap (HDC hdc, HBITMAP hBitmap,

short xStart, short yStart)

{

BITMAP bm ;

HDC hdcMem ;

DWORD dwSize ;

POINT ptSize, ptOrg ;

hdcMem = CreateCompatibleDC (hdc) ;

SelectObject (hdcMem, hBitmap) ;

SetMapMode (hdcMem, GetMapMode (hdc)) ;

GetObject (hBitmap, sizeof (BITMAP), (LPSTR) &bm) ;

ptSize.x = bm.bmWidth ;

ptSize.y = bm.bmHeight ;

DPtoLP (hdc, &ptSize, 1) ;

ptOrg.x = 0 ;

ptOrg.y = 0 ;

DPtoLP (hdcMem, &ptOrg, 1) ;

BitBlt (hdc, xStart, yStart, ptSize.x, ptSize.y,

hdcMem, ptOrg.x, ptOrg.y, SRCCOPY) ;

DeleteDC (hdcMem) ;

}

I'm assuming here that you don't want the height or width of the bitmap stretched or compressed in any way. That is, if your bitmap is 100 pixels wide, you want it to cover a 100-pixel-wide rectangle of your client area regardless of the mapping mode.

DrawBitmap first creates a memory device context using CreateCompatibleDC and then selects the bitmap into it with SelectObject. The mapping mode of the memory device context is set to the same mapping mode as the video device context. Because BitBlt works with logical coordinates and logical sizes and you don't want the bitmap stretched or compressed, the xWidth and yHeight parameters to BitBlt must be logical units that correspond to the physical pixel size of the bitmap. For this reason, DrawBitmap gets the dimensions of the bitmap using GetObject and makes a POINT structure out of the width and height. It then converts this point to logical coordinates. This is done similarly for the origin of the bitmap—the point (0, 0) in device coordinates.

Note that it doesn't matter what brush is currently selected in the destination device context (hdc), because SRCCOPY doesn't use the brush.