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

StackOverflow https://stackoverflow.com/questions/369788

Вопрос

Я создал простое диалоговое приложение и в 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.

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

Что я хочу:

http://i33.tinypic.com/11t8pkl.png

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

http://i37.tinypic.com/160q5hw.png

Это было полезно?

Решение 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);

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top