Link to home
Start Free TrialLog in
Avatar of joakimf
joakimf

asked on

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?
Avatar of vachooho
vachooho
Flag of United States of America image

pView->m_dlgProgress.PostMessage(WM_CLOSE);

instead of
pView->m_dlgProgress.DestroyWindow ();


Avatar of joakimf
joakimf

ASKER

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?
pView->m_dlgProgress.PostMessage(WM_COMMAND, ID_CANCEL);
Avatar of joakimf

ASKER

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?
pView->m_dlgProgress.PostMessage(WM_COMMAND, ID_CANCEL);
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
Avatar of joakimf

ASKER

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.
ASKER CERTIFIED SOLUTION
Avatar of Vinayak Kumbar
Vinayak Kumbar

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of joakimf

ASKER

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