diff --git a/docs/changes.txt b/docs/changes.txt index b2891a46ba..9cd86bbe5f 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -644,6 +644,7 @@ wxMSW: - Fix handling of controls in the vertical toolbars (Artur Wieczorek). - Fix loading of top to bottom BMP files in wxBitmap (Artur Wieczorek). - Fix resource leak in wxStaticBitmap with RGBA icons (Artur Wieczorek). +- Fix handling of deleting directories in wxFileSystemWatcher (Eric Raijmakers). - Disable the use of new style wxDirDialog under Vista to work around a bug in its implementation under this system (jtrauntvein). diff --git a/include/wx/msw/private/fswatcher.h b/include/wx/msw/private/fswatcher.h index cfd1d5b7b4..d0329194a4 100644 --- a/include/wx/msw/private/fswatcher.h +++ b/include/wx/msw/private/fswatcher.h @@ -225,7 +225,10 @@ public: // Special status indicating that we should exit retrieved. Status_Exit, - // Some error occurred. + // An error occurred because the watched directory was deleted. + Status_Deleted, + + // Some other error occurred. Status_Error }; @@ -248,6 +251,14 @@ public: return *count || *watch || *overlapped ? Status_OK : Status_Exit; } + // An error is returned if the underlying directory has been deleted, + // but this is not really an unexpected failure, so handle it + // specially. + if ( wxSysErrorCode() == ERROR_ACCESS_DENIED && + *watch && !wxFileName::DirExists((*watch)->GetPath()) ) + return Status_Deleted; + + // Some other error, at least log it. wxLogSysError(_("Unable to dequeue completion packet")); return Status_Error; diff --git a/src/msw/fswatcher.cpp b/src/msw/fswatcher.cpp index 98b1c1609f..cbfc0a8860 100644 --- a/src/msw/fswatcher.cpp +++ b/src/msw/fswatcher.cpp @@ -232,6 +232,21 @@ bool wxIOCPThread::ReadEvents() case wxIOCPService::Status_Error: return true; // error was logged already, we don't want to exit + case wxIOCPService::Status_Deleted: + { + wxFileSystemWatcherEvent + removeEvent(wxFSW_EVENT_DELETE, + watch->GetPath(), + wxFileName()); + SendEvent(removeEvent); + } + + // It isn't useful to continue watching this directory as it + // doesn't exist any more -- and even recreating a directory with + // the same name still wouldn't resume generating events for the + // existing wxIOCPService, so it's useless to continue. + return false; + case wxIOCPService::Status_Exit: return false; // stop reading events }