Print Page | Close Window

CXTDirWatcher Crash

Printed From: Codejock Forums
Category: Codejock Products
Forum Name: Toolkit Pro
Forum Description: Topics Related to Codejock Toolkit Pro
URL: http://forum.codejock.com/forum_posts.asp?TID=3685
Printed Date: 11 November 2025 at 4:48pm
Software Version: Web Wiz Forums 12.04 - http://www.webwizforums.com


Topic: CXTDirWatcher Crash
Posted By: AliRafiee
Subject: CXTDirWatcher Crash
Date Posted: 21 February 2006 at 11:51am

Hi,

I have a CXTShellListCtrl in a dialog box.  When I close the dialog box and then navigate using the Windows Explorer to the directory that the CXTShellListCtrl was displaying and delete a file, or add a file my program will crash. 

It crashes in CXTDirWatcher, there is a WaitForMultipleObject(...,INIFINT) in the InitInstance, since the dialog box is closed thread object is actually deleted, but it is still running, when the event hits, the thread crashes.

If I remember correctly I sent you guys a fix for this a year or so ago?

Do you guys have a fix for this?

If I remember correctly the fix is to change the thread into a worker thread instead of a gui thread.

 

// XTDirWatcher.cpp : implementation file
//
// This file is a part of the XTREME TOOLKIT MFC class library.
// ©2004 Codejock Software, All Rights Reserved.
//
// THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
// RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
// CONSENT OF CODEJOCK SOFTWARE.
//
// THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
// IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT.  CODEJOCK SOFTWARE GRANTS TO
// YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
// SINGLE COMPUTER.
//
// CONTACT INFORMATION:
// mailto:support@codejock.com - support@codejock.com
// http://www.codejock.com - http://www.codejock.com
//
//////////////////////////////////////////////////////////// /////////////////

#include "stdafx.h"
#include "XTDefines.h"
#include "XTGlobal.h"
#include "XTDirWatcher.h"

#include <io.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

UINT DirWatcherThread(void *pParam);
//////////////////////////////////////////////////////////// /////////////////
// CXTDirWatcher

CXTDirWatcher::CXTDirWatcher()
: m_Exit(FALSE)
, m_pThread(NULL)
{
// m_bAutoDelete = FALSE;
}

CXTDirWatcher::~CXTDirWatcher()
{
   m_Exit = TRUE;
}

void CXTDirWatcher::StartMonitoring()
{
   m_pThread = AfxBeginThread(DirWatcherThread,this);
}

void CXTDirWatcher::SuspendThread()
{
   ASSERT(m_pThread);
   m_pThread->SuspendThread();
}

void CXTDirWatcher::ResumeThread()
{
   ASSERT(m_pThread);
   m_pThread->ResumeThread();
}

BOOL CXTDirWatcher::IsPathValid(LPCTSTR lpszFolderPath)
{
 if (_tcslen(lpszFolderPath) == 0)
  return FALSE;

 if (_taccess(lpszFolderPath, 0) == -1)
  return FALSE;

 return TRUE;
}

BOOL CXTDirWatcher::SetFolderPath(CWnd* pMainWnd, LPCTSTR lpszFolderPath)
{
 if (IsPathValid(lpszFolderPath))
 {
  if (GetFolderData(lpszFolderPath, m_tvid))
  {
   m_pMainWnd = pMainWnd;
   m_strFolderPath = lpszFolderPath;

   return TRUE;
  }
 }

 return FALSE;
}

BOOL CXTDirWatcher::SetFolderData(CWnd* pMainWnd, XT_TVITEMDATA* lpTVID)
{
 if (!lpTVID)
  return FALSE;

 TCHAR szFolderPath[_MAX_PATH];
 if (::SHGetPathFromIDList(lpTVID->lpifq, szFolderPath))
 {
  return SetFolderPath(pMainWnd, szFolderPath);
 }

 return FALSE;
}

BOOL CXTDirWatcher::GetFolderData(LPCTSTR lpszFolderPath, XT_TVITEMDATA& lpTVID)
{
 LPITEMIDLIST  pidl;
 LPSHELLFOLDER pDesktopFolder;
 OLECHAR       szOleChar[MAX_PATH];
 ULONG         chEaten;
 ULONG         dwAttributes;

 if (!IsPathValid(lpszFolderPath))
  return FALSE;
 
 // Get a pointer to the Desktop's IShellFolder interface.
 if ( SUCCEEDED( ::SHGetDesktopFolder( &pDesktopFolder ) ) )
 {
  // IShellFolder::ParseDisplayName requires the file name be in
  // Unicode.

#if !defined( _UNICODE )
  ::MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, lpszFolderPath, -1,
   szOleChar, MAX_PATH );
#else
  ::_tcscpy( szOleChar, lpszFolderPath );
#endif

  // Convert the path to an ITEMIDLIST.
  if ( SUCCEEDED( pDesktopFolder->ParseDisplayName( NULL,NULL,szOleChar,
   &chEaten,&pidl,&dwAttributes) ) )
  {
   IShellFolder *psfMyFolder;
   
   lpTVID.lpi = lpTVID.lpifq = pidl;
   
   pDesktopFolder->BindToObject( lpTVID.lpifq,NULL,
    IID_IShellFolder,(LPVOID*)&psfMy Folder );

   lpTVID.lpsfParent = psfMyFolder;
   pDesktopFolder->Release();

   return TRUE;
  }
  
  pDesktopFolder->Release();
 }

 return FALSE;
}

