{"id":14313,"date":"2010-04-16T07:00:00","date_gmt":"2010-04-16T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2010\/04\/16\/the-mysterious-stock-bitmap-theres-no-way-to-summon-it-but-it-shows-up-in-various-places\/"},"modified":"2010-04-16T07:00:00","modified_gmt":"2010-04-16T07:00:00","slug":"the-mysterious-stock-bitmap-theres-no-way-to-summon-it-but-it-shows-up-in-various-places","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20100416-00\/?p=14313","title":{"rendered":"The mysterious stock bitmap: There&#039;s no way to summon it, but it shows up in various places"},"content":{"rendered":"<p>\nA number of stock GDI objects are made available by the\n<code>Get&shy;Stock&shy;Object<\/code> function, but one stock GDI object\nthat is mysteriously missing is the stock bitmap.\nYou can&#8217;t summon the stock bitmap, but it manages to show up in\nvarious places,\nsome of them perhaps unexpected.\n<\/p>\n<p>\nThe stock bitmap is a monochrome 1&times;1 bitmap which GDI uses\nin various places where it has to produce a <code>HBITMAP<\/code>\neven though there really isn&#8217;t any bitmap worth speaking of.\nIn other words, it&#8217;s used when GDI has to return <i>something<\/i>\nbut would rather return <i>nothing<\/i>.\n<\/p>\n<ul>\n<li>When you create a memory DC, the current bitmap selected into it\n    is the stock bitmap.<\/p>\n<li>When you create a metafile, the current bitmap is the stock bitmap.\n<\/ul>\n<p>\nEvery DC and metafile has a current bitmap (which you can retrieve\nwith <code>Get&shy;Current&shy;Object<\/code>), but when GDI creates a brand\nnew DC or metafile, it doesn&#8217;t know what bitmap the program is\ngoing to pass to <code>Select&shy;Object<\/code>&mdash;after all,\npredicting the future has yet to be perfected.\nAs a placeholder, it sticks in the dummy static bitmap.\n<\/p>\n<p>\nThere has to be a bitmap (as opposed to just leaving it <code>NULL<\/code>),\nbecause the <code>Select&shy;Object<\/code> function returns the previous\nobject or <code>NULL<\/code> on failure,\nso there needs to be a way to tell the difference between\n&#8220;I wasn&#8217;t able to select the bitmap you requested&#8221;\nand\n&#8220;I was able to select the bitmap you requested, but there was no\nold bitmap.&#8221;\nReturning <code>NULL<\/code> would also break the common coding pattern:\n<\/p>\n<pre>\n\/\/ select the new bitmap and save the old one\nHBITMAP hbmPrev = SelectObject(hdc, hbmNew);\n    ... do something with hdc ...\n\/\/ all done - restore the original bitmap\nSelectObject(hdc, hbmPrev);\n<\/pre>\n<p>\nIf <code>Select&shy;Object<\/code> had returned <code>NULL<\/code>\nwhen there was no bitmap previously selected into the DC,\nthen the attempt to restore the original bitmap would fail.\n(Because GDI can&#8217;t tell whether you passed it a\n<code>(HBITMAP)NULL<\/code> or a\n<code>(HBRUSH)NULL<\/code> or a\n<code>(HPEN)NULL<\/code> or&#8230;)\n<\/p>\n<p>\nNormally, a single bitmap cannot be selected into more than one DC,\nbut the stock bitmap has the magical power that\nit can be selected into multiple DCs at once.\nWithout this magical power, GDI would have to create a different\ndummy bitmap to select into each newly-created DC and carry it\naround so that it can be selected back into the DC just before it\nis destroyed.\nSeems awful wasteful to allocate an extra bitmap per DC just for\nthis,\nespecially back in the days of 16-bit Windows when GDI heap space\nwas extremely limited.\n<\/p>\n<p>\nThere is one more place (that comes to mind) where the stock\nbitmap appears, and it&#8217;s somewhat unexpected:\n<\/p>\n<ul>\n<li>When you try to create a 0&times;<i>y<\/i> or a\n    <i>x<\/i>&times;0 bitmap with the <code>Create&shy;Bitmap<\/code>\n    or <code>Create&shy;Compatible&shy;Bitmap<\/code> function\n    you get the stock bitmap back.\n<\/ul>\n<p>\nIn other words, if you ask for a nothing-bitmap,\nyou get the dummy bitmap back.\nThis is analogous to the case of calling <code>malloc(0)<\/code>,\nwhere the implementation is permitted to return a pointer to zero bytes.\nIn other words, <code>malloc(0)<\/code>\ncan return a non-<code>NULL<\/code> value which\nyou can&#8217;t dereference; the only things you can do with it is\n<code>free()<\/code> it or <code>realloc()<\/code> it to something bigger.\nIn the same way that allowing zero-byte allocations simplifies boundary cases\nof certain algorithms,\nallowing impossibly thin bitmaps (and returning a dummy handle)\nmay simplify certain graphical algorithms.\n<\/p>\n<p>\nNote however that this behavior of returning the stock bitmap handle\nwhen asked to create an impossibly thin bitmap\n<i>does not apply to the <code>Create&shy;DIB&shy;Section<\/code> function<\/i>!\nIf you ask <code>Create&shy;DIB&shy;Section<\/code> for an impossibly thin\nbitmap, it returns <code>NULL<\/code>.\nSo much for consistency.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A number of stock GDI objects are made available by the Get&shy;Stock&shy;Object function, but one stock GDI object that is mysteriously missing is the stock bitmap. You can&#8217;t summon the stock bitmap, but it manages to show up in various places, some of them perhaps unexpected. The stock bitmap is a monochrome 1&times;1 bitmap which [&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-14313","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>A number of stock GDI objects are made available by the Get&shy;Stock&shy;Object function, but one stock GDI object that is mysteriously missing is the stock bitmap. You can&#8217;t summon the stock bitmap, but it manages to show up in various places, some of them perhaps unexpected. The stock bitmap is a monochrome 1&times;1 bitmap which [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/14313","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=14313"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/14313\/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=14313"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=14313"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=14313"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}