Assertion Error with DoModal(), activated from a thread


DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Results 1 to 4 of 4

Thread: Assertion Error with DoModal(), activated from a thread

  1. #1
    Join Date
    May 2004
    Posts
    70

    Assertion Error with DoModal(), activated from a thread

    hi, as with the topic, i am a newbie at MFC programming and ii am having trouble with DoModal
    it shows the window but immediately give an assertion error



    here's how the application init looks like:
    Code:
    BOOL CAsevApp::InitInstance()
    {
    	time_stop_dlg dlg;
    	m_pMainWnd = &dlg;
    	AfxBeginThread ( th_start_accept, (LPVOID)this );
    	return TRUE;
    }
    over here, time_stop_dlg is a class derived from CDialog, without any changes, but has been linked to IDD_MY_DIALOG_TO_SHOW (as suggested by classwizard)



    this is the thread procedure:
    Code:
    UINT CAsevApp::th_start_accept( LPVOID lpvParam )
    {
        CAsevApp *th_start_accept = (CAsevApp*)lpvParam;
        th_start_accept->process_received_msg(buffer);
       return 0;
    }
    process_received_msg(buffer) is a function member of CAsevApp
    Code:
    void CAsevApp::process_received_msg(char *msg)
    {
    		time_stop_dlg time_stop_dlg_obj;
    		time_stop_dlg_obj.DoModal(); // NIGHTMARE BEGINS HERE!
    }

    a snippet of wincore assertion error:
    Code:
    BOOL PASCAL CWnd::WalkPreTranslateTree(HWND hWndStop, MSG* pMsg)
    {
    	ASSERT(hWndStop == NULL || ::IsWindow(hWndStop));
    	ASSERT(pMsg != NULL);
    
    	// walk from the target window up to the hWndStop window checking
    	//  if any window wants to translate this message
    
    	for (HWND hWnd = pMsg->hwnd; hWnd != NULL; hWnd = ::GetParent(hWnd))
    	{
    		CWnd* pWnd = CWnd::FromHandlePermanent(hWnd);
    		if (pWnd != NULL)
    		{
    			// target window is a C++ window
    			if (pWnd->PreTranslateMessage(pMsg))
    				return TRUE; // trapped by target window (eg: accelerators)
    		}
    
    		// got to hWndStop window without interest
    		if (hWnd == hWndStop)
    			break;
    	}
    	return FALSE;       // no special processing
    }


    using
    vc6.0 sp6

    your assistance please! :WAVE:

  2. #2
    Join Date
    Jul 2005
    Posts
    26
    MFC window objects are not thread safe, AFAIK MFC uses thread local storage. Do never access MFC window objects (including controls) created by one thread in another thread.

  3. #3
    Join Date
    Dec 2003
    Posts
    3,366
    You can work around this problem (sometimes), if you *must* using critical sections, volatile variables, and whatnot to ensure only one thread is touching a mfc object at any one time but in general try not to design code that needs this. The problem is a lot of the automatic windows stuff can't be wrapped on your end in a critical section, so sometimes the problem can't be fixed at all.

  4. #4
    Join Date
    Jul 2005
    Posts
    26
    Quote Originally Posted by jonnin
    You can work around this problem (sometimes), if you *must* using critical sections, volatile variables, and whatnot to ensure only one thread is touching a mfc object at any one time...
    AFAIK this is not true. I just looked up the issue to brush up my knowledge: The handle maps internally used by the MFC are thread global. You generally cannot pass CWnd (/derived) objects between threads.

    If you need a CWnd object in another thread, just pass its handle and call CWnd::FromHandle(HWND) to get a temporary CWnd object for the referenced window. Be warned that (a) this object is temporary and (b) it is a pointer to a CWnd, not to a derived class.

    Let me further explain the importance of (b) for short: You can get a CWnd* from a HWND and (reinterpret) cast it to a derived class, e.g.
    Code:
    CWndDerived * pWndDerived = reinterpret_cast<CWndDerived*>(CWnd::FromHandle(hWnd));
    You can successfully call CWnd functions on pWndDerived. You can successfully call CWndDerived functions on pWndDerived that just use the wrapped windows handle to send functions to the window, for example. But you cannot call (for example) a function that uses data members specific to the CWndDerived class. Most of the time, you won't do so or need it, anyway.

    Also, note that you do not need to synchronize sending windows messages using the HWND. A window has only one message queue and thus can process messages only sequentially.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center