Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to show a MFC dialog without stealing focus on the other window

Tags:

c++

mfc

I have the dialog shown with ShowWindow(hWnd, SW_SHOWNOACTIVATE); But it doesn't work, the new dialog still steals the focus, why is it?

here is the some code snippets from my program, QueryWindow is the MFC dialog class linked with the dialog:

QueryWindow window;
//window.DoModal();
window.Create(QueryWindow::IDD);
window.ShowWindow(SW_SHOWNOACTIVATE);
like image 838
jay Avatar asked Jan 23 '10 05:01

jay


People also ask

How do I display dialog in MFC?

To create a modal dialog box, call either of the two public constructors declared in CDialog. Next, call the dialog object's DoModal member function to display the dialog box and manage interaction with it until the user chooses OK or Cancel. This management by DoModal is what makes the dialog box modal.

How do you make a modeless dialog box in MFC?

To create a modeless dialog box, call your public constructor and then call the dialog object's Create member function to load the dialog resource. You can call Create either during or after the constructor call. If the dialog resource has the property WS_VISIBLE, the dialog box appears immediately.

How do I close a dialog box in MFC?

A modal dialog box closes when the user chooses one of its buttons, typically the OK button or the Cancel button. Choosing the OK or Cancel button causes Windows to send the dialog object a BN_CLICKED control-notification message with the button's ID, either IDOK or IDCANCEL.

What is MFC dialog box?

MFC supports both kinds of dialog box with class CDialog . The controls are arranged and managed using a dialog-template resource, created with the dialog editor. Property sheets, also known as tab dialog boxes, are dialog boxes that contain "pages" of distinct dialog-box controls.


1 Answers

There are few ways to skip dialog from getting focused:

  • Make you OnInitDialog() to return zero value. Example:

    BOOL QueryWindow::OnInitDialog()
    {
        CDialog::OnInitDialog();
    
        return FALSE; // return 0 to tell MFC not to activate dialog window
    }
    

    This is the best and most correct solution.

  • Add WS_EX_NOACTIVATE style to your dialog window. You can edit dialog resource properties or change it in runtime:

    BOOL QueryWindow::PreCreateWindow(CREATESTRUCT& cs)
    {
        cs.dwExStyle |= WS_EX_NOACTIVATE;
    
        return CDialog::PreCreateWindow(cs);
    }
    

    Side-effect: you can use controls on your window, but it will look like it was not activated.

  • Last way is to save foreground window before creating your dialog and set foreground window at the end:

    BOOL QueryWindow::Create(LPCTSTR lpszTemplateName, CWnd* pParentWnd)
    {
        CWnd* pForeground = GetForegroundWindow();
    
        const BOOL bRes = CAlertDialog::Create(lpszTemplateName, pParentWnd);
    
        if(pForeground)
            pForeground->SetForegroundWindow();
        return bRes;
    }
    

    This is the worth solution because potentially you can get flicker.

Important!

Don't forget to control following API calls:

  • ShowWindow - you can use SW_SHOWNOACTIVATE, but can't use SW_SHOW
  • SetWindowPos - add flag SWP_NOACTIVATE
like image 196
Sergey Avatar answered Jan 30 '23 01:01

Sergey