void CXTDirWatcher::RefreshFolder()
{
 m_pMainWnd->SendMessage( XTWM_SHELL_NOTIFY,
  SHN_XT_REFRESHFOLDER, (LPARAM)&m_tvid );
}

void CXTDirWatcher::RefreshTree()
{
 m_pMainWnd->SendMessage( XTWM_SHELL_NOTIFY,
  SHN_XT_REFRESHTREE, (LPARAM)&m_tvid );
}


UINT DirWatcherThread(void *pParam)
{
   CXTDirWatcher *pWatcher = reinterpret_cast<CXTDirWatcher *>(pParam);

 HANDLE   m_dwChangeHandles[2]; // Change event handles.

   m_dwChangeHandles[0] = INVALID_HANDLE_VALUE;
 m_dwChangeHandles[1] = INVALID_HANDLE_VALUE;

   if (pWatcher->IsPathValid(pWatcher->GetFolderPath()))
 {
  // Watch the directory for file creation and
  // deletion.
  
  m_dwChangeHandles[0] = ::FindFirstChangeNotification(
         pWatcher->GetFolderPath(),     & amp; nbsp;         // directory to watch
   FALSE,                           // do not watch the subtree
   FILE_NOTIFY_CHANGE_FILE_NAME); // watch file name changes
  
  if (m_dwChangeHandles[0] == INVALID_HANDLE_VALUE)
   return 0;
  
  // Watch the tree for directory creation and
  // deletion.
  
  m_dwChangeHandles[1] = ::FindFirstChangeNotification(
    pWatcher->GetFolderPath(),     & amp; nbsp;         // directory to watch
   TRUE,      & amp; nbsp;         & amp; nbsp;         // watch the subtree
   FILE_NOTIFY_CHANGE_DIR_NAME);  // watch dir. name changes
  
  if (m_dwChangeHandles[1] == INVALID_HANDLE_VALUE)
   return 0;
  
  // Change notification is set. Now wait on both notification
  // handles and refresh accordingly.

  while (!pWatcher->MustExit())
  {
   // Wait for notification.
   
   DWORD m_dwWaitStatus = ::WaitForMultipleObjects(_countof(m_dwChangeHandles),
    m_dwChangeHandles, FALSE, 10);

   switch (m_dwWaitStatus)
   {
   case WAIT_OBJECT_0:
    
    // A file was created or deleted in C:\WINDOWS.
    // Refresh this directory and restart the
    // change notification. RefreshDirectory is an
    // application-defined function.
    
    pWatcher->RefreshFolder();

    if (!::FindNextChangeNotification(m_dwChangeHandles[0]))
     return 0;

    break;
     
   case WAIT_OBJECT_0 + 1:
    
    // A directory was created or deleted in C:\.
    // Refresh the directory tree and restart the
    // change notification. RefreshTree is an
    // application-defined function.
    
    pWatcher->RefreshTree();

    if (!FindNextChangeNotification(m_dwChangeHandles[1]))
     return 0;

    break;
   
   }
  }
 }
   return 0;
}

Ali Rafiee




Replies:
Posted By: RedDragon
Date Posted: 14 November 2006 at 11:40am
No answer to this question yet?

I have a problem with object as well... the CXTShellListCtrlEx object sends notifications in RefreshFolder() even though the window is destroyed, and the DirWatcher is protected so there is no way to stop this behavior...

Well, the solution I'm using now is to override this object which gives me access to the StopNotifications function. But I'd rather like this to be within CodeJock, if possible?



Posted By: AliRafiee
Date Posted: 14 November 2006 at 11:50am
I believe they fixed this problem in 9.7.  What they did to fix the problem is that they added another event to the event list that the thread listens for, this event is a quit event. And then they set this event in the destructor of the controls that use this threads, so that the thread actually ends when the control is destroyed.
 
Ali


Posted By: Oleg
Date Posted: 14 November 2006 at 1:37pm
Yes, it was fixed in some old version.

-------------
Oleg, Support Team
CODEJOCK SOFTWARE SOLUTIONS



Print Page | Close Window

Forum Software by Web Wiz Forums® version 12.04 - http://www.webwizforums.com
Copyright ©2001-2021 Web Wiz Ltd. - https://www.webwiz.net