{"id":34743,"date":"2005-08-02T10:00:13","date_gmt":"2005-08-02T10:00:13","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2005\/08\/02\/rendering-menu-glyphs-is-slightly-trickier\/"},"modified":"2005-08-02T10:00:13","modified_gmt":"2005-08-02T10:00:13","slug":"rendering-menu-glyphs-is-slightly-trickier","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20050802-13\/?p=34743","title":{"rendered":"Rendering menu glyphs is slightly trickier"},"content":{"rendered":"<p><P>\n<A HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2005\/08\/01\/445998.aspx\">\nLast time, we saw how to draw themed and unthemed radio buttons<\/A>,\nand I mentioned that menu glyphs are trickier.\nThey&#8217;re trickier because they are provided as raw monochrome bitmaps\ninstead of fully-formed color-coordinated bitmaps.\nFirst, let&#8217;s do it wrong in order to see what we get.\nThen we&#8217;ll try to fix it.\nStart with a clean\n<A HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2005\/04\/22\/410773.aspx\">\nnew scratch program<\/A>\n<\/P>\n<PRE>\nclass RootWindow : public Window\n{\n &#8230;\nprotected:\n <FONT COLOR=\"blue\">void PaintContent(PAINTSTRUCT *pps);\n BOOL WinRegisterClass(WNDCLASS *pwc)\n {\n  pwc-&gt;hbrBackground = (HBRUSH)(COLOR_MENU + 1);\n  return __super::WinRegisterClass(pwc);\n }<\/FONT>\n &#8230;\n};<\/p>\n<p><FONT COLOR=\"blue\">void RootWindow::PaintContent(PAINTSTRUCT *pps)\n{\n int cxCheck = GetSystemMetrics(SM_CXMENUCHECK);\n int cyCheck = GetSystemMetrics(SM_CYMENUCHECK);\n RECT rc = { 0, 0, cxCheck, cyCheck };\n DrawFrameControl(pps-&gt;hdc, &amp;rc, DFC_MENU, DFCS_MENUCHECK);\n}<\/FONT>\n<\/PRE>\n<P>\nThis na&iuml;vely uses\n<A HREF=\"http:\/\/msdn.microsoft.com\/library\/en-us\/gdi\/pantdraw_4b3g.asp\">\nthe <CODE>DrawFrameControl<\/CODE> function<\/A>\nto draw the menu check mark directly into the paint DC.\nIf you are running with the default Windows&nbsp;XP theme you\nprobably won&#8217;t notice anything amiss, but switch to the Windows Classic\ntheme and you&#8217;ll see that the check mark is drawn in black and white\neven though the Classic menu background color is gray.\n<\/P>\n<P>\nThe reason for this is called out in the documentation for\n<CODE>DrawFrameControl<\/CODE>:\n<\/P>\n<BLOCKQUOTE CLASS=\"q\">\nIf uType is either DFC_MENU or DFC_BUTTON and uState is not DFCS_BUTTONPUSH,\nthe frame control is a black-on-white mask\n(that is, a black frame control on a white background).\n<\/BLOCKQUOTE>\n<P>\nAll we get from <CODE>DrawFrameControl<\/CODE> is a monochrome mask.\nIt is our responsibility to colorize it as necessary.\nTo do this, we draw the mask into a monochrome bitmap, and then\nuse\n<A HREF=\"http:\/\/msdn.microsoft.com\/library\/en-us\/gdi\/bitmaps_0fzo.asp\">\nthe <CODE>BitBlt<\/CODE> function<\/A>\nto colorize it.\nRecall that when blitting from a monochrome bitmap to a color bitmap,\nthe color black in the source bitmap\nbecomes the destination DC&#8217;s text color,\nand the color white in the source bitmap\nbecomes the destination DC&#8217;s background color.\n<\/P>\n<PRE>\nvoid RootWindow::PaintContent(PAINTSTRUCT *pps)\n{\n <FONT COLOR=\"blue\">HDC hdcMem = CreateCompatibleDC(pps-&gt;hdc);\n if (hdcMem) {<\/FONT>\n  int cxCheck = GetSystemMetrics(SM_CXMENUCHECK);\n  int cyCheck = GetSystemMetrics(SM_CYMENUCHECK);\n  <FONT COLOR=\"blue\">HBITMAP hbmMono = CreateBitmap(cxCheck, cyCheck, 1, 1, NULL);\n  if (hbmMono) {\n   HBITMAP hbmPrev = SelectBitmap(hdcMem, hbmMono);\n   if (hbmPrev) {<\/FONT>\n    RECT rc = { 0, 0, cxCheck, cyCheck };\n    DrawFrameControl(<FONT COLOR=\"blue\">hdcMem<\/FONT>, &amp;rc, DFC_MENU, DFCS_MENUCHECK);\n    <FONT COLOR=\"blue\">COLORREF clrTextPrev = SetTextColor(pps-&gt;hdc,\n                                     GetSysColor(COLOR_MENUTEXT));\n    COLORREF clrBkPrev = SetBkColor(pps-&gt;hdc,\n                                         GetSysColor(COLOR_MENU));\n    BitBlt(pps-&gt;hdc, 0, 0, cxCheck, cyCheck,\n           hdcMem, 0, 0, SRCCOPY);\n    SetBkColor(pps-&gt;hdc, clrBkPrev);\n    SetTextColor(pps-&gt;hdc, clrTextPrev);\n    SelectBitmap(hdcMem, hbmPrev);\n   }\n   DeleteObject(hbmMono);\n  }\n  DeleteDC(hdcMem);\n }<\/FONT>\n}\n<\/PRE>\n<P>\nThe key steps here are\n(1)&nbsp;drawing into a temporary monochrome bitmap to generate the mask,\n(2)&nbsp;setting the text and background colors of the destination DC,\n(3)&nbsp;using <CODE>BitBlt<\/CODE> to do the color mapping.\nThe rest of the function is just boring bookkeeping.\n<\/P>\n<P>\nObserve that the checkmark&#8217;s colors now match the system menu colors\nbecause we set them as the text and background colors for the\nmono-to-color blit.\n<\/P>\n<P>\nArmed with this knowledge,\n<A HREF=\"http:\/\/groups-beta.google.com\/group\/comp.os.ms-windows.programmer.win32\/msg\/8e548d08f7261932\">\nperhaps you can help this person<\/A>,\nwho is trying to draw the menu check marks transparently.\nI can think of two different solutions off the top of my head.\n<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Last time, we saw how to draw themed and unthemed radio buttons, and I mentioned that menu glyphs are trickier. They&#8217;re trickier because they are provided as raw monochrome bitmaps instead of fully-formed color-coordinated bitmaps. First, let&#8217;s do it wrong in order to see what we get. Then we&#8217;ll try to fix it. Start with [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-34743","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Last time, we saw how to draw themed and unthemed radio buttons, and I mentioned that menu glyphs are trickier. They&#8217;re trickier because they are provided as raw monochrome bitmaps instead of fully-formed color-coordinated bitmaps. First, let&#8217;s do it wrong in order to see what we get. Then we&#8217;ll try to fix it. Start with [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/34743","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=34743"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/34743\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=34743"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=34743"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=34743"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}