Click here to Skip to main content
15,915,160 members
Home / Discussions / C / C++ / MFC
   

C / C++ / MFC

 
AnswerRe: Question about Threads Pin
QuickDeveloper16-Feb-06 19:16
QuickDeveloper16-Feb-06 19:16 
AnswerRe: Question about Threads Pin
Stephen Hewitt16-Feb-06 19:47
Stephen Hewitt16-Feb-06 19:47 
GeneralRe: Question about Threads Pin
Nick_Kisialiou16-Feb-06 19:54
Nick_Kisialiou16-Feb-06 19:54 
GeneralRe: Question about Threads Pin
Stephen Hewitt16-Feb-06 19:58
Stephen Hewitt16-Feb-06 19:58 
GeneralRe: Question about Threads Pin
Nick_Kisialiou16-Feb-06 20:14
Nick_Kisialiou16-Feb-06 20:14 
GeneralRe: Question about Threads Pin
Stephen Hewitt19-Feb-06 11:11
Stephen Hewitt19-Feb-06 11:11 
AnswerRe: Question about Threads Pin
BadKarma16-Feb-06 20:53
BadKarma16-Feb-06 20:53 
GeneralRe: Question about Threads [modified] Pin
BadKarma25-May-06 12:52
BadKarma25-May-06 12:52 
Hi, someone has PM'med me but I can't sent a reply, so i will answer here.

Barry wrote:
I have a situation where I have a user interface thread that is opening a dialog with a progress dialog that is used to show progress on processing going on in the parent thread. The underlying dialog is wrapped in a thread-safe class so messages to the dialog are handled properly. When processing in the parent thread is complete the dialog is gracefully shut down. If the dialog is being moved around when the parent thread tries to shut the thread down by posting a WM_QUIT method to the thread, the ExitInstance method in the CWinThread-derived class used to handle the thread never gets invoked and the thread remains active. I also tried to add a user-defined message with a message handler but the message handler never got invoked when the parent thread sent the message to the thread. Any clues?


I have created a simular test version an can confirm the same error.
I have browsed to the MFC source and have found the problem I have found a solution probably on of the worst in oo design but what the heck if even MFC isn't working like it should Smile | :)

First let me explain what happens.

I have a DLG(main) application wich creates a thread. This thread creates a Modless dlg and closes it on exiting the thread.
The main applaction sends a m_pCloseThread->PostThreadMessage(WM_QUIT,0,0);
To let the thread exit.

This works like intended as long as the dlg in the thread doesn't get moved.
The normal WM_QUIT is getting processed in CWinthread::Run function
...
// pump message, but quit on WM_QUIT
if (!PumpMessage())
	return ExitInstance();
..


But when you move over the window with you mouse the messages of your movement should be redirected to the Message loop of the dialog.
If you click and hold down the left mouse button (in order to drag, but not nessacary) the full message handling is done by the DLG message loop. The thread message loop never gets called any more until you leave the mousebutton. The posted WM_QUIT message isn't processed by the thread message loop (let me call this the parent loop) but by another loop, this loop (child) probably see that the message isn't for him and neglects it.
The parent loop doesn't know anything of that message. I believe it’s a design flaw in the MFC, but this is just my 2 cents :P

I hope that I explained it correctly.

But how do we solve this Design-flaw: Like I said before I have done it Quick and dirty.

1. I've added a Boolean member in the dialog to notify the thread that There was a WM_QUIT sent

2. In the dialog I need to capture a WM_QUIT message. This is done by overriding the WindowProc function (child loop)
LRESULT CClosingInfo::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
  // ADD THIS HERE
  if(message == WM_QUIT)
  {
    m_bOopsImDead = true;
  }

  return CDialog::WindowProc(message, wParam, lParam);
}


