DestroyWindow () in a seperat thread.

I am trying to destroy a dialog in a thread. The dialog is created in the main thread and then I start a new thread and in that thread I want to use DestroyWindow (). GPF every time I try to destroy it. This is the code used:

void CMyView::ScanDirectory (LPCTSTR lpszDirectory)
{
if (!this->IsWindowVisible ())
     return;
m_dlgProgress.Create (IDD_PROGRESS_DIALOG, this);

//Start the thread
AfxBeginThread (ScanThread, this);
}

UINT ScanThread( LPVOID pParam )
{
CMyView* pView = (CMyView*)pParam;

  //Do my stuff
pView->m_dlgProgress.DestroyWindow ();
}

Last line kills the program, why can't I do it like this? The DestroyWindow function is called but when CDialog::DestroyWindow is called, kaboom. Is there any other way to destroy the dialog? How can I fix this?
LVL 1
joakimfAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

vachoohoCommented:
pView->m_dlgProgress.PostMessage(WM_CLOSE);

instead of
pView->m_dlgProgress.DestroyWindow ();


0
joakimfAuthor Commented:
I tried to use the PostMessage method and the dialog doesn't close. On the other hand the program doesn't krash either, any other ideas?
0
vachoohoCommented:
pView->m_dlgProgress.PostMessage(WM_COMMAND, ID_CANCEL);
0
Cloud Class® Course: Microsoft Exchange Server

The MCTS: Microsoft Exchange Server 2010 certification validates your skills in supporting the maintenance and administration of the Exchange servers in an enterprise environment. Learn everything you need to know with this course.

joakimfAuthor Commented:
I tried to use the PostMessage method and the dialog doesn't close. On the other hand the program doesn't krash either, any other ideas?
0
vachoohoCommented:
pView->m_dlgProgress.PostMessage(WM_COMMAND, ID_CANCEL);
0
vachoohoCommented:
You can try to create dialog in the tread


UINT ScanThread( LPVOID pParam )
{
CMyView* pView = (CMyView*)pParam;
m_dlgProgress.Create (IDD_PROGRESS_DIALOG, this);

  //Do my stuff
pView->m_dlgProgress.CloseWindow ();
pView->m_dlgProgress.DestroyWindow ();
}

this could help
0
joakimfAuthor Commented:
Yes I tried that and it works fine, the problem is that I want to be able to cancel the operation by pressing the cancel button. By creating the dialog in the same thread I destory it, the cancel button doesn't work.
0
Vinayak KumbarSr Program ManagerCommented:
HI,

modify the code like
void CMyView::ScanDirectory (LPCTSTR lpszDirectory)
                     {
                     if (!this->IsWindowVisible ())
                          return;
                     m_dlgProgress.Create (IDD_PROGRESS_DIALOG, this);

                     //Start the thread
                     AfxBeginThread (ScanThread, this);
                     }

                     UINT ScanThread( LPVOID pParam )
                     {
                     CMyView* pView = (CMyView*)pParam;

                       //Do my stuff
                     pView->m_dlgProgress.EndDialog (0);
                     }

Or
u can map the OnOK() for that dialog class, then make that function declaration as public in .h file and then use
pView->m_dlgProgress.OnOK();//similarly OnCancel()

But the best way I suggest is to make use of pointer. U have declared as
CDialog m_dlgProgress; instead of that declare as
CDialog *m_dlgProgress;
then in the constructor do
m_dlgProgress = NULL;
then the thread code will be

void CMyView::ScanDirectory (LPCTSTR lpszDirectory)
                     {
                     if (!this->IsWindowVisible ())
                          return;
                     m_dlgProgress = new CDialog;//Or Ur dialog class name
                     m_dlgProgress->Create (IDD_PROGRESS_DIALOG, this);
                     m_dlgProgress->ShowWindow(SW_SHOW);
                     //Start the thread
                     AfxBeginThread (ScanThread, this);
                     }

                     UINT ScanThread( LPVOID pParam )
                     {
                     CMyView* pView = (CMyView*)pParam;

                       //Do my stuff
                     if(pView->m_dlgProgress)
                    {
                              delete pView->m_dlgProgress;
                              pView->m_dlgProgress = NULL;
                    }
                   
                     }
Thats it.

Try it out.
VinExpert
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
joakimfAuthor Commented:
The pointer thing didn't work, so I had to use the following:

if (m_dlgProgress.m_hWnd != NULL)
      m_dlgProgress.DestroyWindow ();
m_dlgProgress.Create (IDD_PROGRESS_DIALOG, this);


And then in the thread:
pView->m_dlgProgress.EndDialog (0);

Thanks for your help....
0
vachoohoCommented:
The problem is that when you press Cancel button dialog is closed and when thread is finished you try to destroy already destroyed dialog. This is the source of GPF you receive.


You can do the following:
add member variable in you dialog class
HANDLE m_hThread;

in dialog constructor you use add
m_hThread = NULL;

//Start the thread and store handle in dialog
m_dlgProgress.m_hThread =
AfxBeginThread(ScanThread, this)->m_hThread;

overwrite dialog's ONCancel() function
add the following before calling default CDialog::OnCalcel() method

TerminateThread(m_hThread, 1);

this will stop the thread and close your progress dialog.

But this is not the best way
because your thread stack will not be freed.



You can try the following code before DestroyWindow()

if(::IsWindow(pView->m_dlgProgress.m_hWnd))
pView->m_dlgProgress.DestroyWindow ();

this will not cause GPF in code but your cancel button will not actualy cancel scan operation - it will only close progress dialog.

0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
System Programming

From novice to tech pro — start learning today.