{"id":102978,"date":"2019-10-10T07:00:00","date_gmt":"2019-10-10T14:00:00","guid":{"rendered":"http:\/\/devblogs.microsoft.com\/oldnewthing\/?p=102978"},"modified":"2019-10-09T19:40:34","modified_gmt":"2019-10-10T02:40:34","slug":"20191010-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20191010-00\/?p=102978","title":{"rendered":"Why are timer IDs and dialog control IDs 64-bit values on 64-bit Windows? Did you really expect people to create more than 4 billion timers or dialog controls?"},"content":{"rendered":"<p>In 32-bit Windows, timer IDs and dialog control IDs are 32-bit values, but in 64-bit windows, timer IDs and dialog control IDs are 64-bit values. Seriously? Did you really expect people to create more than 4 billion timers or dialog controls?<\/p>\n<p>No, that&#8217;s not why they are 64-bit values.<\/p>\n<p>Values were expanded from 32-bit values to 64-bit values whenever they could be used to store a pointer, because pointers on 64-bit Windows are 64 bits in size.<\/p>\n<p>Sometimes this was obvious, like the message <code>WPARAM<\/code> and <code>LPARAM<\/code>, which are often window handles or pointers to supplementary structures. Or values used as reference data for callbacks, since a common pattern is to use a pointer to a helper structure in order to pass a large amount of information. The <code>GWLP_<\/code><code>USER\u00adDATA<\/code> storage that comes with every window is another place where it is common practice to store a pointer.<\/p>\n<p>We saw last time that <a href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20191009-00\/?p=102974\"> a common convention is to use pointers to assign unique IDs<\/a>, particularly for timers, and that meant that timer IDs needed to be expanded from 32-bit values to 64-bit values.<\/p>\n<p>Dialog controls are stored in the <code>GWL_ID<\/code> window data. Why was this expanded to a 64-bit value <code>GWLP_ID<\/code>? You can&#8217;t actually use a 64-bit dialog control ID because the <code>GetDlgCtrlID<\/code> function returns a 32-bit integer, and window messages that use the dialog control ID (such as <code>WM_<\/code><code>COMMAND<\/code>) have only a 16-bit field for the dialog control ID. So it seems that there&#8217;s no point in expanding the dialog control ID to a 64-bit value, since nobody actually reports it as a 64-bit value.<\/p>\n<p>While it&#8217;s true that nobody reports it as a 64-bit value, you can still retrieve the full 64-bit value by asking for the <code>GWLP_ID<\/code>.<\/p>\n<p>Pointers are like weeds. Anywhere it&#8217;s possible to fit a pointer, a pointer will try to squeeze in there.<\/p>\n<p>Since it was possible in 32-bit Windows to store a 32-bit value in the place that holds the dialog control ID, people used it to store a pointer because <i>hey, look, free pointer-sized memory<\/i>. They never intended to use it as a dialog control ID, but if somebody&#8217;s going to give you free memory, why not use it!<\/p>\n<p>This creative use of the dialog control ID were discovered during the development of 64-bit Windows, and the dialog control ID storage was expanded to a 64-bit value to accommodate it.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Anywhere it&#8217;s possible to put a pointer, somebody will try to put a pointer.<\/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-102978","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-history"],"acf":[],"blog_post_summary":"<p>Anywhere it&#8217;s possible to put a pointer, somebody will try to put a pointer.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/102978","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=102978"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/102978\/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=102978"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=102978"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=102978"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}