Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win


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
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
  • 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

Enroll in October's Free Course of the Month

Do you work with and analyze data? Enroll in October's Course of the Month for 7+ hours of SQL training, allowing you to quickly and efficiently store or retrieve data. It's free for Premium Members, Team Accounts, and Qualified Experts!

Question has a verified solution.

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

Introduction: The undo support, implementing a stack. Continuing from the eigth article about sudoku.   We need a mechanism to keep track of the digits entered so as to implement an undo mechanism.  This should be a ‘Last In First Out’ collec…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
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.
How to fix incompatible JVM issue while installing Eclipse While installing Eclipse in windows, got one error like above and unable to proceed with the installation. This video describes how to successfully install Eclipse. How to solve incompa…
Suggested Courses

618 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