While I do not use color swatches, and, strictly speaking, MFC, I am doing bitmap rendering in my derived menu items. You must be able to adapt the following to your needs.
When measuring element text, I use the dc desktop.
CClientDC dc(CWnd::GetDesktopWindow()); SIZE size; GetTextExtentPoint32(dc.m_hDC, buff, buff.GetLength(), &size ); lpMeasureItemStruct->itemWidth = size.cx+12; lpMeasureItemStruct->itemHeight = size.cy+8;
Along with some small adjustments through experiments, I came up with what I need for size.
To display the actual bitmap and text, I check if the theme is active and displays the menu item in one of two ways. Either as a thematic menu item, or a standard menu item. To make the text, I start with the rectangle that was passed through LPDRAWITEMSTRUCT. Then I do the following setup before rendering the text.
// adjust if non-themed. if (!IsThemeActive()) rectt.left+= m_bmWidth+4; else rectt.left+= BITMAP_ADJUSTMENT;
Through a trial version and an error, I found that BITMAP_ADJUSTMENT, equal to 30, works for me. Then, depending on the installed item (disabled, selected), the correction is corrected further.
// draw disabled text. if (disabled) { // draw selected text. if (selected) { pDC->SetTextColor(::GetSysColor(COLOR_GRAYTEXT)); pDC->DrawText(text, &rectt, format); } else { offset = rectt; offset.left+= 1; offset.right+=1; offset.top+= 1; offset.bottom+= 1; pDC->SetTextColor(::GetSysColor(COLOR_BTNHILIGHT)); pDC->DrawText(text, &offset, format); pDC->SetTextColor(::GetSysColor(COLOR_GRAYTEXT)); pDC->DrawText(text, &rectt, format); } } else // draw normal text. pDC->DrawText(text, &rectt, format);
Finally, to display the checkmark, I create a list of images using a predefined bitmap (maybe I extracted it from the Microsoft dll). Again, the bitmap is displayed according to the state of the item.
// draw non-disabled bitmap. if (!disabled) { bmp.GetBitmap(&bm); m_bmWidth = bm.bmWidth; imgList.Create(bm.bmWidth, bm.bmWidth, ILC_COLOR24|ILC_MASK, 1, 1); imgList.Add(&bmp, COLOR_BITMAP_BACKGROUND); if (checked) { if (!selected) imgList.DrawEx(pDC, 0, CPoint(4,rect.top+4), CSize(bm.bmWidth, bm.bmWidth), COLOR_NOT_SELECTED, 0, ILD_NORMAL); else imgList.DrawEx(pDC, 0, CPoint(4,rect.top+4), CSize(bm.bmWidth, bm.bmWidth), 0, COLOR_SELECTED, ILD_SELECTED); } else imgList.DrawEx(pDC, 0, CPoint(4,rect.top+4), CSize(bm.bmWidth, bm.bmWidth), 0, 0, ILD_TRANSPARENT); } else // draw a disabled bitmap. AfxDrawGrayBitmap(pDC, 4, rect.top+4, bmp, ::GetSysColor(COLOR_3DFACE));
Most of the rendering was done using an iterative approach that tuned straight objects after each attempt.