Solved

MFC Dialog Application with Splash Dialog Box

Posted on 1998-02-17
8
833 Views
Last Modified: 2008-02-01
Application:  MFC Dialog base program with no Main Window.
Before I display the Main Dialog Box, I am doing some processing and displaying a Splash Message Dialog Box to user using a thread.

CMsgDlg  m_MsgDlg;                  // Message CDialog
AfxBeginThread(MessageProc,&m_MsgDlg);      // Start Message
m_MsgDlg.EndDialog(0);                  // Terminate Message

UINT MessageProc (LPVOID pParam)
      {
      CMsgDlg* pDlg = (CMsgDlg*) pParam;      
      pDlg->DoModal();    // Execute Splash Message Dialog
      return 0;          // Terminal Thread
      }

Problem:
If I display a "AfxMessageBox" after terminating the thread "EndDialog", the Message Title Bar of the Message Box is grayed out and not Top Most Window.

If I display my Application Dialog, I get same result until
I select "Set Foreground" in dialog properties.
How can I correct this so it behaves correctly??? Thank You
J Jones...
0
Comment
Question by:JJONES
8 Comments
 

Author Comment

by:JJONES
ID: 1182447
Edited text of question
0
 
LVL 3

Expert Comment

by:q2guo
ID: 1182448
I think the problem here is that after line

m_MsgDlg.EndDialog(0); // Terminate Message

the thread doesn't terminate right away.

So, solution would be to wait till the thread actually terminates

try adding this do loop after the endDialog

LPDWORD exitcode == STILL_ACTIVE;
do {
      ::GetExitCodeThread(PASSIN_HANDTOTHETHREAD, &exitcode);
}while (exitcode == STILL_ACTIVE);

If the specified thread has not terminated, the termination status returned is STILL_ACTIVE

So this loop would make sure that the thread ends before you go on.
0
 

Author Comment

by:JJONES
ID: 1182449
I try your solution but did not work. The Thread is terminated,
but the AfxMessagebox Dialog is gray out and not top most window.

If I issue a AfxMessageBox before starting the my Splash Dialog,
it works great.

The Problem is after splash screen is removed the next window  brought up is not at the top of the Z Order.
SetForegroundWindow() does not work since there is no active
window before AfxMessageBox message is display.

I appreciate your answer, but is there another solution?....
Thank You...

0
Active Directory Webinar

We all know we need to protect and secure our privileges, but where to start? Join Experts Exchange and ManageEngine on Tuesday, April 11, 2017 10:00 AM PDT to learn how to track and secure privileged users in Active Directory.

 
LVL 11

Expert Comment

by:mikeblas
ID: 1182450
This code:

CMsgDlg m_MsgDlg; // Message CDialog
AfxBeginThread(MessageProc,&m_MsgDlg); // Start Message
m_MsgDlg.EndDialog(0); // Terminate Message

is wrong. You shouldn't close the window asyncronously from another thread. Instead, you should post a WM_CLOSE message to the dialog box.

The way you're handling the box is confusing MFC about the owner of the box and the state of the main thread's message pump.

.B ekiM

PS: q2guo's suggstion is bogus; the correct way to wait for the termination of a thread is to use WaitForSingleObject(). Using a relentless loop as he suggested wastes CPU time that the running thread needs, and it isn't a reliable method.
0
 

Author Comment

by:JJONES
ID: 1182451
What's m_pMainWnd at the time you create the thread?

.B ekiM


0
 
LVL 11

Expert Comment

by:mikeblas
ID: 1182452
mikeblas...
m_pMainWnd = 0x00000000 {CWnd hWnd=0xc8000000}

I execute my Splash Message Thread before I create my Main Dialog
Object and DO NOT set "m_pMainWnd" in "InitInstance".
If I set "m_pMainWnd", what would I set it to???

Here is my Code....

BOOL CLoan32App::InitInstance()
{
CMsgDlg m_MsgDlg;       // Splash Message CDialog
AfxBeginThread(MessageProc,&m_MsgDlg);
.
.
EndMessageThread();     // End of Thread
AfxMessageBox.....      // Could Issue an Error Message [Here]
.
CLoan32Dlg  MainDlg;    // Main Dialog Object
int nReturn = MainDlg.DoModal();
.
.
return FALSE;
}

void CLoan32App::EndMessageThread()
{
m_pThread->SuspendThread();  
m_pThread->SetThreadPriority(THREAD_PRIORITY_TIME_CRITICAL);
m_pThread->ResumeThread();

// Put this code here to check for Validate m_MsgDlg Windows
// I have discovered that sometimes this code may execute before
// Thread fully created...

if (IsWindow (m_MsgDlg) ==0)      // Dialog a Valid Window?
    SleepEx (20, TRUE);            // No - Sleep for 20 MilliSeconds

if (IsWindow (m_MsgDlg) ==0)      // Dialog Still Invalid?
    SleepEx (20, TRUE);            // No - Sleep for another 20 ms

m_MsgDlg.SendMessage(WM_CLOSE);
WaitForSingleObject(m_pThread, INFINITE);
}

Thanks again for your Help ....      
0
 

Author Comment

by:JJONES
ID: 1182453
First of all do not pass CWnd derived class pointers across thread boundaries, only variable of type HWND can be passsed. Then I don't understand why you need to display splash screen using another thread, it can be implemented in the main thread without a problem. If you still need create splash screen using multithreading create it in the main htread but other background calculations do in another worker thread. Also use global Win#@ API functions PostMessage and SendMessage to communicate from worker thread to main UI thread.
0
 
LVL 7

Accepted Solution

by:
galkin earned 50 total points
ID: 1182454
Thank you for your help.
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

820 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question