]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/volume.cpp
Avoid core dumps when SetImageList is used.
[wxWidgets.git] / src / msw / volume.cpp
index dacb7542a257fcbf07ec5482231c0da8f2684e78..f1750775a5e6635fb2598a6719e07bae85952d41 100644 (file)
@@ -6,7 +6,7 @@
 // Created:     28 Jan 02
 // RCS-ID:      $Id$
 // Copyright:   (c) 2002 George Policello
-// Licence:     wxWindows license
+// Licence:     wxWindows licence
 ///////////////////////////////////////////////////////////////////////////////
 
 // ============================================================================
@@ -17,7 +17,7 @@
 // headers
 // ----------------------------------------------------------------------------
 
-#ifdef __GNUG__
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
     #pragma implementation "fsvolume.h"
 #endif
 
     #pragma hdrstop
 #endif
 
+#if wxUSE_FSVOLUME
+
 #ifndef WX_PRECOMP
-#include <wx/icon.h>
-#include <wx/intl.h>
+    #if wxUSE_GUI
+        #include "wx/icon.h"
+    #endif
+    #include "wx/intl.h"
 #endif // WX_PRECOMP
 
 #include "wx/dir.h"
 
 #include "wx/volume.h"
 
-// Win32 headers
+#include <shellapi.h>
 #include <shlobj.h>
+#include "wx/msw/missing.h"
+
+#if wxUSE_BASE
 
 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 // Dynamic library function defs.
@@ -61,20 +68,31 @@ static WNetCloseEnumPtr s_pWNetCloseEnum;
 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 static long s_cancelSearch = FALSE;
 
-struct FileInfo : public wxObject
+struct FileInfo
 {
     FileInfo(unsigned flag=0, wxFSVolumeKind type=wxFS_VOL_OTHER) :
         m_flags(flag), m_type(type) {}
+
+    FileInfo(const FileInfo& other) { *this = other; }
+    FileInfo& operator=(const FileInfo& other)
+    {
+        m_flags = other.m_flags;
+        m_type = other.m_type;
+        return *this;
+    }
+
     unsigned m_flags;
     wxFSVolumeKind m_type;
 };
 WX_DECLARE_STRING_HASH_MAP(FileInfo, FileInfoMap);
-static FileInfoMap s_fileInfo(25);
+// Cygwin bug (?) destructor for global s_fileInfo is called twice...
+static FileInfoMap& GetFileInfoMap()
+{
+    static FileInfoMap s_fileInfo(25);
 
-//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-// Other initialization.
-//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-WX_DEFINE_OBJARRAY(wxIconArray);
+    return s_fileInfo;
+}
+#define s_fileInfo (GetFileInfoMap())
 
 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 // Local helper functions.
@@ -89,7 +107,7 @@ WX_DEFINE_OBJARRAY(wxIconArray);
 //        - Other flags are 'best guess' from type of drive.  The system will
 //          not report the file attributes with any degree of accuracy.
 //=============================================================================
