{"id":25203,"date":"2007-09-10T10:00:00","date_gmt":"2007-09-10T10:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2007\/09\/10\/if-control-specific-messages-belong-to-the-wm_user-range-why-are-messages-like-bm_setcheck-in-the-system-message-range\/"},"modified":"2007-09-10T10:00:00","modified_gmt":"2007-09-10T10:00:00","slug":"if-control-specific-messages-belong-to-the-wm_user-range-why-are-messages-like-bm_setcheck-in-the-system-message-range","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20070910-00\/?p=25203\/","title":{"rendered":"If control-specific messages belong to the WM_USER range, why are messages like BM_SETCHECK in the system message range?"},"content":{"rendered":"<p>\n<a HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2003\/12\/02\/55914.aspx\">\nWhen I discussed which message numbers belong to whom<\/a>,\nyou may have noticed that the messages for edit boxes,\nbuttons, list boxes, combo boxes,\nscroll bars,\nand static controls go into the system range even though\nthey are control-specific.\nHow did those messages end up there?\n<\/p>\n<p>\nThey didn&#8217;t start out there.\n<\/p>\n<p>\nIn 16-bit windows, these control-specific messages\nwere in the control-specific message range,\nas you would expect.\n<\/p>\n<pre>\n#define LB_ADDSTRING      (WM_USER + 1)\n#define LB_INSERTSTRING   (WM_USER + 2)\n#define LB_DELETESTRING   (WM_USER + 3)\n#define LB_RESETCONTENT   (WM_USER + 5)\n#define LB_SETSEL         (WM_USER + 6)\n#define LB_SETCURSEL      (WM_USER + 7)\n#define LB_GETSEL         (WM_USER + 8)\n#define LB_GETCURSEL      (WM_USER + 9)\n#define LB_GETTEXT        (WM_USER + 10)\n...\n<\/pre>\n<p>\nImagine what would have happened had these message\nnumbers been preserved during the transition to Win32,\n<\/p>\n<p>\n(Giving you time to exercise your imagination.)\n<\/p>\n<p>\nHere&#8217;s a hint.\nSince 16-bit Windows ran all programs in the same address space,\nprograms could do things like this:\n<\/p>\n<pre>\nchar buffer[100];\nHWND hwndLB = &lt;a list box that belongs to another process&gt;\nSendMessage(hwndLB, LB_GETTEXT, 0, <a HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2004\/11\/03\/251670.aspx\">(LPARAM)(LPSTR)<\/a>buffer);\n<\/pre>\n<p>\nThis reads the text of an item in a list box that belongs to\nanother process.\nSince processes ran in the same address space, the address of the\nbuffer in the sending process is valid in the receiving process,\nso that when the receiving list box copies the result to the buffer,\nit all works.\n<\/p>\n<p>\nNow go back and imagine what would have happened had these\nmessage numbers been preserved during the transition to Win32.\n<\/p>\n<p>\n(Giving you time to exercise your imagination.)\n<\/p>\n<p>\nConsider a 32-bit program that does exactly the same thing\nthat the code fragment above does.\nThe code probably was simply left unchanged when the\nprogram was ported from 16-bit to 32-bit code,\nsince it doesn&#8217;t generate any compiler warnings\nand therefore does nothing to draw attention to itself\nas needing special treatment.\n<\/p>\n<p>\nBut since processes run in separate address spaces\nin Win32, the program now crashes.\nWell, more accurately, it crashes <i>that other program<\/i>,\nsince it is the other program that tries to copy the text\ninto the pointer that it was led to believe was a valid buffer\nbut in fact was a pointer into the wrong address space.\n<\/p>\n<p>\nJust what you want.\nA perfectly legitimate program crashes because of somebody\nelse&#8217;s bug.\nIf you&#8217;re lucky, the programmers will catch this bug during testing,\nbut how will they know what the problem is, since their program doesn&#8217;t\ncrash; it&#8217;s some other program that crashes!\nIf you&#8217;re not lucky, the bug will slip through testing\n(for example, it might be in a rarely-executed code path),\nand the experience of the end user is\n&#8220;Microsoft Word crashes randomly. What a piece of junk.&#8221;\n(When in reality, the crash is being caused by some other program entirely.)\n<\/p>\n<p>\nTo avoid this problem, all the &#8220;legacy&#8221; messages from the\ncontrols built into the window manager were moved into\nthe system message category.\nThat way, when you sent message 0x0189, the window manager\nknew that it was <code>LB_GETTEXT<\/code> and could do the\nparameter marshalling for you.\nIf it had been left in the <code>WM_USER<\/code> range,\nthe window manager wouldn&#8217;t know what to do when it gets message\n<code>0x040A<\/code> since that might be <code>LB_GETTEXT<\/code>,\nor it might be\n<code>TTM_HITTESTA<\/code> or <code>TBM_SETSEL<\/code>\nor any of a number of other control-specific messages.\n<\/p>\n<p>\nTheoretically, this motion needed to be done only for legacy messages;\ni.e., window messages that existed in 16-bit Windows.\n(Noting that Windows&nbsp;95 added some new 16-bit messages,\nso this remapping had to continue at least through Windows&nbsp;NT&nbsp;4\nwith the shell update release.)\nNevertheless, the window manager team added the <code>*_GET*INFO<\/code>\nmessages in the system message range even though there was no need\nto put them there\nfrom a compatibility standpoint.\nMy suspicion is that it was done to make things easier for\naccessibility tools.\n<\/p>\n<p>\nNote however that placing new messages in the system message range\nis more the exception than the rule\nfor the edit box and other &#8220;core&#8221; controls.\nFor example, the new message <code>EM_SETCUEBANNER<\/code>\nhas the numeric value <code>0x1501<\/code>,\nwhich is well into the <code>WM_USER<\/code> range.\nIf you try to send this message across processes\nwithout taking the necessary precautions,\nyou will crash the target process.\n<\/p>\n<p>\n(Note:\n<a HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/pages\/4520252.aspx\">\nStandard disclaimers apply<\/a>.\nI won&#8217;t bother repeating this disclaimer on future articles.)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When I discussed which message numbers belong to whom, you may have noticed that the messages for edit boxes, buttons, list boxes, combo boxes, scroll bars, and static controls go into the system range even though they are control-specific. How did those messages end up there? They didn&#8217;t start out there. In 16-bit windows, these [&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-25203","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>When I discussed which message numbers belong to whom, you may have noticed that the messages for edit boxes, buttons, list boxes, combo boxes, scroll bars, and static controls go into the system range even though they are control-specific. How did those messages end up there? They didn&#8217;t start out there. In 16-bit windows, these [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/25203","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=25203"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/25203\/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=25203"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=25203"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=25203"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}