It has been a while since I worked on this, so what I am describing is what I did, and not necessarily a direct answer to the question.
I happen to use bit maps 13 x 13 rather than 12 x 12. The bitmap part of the check box seems to be passed in the WM_DRAWITEM. However, I had also set up WM_MEASUREITEM and fed it the same values, so my answer may well be "Begging the question" in the correct philosophical sense.
case WM_MEASUREITEM:
lpmis = (LPMEASUREITEMSTRUCT) lParam;
lpmis->itemHeight = 13;
lpmis->itemWidth = 13;
break;
case WM_DRAWITEM:
lpdis = (LPDRAWITEMSTRUCT) lParam;
hdcMem = CreateCompatibleDC(lpdis->hDC);
if (lpdis->itemState & ODS_CHECKED) // if selected
{
SelectObject(hdcMem, hbmChecked);
}
else
{
if (lpdis->itemState & ODS_GRAYED)
{
SelectObject(hdcMem, hbmDefault);
}
else
{
SelectObject(hdcMem, hbmUnChecked);
}
}
StretchBlt(
lpdis->hDC, // destination DC
lpdis->rcItem.left, // x upper left
lpdis->rcItem.top, // y upper left
// The next two lines specify the width and
// height.
lpdis->rcItem.right - lpdis->rcItem.left,
lpdis->rcItem.bottom - lpdis->rcItem.top,
hdcMem, // source device context
0, 0, // x and y upper left
13, // source bitmap width
13, // source bitmap height
SRCCOPY); // raster operation
DeleteDC(hdcMem);
return TRUE;
This seems to work well for both Win2000 and XP, though I have nbo idea what Vista might do.
It might be worth an experiment to see what leaving out WM_MEASUREITEM does, though I usually discover with old code that I usually had perfectly good reason for doing something that looks redundant.