Solved

MFC Dialog Application with Splash Dialog Box

Posted on 1998-02-17
8
853 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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

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

What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.

726 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