{"id":36003,"date":"2005-03-31T06:58:00","date_gmt":"2005-03-31T06:58:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2005\/03\/31\/the-dialog-manager-part-3-creating-the-controls\/"},"modified":"2005-03-31T06:58:00","modified_gmt":"2005-03-31T06:58:00","slug":"the-dialog-manager-part-3-creating-the-controls","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20050331-00\/?p=36003","title":{"rendered":"The dialog manager, part 3: Creating the controls"},"content":{"rendered":"<p>\nThis is actually a lot less work than creating the frame,\nbelieve it or not.\n<\/p>\n<p>\nFor each control in the template, the corresponding child\nwindow is created.  The control&#8217;s sizes and position is\nspecified in the template in DLUs, so of course they need\nto be converted to pixels.\n<\/p>\n<pre>\n  int x = XDLU2Pix(ItemTemplate.x);\n  int y = YDLU2Pix(ItemTemplate.y);\n  int cx = XDLU2Pix(ItemTemplate.cx);\n  int cy = YDLU2Pix(ItemTemplate.cy);\n<\/pre>\n<p>\nThe class name and caption also come from the template.\nThere are also the optional extra bytes <code>pExtra<\/code> which nobody uses\nbut which remain in the template definition for historical reasons.\nOnce that information has been collected,\nit&#8217;s\n<a HREF=\"http:\/\/www.dunkindonuts.com\/\" \/>time to make the donuts<\/a>.\n<\/p>\n<pre>\n  HWND hwndChild = CreateWindowEx(\n              ItemTemplate.dwExStyle | WS_EX_NOPARENTNOTIFY,\n              pszClass, pwzCaption, ItemTemplate.dwStyle,\n              x, y, cx, cy, hdlg, ItemTemplate.dwId,\n              hinst, pExtra);\n<\/pre>\n<p>\nNotice that the <code>WS_EX_NOPARENTNOTIFY<\/code> style is forced on\nfor dialog controls.\n<\/p>\n<p>\nThis next part often trips people up.  &#8220;When I try to create\nmy dialog, it fails and I don&#8217;t know why.&#8221;  It&#8217;s probably\nbecause one of the controls on the dialog could not be created,\nusually\nbecause you forgot to register the window class for that\ncontrol.  (For example, you forgot to call\n<a HREF=\"http:\/\/msdn.microsoft.com\/library\/en-us\/shellcc\/platform\/commctls\/common\/functions\/initcommoncontrolsex.asp\">\nthe <code>InitCommonControlsEx<\/code> function<\/a>\nor\nyou forgot to\n<code>LoadLibrary<\/code> the appropriate version of the RichEdit control.)\n<\/p>\n<pre>\n  if (!hwndChild) {\n    DestroyWindow(hdlg);\n    return NULL;\n  }\n<\/pre>\n<p>\nThe <code>DS_NOFAILCREATE<\/code> style suppresses the failure check above.\n<\/p>\n<p>\nBut if the control did get created, then it needs to be\ninitialized.\n<\/p>\n<pre>\n  SetWindowContextHelpId(hwndChild, ItemTemplate.dwHelpID);\n  SetWindowFont(hwndChild, hf, FALSE);\n<\/pre>\n<p>\nRepeat once for each item template, and you now have a dialog\nbox with all its child controls.\nTell the dialog procedure that it can initialize its child windows,\nshow the (now-ready) dialog box\n<a HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2004\/03\/11\/87941.aspx\">\nif we deferred the <code>WS_VISIBLE<\/code> bit\nwhen constructing the frame<\/a>,\nand return the dialog box to our caller, ready for action.\n<\/p>\n<pre>\n  \/\/ The default focus is the first item that is a valid tab-stop.\n  HWND hwndDefaultFocus = GetNextDlgTabItem(hdlg, NULL, FALSE);\n  if (SendMessage(hdlg, WM_INITDIALOG, hwndDefaultFocus, lParam)) {\n     SetDialogFocus(hwndDefaultFocus);\n  }\n  if (fWasVisible) ShowWindow(hdlg);\n  return hdlg;\n}\n<\/pre>\n<p>\nThe <code>SetDialogFocus<\/code> function\n<a HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2004\/08\/02\/205624.aspx\">\nwe saw last year<\/a>.\n<\/p>\n<p>\nSo there you have it:  You have now seen how dialog box\nsausages are made.\n<\/p>\n<p>\n(Actually, reality is much sausagier, since I skipped\nover all the app compat hacks!  For example, there&#8217;s a\nprogram out there that relies on the subtle placement and absence\nof the <code>WS_BORDER<\/code> style to decide whether a control is a combo\nbox or a listbox.  I guess\n<a HREF=\"http:\/\/msdn.microsoft.com\/library\/en-us\/winui\/WinUI\/WindowsUserInterface\/Windowing\/WindowClasses\/WindowClassReference\/WindowClassFunctions\/GetClassName.asp\">\nthe <code>GetClassName<\/code> function<\/a> was too much work?)\n<\/p>\n<p>\nI hope this helps you understand\na little better how dialog templates fit into the big picture.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is actually a lot less work than creating the frame, believe it or not. For each control in the template, the corresponding child window is created. The control&#8217;s sizes and position is specified in the template in DLUs, so of course they need to be converted to pixels. int x = XDLU2Pix(ItemTemplate.x); int y [&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-36003","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>This is actually a lot less work than creating the frame, believe it or not. For each control in the template, the corresponding child window is created. The control&#8217;s sizes and position is specified in the template in DLUs, so of course they need to be converted to pixels. int x = XDLU2Pix(ItemTemplate.x); int y [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/36003","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=36003"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/36003\/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=36003"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=36003"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=36003"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}