]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/gdiimage.cpp
Fixed toolbar crash for MinGW/Cygwin
[wxWidgets.git] / src / msw / gdiimage.cpp
index 5ca0afc43ff9a692e13b272ce9c4450630b1c57f..87fb6add432aae0c5ae1e855270b56d469bc48c9 100644 (file)
@@ -175,10 +175,10 @@ private:
 // wxWin macros
 // ----------------------------------------------------------------------------
 
-    IMPLEMENT_DYNAMIC_CLASS(wxBMPFileHandler, wxBitmapHandler)
-    IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler)
-    IMPLEMENT_DYNAMIC_CLASS(wxICOFileHandler, wxGDIImageHandler)
-    IMPLEMENT_DYNAMIC_CLASS(wxICOResourceHandler, wxGDIImageHandler)
+IMPLEMENT_DYNAMIC_CLASS(wxBMPFileHandler, wxBitmapHandler)
+IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler)
+IMPLEMENT_DYNAMIC_CLASS(wxICOFileHandler, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxICOResourceHandler, wxObject)
 
 // ----------------------------------------------------------------------------
 // private functions
@@ -355,6 +355,8 @@ bool wxBMPFileHandler::LoadFile(wxBitmap *bitmap,
 #if wxUSE_IMAGE_LOADING_IN_MSW
     wxPalette *palette = NULL;
     bool success = wxLoadIntoBitmap(WXSTRINGCAST name, bitmap, &palette) != 0;
+
+#if wxUSE_PALETTE
     if ( success && palette )
     {
         bitmap->SetPalette(*palette);
@@ -362,6 +364,7 @@ bool wxBMPFileHandler::LoadFile(wxBitmap *bitmap,
 
     // it was copied by the bitmap if it was loaded successfully
     delete palette;
+#endif // wxUSE_PALETTE
 
     return success;
 #else
@@ -375,9 +378,15 @@ bool wxBMPFileHandler::SaveFile(wxBitmap *bitmap,
                                 const wxPalette *pal)
 {
 #if wxUSE_IMAGE_LOADING_IN_MSW
+
+#if wxUSE_PALETTE
     wxPalette *actualPalette = (wxPalette *)pal;
     if ( !actualPalette )
         actualPalette = bitmap->GetPalette();
+#else
+    wxPalette *actualPalette = NULL;
+#endif // wxUSE_PALETTE
+
     return wxSaveBitmap(WXSTRINGCAST name, bitmap, actualPalette) != 0;
 #else
     return FALSE;
@@ -402,16 +411,18 @@ bool wxICOFileHandler::LoadIcon(wxIcon *icon,
 #ifdef __WIN32__
     HICON hicon = NULL;
 
-    // Parse the filename: it may be of the form
-    // filename;n in order to specify the nth icon in the file.
-    // For the moment, ignore the issue of possible semicolons in the filename.
+    // Parse the filename: it may be of the form "filename;n" in order to
+    // specify the nth icon in the file.
+    //
+    // For the moment, ignore the issue of possible semicolons in the
+    // filename.
     int iconIndex = 0;
-    wxString name1(name);
+    wxString nameReal(name);
     wxString strIconIndex = name.AfterLast(wxT(';'));
     if (strIconIndex != name)
     {
         iconIndex = wxAtoi(strIconIndex);
-        name1 = name.BeforeLast(wxT(';'));
+        nameReal = name.BeforeLast(wxT(';'));
     }
 
     // were we asked for a large icon?
@@ -419,7 +430,7 @@ bool wxICOFileHandler::LoadIcon(wxIcon *icon,
          desiredHeight == ::GetSystemMetrics(SM_CYICON) )
     {
         // get the specified large icon from file
-        if ( !::ExtractIconEx(name1, iconIndex, &hicon, NULL, 1) )
+        if ( !::ExtractIconEx(nameReal, iconIndex, &hicon, NULL, 1) )
         {
             // it is not an error, but it might still be useful to be informed
             // about it optionally
@@ -432,7 +443,7 @@ bool wxICOFileHandler::LoadIcon(wxIcon *icon,
               desiredHeight == ::GetSystemMetrics(SM_CYSMICON) )
     {
         // get the specified small icon from file
-        if ( !::ExtractIconEx(name1, iconIndex, NULL, &hicon, 1) )
+        if ( !::ExtractIconEx(nameReal, iconIndex, NULL, &hicon, 1) )
         {
             wxLogTrace(_T("iconload"),
                        _T("No small icons found in the file '%s'."),
@@ -444,7 +455,7 @@ bool wxICOFileHandler::LoadIcon(wxIcon *icon,
     if ( !hicon )
     {
         // take any (the first one) icon from the file by default
-        hicon = ::ExtractIcon(wxGetInstance(), name1, 0 /* first */);
+        hicon = ::ExtractIcon(wxGetInstance(), nameReal, 0 /* first */);
     }
 
     if ( !hicon )
@@ -491,28 +502,58 @@ bool wxICOResourceHandler::LoadIcon(wxIcon *icon,
 {
     HICON hicon;
 
+    // do we need the icon of the specific size or would any icon do?
+    bool hasSize = desiredWidth != -1 || desiredHeight != -1;
+
+    wxASSERT_MSG( !hasSize || (desiredWidth != -1 && desiredHeight != -1),
+                  _T("width and height should be either both -1 or not") );
+
+    // try to load the icon from this program first to allow overriding the
+    // standard icons (although why one would want to do it considering that
+    // we already have wxApp::GetStdIcon() is unclear)
+
+    // note that we can't just always call LoadImage() because it seems to do
+    // some icon rescaling internally which results in very ugly 16x16 icons
 #if defined(__WIN32__) && !defined(__SC__)
-    if ( desiredWidth != -1 && desiredHeight != -1 )
+    if ( hasSize )
     {
         hicon = (HICON)::LoadImage(wxGetInstance(), name, IMAGE_ICON,
                                     desiredWidth, desiredHeight,
                                     LR_DEFAULTCOLOR);
     }
     else
-#endif // Win32
+#endif // Win32/!Win32
     {
         hicon = ::LoadIcon(wxGetInstance(), name);
     }
 
-    wxSize size = GetHiconSize(hicon);
-    icon->SetSize(size.x, size.y);
-
-    // Override the found values with desired values
-    if ( desiredWidth > -1 && desiredHeight > -1 )
+    // next check if it's not a standard icon
+    if ( !hicon && !hasSize )
     {
-        icon->SetSize(desiredWidth, desiredHeight);
+        static const struct
+        {
+            const wxChar *name;
+            LPTSTR id;
+        } stdIcons[] =
+        {
+            { wxT("wxICON_QUESTION"),   IDI_QUESTION    },
+            { wxT("wxICON_WARNING"),    IDI_EXCLAMATION },
+            { wxT("wxICON_ERROR"),      IDI_HAND        },
+            { wxT("wxICON_INFO"),       IDI_ASTERISK    },
+        };
+
+        for ( size_t nIcon = 0; !hicon && nIcon < WXSIZEOF(stdIcons); nIcon++ )
+        {
+            if ( name == stdIcons[nIcon].name )
+            {
+                hicon = ::LoadIcon((HINSTANCE)NULL, stdIcons[nIcon].id);
+            }
+        }
     }
 
+    wxSize size = GetHiconSize(hicon);
+    icon->SetSize(size.x, size.y);
+
     icon->SetHICON((WXHICON)hicon);
 
     return icon->Ok();