3. I also need to override the thread loop (parent) which is in the CWinthread::run function.
The code inside the function can be found in the thrdcore.cpp file of the MFC source codes
int CCloseTrhread::Run()
{
  ASSERT_VALID(this);
  _AFX_THREAD_STATE* pState = AfxGetThreadState();

  // for tracking the idle time state
  BOOL bIdle = TRUE;
  LONG lIdleCount = 0;

  // acquire and dispatch messages until a WM_QUIT message is received.
  for (;; )
  {
    // phase1: check to see if we can do idle work
    while (bIdle &&
	!::PeekMessage(&(pState->m_msgCur), NULL, NULL, NULL, PM_NOREMOVE))
    {
      // call OnIdle while in bIdle state
	if (!OnIdle(lIdleCount++))
	  bIdle = FALSE; // assume "no idle" state
    }

    // phase2: pump messages while available
    do
    {
      // pump message, but quit on WM_QUIT
	if (!PumpMessage())
	  return ExitInstance();

	// reset "no idle" state after pumping "normal" message
	//if (IsIdleMessage(&m_msgCur))
	if (IsIdleMessage(&(pState->m_msgCur)))
	{
	  bIdle = TRUE;
	  lIdleCount = 0;
	}

    } while (::PeekMessage(&(pState->m_msgCur), NULL, NULL, NULL, PM_NOREMOVE));


    //  ADD THIS HERE TO CHECK IF THE THREAD SHOULD BE CLOSED
    if(m_pCloseWindow->m_bOopsImDead)
    {
      return ExitInstance();
    }
  }    // end for(;; )
}


4. Now instead of calling the thread to close, call the dlg
<code>m_pCloseThread->m_pCloseWindow->PostMessage(WM_QUIT, 0 ,0); 
//  m_pCloseThread->PostThreadMessage(WM_QUIT, 0 ,0);</</code>pre>

This works also when no one is dragging or holding the dialog.

Hope that this helps, or at least sets you on its way.
Let me know

Kurt Pattyn
 

codito ergo sum

 -- modified at 18:52 Thursday 25th May, 2006

AnswerRe: Question about Threads Pin
Aqueel17-Feb-06 17:31
Aqueel17-Feb-06 17:31 
AnswerRe: Question about Threads Pin
ThatsAlok17-Feb-06 21:47
ThatsAlok17-Feb-06 21:47 
QuestionGetSafeHdc() allocates new memory or not Pin
anilksingh16-Feb-06 18:38
anilksingh16-Feb-06 18:38 
AnswerRe: GetSafeHdc() allocates new memory or not Pin
Ryan Binns16-Feb-06 19:45
Ryan Binns16-Feb-06 19:45 
AnswerRe: GetSafeHdc() allocates new memory or not Pin
John R. Shaw16-Feb-06 19:57
John R. Shaw16-Feb-06 19:57 
AnswerRe: GetSafeHdc() allocates new memory or not Pin
ThatsAlok17-Feb-06 3:42
ThatsAlok17-Feb-06 3:42 
QuestionQuestion about create simple image in c++/MFC Pin
Yanshof16-Feb-06 18:20
Yanshof16-Feb-06 18:20 
AnswerRe: Question about create simple image in c++/MFC Pin
Stephen Hewitt16-Feb-06 18:36
Stephen Hewitt16-Feb-06 18:36 
AnswerRe: Question about create simple image in c++/MFC Pin
John R. Shaw16-Feb-06 20:03
John R. Shaw16-Feb-06 20:03 
AnswerRe: Question about create simple image in c++/MFC Pin
ThatsAlok17-Feb-06 3:40
ThatsAlok17-Feb-06 3:40 
QuestionIssue with debug and release Pin
super16-Feb-06 16:03
professionalsuper16-Feb-06 16:03 
AnswerRe: Issue with debug and release Pin
ThatsAlok17-Feb-06 3:38
ThatsAlok17-Feb-06 3:38 
GeneralRe: Issue with debug and release Pin
Blake Miller17-Feb-06 4:26
Blake Miller17-Feb-06 4:26 
QuestionHow to realize my own shell format? Pin
Jerry New16-Feb-06 15:22
Jerry New16-Feb-06 15:22 
Questiondynamically creating controls Pin
britboyjohnson16-Feb-06 14:50
britboyjohnson16-Feb-06 14:50 
AnswerRe: dynamically creating controls Pin
Naveen16-Feb-06 16:16
Naveen16-Feb-06 16:16 
AnswerRe: dynamically creating controls Pin
Ganesh_T16-Feb-06 16:20
Ganesh_T16-Feb-06 16:20 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.