-unsigned GetBasicFlags(const char* filename)
+static unsigned GetBasicFlags(const wxChar* filename)
 {
     unsigned flags = wxFS_VOL_MOUNTED;
 
@@ -162,7 +180,8 @@ unsigned GetBasicFlags(const char* filename)
 // Purpose: Add a file to the list if it meets the filter requirement.
 // Notes: - See GetBasicFlags for remarks about the Mounted flag.
 //=============================================================================
-bool FilteredAdd(wxArrayString& list, const char* filename, unsigned flagsSet, unsigned flagsUnset)
+static bool FilteredAdd(wxArrayString& list, const wxChar* filename, 
+                        unsigned flagsSet, unsigned flagsUnset)
 {
     bool accept = TRUE;
     unsigned flags = GetBasicFlags(filename);
@@ -198,7 +217,8 @@ bool FilteredAdd(wxArrayString& list, const char* filename, unsigned flagsSet, u
 //          all items while determining which are connected and not.  So this
 //          function will find either all items or connected items.
 //=============================================================================
-void BuildListFromNN(wxArrayString& list, NETRESOURCE* pResSrc, unsigned flagsSet, unsigned flagsUnset)
+static void BuildListFromNN(wxArrayString& list, NETRESOURCE* pResSrc, 
+                            unsigned flagsSet, unsigned flagsUnset)
 {
     HANDLE hEnum;
     int rc;
@@ -217,8 +237,8 @@ void BuildListFromNN(wxArrayString& list, NETRESOURCE* pResSrc, unsigned flagsSe
     //----------------------------------------------------------------------
     if (rc = s_pWNetOpenEnum(scope, RESOURCETYPE_DISK, 0, pResSrc, &hEnum), rc == NO_ERROR)
     {
-        unsigned long count = 1;
-        unsigned long size = 256;
+        DWORD count = 1;
+        DWORD size = 256;
         NETRESOURCE* pRes = (NETRESOURCE*)malloc(size);
         memset(pRes, 0, sizeof(NETRESOURCE));
         while (rc = s_pWNetEnumResource(hEnum, &count, pRes, &size), rc == NO_ERROR || rc == ERROR_MORE_DATA)
@@ -270,9 +290,9 @@ void BuildListFromNN(wxArrayString& list, NETRESOURCE* pResSrc, unsigned flagsSe
 // Function: CompareFcn
 // Purpose: Used to sort the NN list alphabetically, case insensitive.
 //=============================================================================
-static int CompareFcn(const wxString& first, const wxString& second)
+static int CompareFcn(wxString* first, wxString* second)
 {
-    return stricmp(first.c_str(), second.c_str());
+    return wxStricmp(first->c_str(), second->c_str());
 } // CompareFcn
 
 //=============================================================================
@@ -283,7 +303,8 @@ static int CompareFcn(const wxString& first, const wxString& second)
 //          way manually.
 //        - The resulting list is sorted alphabetically.
 //=============================================================================
-bool BuildRemoteList(wxArrayString& list, NETRESOURCE* pResSrc, unsigned flagsSet, unsigned flagsUnset)
+static bool BuildRemoteList(wxArrayString& list, NETRESOURCE* pResSrc, 
+                            unsigned flagsSet, unsigned flagsUnset)
 {
     // NN query depends on dynamically loaded library.
     if (!s_pWNetOpenEnum || !s_pWNetEnumResource || !s_pWNetCloseEnum)
@@ -323,7 +344,9 @@ bool BuildRemoteList(wxArrayString& list, NETRESOURCE* pResSrc, unsigned flagsSe
             wxString all(list[iList]);
             wxString mount(mounted[iMounted]);
 
-            while (compare = stricmp(list[iList], mounted[iMounted]), compare > 0 && iList >= 0)
+            while (compare = 
+                     wxStricmp(list[iList].c_str(), mounted[iMounted].c_str()),
+                   compare > 0 && iList >= 0)
             {
                 iList--;
                 all = list[iList];
@@ -334,7 +357,7 @@ bool BuildRemoteList(wxArrayString& list, NETRESOURCE* pResSrc, unsigned flagsSe
             {
                 // Found the element.  Remove it or mark it mounted.
                 if (flagsUnset & wxFS_VOL_MOUNTED)
-                    list.Remove(iList);
+                    list.RemoveAt(iList);
                 else
                     s_fileInfo[list[iList]].m_flags |= wxFS_VOL_MOUNTED;
 
@@ -356,7 +379,7 @@ bool BuildRemoteList(wxArrayString& list, NETRESOURCE* pResSrc, unsigned flagsSe
 // Purpose: Generate and return a list of all volumes (drives) available.
 // Notes:
 //=============================================================================
-wxArrayString wxFSVolume::GetVolumes(int flagsSet, int flagsUnset)
+wxArrayString wxFSVolumeBase::GetVolumes(int flagsSet, int flagsUnset)
 {
     InterlockedExchange(&s_cancelSearch, FALSE);     // reset
 
@@ -364,7 +387,7 @@ wxArrayString wxFSVolume::GetVolumes(int flagsSet, int flagsUnset)
     {
 #ifdef UNICODE
         s_pWNetOpenEnum = (WNetOpenEnumPtr)s_mprLib.GetSymbol(_T("WNetOpenEnumW"));
-        s_pWNetEnumResource = (WNetEnumResourcePtr)s_mprLib.GetSymbol("WNetEnumResourceW");
+        s_pWNetEnumResource = (WNetEnumResourcePtr)s_mprLib.GetSymbol(_T("WNetEnumResourceW"));
 #else
         s_pWNetOpenEnum = (WNetOpenEnumPtr)s_mprLib.GetSymbol(_T("WNetOpenEnumA"));
         s_pWNetEnumResource = (WNetEnumResourcePtr)s_mprLib.GetSymbol(_T("WNetEnumResourceA"));
@@ -382,7 +405,7 @@ wxArrayString wxFSVolume::GetVolumes(int flagsSet, int flagsUnset)
     TCHAR* buf = new TCHAR[chars+1];
 
     // Get the list of drives.
-    chars = GetLogicalDriveStrings(chars, buf);
+    GetLogicalDriveStrings(chars, buf);
 
     // Parse the list into an array, applying appropriate filters.
     TCHAR *pVol;
@@ -425,7 +448,7 @@ wxArrayString wxFSVolume::GetVolumes(int flagsSet, int flagsUnset)
 //          performing the search.  This is the only thread-safe function
 //          provided by the class.
 //=============================================================================
-void wxFSVolume::CancelSearch()
+void wxFSVolumeBase::CancelSearch()
 {
     InterlockedExchange(&s_cancelSearch, TRUE);
 } // CancelSearch
@@ -434,7 +457,7 @@ void wxFSVolume::CancelSearch()
 // Function: constructor
 // Purpose: default constructor
 //=============================================================================
-wxFSVolume::wxFSVolume()
+wxFSVolumeBase::wxFSVolumeBase()
 {
     m_isOk = FALSE;
 } // wxVolume
@@ -443,7 +466,7 @@ wxFSVolume::wxFSVolume()
 // Function: constructor
 // Purpose: constructor that calls Create
 //=============================================================================
-wxFSVolume::wxFSVolume(const wxString& name)
+wxFSVolumeBase::wxFSVolumeBase(const wxString& name)
 {
     Create(name);
 } // wxVolume
@@ -452,7 +475,7 @@ wxFSVolume::wxFSVolume(const wxString& name)
 // Function: Create
 // Purpose: Finds, logs in, etc. to the request volume.
 //=============================================================================
-bool wxFSVolume::Create(const wxString& name)
+bool wxFSVolumeBase::Create(const wxString& name)
 {
     // assume fail.
     m_isOk = FALSE;
@@ -465,21 +488,11 @@ bool wxFSVolume::Create(const wxString& name)
     long rc = SHGetFileInfo(m_volName, 0, &fi, sizeof(fi), SHGFI_DISPLAYNAME);
     if (!rc)
     {
-        wxLogError(_("Cannot read typename from '%s'!"), m_volName);
+        wxLogError(_("Cannot read typename from '%s'!"), m_volName.c_str());
         return m_isOk;
     }
     m_dispName = fi.szDisplayName;
 
-#ifdef wxUSE_GUI
-
-    m_icons.Alloc(wxFS_VOL_ICO_MAX);
-    int idx;
-    wxIcon null;
-    for (idx = 0; idx < wxFS_VOL_ICO_MAX; idx++)
-        m_icons.Add(null);
-
-#endif
-
     // all tests passed.
     return m_isOk = TRUE;
 } // Create
@@ -490,7 +503,7 @@ bool wxFSVolume::Create(const wxString& name)
 // Notes: For fixed disks, it must exist.  For removable disks, it must also
 //        be present.  For Network Shares, it must also be logged in, etc.
 //=============================================================================
-bool wxFSVolume::IsOk() const
+bool wxFSVolumeBase::IsOk() const
 {
     return m_isOk;
 } // IsOk
@@ -499,7 +512,7 @@ bool wxFSVolume::IsOk() const
 // Function: GetKind
 // Purpose: Return the type of the volume.
 //=============================================================================
-wxFSVolumeKind wxFSVolume::GetKind() const
+wxFSVolumeKind wxFSVolumeBase::GetKind() const
 {
     if (!m_isOk)
         return wxFS_VOL_OTHER;
@@ -516,7 +529,7 @@ wxFSVolumeKind wxFSVolume::GetKind() const
 // Purpose: Return the caches flags for this volume.
 // Notes: - Returns -1 if no flags were cached.
 //=============================================================================
-int wxFSVolume::GetFlags() const
+int wxFSVolumeBase::GetFlags() const
 {
     if (!m_isOk)
         return -1;
@@ -528,38 +541,56 @@ int wxFSVolume::GetFlags() const
     return itr->second.m_flags;
 } // GetFlags
 
-#ifdef wxUSE_GUI
+#endif // wxUSE_BASE
+
+// ============================================================================
+// wxFSVolume
+// ============================================================================
+
+#if wxUSE_GUI
+
+void wxFSVolume::InitIcons()
+{
+    m_icons.Alloc(wxFS_VOL_ICO_MAX);
+    wxIcon null;
+    for (int idx = 0; idx < wxFS_VOL_ICO_MAX; idx++)
+        m_icons.Add(null);
+}
 
 //=============================================================================
 // Function: GetIcon
 // Purpose: return the requested icon.
 //=============================================================================
+
 wxIcon wxFSVolume::GetIcon(wxFSIconType type) const
 {
-    wxCHECK_MSG( type >= 0 && (size_t)type < m_icons.GetCount(),
-                 wxIcon(),                 
-                 _T("invalid icon index") );
+    wxCHECK_MSG( type >= 0 && (size_t)type < m_icons.GetCount(), wxNullIcon,
+                 _T("wxFSIconType::GetIcon(): invalid icon index") );
 
     // Load on demand.
     if (m_icons[type].IsNull())
     {
-        unsigned flags = 0;
+        UINT flags = SHGFI_ICON;
         switch (type)
         {
         case wxFS_VOL_ICO_SMALL:
-            flags = SHGFI_ICON | SHGFI_SMALLICON;
+            flags |= SHGFI_SMALLICON;
             break;
 
         case wxFS_VOL_ICO_LARGE:
-            flags = SHGFI_ICON | SHGFI_SHELLICONSIZE;
+            flags |= SHGFI_SHELLICONSIZE;
             break;
 
         case wxFS_VOL_ICO_SEL_SMALL:
-            flags = SHGFI_ICON | SHGFI_SMALLICON | SHGFI_OPENICON;
+            flags |= SHGFI_SMALLICON | SHGFI_OPENICON;
             break;
 
         case wxFS_VOL_ICO_SEL_LARGE:
-            flags = SHGFI_ICON | SHGFI_SHELLICONSIZE | SHGFI_OPENICON;
+            flags |= SHGFI_SHELLICONSIZE | SHGFI_OPENICON;
+            break;
+            
+        case wxFS_VOL_ICO_MAX:
+            wxFAIL_MSG(_T("wxFS_VOL_ICO_MAX is not valid icon type"));
             break;
         }
 
@@ -567,7 +598,7 @@ wxIcon wxFSVolume::GetIcon(wxFSIconType type) const
         long rc = SHGetFileInfo(m_volName, 0, &fi, sizeof(fi), flags);
         m_icons[type].SetHICON((WXHICON)fi.hIcon);
         if (!rc || !fi.hIcon)
-            wxLogError(_("Cannot load icon from '%s'."), m_volName);
+            wxLogError(_("Cannot load icon from '%s'."), m_volName.c_str());
     }
 
     return m_icons[type];
@@ -575,3 +606,5 @@ wxIcon wxFSVolume::GetIcon(wxFSIconType type) const
 
 #endif // wxUSE_GUI
 
+#endif // wxUSE_FSVOLUME
+