{"id":36373,"date":"2005-02-24T06:58:00","date_gmt":"2005-02-24T06:58:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2005\/02\/24\/modality-part-5-setting-the-correct-owner-for-modal-ui\/"},"modified":"2005-02-24T06:58:00","modified_gmt":"2005-02-24T06:58:00","slug":"modality-part-5-setting-the-correct-owner-for-modal-ui","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20050224-00\/?p=36373","title":{"rendered":"Modality, part 5: Setting the correct owner for modal UI"},"content":{"rendered":"<p>\nHere is the very simple fix for\n<a href=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2005\/02\/23\/378866.aspx\">\nthe buggy program we presented last time<\/a>.\n<\/p>\n<pre>\nvoid OnChar(HWND hwnd, TCHAR ch, int cRepeat)\n{\n  switch (ch) {\n  case ' ':\n    MessageBox(<font COLOR=\"blue\">hwnd<\/font>, TEXT(\"Message\"), TEXT(\"Title\"), MB_OK);\n    if (!IsWindow(hwnd)) MessageBeep(-1);\n    break;\n  }\n}\n<\/pre>\n<p>\nWe have fixed the problem by passing the correct owner window\nfor the modal UI.  Since <code>MessageBox<\/code> is modal,\nit disables the owner while the modal UI is being displayed,\nthereby preventing the user from destroying or\nchanging the owner window&#8217;s state when it is not expecting it.\n<\/p>\n<p>\nThis is why all the shell functions that can potentially display\nUI accept a window handle as one of its parameters.\nThey need to know which window to use as the owner for any\nnecessary UI dialogs. If you call such functions from a thread\nthat is hosting UI, you must pass the handle to the window you\nwant the shell to use as the UI owner.  If you pass NULL\n(or worse, <code>GetDesktopWindow<\/code>), you may find yourself\nin the same bad state that our buggy sample program demonstrated.\n<\/p>\n<p>\nIf you are displaying a modal dialog from another modal dialog,\nit is important to pass the correct window as the owner for\nthe second dialog.  Specifically, you need to pass the modal dialog\ninitiating the sub-dialog and not the original frame window.\nHere&#8217;s a stack diagram illustrating:\n<\/p>\n<pre>\n MainWindow\n  DialogBox(hwndOwner = main window) [dialog 1]\n   ... dialog manager ...\n    DlgProc\n     DialogBox(hwndOwner = <u>dialog 1<\/u>) [dialog 2]\n<\/pre>\n<p>\nIf you mess up and pass the main window handle when\ncreating the second modal dialog, you will find yourself\nback in a situation analogous to what we had last time:\nThe user can dismiss the first dialog while the second\ndialog is up, leaving its stack frames orphaned.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Here is the very simple fix for the buggy program we presented last time. void OnChar(HWND hwnd, TCHAR ch, int cRepeat) { switch (ch) { case &#8216; &#8216;: MessageBox(hwnd, TEXT(&#8220;Message&#8221;), TEXT(&#8220;Title&#8221;), MB_OK); if (!IsWindow(hwnd)) MessageBeep(-1); break; } } We have fixed the problem by passing the correct owner window for the modal UI. Since MessageBox [&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,143],"class_list":["post-36373","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code","tag-modality"],"acf":[],"blog_post_summary":"<p>Here is the very simple fix for the buggy program we presented last time. void OnChar(HWND hwnd, TCHAR ch, int cRepeat) { switch (ch) { case &#8216; &#8216;: MessageBox(hwnd, TEXT(&#8220;Message&#8221;), TEXT(&#8220;Title&#8221;), MB_OK); if (!IsWindow(hwnd)) MessageBeep(-1); break; } } We have fixed the problem by passing the correct owner window for the modal UI. Since MessageBox [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/36373","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=36373"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/36373\/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=36373"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=36373"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=36373"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}