22

I created an application in which I use window procedure to keep track of all the controls in the window.

My question is, how do I initially set the focus to the first created control in the window?

Cody Gray
  • 222,280
  • 47
  • 466
  • 543
karthik
  • 16,456
  • 70
  • 72
  • 119

1 Answers1

45

There are two ways to set the initial focus to a particular control in MFC.

  1. The first, and simplest, method is to take advantage of your controls' tab order. When you use the Resource Editor in Visual Studio to lay out a dialog, you can assign each control a tab index. The control with the lowest tab index will automatically receive the initial focus. To set the tab order of your controls, select "Tab Order" from the "Format" menu, or press Ctrl+D.

  2. The second, slightly more complicated, method is to override the OnInitDialog function in the class that represents your dialog. In that function, you can set the input focus to any control you wish, and then return FALSE to indicate that you have explicitly set the input focus to one of the controls in the dialog box. If you return TRUE, the framework automatically sets the focus to the default location, described above as the first control in the dialog box. To set the focus to a particular control, call the GotoDlgCtrl method and specify your control. For example:

    BOOL CMyDialog::OnInitDialog()
    {
        CDialog::OnInitDialog();
    
        // Add your initialization code here
        // ...
    
        // Set the input focus to your control
        GotoDlgCtrl(GetDlgItem(IDC_EDIT)); 
    
        // Return FALSE because you manually set the focus to a control
        return FALSE;
    }
    

    Note that you should not set focus in a dialog box by simply calling the SetFocus method of a particular control. Raymond Chen explains here on his blog why it's more complicated than that, and why the GotoDlgCtrl function (or its equivalent, the WM_NEXTDLGCTRL message) is preferred.

Nathan Campos
  • 26,567
  • 57
  • 185
  • 289
Cody Gray
  • 222,280
  • 47
  • 466
  • 543
  • 1
    @Karthik: If you're doing it in the window procedure, you're not setting the initial focus. The initial focus is the control that has the focus when your dialog is first displayed. To set that, you need to use one of the two methods I described. Furthermore, there's *rarely* a need to override the `WndProc` function when you're using MFC. You should use the specific functions for the messages you want to respond to. But if you insist on doing it that way, you can still use the `GotoDlgCtrl` method, as I demonstrated in the second portion of my answer. – Cody Gray Feb 25 '11 at 07:21
  • 1
    My error was in that I called SetFocus() on the GetDlgItem() CWnd pointer, not GotoDlgCtrl(). GotoDlgCtrl() worked, but SetFocus() did not. – franji1 Apr 29 '15 at 18:36
  • 2
    For anyone wondering how the tab order is stored in the resource file code (`*.rc`), it appears to be determined by the order of the control entries. – Herohtar May 23 '19 at 20:55
  • Yes, that's correct, @Herohtar. The default tab order is equivalent to the Z order. – Cody Gray May 23 '19 at 20:58