{"id":42663,"date":"2003-09-04T07:00:00","date_gmt":"2003-09-04T14:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2003\/09\/04\/why-are-the-rules-for-getwindowtext-so-weird\/"},"modified":"2003-09-04T07:00:00","modified_gmt":"2003-09-04T14:00:00","slug":"why-are-the-rules-for-getwindowtext-so-weird","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20030904-00\/?p=42663","title":{"rendered":"Why are the rules for GetWindowText so weird?"},"content":{"rendered":"<p>\n        <a href=\"http:\/\/www.joelonsoftware.com\/\">Joel Spolsky<\/a> rightly points out that <a href=\"http:\/\/www.joelonsoftware.com\/items\/2003\/08\/22.html\">the\n        rules for <code>GetWindowText<\/code> exhibit abstraction leakage<\/a>. Why are the\n        rules for <code>GetWindowText<\/code> so weird?\n    <\/p>\n<p>\n        Set the wayback machine to 1983. Your typical PC had an 8086 processor running at\n        a whopping 4.7MHz, two 360K 5&frac14;-inch floppy drives (or if you were really loaded, one\n        floppy drive and a 10MB hard drive), and 256KB of memory. [<i>Original entry said\n        256MB &#8211; oops. Thanks to\n<a HREF=\"http:\/\/www.eightypercent.net\/\" \/>Joe Beda<\/a> for pointing this out.<\/i>]\n    <\/p>\n<p>\n        This was the world of Windows 1.0.\n    <\/p>\n<p>\n        Windows 1.0 was a co&ouml;peratively-multitasked system. No pre-emptive multitasking here.\n        When your program got control, it had control for as long as it wanted it. Only when\n        you called a function like <code>PeekMessage<\/code> or <code>GetMessage<\/code> did\n        you release control to other applications.\n    <\/p>\n<p>\n        This was important, because in the absence of a hardware memory manager, you really\n        had to make sure that your memory didn&#8217;t get ripped out from under you.\n    <\/p>\n<p>\n        One important consequence of co&ouml;perative multitasking is that if your program is running,\n        not only do you know that no other program is running, but you also know that <strong>every\n        window is responding to messages<\/strong>. Why? Because if they were hung, they wouldn&#8217;t\n        have released control to you!\n    <\/p>\n<p>\n        This means that it is <strong>always<\/strong> safe to send a message. You never had\n        to worry about the possibility of sending a message to a hung window, since you knew\n        that no windows were hung.\n    <\/p>\n<p>\n        In this simpler world, <code>GetWindowText<\/code> was a straightforward function:\n    <\/p>\n<pre>int WINAPI\nGetWindowText(HWND hwnd, LPSTR pchBuf, int cch)\n{\n    \/\/ ah for the simpler days\n    return SendMessage(hwnd, WM_GETTEXT, (WPARAM)cch, (LPARAM)pchBuf);\n}\n<\/pre>\n<p>\n        This worked for all windows, all the time. No special handling of windows in a different\n        process.\n    <\/p>\n<p>\n        It was the transition to Win32 and pre-emptive multitasking that forced the change\n        in the rules, because for the first time, there was the possibility that (gasp) the\n        window you were trying to communicate with was not responding to messages.\n    <\/p>\n<p>\n        Now you have the backwards compatibility problem. As I described <a href=\"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/20030821-00\/?p=42833\">in\n        my original article<\/a>, many parts of the system and many programs rely on the ability\n        to retrieve window text without hanging. So how do you make it possible to retrieve\n        window text without hanging, while still giving controls like the edit control the\n        ability to do their own window text management?\n    <\/p>\n<p>\n        The Win32 rules on <code>GetWindowText<\/code> are the result of this attempt to reconcile\n        conflicting goals.\n    <\/p>\n<p>\n        (This same story, with slight changes, also works as a discussion of why DDE works\n        the way it does. But fewer people use DDE nowadays, so the effect is not as dramatic.)\n    <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Set the wayback machine to 1983.<\/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":[2],"class_list":["post-42663","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-history"],"acf":[],"blog_post_summary":"<p>Set the wayback machine to 1983.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/42663","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=42663"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/42663\/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=42663"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=42663"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=42663"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}