{"id":563,"date":"2014-07-07T07:00:00","date_gmt":"2014-07-07T14:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2014\/07\/07\/customing-the-standard-color-picker-dialog\/"},"modified":"2014-07-07T07:00:00","modified_gmt":"2014-07-07T14:00:00","slug":"customing-the-standard-color-picker-dialog","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20140707-00\/?p=563","title":{"rendered":"Customing the standard color-picker dialog"},"content":{"rendered":"<p>\nToday&#8217;s Little Program does a little bit of customization\nof the <code>Choose&shy;Color<\/code> dialog.\nWe do this by, um,\n<a HREF=\"http:\/\/msdn.microsoft.com\/library\/ms646951\">\ndoing what the documentation says<\/a>.\n<\/p>\n<p>\nFor the color dialog, we take the template in\n<code>color.dlg<\/code> and modify it.\nJust to get our feet wet, we won&#8217;t customize anything at all!\nThis ensures that we have the basics down\nbefore we start trying anything fancy.\n<\/p>\n<p>\n<b>Handy tip<\/b>:\nBefore trying to customize something,\nfirst write code that does it uncustomized.\nThat way, you have a known working starting point.\n<\/p>\n<pre>\n#include &lt;windows.h&gt;\n#include &lt;colordlg.h&gt;\n1 DIALOG LOADONCALL MOVEABLE DISCARDABLE 2, 0, 298, 184\nSTYLE WS_BORDER | DS_MODALFRAME | WS_CAPTION | WS_POPUP | WS_SYSMENU |\n      DS_3DLOOK\nCAPTION \"Color\"\nFONT 8 \"MS Shell Dlg\"\nBEGIN\n    LTEXT           \"&amp;Basic colors:\", -1, 4, 4, 140, 9\n    CONTROL         \"\", COLOR_BOX1, \"static\",\n                    SS_SIMPLE | WS_CHILD | WS_TABSTOP | WS_GROUP,\n                    4, 14, 140, 86\n    LTEXT           \"&amp;Custom colors:\", -1, 4, 106, 140, 9\n    CONTROL         \"\",  COLOR_CUSTOM1, \"static\",\n                    SS_SIMPLE | WS_CHILD | WS_TABSTOP | WS_GROUP,\n                    4, 116, 140, 28\n    PUSHBUTTON      \"&amp;Define Custom Colors &gt;&gt;\" COLOR_MIX, 4, 150, 138, 14,\n                    WS_TABSTOP | WS_GROUP\n    DEFPUSHBUTTON   \"OK\", IDOK, 4, 166, 44, 14, WS_GROUP | WS_TABSTOP\n    PUSHBUTTON      \"Cancel\", IDCANCEL, 52, 166, 44, 14, WS_GROUP | WS_TABSTOP\n    PUSHBUTTON      \"&amp;Help\", pshHelp, 100, 166, 44, 14, WS_GROUP | WS_TABSTOP\n    CONTROL         \"\", COLOR_RAINBOW, \"static\",\n                    SS_SUNKEN | SS_SIMPLE | WS_CHILD, 152, 4, 118, 116\n    CONTROL         \"\", COLOR_LUMSCROLL, \"static\",\n                    SS_SUNKEN | SS_SIMPLE | WS_CHILD, 280, 4, 8, 116\n    CONTROL         \"\", COLOR_CURRENT, \"static\",\n                    SS_SUNKEN | SS_SIMPLE | WS_CHILD, 152, 124, 40, 26\n    PUSHBUTTON      \"&amp;o\", COLOR_SOLID, 300, 200, 4, 14, WS_GROUP\n    RTEXT           \"Color\", COLOR_SOLID_LEFT, 152, 151, 20, 9\n    LTEXT           \"|S&amp;olid\", COLOR_SOLID_RIGHT, 172, 151, 20, 9\n    RTEXT           \"Hu&amp;e:\", COLOR_HUEACCEL, 194, 126, 20, 9\n    EDITTEXT,       COLOR_HUE, 216, 124, 18, 12, WS_GROUP | WS_TABSTOP\n    RTEXT           \"&amp;Sat:\", COLOR_SATACCEL, 194, 140, 20, 9\n    EDITTEXT,       COLOR_SAT, 216, 138, 18, 12, WS_GROUP | WS_TABSTOP\n    RTEXT           \"&amp;Lum:\", COLOR_LUMACCEL, 194, 154, 20, 9\n    EDITTEXT,       COLOR_LUM, 216, 152, 18, 12, WS_GROUP | WS_TABSTOP\n    RTEXT           \"&amp;Red:\", COLOR_REDACCEL, 243, 126, 24, 9\n    EDITTEXT,       COLOR_RED, 269, 124, 18, 12, WS_GROUP | WS_TABSTOP\n    RTEXT           \"&amp;Green:\", COLOR_GREENACCEL, 243, 140, 24, 9\n    EDITTEXT,       COLOR_GREEN, 269, 138, 18, 12, WS_GROUP | WS_TABSTOP\n    RTEXT           \"Bl&amp;ue:\", COLOR_BLUEACCEL, 243, 154, 24, 9\n    EDITTEXT,       COLOR_BLUE, 269, 152, 18, 12, WS_GROUP | WS_TABSTOP\n    PUSHBUTTON      \"&amp;Add to Custom Colors\", COLOR_ADD, 152, 166, 142, 14,\n                    WS_GROUP | WS_TABSTOP\nEND\n<\/pre>\n<p>\nOur resource file is just a copy of the original\n<code>color.dlg<\/code> file with no customizations.\nWe stick a\n<code>windows.h<\/cODE> in front,\nand assign it a custom resource ID of 1.\nLet's see if we can display it.\n<\/p>\n<pre>\n#define UNICODE\n#define <a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2004\/02\/12\/71851.aspx\">_UNICODE<\/a>\n#define STRICT\n#include &lt;windows.h&gt;\n#include &lt;commdlg.h&gt;\nint WINAPI wWinMain(\n    HINSTANCE hinst, HINSTANCE hinstPrev,\n    LPWSTR lpCmdLine, int nCmdShow)\n{\n COLORREF rgCustColors[16] = { 0 };\n CHOOSECOLOR cc = { sizeof(cc) };\n cc.hInstance = reinterpret_cast&lt;HWND&gt;(hinst);\n cc.lpTemplateName = MAKEINTRESOURCE(1);\n cc.Flags = CC_ENABLETEMPLATE;\n cc.lpCustColors = rgCustColors;\n if (ChooseColor(&amp;cc)) {\n  MessageBox(nullptr, TEXT(\"Thank you\"), TEXT(\"Sample\"), MB_OK);\n }\n return 0;\n}\n<\/pre>\n<p>\nThe <code>hInstance<\/code> member of the\n<code>CHOOSE&shy;COLOR<\/code>\nstructure is incorrectly declared as <code>HWND<\/code>,\nso we need to stick in a cast to keep everybody happy.\n<\/p>\n<p>\nRun this program, and... everything looks perfectly normal.\nGood!\nNow we can customize it.\n<\/p>\n<p>\nFirst, let's just add a message to the dialog.\n<\/p>\n<pre>\n1 DIALOG LOADONCALL MOVEABLE DISCARDABLE 2, 0, 298, <font COLOR=\"blue\">198<\/font>\n...\n    <font COLOR=\"blue\">LTEXT           \"Don't forget to smile!\",\n                    -1, 4, 166, 138, 14<\/font>\n    DEFPUSHBUTTON   \"OK\", IDOK, 4, <font COLOR=\"blue\">180<\/font>, 44, 14, WS_GROUP | WS_TABSTOP\n    PUSHBUTTON      \"Cancel\", IDCANCEL, 52, <font COLOR=\"blue\">180<\/font>, 44, 14, WS_GROUP | WS_TABSTOP\n    PUSHBUTTON      \"&amp;Help\", pshHelp, 100, <font COLOR=\"blue\">180<\/font>, 44, 14, WS_GROUP | WS_TABSTOP\n...\n<\/pre>\n<p>\nRebuild the program and run it.\nHey look, a happy message!\nNote that in order to fit the message in the dialog box,\nwe had to make the dialog box taller\nand move some buttons out of the way.\n<\/p>\n<p>\nJust adding static text is nice,\nbut it's not particularly interesting.\nSo let's add a check box to the dialog too.\n<\/p>\n<pre>\n    <font COLOR=\"blue\">AUTOCHECKBOX    \"I remembered to s&amp;mile\",\n                    1000<\/font>, 4, 166, 138, 14<font COLOR=\"blue\">, WS_TABSTOP<\/font>\n<\/pre>\n<p>\nIn addition to remembering the color the user chose,\nwe also want to remember whether they checked the box that\nsays that they smiled.\nThe documentation says that when the hook procedure receives a\n<code>WM_INIT&shy;DIALOG<\/code>,\nthe <code>lParam<\/code> points to the\n<code>CHOOSE&shy;COLOR<\/code> dialog.\nWe therefore have two options for passing extra data to the\nhook procedure.\n<\/p>\n<ul>\n<li>We can pass a pointer to extra data in the\n    <code>lCust&shy;Data<\/code> member.\n    This is the traditional method.<\/p>\n<li>We can append our custom data to the\n    <code>CHOOSE&shy;COLOR<\/code> structure.\n    This is\n    <a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2010\/12\/17\/10106259.aspx\">\n    the technique used by the <code>OVERLAPPED<\/code> structure<\/a>.\n<\/ul>\n<p>\nI'll use the traditional method for now.\nThe <code>lCust&shy;Data<\/code> is a pointer to a <code>BOOL<\/code>\nthat receives the checkbox state on exit.\n<\/p>\n<pre>\n<font COLOR=\"blue\">UINT_PTR CALLBACK CCHookProc(\n    HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam)\n{\n  switch (uMsg)\n  {\n  case WM_INITDIALOG:\n    {\n      auto pcc = reinterpret_cast&lt;CHOOSECOLOR*&gt;(lParam);\n      auto pfSmiled = reinterpret_cast&lt;BOOL*&gt;(pcc-&gt;lCustData);\n      SetProp(hdlg, TEXT(\"SmileResult\"), pfSmiled);\n    }\n    break;\n  case WM_DESTROY:\n    {\n      auto pfSmiled = reinterpret_cast&lt;BOOL*&gt;(\n           GetProp(hdlg, TEXT(\"SmileResult\")));\n      if (pfSmiled) {\n       *pfSmiled = IsDlgButtonChecked(hdlg, 1000);\n      }\n      RemoveProp(hdlg, TEXT(\"SmileResult\"));\n    }\n  }\n  return 0;\n}<\/font>\nint WINAPI wWinMain(\n    HINSTANCE hinst, HINSTANCE hinstPrev,\n    LPWSTR lpCmdLine, int nCmdShow)\n{\n COLORREF rgCustColors[16] = { 0 };\n <font COLOR=\"blue\">BOOL fSmiled = FALSE;<\/font>\n CHOOSECOLOR cc = { sizeof(cc) };\n cc.hInstance = reinterpret_cast&lt;HWND&gt;(hinst);\n cc.lpTemplateName = MAKEINTRESOURCE(1);\n cc.Flags = CC_ENABLETEMPLATE <font COLOR=\"blue\"> | CC_ENABLEHOOK<\/font>;\n cc.lpCustColors = rgCustColors;\n <font COLOR=\"blue\">cc.lCustData = reinterpret_cast&lt;LPARAM&gt;(&amp;fSmiled);\n cc.lpfnHook = CCHookProc<\/font>;\n if (ChooseColor(&amp;cc) <font COLOR=\"blue\">&amp;&amp; !fSmiled<\/font>) {\n  MessageBox(nullptr, TEXT(\"<font COLOR=\"blue\">You forgot to smile.<\/font>\"),\n             TEXT(\"Sample\"), MB_OK);\n }\n return 0;\n}\n<\/pre>\n<p>\nNow, the program displays a message if you selected a color\nbut did not check the\n<i>I remembered to smile<\/i>\nbox.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A custom template, or possibly a custom hook function.<\/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-563","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>A custom template, or possibly a custom hook function.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/563","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=563"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/563\/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=563"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=563"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=563"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}