Running a CDialog in a separate Thread

Posted on 2001-08-12
Medium Priority
Last Modified: 2013-11-20
My app is an SDI. I Have a class that serves as a Singleton and it contains a meethod that should start a thread and display a modeless CDialog derived class within that thread. The reason I do this is so that when the Dialog is displayed, the user can still do something else in the app.

Now, my major prob is that I am getting an ASSERT failure during the CDialog::Create(). I've posted the relevant pieces of code below:

 //   Create Progress Dialog and Display it    
 BOOL ret = m_configProgress.Create();
 if(!ret)   //Create failed.
    AfxMessageBox("Error creating Processing Dialog");



The m_configProgress variable is a member of CFrameWnd class. Any help would be appreciated as I've been on tis for a while now!
Question by:ruff_ryder
  • 3

Author Comment

ID: 6377552
Here's the a copy of the Call Stack:

CWnd::AssertValid() line 884 + 27 bytes
CFrameWnd::AssertValid() line 2123
CMainFrame::AssertValid() line 92
AfxAssertValidObject(const CObject * 0x007b4b98 {CMainFrame}, const char * 0x5f4cd330 THIS_FILE, int 258) line 108
CWnd::CreateDlgIndirect(const DLGTEMPLATE * 0x0042fcf0, CWnd * 0x007b4b98 {CMainFrame hWnd=???}, HINSTANCE__ * 0x00400000) line 260
CDialog::CreateIndirect(const DLGTEMPLATE * 0x0042fcf0, CWnd * 0x007b4b98 {CMainFrame hWnd=???}, void * 0x00000000, HINSTANCE__ * 0x00400000) line 223
CDialog::CreateIndirect(void * 0x0042fcf0, CWnd * 0x00000000 {CWnd hWnd=???}, HINSTANCE__ * 0x00400000) line 200 + 22 bytes
CDialog::Create(const char * 0x0000006b, CWnd * 0x00000000 {CWnd hWnd=???}) line 182 + 20 bytes
CDialog::Create(unsigned int 107, CWnd * 0x00000000 {CWnd hWnd=???}) line 543 + 29 bytes
CXMLToolProgressDlg::Create(CWnd * 0x00000000 {CWnd hWnd=???}) line 73 + 14 bytes
CXMLToolApp::OnConfigurationStart() line 185 + 13 bytes
EvalManager::BeginProcessing(Configuration * 0x007e2378) line 110 + 33 bytes
EvalManager::RunInternal() line 46 + 17 bytes
RunInternalThreadProc(void * 0x007e1f58) line 18 + 13 bytes
_AfxThreadEntry(void * 0x0012f938) line 112 + 13 bytes
_threadstartex(void * 0x007e24c0) line 212 + 13 bytes
KERNEL32! 77e92ca8()

and here's the line of wincore.cpp [Line 884] where the error occurs:

ASSERT((CWnd*)p == this);   // must be us

The "this" variable looks like this in the variable watch window:

this     0x007b4b98 {CMainFrame hWnd=???}

LVL 49

Accepted Solution

DanRollins earned 600 total points
ID: 6378088
The MFC source code in wincore.cpp (directly below the line that asserted) contains this relevant info:

// Note: if either of the above asserts fire and you are
// writing a multithreaded application, it is likely that
// you have passed a C++ object from one thread to another
// and have used that object in a way that was not intended.
// (only simple inline wrapper functions should be used)
// In general, CWnd objects should be passed by HWND from
// one thread to another.  The receiving thread can wrap
// the HWND with a CWnd object by using CWnd::FromHandle.
// It is dangerous to pass C++ objects from one thread to
// another, unless the objects are designed to be used in
// such a manner.

So, you should be able to make it work by using code like this in the thread:

CWnd* pParent= FromHandle( AfxGetMainWnd()->m_hWnd );
BOOL ret= m_configProgress.Create( CMyDlg::IDD, pParent );

But lets back up a bit:
>>The reason I do this is so that when the Dialog is displayed, the user can still do something else in the app

Modeless dialogs are designed to be used that way -- they float above the frame and the user can continue to use the Frame's menus and commands, etc.  What I'm saying, is that it is not usually necessary to spin off a new thread just to display a modeless dialog.

I'm thinking that this dlg box shows the progress of some lengthy operation.  Describe what operation you are doing, and I can give you specific help.  But one common way to do this is this is to drive the dialog's progress control from outside of the dialog.  For instance,

  gpMyModelessDlg->m_cCtlProgress->SetPos( n )

I have used a timer to make calls like this and I have also split off a worker thread to do the work and had it post messages to the dialog and/or progress control.

If your app is stopping during some lengthy operation, a common way to avoid that is to pump messages while doing the lenghty operation:

// start the operation
while( !fDone ) {
   MSG rMsg;
   while ( ::PeekMessage( &rMsg, 0, 0,0, PM_NOREMOVE) ){
   // do some more work, set fDone= TRUE when done

-- Dan

Author Comment

ID: 6382744
Thanx dude! worked nicely!!

Author Comment

ID: 6440883
Dan I'm having another problem now. I split off a worker thread to do some work but I need the main thread to update the Modeless Dialog. I looked on your code:

// start the operation
while( !fDone ) {
  MSG rMsg;
  while ( ::PeekMessage( &rMsg, 0, 0,0, PM_NOREMOVE) ){
  // do some more work, set fDone= TRUE when done

My question is, if im doingthe work in the Worker Thread, how do i access the main thread so that I can call the ::PeekMessage

Featured Post


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

Question has a verified solution.

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

Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
This video shows how to quickly and easily deploy an email signature for all users in Office 365 and prevent it from being added to replies and forwards. (the resulting signature is applied on the server level in Exchange Online) The email signat…
Suggested Courses
Course of the Month17 days, 9 hours left to enroll

830 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