[Last Call] Learn about multicloud storage options and how to improve your company's cloud strategy. Register Now

x
?
Solved

MFC Dialog Application with Splash Dialog Box

Posted on 1998-02-17
8
Medium Priority
?
896 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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
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

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

Question has a verified solution.

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

In days of old, returning something by value from a function in C++ was necessarily avoided because it would, invariably, involve one or even two copies of the object being created and potentially costly calls to a copy-constructor and destructor. A…
Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
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.

650 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