{"id":106021,"date":"2021-12-10T07:00:00","date_gmt":"2021-12-10T15:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=106021"},"modified":"2021-12-10T06:36:38","modified_gmt":"2021-12-10T14:36:38","slug":"20211210-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20211210-00\/?p=106021","title":{"rendered":"It&#8217;s okay to be contrary, but you need to be consistently contrary: Going against the ambient character set"},"content":{"rendered":"<p>In Windows, you declare your character set preference implicitly by defining or not defining the symbol <code>UNICODE<\/code> <a title=\"If you're going to configure a header file, you have to do it before you include the header file\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20211209-00\/?p=106017\"> before including the <code>windows.h<\/code> header file<\/a>. (Related: <a title=\"TEXT vs. _TEXT vs. _T, and UNICODE vs. _UNICODE\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20040212-00\/?p=40643\"> TEXT vs. _TEXT vs. _T, and UNICODE vs. _UNICODE<\/a>.) This determines whether undecorated function names redirect to the ANSI version or the Unicode version, but it doesn&#8217;t make the opposite-version inaccessible. You just have to call them by their explicit names. And it&#8217;s important that you be consistent about it. If you miss a spot, the characters get all messed up.<\/p>\n<pre>\/\/ UNICODE not defined\r\n#include &lt;windows.h&gt;\r\n\r\nvoid UpdateTitle(HWND hwnd, PCWSTR title)\r\n{\r\n    <span style=\"color: blue;\">SetWindowTextW<\/span>(hwnd, title);\r\n}\r\n<\/pre>\n<p>In the above example, we did not define the symbol <code>UNICODE<\/code>, so the ambient character set is ANSI. Since we want to call the Unicode version of <code>Set\u00adWindow\u00adText<\/code>, we must use its explicit Unicode name <code>Set\u00adWindow\u00adTextW<\/code>.<\/p>\n<p>Most of the time, these errors are detected at compile time due to type mismatches. For example, if we forgot to put the trailing <code>W<\/code> on the function name, we would get the error<\/p>\n<pre style=\"white-space: pre-wrap;\">error C2664: 'BOOL SetWindowTextA(HWND,const char *)': cannot convert argument 2 from 'const wchar_t *' to 'const char *'\r\nnote: Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast\r\n<\/pre>\n<p>And that&#8217;s your clue that you forgot to W-ize the <code>Set\u00adWindow\u00adText<\/code> call. You should have called the W version explicitly: <code>Set\u00adWindow\u00adTextW<\/code>.<\/p>\n<p>However, there&#8217;s a category of functions that elude this compile-time detection: The functions that have separate ANSI and Unicode versions but take only character-set-independent parameters. <a title=\"If the prototypes of DispatchMessageA and DispatchMessageW are identical, why have both?\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20181101-00\/?p=100105\"> Common examples<\/a> are <code>Dispatch\u00adMessage<\/code>, <code>Translate\u00adMessage<\/code>, <code>Translate\u00adAccelerator<\/code>, <code>Create\u00adAccelerator\u00adTable<\/code>, and most notably, <a title=\"Why am I getting mojibake when I try to create a window?\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20190110-00\/?p=100675\"> <code>Def\u00adWindow\u00adProc<\/code><\/a>.<\/p>\n<p>For some reason, when I get called in to investigate this sort of problem, <a href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20191030-00\/?p=103036\"> it&#8217;s usually the <code>Def\u00adWindow\u00adProc<\/code><\/a> that is the source of the problem.<\/p>\n<p>But I don&#8217;t think it&#8217;s because people get the others right and miss the <code>Def\u00adWindow\u00adProc<\/code>. I think it&#8217;s because the mistakes in the other functions are much less noticeable. The mistakes are still there, and maybe you&#8217;ll get a bug report from a user in Japan when they run into it, but that&#8217;s not something that is going to be noticed in English-based testing as much as a string that is <a title=\"Why does misinterpreting UTF16-LE Unicode text as ANSI tend to show up as just one character?\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20180207-00\/?p=97985\"> truncated down to its first letter<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Code different.<\/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-106021","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Code different.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/106021","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=106021"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/106021\/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=106021"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=106021"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=106021"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}