{"id":35023,"date":"2005-07-06T10:00:26","date_gmt":"2005-07-06T10:00:26","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2005\/07\/06\/whats-the-point-of-deferwindowpos\/"},"modified":"2005-07-06T10:00:26","modified_gmt":"2005-07-06T10:00:26","slug":"whats-the-point-of-deferwindowpos","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20050706-26\/?p=35023","title":{"rendered":"What&#8217;s the point of DeferWindowPos?"},"content":{"rendered":"<p><P>\nThe purpose of\n<A HREF=\"http:\/\/msdn.microsoft.com\/library\/en-us\/winui\/WinUI\/WindowsUserInterface\/Windowing\/Windows\/WindowReference\/WindowFunctions\/DeferWindowPos.asp\">\nthe <CODE>DeferWindowPos<\/CODE> function<\/A>\nis to move multiple child windows at one go.\nThis reduces somewhat the amount of repainting that goes on\nwhen windows move around.\n<P>\n<\/P>\nTake\n<A HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2005\/04\/20\/410031.aspx\">\nthat DC brush sample from a few months ago<\/A>\nand make the following changes:\n<\/P>\n<PRE>\n<FONT COLOR=\"blue\">HWND g_hwndChildren[2];<\/FONT><\/p>\n<p>BOOL\nOnCreate(HWND hwnd, LPCREATESTRUCT lpcs)\n{\n <FONT COLOR=\"blue\">const static COLORREF s_rgclr[2] =\n    { RGB(255,0,0), RGB(0,255,0) };\n for (int i = 0; i &lt; 2; i++) {\n  g_hwndChildren[i]<\/FONT> = CreateWindow(TEXT(&#8220;static&#8221;), NULL,\n        WS_VISIBLE | WS_CHILD, 0, 0, 0, 0,\n        hwnd, <FONT COLOR=\"blue\">(HMENU)IntToPtr(s_rgclr[i])<\/FONT>, g_hinst, 0);\n  if (!<FONT COLOR=\"blue\">g_hwndChildren[i]<\/FONT>) return FALSE;\n <FONT COLOR=\"blue\">}<\/FONT>\n return TRUE;\n}\n<\/PRE>\n<P>\nNotice that I&#8217;m using the control ID to hold the desired color.\nWe retrieve it when choosing our background color.\n<\/P>\n<PRE>\nHBRUSH OnCtlColor(HWND hwnd, HDC hdc, HWND hwndChild, int type)\n{\n  <FONT COLOR=\"blue\">Sleep(500);<\/FONT>\n  SetDCBrushColor(hdc, <FONT COLOR=\"blue\">(COLORREF)GetDlgCtrlID(hwndChild)<\/FONT>);\n  return GetStockBrush(DC_BRUSH);\n}<\/p>\n<p>    HANDLE_MSG(hwnd, WM_CTLCOLORSTATIC, OnCtlColor);\n<\/PRE>\n<P>\nI threw in a half-second sleep.\nThis will make the painting a little easier to see.\n<\/P>\n<PRE>\nvoid\nOnSize(HWND hwnd, UINT state, int cx, int cy)\n{\n  <FONT COLOR=\"blue\">int cxHalf = cx\/2;\n  SetWindowPos(g_hwndChildren[0],\n               NULL, 0, 0, cxHalf, cy,\n               SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE);\n  SetWindowPos(g_hwndChildren[1],\n               NULL, cxHalf, 0, cx-cxHalf, cy,\n               SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE);<\/FONT>\n}\n<\/PRE>\n<P>\nWe place the two child windows side by side in our client area.\nFor our first pass, we&#8217;ll use\n<A HREF=\"http:\/\/msdn.microsoft.com\/library\/en-us\/winui\/WinUI\/WindowsUserInterface\/Windowing\/Windows\/WindowReference\/WindowFunctions\/SetWindowPos.asp\">\nthe <CODE>SetWindowPos<\/CODE> function<\/A>\nto position the windows.\n<\/P>\n<P>\nCompile and run this program, and once it&#8217;s up, click the maximize box.\nObserve carefully which parts of the green rectangle get repainted.\n<\/P>\n<P>\nNow let&#8217;s change our positioning code to use\n<A HREF=\"http:\/\/msdn.microsoft.com\/library\/en-us\/winui\/WinUI\/WindowsUserInterface\/Windowing\/Windows\/WindowReference\/WindowFunctions\/DeferWindowPos.asp\">\nthe <CODE>DeferWindowPos<\/CODE> function<\/A>.\nThe usage pattern for the deferred window positioning functions is\nas follows:\n<\/P>\n<PRE>\nHDWP hdwp = BeginDeferWindowPos(n);\nif (hdwp) hdwp = DeferWindowPos(hdwp, &#8230;); \/\/ 1 [fixed 7\/7]\nif (hdwp) hdwp = DeferWindowPos(hdwp, &#8230;); \/\/ 2\nif (hdwp) hdwp = DeferWindowPos(hdwp, &#8230;); \/\/ 3\n&#8230;\nif (hdwp) hdwp = DeferWindowPos(hdwp, &#8230;); \/\/ n\nif (hdwp) EndDeferWindowPos(hdwp);\n<\/PRE>\n<P>\nThere are some key points here.\n<\/P>\n<UL>\n<LI>The value you pass to\n<A HREF=\"http:\/\/msdn.microsoft.com\/library\/en-us\/winui\/winui\/windowsuserinterface\/windowing\/windows\/windowreference\/windowfunctions\/begindeferwindowpos.asp\">\nthe <CODE>BeginDeferWindowPos<\/CODE> function<\/A>\nis the number of windows you intend to move.\nIt&#8217;s okay if you get this value wrong, but getting it right\nwill reduce the number of internal reallocations.\n<LI>The return value from <CODE>DeferWindowPos<\/CODE> is stored\nback into the <CODE>hdwp<\/CODE> because the return value is not\nnecessarily the same as the value originally passed in.\nIf the deferral bookkeeping needs to perform a reallocation,\nthe <CODE>DeferWindowPos<\/CODE> function returns a handle to the\nnew defer information; the old defer information is no longer valid.\nWhat&#8217;s more, if the deferral fails, the old defer information is\n<STRONG>destroyed<\/STRONG>.  This is different from the\n<CODE>realloc<\/CODE> function which leaves the original object\nunchanged if the reallocation fails.\nThe pattern <CODE>p = realloc(p, &#8230;)<\/CODE> is a memory leak,\nbut the pattern <CODE>hdwp = DeferWindowPos(hdwp, &#8230;)<\/CODE>\nis not.\n<\/UL>\n<P>\nThat second point is important.\n<A HREF=\"http:\/\/msdn.microsoft.com\/library\/en-us\/dnwui\/html\/msdn_chicoapp.asp\">\nMany people get it wrong<\/A>.\n<\/P>\n<P>\nOkay, now that you&#8217;re all probably scared of this function,\nlet&#8217;s change our repositioning code to take advantage of deferred\nwindow positioning.\nIt&#8217;s really not that hard at all.\n(Save these changes to a new file, though. We&#8217;ll want to run the old\nand new versions side by side.)\n<\/P>\n<PRE>\nvoid\nOnSize(HWND hwnd, UINT state, int cx, int cy)\n{\n  <FONT COLOR=\"blue\">HDWP hdwp = BeginDeferWindowPos(2);<\/FONT>\n  int cxHalf = cx\/2;\n  <FONT COLOR=\"blue\">if (hdwp) hdwp = DeferWindowPos(hdwp,<\/FONT> g_hwndChildren[0],\n               NULL, 0, 0, cxHalf, cy,\n               SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE);\n  <FONT COLOR=\"blue\">if (hdwp) hdwp = DeferWindowPos(hdwp,<\/FONT> g_hwndChildren[1],\n               NULL, cxHalf, 0, cx-cxHalf, cy,\n               SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE);\n  <FONT COLOR=\"blue\">if (hdwp) EndDeferWindowPos(hdwp);<\/FONT>\n}\n<\/PRE>\n<P>\nCompile and run this program, and again, once it&#8217;s up, maximize\nthe window and observe which regions repaint.  Observe that there\nis slightly less repainting in the new version compared to the old version.\n<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The purpose of the DeferWindowPos function is to move multiple child windows at one go. This reduces somewhat the amount of repainting that goes on when windows move around. Take that DC brush sample from a few months ago and make the following changes: HWND g_hwndChildren[2]; BOOL OnCreate(HWND hwnd, LPCREATESTRUCT lpcs) { const static COLORREF [&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-35023","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>The purpose of the DeferWindowPos function is to move multiple child windows at one go. This reduces somewhat the amount of repainting that goes on when windows move around. Take that DC brush sample from a few months ago and make the following changes: HWND g_hwndChildren[2]; BOOL OnCreate(HWND hwnd, LPCREATESTRUCT lpcs) { const static COLORREF [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/35023","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=35023"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/35023\/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=35023"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=35023"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=35023"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}