{"id":3074,"date":"2020-04-14T22:02:00","date_gmt":"2020-04-14T14:02:00","guid":{"rendered":"https:\/\/www.aoisnow.net\/blog\/?p=3074"},"modified":"2020-04-14T22:02:00","modified_gmt":"2020-04-14T14:02:00","slug":"tont-36183-%e7%aa%97%e4%bd%93%e4%b8%8d%e6%98%af%e4%be%bf%e5%ae%9c%e7%9a%84%e5%af%b9%e8%b1%a1","status":"publish","type":"post","link":"https:\/\/www.aoisnow.net\/blog\/archives\/3074","title":{"rendered":"TONT 36183 \u7a97\u4f53\u4e0d\u662f\u4fbf\u5b9c\u7684\u5bf9\u8c61"},"content":{"rendered":"<p>\u539f\u6587\u94fe\u63a5\uff1a<a href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20050315-00\/?p=36183\" target=\"_blank\" rel=\"noopener\">https:\/\/devblogs.microsoft.com\/oldnewthing\/20050315-00\/?p=36183<\/a><\/p>\n<p>\uff08\u8bd1\u6ce8\uff1a\u6211\u6df1\u77e5\u8fd9\u4e00\u7bc7\u7684\u7ffb\u8bd1\u8d28\u91cf\u5e94\u8be5\u5f88\u5dee\uff0c\u770b\u4e0d\u4e0b\u53bb\u7684\u8bdd\u8bf7\u76f4\u63a5\u8df3\u8fc7\u2026\u2026\uff09<\/p>\n<p>Although Windows is centered around, well, windows, a window itself is not a cheap object. What\u2019s more, the tight memory constraints of systems of 1985 forced various design decisions.<\/p>\n<p>\u5c3d\u7ba1 Windows \u662f\u56f4\u7ed5\u7740\u7a97\u4f53\uff08windows\uff09\u8bbe\u8ba1\u7684\uff0c\u4e0d\u8fc7\u7a97\u4f53\u5e76\u4e0d\u662f\u4fbf\u5b9c\u5927\u628a\u7684\u5bf9\u8c61\u3002\u6b64\u5916\uff0c1985\u5e74\u786c\u4ef6\u914d\u7f6e\u4e2d\u7d27\u4fcf\u7684\u5185\u5b58\u9650\u5236\u50ac\u751f\u4e86\u5f88\u591a\u88ab\u8feb\u7684\u8bbe\u8ba1\u51b3\u5b9a\u3002<\/p>\n<p>Let\u2019s take for example the design of the list box control. In a modern design, you might design the list box control as accepting a list of child windows, each of which represents an entry in the list. A list box with 20,000 items would have 20,000 child windows.<\/p>\n<p>\u4ee5 Listbox \u63a7\u4ef6\u7684\u8bbe\u8ba1\u4e3a\u4f8b\u3002\u5728\u5982\u4eca\u7684\u8bbe\u8ba1\u7406\u5ff5\u4e2d\uff0c\u4f60\u53ef\u80fd\u4f1a\u5c06\u5176\u8bbe\u8ba1\u4e3a\u5305\u542b\u4e00\u5217\u5b50\u7a97\u4f53\u7684\u63a7\u4ef6\uff0c\u6bcf\u4e2a\u5b50\u7a97\u4f53\u4ee3\u8868\u5217\u8868\u4e2d\u7684\u4e00\u4e2a\u6761\u76ee\u3002\u4e00\u4e2a\u62e5\u670920000\u9879\u6761\u76ee\u7684 Listbox \u5c31\u4f1a\u670920000\u4e2a\u5b50\u7a97\u4f53\u3002<\/p>\n<p>That would have been completely laughable in 1985.<\/p>\n<p>\u8fd9\u79cd\u8bbe\u8ba1\u57281985\u5e74\u4f1a\u8ba9\u4eba\u7b11\u6389\u5927\u7259\u3002<\/p>\n<p>Recall that Windows was built around a 16-bit processor. Window handles were 16-bit values and internally were just near pointers into a 64K heap. A window object was 88 bytes (I counted), which means that you could squeeze in a maximum of 700 or so before you ran out of memory. What\u2019s more, menus hung out in this same 64K heap, so the actual limit was much lower.<\/p>\n<p>\u56de\u5fc6\u4e00\u4e0b\uff0c\u5f53\u65f6 Windows \u662f\u56f4\u7ed516\u4f4d\u5904\u7406\u5668\u8bbe\u8ba1\u7684\u3002\u7a97\u4f53\u53e5\u67c4\u662f\u4e00\u7cfb\u521716\u4f4d\u7684\u503c\uff0c\u5728\u5185\u90e8\u5219\u8868\u73b0\u4e3a\u4e00\u4e2a 64K \u5806\u4e2d\u76f8\u90bb\u7684\u6307\u9488\u3002\u4e00\u4e2a\u7a97\u4f53\u5bf9\u8c61\u8981\u7528\u638988\u4e2a\u5b57\u8282\uff08\u6211\u6570\u8fc7\u4e86\uff09\uff0c\u8fd9\u5c31\u610f\u5473\u7740\u4f60\u6700\u591a\u80fd\u5728\u5185\u5b58\u91cc\u585e\u4e0b700\u4e2a\u7a97\u4f53\uff0c\u518d\u585e\u5c31\u8981\u5185\u5b58\u6ea2\u51fa\u4e86\u3002\u53e6\u5916\uff0c\u83dc\u5355\u4e5f\u5728\u540c\u4e00\u4e2a 64K \u5806\u4e2d\uff0c\u6545\u800c\u5b9e\u9645\u7684\u4e0a\u9650\u53ef\u80fd\u4f1a\u66f4\u4f4e\u3002<\/p>\n<p>Even if the window manager internally used a heap larger than 64K (which Windows 95 did), 20,000 windows comes out to over 1.5MB. Since the 8086 had a maximum address space of 1MB, even if you devoted every single byte of memory to window objects, you\u2019d still not have enough memory.<\/p>\n<p>\u5373\u4fbf\u7a97\u4f53\u7ba1\u7406\u5668\u5728\u5185\u90e8\u4f7f\u7528\u7684\u662f\u4e00\u4e2a\u5927\u4e8e 64K \u7684\u5806\uff08Windows 95\u5373\u662f\u5982\u6b64\uff09\uff0c20000\u4e2a\u7a97\u4f53\u4e5f\u8981\u6d88\u8017\u5c06\u8fd1 1.5MB \u7684\u7a7a\u95f4\u3002\u7531\u4e8e 8086 \u5904\u7406\u5668\u7684\u5730\u5740\u7a7a\u95f4\u4e0a\u9650\u662f 1MB\uff0c\u5c31\u7b97\u4f60\u5c06\u5185\u5b58\u7684\u6bcf\u4e00\u4e2a\u5b57\u8282\u90fd\u8d21\u732e\u7ed9\u7a97\u4f53\u5bf9\u8c61\u4f7f\u7528\uff0c\u8fd8\u662f\u6ca1\u6709\u8db3\u591f\u7684\u5185\u5b58\u53ef\u4ee5\u7528\u3002<\/p>\n<p>Furthermore, making each list box item a window means that every list box would be a variable-height list box, which carries with it the complexity of managing a container with variable-height items. This goes against two general principles of API design: (1) simple things should be simple, and (2) \u201cpay-for-play\u201d, that if you are doing the simple thing, you shouldn\u2019t have to pay the cost of the complex thing.<\/p>\n<p>\u9664\u6b64\u4e4b\u5916\uff0c\u8ba9\u6bcf\u4e00\u4e2a Listbox \u7684\u9879\u76ee\u90fd\u4f5c\u4e3a\u4e00\u4e2a\u7a97\u4f53\uff0c\u610f\u5473\u7740\u6bcf\u4e2a Listbox \u90fd\u4f1a\u662f\u9ad8\u5ea6\u53ef\u53d8\u7684\uff0c\u8fd9\u5c31\u5e26\u6765\u4e86\u7ba1\u7406\u5305\u542b\u7740\u53ef\u53d8\u9ad8\u5ea6\u9879\u76ee\u7684\u5bb9\u5668\u7684\u590d\u6742\u6027\u3002\u5982\u6b64\u7684\u8bbe\u8ba1\u8fdd\u80cc\u4e86 API \u8bbe\u8ba1\u7684\u4e24\u9879\u57fa\u672c\u539f\u5219\uff1a\uff081\uff09\u7b80\u5355\u7684\u4e8b\u7269\u5c31\u5e94\u8be5\u7b80\u5355\uff0c\u4ee5\u53ca\uff082\uff09\u300e\u529e\u591a\u5c11\u4e8b\u82b1\u591a\u5c11\u94b1\u300f\uff0c\u4e5f\u5c31\u662f\u5982\u679c\u4e8b\u60c5\u672c\u8eab\u5c31\u5f88\u7b80\u5355\uff0c\u4fbf\u4e0d\u5e94\u5f53\u4e3a\u590d\u6742\u7684\u4e8b\u60c5\u4ed8\u51fa\u4ee3\u4ef7\u3002<\/p>\n<p>Filling a list box with actual windows also would have made the \u201cvirtual list box\u201d design significantly trickier. With the current design, you can say, \u201cThere are a million items\u201d without actually having to create them.<\/p>\n<p>\u5c06\u4e00\u4e2a Listbox \u586b\u6ee1\u4e8b\u5b9e\u610f\u4e49\u4e0a\u7684\u7a97\u4f53\uff0c\u4e5f\u4f1a\u5c06\u8fd9\u4e2a\u300e\u865a\u62df Listbox\u300f\u7684\u8bbe\u8ba1\u53d8\u5f97\u9661\u7136\u590d\u6742\u8d77\u6765\u3002\u6309\u7167\u5176\u76ee\u524d\u7684\u8bbe\u8ba1\uff0c\u4f60\u53ef\u4ee5\u58f0\u660e\u300e\u5217\u8868\u4e2d\u6709\u4e00\u767e\u4e07\u9879\u300f\uff0c\u4f46\u4e0d\u5fc5\u5b9e\u9645\u53bb\u521b\u5efa\u8fd9\u4e48\u591a\u9879\u76ee\u3002<\/p>\n<p>(This is also why the window space is divided into \u201cclient\u201d and \u201cnon-client\u201d areas rather than making the non-client area consist of little child windows.)<\/p>\n<p>\uff08\u8fd9\u4e5f\u662f\u4e3a\u4ec0\u4e48\u7a97\u4f53\u63a7\u4ef6\u88ab\u5206\u5272\u4e3a\u300e\u5de5\u4f5c\u533a\u300f\u548c\u300e\u975e\u5de5\u4f5c\u533a\u300f\uff0c\u800c\u4e0d\u662f\u8ba9\u975e\u5de5\u4f5c\u533a\u4e5f\u586b\u6ee1\u4e86\u5c0f\u5c0f\u7684\u5b50\u7a97\u4f53\u7684\u7f18\u6545\u3002\uff09<\/p>\n<p>To maintain compatibility with 16-bit Windows programs (which still run on Windows XP thanks to the WOW layer), there cannot be more than 65536 window handles in the system, because any more than that would prevent 16-bit programs from being able to talk meaningfully about windows. (Once you create your 65537\u2019th window, there will be two windows with the same 16-bit handle value, thanks to the pigeonhole principle.)<\/p>\n<p>\u4e3a\u4e86\u7ef4\u6301\u4e0e16\u4f4dWindows\u5e94\u7528\u7a0b\u5e8f\u7684\u517c\u5bb9\u6027\uff08\u9274\u4e8eWOW\uff08\u8bd1\u6ce8\uff1aWindows-On-Windows\uff0c\u5728\u65b0\u7248Windows\u4e0a\u4e3a\u9762\u5411\u65e7\u7248\u7cfb\u7edf\u8bbe\u8ba1\u7684\u5e94\u7528\u7a0b\u5e8f\u63d0\u4f9b\u6709\u9650\u517c\u5bb9\u6027\u7684\u517c\u5bb9\u5c42\uff0c\u6b64\u5904\u4e3a32\u4f4d\u7cfb\u7edf\u517c\u5bb916\u4f4d\u5e94\u7528\u7a0b\u5e8f\uff09\u5c42\uff0c\u8fd9\u4e9b\u7a0b\u5e8f\u5728 Windows XP \u4e0a\u4ecd\u7136\u53ef\u7528\uff09\uff0c\u7cfb\u7edf\u4e2d\u7684\u7a97\u4f53\u53e5\u67c4\u4e0d\u80fd\u8d85\u8fc765536\u4e2a\uff0c\u56e0\u4e3a\u8d85\u8fc7\u8fd9\u4e2a\u9650\u5236\u4f1a\u963b\u6b6216\u4f4d\u5e94\u7528\u7a0b\u5e8f\u4e0e\u7cfb\u7edf\u5bf9\u7a97\u4f53\u8fdb\u884c\u6709\u610f\u4e49\u7684\u6c9f\u901a\u3002\uff08\u4e00\u65e6\u521b\u5efa\u4e86\u7b2c65537\u4e2a\u7a97\u4f53\uff0c\u5c31\u4f1a\u51fa\u73b0\u5177\u6709\u76f8\u540c\u53e5\u67c4\u503c\u7684\u4e24\u4e2a\u7a97\u4f53\u2014\u2014\u611f\u8c22\u9e3d\u5de2\u539f\u7406\uff08\u8bd1\u6ce8\uff1a\u53c8\u53eb\u62bd\u5c49\u539f\u7406\uff0c\u6307\u5982\u679c\u5c1d\u8bd5\u5c06n+1\u4e2a\u5143\u7d20\u653e\u8fdbn\u4e2a\u96c6\u5408\u4e2d\uff0c\u90a3\u4e48\u5fc5\u7136\u6709\u4e00\u4e2a\u96c6\u5408\u4e2d\u5305\u542b2\u4e2a\u5143\u7d20\uff09\u7684\u5b58\u5728\u3002\uff09<\/p>\n<p>(And yes, 16\/32-bit interoperability is still important even today.)<\/p>\n<p>\uff08\u53e6\u5916\u6ca1\u9519\uff0c16\/32\u4f4d\u5e94\u7528\u7a0b\u5e8f\u7684\u4ea4\u4e92\u64cd\u4f5c\u6027\uff0c\u65f6\u81f3\u4eca\u65e5\u4ecd\u7136\u5f88\u91cd\u8981\u3002\uff09<\/p>\n<p>With a limit of 65536 window handles, your directory with 100,000 files in it would be in serious trouble.<\/p>\n<p>\u9274\u4e8e65535\u4e2a\u7a97\u4f53\u53e5\u67c4\u4e0a\u9650\u7684\u5b58\u5728\uff0c\u4f60\u90a3\u62e5\u670910\u4e07\u4e2a\u6587\u4ef6\u7684\u76ee\u5f55\uff08\u5982\u679c\u6309\u7167\u524d\u9762\u90a3\u6837\u5d4c\u5957\u5c0f\u7a97\u4f53\u7684\u8bbe\u8ba1\uff09\u5c31\u4f1a\u6709\u5927\u9ebb\u70e6\u4e86\u3002<\/p>\n<p>The cost of a window object has grown over time, as new features get added to the window manager. Today it\u2019s even heftier than the svelte 88 bytes of yesteryear. It is to your advantage not to create more windows than necessary.<\/p>\n<p>\u968f\u7740\u65b0\u529f\u80fd\u4e0d\u65ad\u52a0\u5165\u7a97\u4f53\u7ba1\u7406\u5668\uff0c\u7a97\u4f53\u5bf9\u8c61\u7684\u6210\u672c\u4e5f\u5728\u4e0d\u65ad\u6500\u5347\u3002\u5982\u4eca\u7a97\u4f53\u6570\u636e\u7684\u5065\u58ee\u7a0b\u5ea6\u5df2\u4e0e\u5f53\u5e74\u90a3\u4e2a\u82d7\u6761\u768488\u5b57\u8282\u5927\u5c0f\u4e0d\u53ef\u540c\u65e5\u800c\u8bed\uff0c\u800c\u4e0d\u8981\u521b\u5efa\u591a\u4e8e\u5fc5\u8981\u7684\u7a97\u4f53\u7684\u8d23\u4efb\u5c31\u843d\u5728\u4e86\u4f60\u7684\u80a9\u4e0a\u3002<\/p>\n<p>If your application design has you creating thousands of windows for sub-objects, you should consider moving to a windowless model, like Internet Explorer, Word, list boxes, treeview, listview, and even our scrollbar sample program. By going windowless, you shed the system overhead of a full window handle, with all the baggage that comes with it. Since window handles are visible to all processes, there is a lot of overhead associated with centrally managing the window list. If you go windowless, then the only program that can access your content is you. You don\u2019t have to worry about marshalling, cross-process synchronization, Unicode\/ANSI translation, external subclassing, hooks\u2026 And you can use a gigabyte of memory to keep track of your windowless data if that\u2019s what you want, since your windowless controls don\u2019t affect any other processes. The fact that window handles are accessible to other processes imposes a practical limit on how many of them can be created without impacting the system as a whole.<\/p>\n<p>\u5982\u679c\u4f60\u7684\u7a0b\u5e8f\u8bbe\u8ba1\u9700\u8981\u4f60\u521b\u5efa\u6210\u5343\u4e0a\u4e07\u4e2a\u7528\u4e8e\u5185\u90e8\u5bf9\u8c61\u7684\u7a97\u4f53\uff0c\u4f60\u5e94\u5f53\u8003\u8651\u8fc1\u79fb\u5230\u65e0\u7a97\u4f53\u7684\u6a21\u578b\uff0c\u5c31\u50cf Internet Explorer\u3001Word\u3001Listbox\u3001TreeView\u3001ListView\uff0c\u751a\u81f3\u6211\u4eec\u7684\u6eda\u52a8\u6761\u793a\u4f8b\u7a0b\u5e8f\u90a3\u6837\u3002\u901a\u8fc7\u4f7f\u7528\u65e0\u7a97\u4f53\u8bbe\u8ba1\uff0c\u4f60\u7684\u7a0b\u5e8f\u5411\u7cfb\u7edf\u5c55\u793a\u7684\u5c31\u53ea\u6709\u4e00\u4e2a\u5b8c\u6574\u7684\u7a97\u4f53\u53e5\u67c4\uff0c\u91cc\u9762\u5305\u542b\u7740\u6240\u6709\u5927\u5927\u5c0f\u5c0f\u7684\u5143\u7d20\u3002\u7531\u4e8e\u7a97\u4f53\u53e5\u67c4\u662f\u5bf9\u6240\u6709\u8fdb\u7a0b\u53ef\u89c1\u7684\uff0c\u5bf9\u4e8e\u96c6\u4e2d\u7ba1\u7406\u7684\u7a97\u4f53\u5217\u8868\u6765\u8bf4\u8d1f\u62c5\u662f\u5f88\u91cd\u7684\u3002\u5982\u679c\u91c7\u7528\u65e0\u7a97\u4f53\u8bbe\u8ba1\uff0c\u90a3\u4e48\u552f\u4e00\u53ef\u4ee5\u8bbf\u95ee\u7a97\u4f53\u4e2d\u5185\u5bb9\u7684\u5c31\u662f\u4f60\u81ea\u5df1\u3002\u4f60\u4e0d\u5fc5\u62c5\u5fc3 Marshalling\u3001\u8de8\u8fdb\u7a0b\u540c\u6b65\u3001Unicode\/ANSI \u8f6c\u6362\u3001\u5916\u90e8\u5b50\u7c7b\u3001\u94a9\u5b50\u2026\u2026 \u7b49\u7b49\u7684\u9ebb\u70e6\u4e8b\u3002\u53e6\u5916\u5982\u679c\u4f60\u613f\u610f\uff0c\u52a8\u7528\u4e00\u4e2aG\u7684\u5185\u5b58\u6765\u8ddf\u8e2a\u4f60\u7684\u65e0\u7a97\u4f53\u6a21\u578b\u4e0b\u7684\u5185\u5bb9\u4e5f\u662f\u523b\u610f\u7684\uff0c\u56e0\u4e3a\u4f60\u7684\u65e0\u7a97\u4f53\u6a21\u578b\u4e2d\u7684\u63a7\u4ef6\u4e0d\u4f1a\u5f71\u54cd\u5176\u5b83\u8fdb\u7a0b\u3002\u7531\u4e8e\u7a97\u4f53\u53e5\u67c4\u5bf9\u5176\u4ed6\u8fdb\u7a0b\u662f\u53ef\u89c1\u7684\uff0c\u4e5f\u5c31\u5bf9\u53ef\u4ee5\u521b\u5efa\u591a\u5c11\u4e2a\u7a97\u4f53\u53e5\u67c4\u800c\u4e0d\u4f1a\u5bf9\u7cfb\u7edf\u6574\u4f53\u4ea7\u751f\u91cd\u5927\u5f71\u54cd\u8fd9\u4e00\u4e8b\u5b9e\u65bd\u52a0\u4e86\u5f71\u54cd\u3002<\/p>\n<p>I believe that WinFX uses the \u201ceverything on the screen is an element\u201d model. It is my understanding that they\u2019ve built a windowless framework so you don\u2019t have to. (I\u2019m not sure about this, though, not being a WinFX person myself.)<\/p>\n<p>\u6211\u76f8\u4fe1 WinFX \u5229\u7528\u4e86\u300e\u5c4f\u5e55\u4e0a\u7684\u4e00\u5207\u90fd\u662f\u5143\u7d20\u300f\u8fd9\u79cd\u6a21\u578b\uff0c\u6211\u7684\u7406\u89e3\u662f\u4ed6\u4eec\u6784\u5efa\u4e86\u4e00\u4e2a\u65e0\u7a97\u4f53\u6846\u67b6\uff0c\u4ee5\u4fbf\u4f60\u4e0d\u7528\u518d\u4ece\u5934\u9020\u4e00\u904d\u8f6e\u5b50\u3002\uff08\u5c3d\u7ba1\u5bf9\u6b64\u6211\u5e76\u4e0d\u786e\u5b9a\uff0c\u6bd5\u7adf\u6211\u4e0d\u662f\u76f8\u5173\u4eba\u58eb\u3002\uff09<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u539f\u6587\u94fe\u63a5\uff1ahttps:\/\/devblogs.microsoft.com\/oldnewthing\/2005031 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-3074","post","type-post","status-publish","format-standard","hentry","category-tont_history"],"_links":{"self":[{"href":"https:\/\/www.aoisnow.net\/blog\/wp-json\/wp\/v2\/posts\/3074","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.aoisnow.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.aoisnow.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.aoisnow.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.aoisnow.net\/blog\/wp-json\/wp\/v2\/comments?post=3074"}],"version-history":[{"count":0,"href":"https:\/\/www.aoisnow.net\/blog\/wp-json\/wp\/v2\/posts\/3074\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.aoisnow.net\/blog\/wp-json\/wp\/v2\/media?parent=3074"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.aoisnow.net\/blog\/wp-json\/wp\/v2\/categories?post=3074"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.aoisnow.net\/blog\/wp-json\/wp\/v2\/tags?post=3074"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}