?
Solved

MFC Dialog Application with Splash Dialog Box

Posted on 1998-02-17
8
Medium Priority
?
861 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
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 150 total points
ID: 1182454
Thank you for your help.
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say 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

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
Suggested Courses

777 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