Как установить фокусировку на CButton, чтобы граница и пунктирная линия фокуса были видны?

Я создал простое диалоговое приложение и в CDialog по умолчанию добавил три кнопки (путем их перетаскивания) с помощью редактора Visual Studio.

Там также есть кнопки ОК и Отмена по умолчанию.

Я хочу установить фокус на кнопку 1, когда я нажимаю кнопку 3.

Я установил для свойства Flat значение true в свойствах кнопок muy.

Я закодировал это:

void CbuttonfocusDlg::OnBnClickedButton3()
{
    // TODO: Add your control notification handler code here
    GetDlgItem(IDC_BUTTON1)->SetFocus();

    Invalidate();

}

Но бодер в button 1 никогда не рисуется. Каретка (пунктирная линия, обозначающая фокус) рисуется только в том случае, если я нажимал клавишу TAB в любое время до нажатия кнопки 3.

Я хочу, чтобы кнопка выглядела точно так же, как она выглядит после нажатия на нее. Показывать пунктирную линию внутри кнопки программно, было бы плюсом.

Что я хочу:

Что я получаю:

4 ответа

Решение

Это рисует толстую границу вокруг кнопки:

static_cast<CButton*>(GetDlgItem(IDC_BUTTON1))->SetButtonStyle(BS_DEFPUSHBUTTON);

Более элегантный способ сделать это - определить переменную-член CButton в CbuttonfocusDlg и связать ее с элементом управления IDC_BUTTON1, а затем вызвать

this->m_myButton.SetButtonStyle(BS_DEFPUSHBUTTON);

Это делает кнопку, на которую я устанавливаю фокус, кнопкой по умолчанию, но учтите, что когда фокус переходит к элементу управления (внутри диалогового окна), который не является кнопкой, кнопка по умолчанию снова становится исходной кнопкой по умолчанию, установленной в ресурс диалога, в данном случае кнопка "ОК".

Использование WM_NEXTDLGCTL,

См . "Как установить фокус в диалоговом окне" Реймонда Чена:

void SetDialogFocus(HWND hdlg, HWND hwndControl)
{
    SendMessage(hdlg, WM_NEXTDLGCTL, (WPARAM)hwndControl, TRUE);
}

При вызове UpdateWindow кнопка перерисовывается, прежде чем изменение фокуса вступит в силу. Invalidate должен быть достаточным сам по себе, окно будет перекрашено, когда все успокоится.

Я следую совету Джоэла. Но немного отличается от API, используемого в этой ссылке, мой:

PostMessage (WM_NEXTDLGCTL, (WPARAM) (pwnd-> GetSafeHwnd ()), TRUE);

Другие вопросы по тегам