{"id":933,"date":"2014-05-22T07:00:00","date_gmt":"2014-05-22T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2014\/05\/22\/why-does-my-radio-button-group-selection-get-reset-each-time-my-window-regains-activation\/"},"modified":"2014-05-22T07:00:00","modified_gmt":"2014-05-22T07:00:00","slug":"why-does-my-radio-button-group-selection-get-reset-each-time-my-window-regains-activation","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20140522-00\/?p=933","title":{"rendered":"Why does my radio button group selection get reset each time my window regains activation?"},"content":{"rendered":"<p>A customer reported (all incomplete information and red herrings preserved):\n<\/p>\n<blockquote CLASS=\"q\">\n<p>\nWe have an issue related to two radio buttons in a window.\nThe code programmatically checks the second button\nby sending the <code>BM_SET&shy;CHECK<\/code> message.\nWe observe that if the user clicks somewhere else on the screen\n(so that our application loses focus),\nand then clicks on the taskbar icon to return to our application,\nthe first radio button spontaneously gets selected.\n<\/p>\n<p>\nWe watched all the messages in Spy++, and it appears\nthat the radio button is receiving a\n<code>WM_SET&shy;FOCUS<\/code>\nfollowed by a\n<code>WM_SET&shy;CHECK<\/code>.\n<\/p>\n<p>\nIs this by design?\nIf not, what should I be looking for in my code that\nis causing this erroneous selection change to occur?\n<\/p>\n<\/blockquote>\n<p>\nThe incomplete information is that the customer\ndidn&#8217;t say how they created those radio buttons.\n<\/p>\n<p>\nThe red herring is that the customer said that\nthey had a problem with their window.\nThis suggested that they were doing a custom window\nimplementation (because if they were using the standard\ndialog implementation, they would have said <i>dialog<\/i>).\n<\/p>\n<p>\nBut from the symptoms,\nit&#8217;s clear that what&#8217;s most likely happening is that\nthe radio button is created as a\n<code>BS_AUTO&shy;RADIO&shy;BUTTON<\/code>.\nAnd automatic radio buttons select themselves\nautomatically (hence the name) when they receive\nfocus.\n<\/p>\n<p>\nThat explains the message sequence\nof\n<code>WM_SET&shy;FOCUS<\/code>\nfollowed by a\n<code>WM_SET&shy;CHECK<\/code>:\nThe automatic radio button receives focus,\nand in response it checks itself.\n<\/p>\n<p>\nTherefore, the next level of investigation\nis why the first radio button is getting focus\nwhen the window is activated.\n<\/p>\n<p>\nIf the application window is a custom window,\nthen the place to look is their window&#8217;s\nactivation and focus code, to see why focus is\ngoing to the first radio button instead of the\nsecond one.\nPerhaps it is putting focus on the first radio\nbutton temporarily, and then later realizes,\n&#8220;Oh wait, I really meant to put it on the second\nradio button.&#8221;\nThe fix would be to get rid of the temporary\nfocus change and go straight to the second\nradio button.\n<\/p>\n<p>\nIf the application window is a standard dialog,\nthen we saw last time that\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2014\/05\/21\/10527168.aspx\">\nthe dialog manager restores focus to the window\nthat had focus last<\/a>,\nand that you could mimic the same behavior in your\nown code.\n<\/p>\n<p>\nIt turns out that the customer was indeed using\na standard dialog,\nin which case the problem is that they put the\ndialog into an inconsistent state:\nThey checked the second radio button but\nleft focus on the first radio button.\nThis is a configuration that exists nowhere in nature,\nand therefore when the dialog manager tries to\nrecreate it (given its lack of specialized knowledge\nabout specific controls), it can&#8217;t.\n<\/p>\n<p>\nThe fix is to put focus on the second radio button\nas well as setting the check box.\nIn fact, you can accomplish both by setting the focus\nto the second radio button\n(noting that\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2004\/08\/02\/205624.aspx\">\nthere is a special process for setting focus in a dialog box<\/a>)\nsince you already are using automatic radio buttons.\n<\/p>\n<p>\nHere&#8217;s a program that demonstrates the problem:\n<\/p>\n<pre>\n\/\/ scratch.rc\n1 DIALOGEX 32, 32, 160, 38\nSTYLE DS_MODALFRAME | DS_SHELLFONT | WS_POPUP | WS_VISIBLE |\n      WS_CAPTION | WS_SYSMENU\nCAPTION \"Test\"\nFONT 9, \"MS Shell Dlg\"\nBEGIN\nCONTROL \"First\", 100, \"Button\",\n        WS_GROUP | WS_TABSTOP | BS_AUTORADIOBUTTON, 4,  4, 152, 13\nCONTROL \"Second\", 101, \"Button\",BS_AUTORADIOBUTTON, 4, 20, 152, 13\nEND\n\/\/ scratch.cpp\n#include &lt;windows.h&gt;\n#include &lt;windowsx.h&gt;\nINT_PTR CALLBACK DlgProc(\n    HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam)\n{\n switch (uMsg) {\n case WM_INITDIALOG:\n  SetFocus(GetDlgItem(hdlg, 100));\n  CheckRadioButton(hdlg, 100, 101, 101);\n  return FALSE;\n case WM_COMMAND:\n  switch (GET_WM_COMMAND_ID(wParam, lParam)) {\n  case 100:\n  case 101:\n    CheckRadioButton(hdlg, 100, 101,\n                     GET_WM_COMMAND_ID(wParam, lParam));\n    break;\n  case IDCANCEL: EndDialog(hdlg, 0); break;\n  }\n }\n return FALSE;\n}\nint WINAPI WinMain(HINSTANCE hinst, HINSTANCE hinstPrev,\n                   LPSTR lpCmdLine, int nShowCmd)\n{\n DialogBox(hinst, MAKEINTRESOURCE(1), nullptr, DlgProc);\n return 0;\n}\n<\/pre>\n<p>\nObserve that we set focus to the first button\nbut check the second button.\nWhen the dialog regains focus, the second button will\nfire a\n<code>WM_COMMAND<\/code> because it thinks it was\nclicked on,\nand in response the dialog box moves the selection to\nthe second button.\n<\/p>\n<p>\nThe fix here is actually pretty simple:\nLet the dialog manager handle the initial focus.\nJust delete the <code>Set&shy;Focus<\/code> call\nand return <code>TRUE<\/code>,\nwhich means,\n&#8220;Hey, dialog manager, you do the focus thing,\ndon&#8217;t worry about me.&#8221;\n<\/p>\n<p>\nAnother fix is to remove the code that updates the radio\nbuttons in response to the <code>WM_COMMAND<\/code> message.\n(I.e., get rid of the entire <code>case 100<\/code> and\n<code>case 101<\/code> handlers.)\nAgain, just let the dialog manager do the usual thing,\nand everything will work out just fine.\n<\/p>\n<p>\nIt&#8217;s great when you can fix a bug by deleting code.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A customer reported (all incomplete information and red herrings preserved): We have an issue related to two radio buttons in a window. The code programmatically checks the second button by sending the BM_SET&shy;CHECK message. We observe that if the user clicks somewhere else on the screen (so that our application loses focus), and then clicks [&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-933","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>A customer reported (all incomplete information and red herrings preserved): We have an issue related to two radio buttons in a window. The code programmatically checks the second button by sending the BM_SET&shy;CHECK message. We observe that if the user clicks somewhere else on the screen (so that our application loses focus), and then clicks [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/933","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=933"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/933\/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=933"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=933"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=933"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}