1

I created a simple dialog-based application, and in the default CDialog added three buttons (by drag-and-dropping them) using the Visual Studio editor.

The default OK and Cancel buttons are there too.

I want to set the focus to button 1 when I click button 3.

I set the property Flat to true in the properties for muy buttons.

I coded this:

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

    Invalidate();

}

But the boder in button1 is never drawn. The caret (the dotted line indicating focus) is only drawn if I pressed TAB any time before clicking button 3.

I want the button to look exactly as it looks after I click it. Showing the dotted line inside the button programatically, would be a plus.

What I want:

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

What I get:

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

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
LLucasAlday
  • 2,349
  • 11
  • 34
  • 41
  • I just tried to duplicate your test app in VC6 and XP - it works correctly, although the default button border alternates between setfocus and OK. – Mark Ransom Dec 16 '08 at 01:55

4 Answers4

4

Use WM_NEXTDLGCTL.

See Reymond Chen's "How to set focus in a dialog box":

void SetDialogFocus(HWND hdlg, HWND hwndControl)
{
    SendMessage(hdlg, WM_NEXTDLGCTL, (WPARAM)hwndControl, TRUE);
}
Thomas Weller
  • 55,411
  • 20
  • 125
  • 222
Joel
  • 369
  • 1
  • 3
  • +1. The OP is asking the wrong question, caused by a misunderstanding of how dialogs work. OP, please be careful that the behavior you implement follows 'normal' window UI rules about default buttons etc. (i.e., that pressing enter after opening the dialog does something intuitive). – Roel Dec 19 '08 at 15:05
0

I am following Joel's suggestion. But slightly different with the API used in that link, my one is :

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

0

By calling UpdateWindow, the button is being redrawn before the focus change can take effect. The Invalidate should be sufficient by itself, the window will get repainted when everything settles down.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
0

This draws the thick border around the button:

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

A more elegant way to do this would be to define a CButton member variable in CbuttonfocusDlg and associate it to the IDC_BUTTON1 control, and then calling

this->m_myButton.SetButtonStyle(BS_DEFPUSHBUTTON);

This makes the button to which I'm setting the focus the default button, but note that when the focus goes to a control (inside the dialog) that is not a button, the default button is once more the original default button set in the dialog resource, in this case the "Ok" button.

LLucasAlday
  • 2,349
  • 11
  • 34
  • 41
  • Aha, I misunderstood the question! I'm sorry, I could have come up with this answer yesterday. You kept emphasizing the word "focus", and the dotted line is the official focus indicator. – Mark Ransom Dec 16 '08 at 23:03