Как установить фокус на CButton, чтобы были видны граница и пунктирная линия фокуса?
Вопрос
Я создал простое диалоговое приложение и в CDialog по умолчанию добавил три кнопки (путем их перетаскивания) с помощью редактора Visual Studio.
Кнопки «ОК» и «Отмена» по умолчанию также присутствуют.
Я хочу установить фокус на кнопку 1, когда я нажимаю кнопку 3.
В свойствах многих кнопок я установил для свойства Flat значение true.
Я закодировал это:
void CbuttonfocusDlg::OnBnClickedButton3()
{
// TODO: Add your control notification handler code here
GetDlgItem(IDC_BUTTON1)->SetFocus();
Invalidate();
}
Но рамка в button1 никогда не рисуется.Каретка (пунктирная линия, обозначающая фокус) рисуется только в том случае, если я нажимал TAB в любой момент перед нажатием кнопки 3.
Я хочу, чтобы кнопка выглядела точно так же, как после того, как я ее нажму.Программное отображение пунктирной линии внутри кнопки было бы плюсом.
Что я хочу:
Что я получаю:
Решение 3
Это рисует толстую рамку вокруг кнопки:
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);