M. Stocco
M. Stocco

Reputation: 11

In MFC, for an initial focus on a checked RadioButton, setting the text label to be "highlighted"

I am using a Win32 app with MFC in C++ and utilizing Forms with a series of Dialog Screens. My problem is, when I have a series of these screens in sequence, I want the initial focus and its associated text label to be set on a particular radio button. In other screens, if I have a first control widget that is an edit text field, this automatically occurs (i.e. the first control widget in creation and tab order sequence is Focused on, and the text inside that edit text field is highlighted). However, in some dialog screens, the first control widget is a Radio Button group. In these cases, focus is correctly implicitly set to the currently checked radio button. However, the associated text label that describes that label button is displayed un-highlighted. Any subsequent user navigation (by mouse clicks or translation by keyboard) will always highlight the associated text label, when any radio button is checked or selected. However, only in this initial dialog screen creation, I cannot get the text label to be highlighted.

To clarify, by "highlight" I mean a perforated outline surrounding the text label beside the circular radio button image.

Here are some of the things I have tried in the OnInitDialog() function of said Dialog screens:

SendDlgItemMessage(IDC_RADIO1, BM_SETCHECK, BST_CHECKED, 0);

Which does display the filled in circular button representing it is checked, but the associated text label is still not highlighted.

I've also tried to "force" it to treat it as a button clicked message:

HWND hwdButton = ::GetDlgItem(m_hWnd, IDC_RADIO1);
::PostMessage(m_hWnd, WM_COMMAND, MAKELONG(IDC_RADIO1, BN_CLICKED),
              (LPARAM) hwdButton);

I've also tried to send an explicit message to set the "State" (where, for a RadioButton, I believe having the State ON or true is represented by the highlighting of the text).

SendDlgItemMessage(IDC_RADIO1, BM_SETSTATE, TRUE, 0);

I've also tried doing these operations with or without a subsequent UpdateData(false) to refresh and with or without separately setting the focus and returning from the OnInitDialog() with a false instead of true. None of these combinations has any apparent impact on the GUI behavior.

The focus is always implicitly set on the correct radio button, and it's displayed as being correctly checked, just no highlighted text label, and any subsequent navigation or traversal yields the appropriate highlighted text labels.

The problem is on the initial dialog screen creation only.

Thanks for any help or recommendations.

Upvotes: 0

Views: 1413

Answers (1)

M. Stocco
M. Stocco

Reputation: 11

Per the reference in @cha comment above, the reason the "focus rectangle" is not appearing has to do with a Microsoft Windows display setting. That column gets into how to change the setting in various flavors of Windows. In actuality, this is apparently the standard configuration for Windows MFC behavior - when focus is on a dialog control widget that is a radio button upon initialization, the "focus rectangle" is intentionally and specifically withheld from being drawn until the user initiates a keyboard navigation event (i.e. tab/enter/arrow keys). The problem with that (as already seen and illustrated in the problem description above) is that it changes the focus - and can be misleading to the user when the focus was actually already correctly set, just wasn't being indicated with the "focus rectangle".

The "exception" which draws the focus rectangle in-place, without having to change focus, is to depress the <Alt> Key on the keyboard.

After some digging elsewhere, I utilized this code to simulate the keyboard event of the depress of an <Alt> Key at the end of the OnInitDialog() function, and this yielded the desired behavior, the focus is set as desired, and the "focus rectangle" is drawn around the label of the currently selected radio button:

// Simulating an <Alt> keystroke.
keybd_event(VK_MENU, 0xb8, 0, 0); // Depress `Alt` key.
keybd_event(VK_MENU, 0xb8, KEYEVENTF_KEYUP, 0); // Release `Alt` key.

Upvotes: 0

Related Questions