{"id":35843,"date":"2005-04-20T09:04:28","date_gmt":"2005-04-20T09:04:28","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2005\/04\/20\/what-is-the-dc-brush-good-for\/"},"modified":"2005-04-20T09:04:28","modified_gmt":"2005-04-20T09:04:28","slug":"what-is-the-dc-brush-good-for","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20050420-28\/?p=35843","title":{"rendered":"What is the DC brush good for?"},"content":{"rendered":"<p>\n<a HREF=\"http:\/\/msdn.microsoft.com\/library\/en-us\/gdi\/devcons_1vl1.asp\">\nThe DC brush<\/a>\n<code>GetStockObject(DC_BRUSH)<\/code>\nis a stock brush associated with the device context.\nLike\n<a HREF=\"http:\/\/msdn.microsoft.com\/library\/en-us\/gdi\/brushes_1mlk.asp\">\nthe system color brushes<\/a>,\nthe color of the DC brush changes dynamically,\nbut whereas the system color brushes change color based\non the system colors, the color of the DC brush changes at your command.\n<\/p>\n<p>\nThe DC brush is handy when you need a solid color brush for\na very short time, since it always exists and doesn&#8217;t need to be\ncreated or destroyed.  Normally, you have to create a solid color brush,\ndraw with it, then destroy it.  With the DC brush, you set its color and\nstart drawing.\nBut it works only for a short time, because the moment somebody else\ncalls\n<a HREF=\"http:\/\/msdn.microsoft.com\/library\/en-us\/gdi\/devcons_0gj6.asp\">\nthe <code>SetDCBrushColor<\/code> function<\/a>\non your DC, the DC brush color will be overwritten.\nIn practice, this means that the DC brush color is not trustworthy\nonce you relinquish control to other code.\n(Note, however, that each DC has its own DC brush color,\nso you need only worry about somebody on another thread messing with\nyour DC simultaneously, which doesn&#8217;t happen under any of the painting models\nI am familiar with.)\n<\/p>\n<p>\nThe DC brush is amazingly useful when handling\n<a HREF=\"http:\/\/msdn.microsoft.com\/library\/en-us\/devnotes\/winprog\/wm_ctlcolor_.asp\">\nthe various WM_CTLCOLOR messages<\/a>.\nThese messages require you to return a brush that will be used\nto draw the control background.\nIf you need a solid color brush, this usually means creating the\nsolid color brush and caching it for the lifetime of the window,\nthen destroying it when the window is destroyed.\n(<a HREF=\"http:\/\/groups.google.com\/groups?selm=388C1662.71CE6F75@sirma.bg\">Some people cache the brush in a static variable<\/a>, which works great\nuntil somebody creates two copies of the dialog\/window.\nThen you get a big mess.)\n<\/p>\n<p>\nLet&#8217;s use the DC brush to customize the colors of a static control.\nThe program is not interesting as a program; it&#8217;s just an illustration\nof one way you can use the DC brush.\n<\/p>\n<p>\nStart, as always, with our\n<a HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2003\/07\/23\/54576.aspx\">\nscratch program<\/a>, and making the following changes.\n<\/p>\n<pre>\nBOOL\nOnCreate(HWND hwnd, LPCREATESTRUCT lpcs)\n{\n  <font COLOR=\"blue\">g_hwndChild = CreateWindow(TEXT(\"static\"), NULL,\n        WS_VISIBLE | WS_CHILD, 0, 0, 0, 0,\n        hwnd, NULL, g_hinst, 0);\n if (!g_hwndChild) return FALSE;<\/font>\n return TRUE;\n}\n<font COLOR=\"blue\">HBRUSH OnCtlColor(HWND hwnd, HDC hdc, HWND hwndChild, int type)\n{\n  FORWARD_WM_CTLCOLORSTATIC(hwnd, hdc, hwndChild, DefWindowProc);\n  SetDCBrushColor(hdc, RGB(255,0,0));\n  return GetStockBrush(DC_BRUSH);\n}\n    HANDLE_MSG(hwnd, WM_CTLCOLORSTATIC, OnCtlColor);<\/font>\n<\/pre>\n<p>\nRun this program and observe that we changed the background color\nof the static window to red.\n<\/p>\n<p>\nThe work happens inside the <code>OnCtlColor<\/code> function.\nWhen asked to customize the colors, we first forward the message\nto\n<a HREF=\"http:\/\/msdn.microsoft.com\/library\/en-us\/winui\/winui\/windowsuserinterface\/windowing\/windowprocedures\/windowprocedurereference\/windowprocedurefunctions\/defwindowproc.asp\">\nthe <code>DefWindowProc<\/code> function<\/a>\nso that the default foreground and background text colors are set.\n(Not relevant here since we draw no text, but a good thing to do\non principle.)\nSince we want to override the background brush color,\nwe set the DC brush color to red and then return the DC brush\nas our desired background brush.\n<\/p>\n<p>\nThe static control then takes the brush we returned (the DC brush)\nand uses it to draw the background, which draws in red because\nthat&#8217;s the color we set it to.\n<\/p>\n<p>\nNormally, when customizing the background brush, we have to create\na brush, return it from the WM_CTLCOLORSTATIC message, then destroy\nit when the parent window is destroyed.\nBut by using the DC brush, we avoided having to do all that bookkeeping.\n<\/p>\n<p>\nThere is also a DC pen <code>GetStockObject(DC_PEN)<\/code> which behaves\nin an entirely analogous manner.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The DC brush GetStockObject(DC_BRUSH) is a stock brush associated with the device context. Like the system color brushes, the color of the DC brush changes dynamically, but whereas the system color brushes change color based on the system colors, the color of the DC brush changes at your command. The DC brush is handy when [&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-35843","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>The DC brush GetStockObject(DC_BRUSH) is a stock brush associated with the device context. Like the system color brushes, the color of the DC brush changes dynamically, but whereas the system color brushes change color based on the system colors, the color of the DC brush changes at your command. The DC brush is handy when [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/35843","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=35843"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/35843\/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=35843"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=35843"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=35843"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}