I have an MFC Dialog application with an outline of the code shown in the code snippet below. Conceptually, I display a Login Dialog, when login is successful, I display a splash screen while the main Dialog window is initilized and data files are loaded into memory. As laidout in the snippet below, the Login window will apper above any existing applications, the splash screen then displays BEHIND any existing application windows, and then the main Dialog displays above any existing applications.
But now this is where is gets weird. If I modifiy the code to skip the login screen, the splash screen displays INFRONT of existing application windows. The splash screen also displays INFRONT of existing application windows if I create it on the stack inside of CMyDlg.OnInitDialog() . It seems the only time the splash screen displays behind existing windows is in the desired senario (as outlined below).
Now I know one fix is to just create the splash window with WS_EX_TOPMOST. But that seems like a silly bandaid. I'm trying to find out from an education standpoint WHY the splash screen appears behind existing windows.
For what it's worth, in the snippet shown below, CSplashScreen is a wrapper class around the logic for the REAL splash screen code. The REAL splash screen code runs in a seperate UI Thread. The Splash Screen consists of a CWnd derived POPUP window with child windows created with MCIWndCreate. The Splash Screen actually displays an AVI file in a seperate thread while the data is loaded in the main thread.
Obviously lots of code has been left out (like exactly how the 2nd thread is started and all the other stuff needed to make this stuff work.
But the crux of the issue is the fact that my splash screen shows as the top window IF I either skip the login screen OR move the instance of the CSplashScreen object to the local stack in OnInitDialog() rather than as a member object of CMyApp.
//General init code here
// Such as INITCOMMONCONTROLSEX and CWinApp::InitInstance()
m_SplashScreen.Initilize(); //Does things like creates the windows
//but keeps the main window hidden
INT_PTR nResponse = IDRETRY;
while( nResponse == IDRETRY )
if( dlg.IsGood() ) nResponse = IDOK;
if( nResponse == IDOK )
m_SplashScreen.MakeVisible(); //Appears BEHIND other applications
m_pMainWnd = &dlg;
//General Init code here, like CDialog::OnInitDialog()
//Optional Location for SplashScreen...
//CSplashScreen Splash; Splash.Initialize(); Splash.MakeVisible();
//Dialog Initilization code here
// Includes creating child windows and loading data files
g_App.HideSplashScreen(); //CMyApp Function that calls CMyApp::m_SplashScreen.Finished()
//If code referencing CMyApp::m_SplashScreen is commented out
// and uncomment out the Splash Screen created on the stack here
// the Splash Screen displays as normal.
//But as shown, or even if I mode the logic that makes the
// CMyApp::m_SplashScreen become visible from within CMyDlg::OnInitDialog()
// The splash screen appears behind other application windows.
//Crude Outline of class that builds the actual splash screen
//Create 'this' Main Window
CWnd* pDesktop = GetDesktopWindow();
CRect ScreenRect; pDesktop->GetWindowRect( ScreenRect );
int Width = ScreenRect.Width(); int Height = ScreenRect.Height();
CreateEx( WS_EX_STATICEDGE, AfxRegisterWndClass( 0 ), "Splash Screen", WS_POPUP, 0, 0, Width, Height, NULL, NULL ) );
//Create AVI window
DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_DISABLED | MCIWNDF_NOMENU | MCIWNDF_NOOPEN | MCIWNDF_NOPLAYBAR | MCIWNDF_NOERRORDLG | MCIWNDF_NOTIFYMODE;
m_hAVIWnd = MCIWndCreate( m_hWnd, AfxGetInstanceHandle(), dwStyle, m_FileNameAVI );