{"id":28513,"date":"2007-01-04T07:00:00","date_gmt":"2007-01-04T15:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2007\/01\/04\/how-a-bullet-turns-into-a-beep\/"},"modified":"2007-01-04T07:00:00","modified_gmt":"2007-01-04T15:00:00","slug":"how-a-bullet-turns-into-a-beep","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20070104-00\/?p=28513","title":{"rendered":"How a bullet turns into a beep"},"content":{"rendered":"<p>\nHere&#8217;s a minor mystery:\n<\/p>\n<pre>\necho &#x2022;\n<\/pre>\n<p><p>\nThat last character is\n<a HREF=\"http:\/\/www.fileformat.info\/info\/unicode\/char\/2022\/index.htm\">U+2022<\/a>.\nSelect that line with the mouse,\nright-click, and select Copy to copy it to the clipboard.\nNow go to a command prompt and paste it and hit Enter.\n<\/p>\n<p>\nYou&#8217;d expect a &#x2022; to be printed, but instead you get a beep.\nWhat happened?\n<\/p>\n<p>\nHere&#8217;s another clue.\nRun this program.\n<\/p>\n<pre>\nclass Mystery {\n public static void Main() {\n  System.Console.WriteLine(\"\\x2022\");\n }\n}\n<\/pre>\n<p>\nHm, there&#8217;s that beep again.\nHow about this program:\n<\/p>\n<pre>\n#include &lt;stdio.h&gt;\n#include &lt;windows.h&gt;\nint __cdecl main(int argc, char **argv)\n{\n char ch;\n if (WideCharToMultiByte(CP_OEMCP, 0, L\"\\x2022\", 1,\n                         &amp;ch,  1, NULL, NULL) == 1) {\n  printf(\"%d\\n\", ch);\n }\n return 0;\n}\n<\/pre>\n<p>\nRun this program and it prints &#8220;7&#8221;.\n<\/p>\n<p>\nBy now you should have figured out what&#8217;s going on.\nIn the OEM code page,\nthe bullet character is being converted to a beep.\nBut why is that?\n<\/p>\n<p>\nWhat you&#8217;re seeing is\n<code>MB_USEGLYPHCHARS<\/code> in reverse.\n<a HREF=\"http:\/\/web.archive.org\/web\/20070326221749\/blogs.msdn.com\/michkap\/archive\/2005\/02\/26\/381020.aspx\">\nMichael Kaplan discussed <code>MB_USEGLYPHCHARS<\/code> a while ago<\/a>.\nIt determines whether certain characters should be treated as\ncontrol characters or as printable characters when converting to\nUnicode.\nFor example, it controls whether\nthe ASCII bell character 0x07 should be converted\nto the Unicode bell character U+0007 or to the Unicode bullet U+2022.\nYou need the <code>MB_USEGLYPHCHARS<\/code> flag to decide which way to\ngo when converting <strong>to<\/strong> Unicode, but there is no\ncorresponding ambiguity when converting <strong>from<\/strong> Unicode.\nWhen converting\n<strong>from<\/strong> Unicode, both U+0007 and\nU+2022 map to the ASCII bell character.\n<\/p>\n<p>\n&#8220;But converting a bullet to 0x07 is clearly wrong.\nI mean, who expects a printable character to turn into a control character?&#8221;\n<\/p>\n<p>\nWell, you&#8217;re assuming that the code who does the conversion is going\nto interpret it as a control character.\nThe code might treat it as a glyph character, like this:\n<\/p>\n<pre>\n\/\/ starting with <a HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2003\/07\/23\/54576.aspx\">the scratch program<\/a>\nvoid\nPaintContent(HWND hwnd, PAINTSTRUCT *pps)\n{\n HFONT hfPrev = SelectFont(pps-&gt;hdc, GetStockFont(OEM_FIXED_FONT));\n TextOut(pps-&gt;hdc, 0, 0, \"\\x07\", 1);\n SelectFont(pps-&gt;hdc, hfPrev);\n}\n<\/pre>\n<p>\nRun this program and you get a happy bullet in the corner of the\nwindow.\nThe <code>TextOut<\/code> function does not interpret control\ncharacters as control characters;\nit interprets them as glyphs.\n<\/p>\n<p>\nThe <code>WideCharToMultiByte<\/code> function doesn&#8217;t know what\nyou&#8217;re going to do with the string it produces.\nIt converts the character and leaves you to decide what to do next.\nThere doesn&#8217;t appear to be a <code>WC_DONTUSEGLYPHCHARS<\/code> flag,\nso you&#8217;re going to get glyph characters whether you like it or not.\n<\/p>\n<p>\n(Postscript: You can see this happening in reverse from the\ncommand prompt.\nThen again, since this problem is itself a reversal, I guess\nyou could say the behavior is happening in the forward direction now&#8230;\nType <code>echo ^A<\/code> where you actually type Ctrl+A where I\nwrote <code>^A<\/code>. The result: A smiling face,\n<font FACE=\"Courier New\">&#x263A;<\/font>\n<a HREF=\"http:\/\/www.fileformat.info\/info\/unicode\/char\/263a\/index.htm\">\nU+263A<\/a>.)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Bangs or bells.<\/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":[26],"class_list":["post-28513","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-other"],"acf":[],"blog_post_summary":"<p>Bangs or bells.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/28513","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=28513"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/28513\/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=28513"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=28513"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=28513"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}