]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/gdiimage.cpp
resource loader structure added for loading menu bar, apple menu will not get multipl...
[wxWidgets.git] / src / msw / gdiimage.cpp
index 9e2947717d5c7b76aca3a303605d475714f2eb88..3ead2479d1d150bc10f7df5accefc8037c70a6f8 100644 (file)
 
 #ifndef WX_PRECOMP
     #include "wx/string.h"
+    #include "wx/log.h"
 #endif // WX_PRECOMP
 
 #include "wx/msw/private.h"
 
 #include "wx/app.h"
 
+#ifndef __WXMICROWIN__
 #include "wx/msw/dib.h"
+#endif
+
+#include "wx/msw/bitmap.h"
 #include "wx/msw/gdiimage.h"
+#include "wx/bitmap.h"
+
+#ifdef __WIN16__
+#   include "wx/msw/curico.h"
+#endif // __WIN16__
 
 // ----------------------------------------------------------------------------
 // private classes
 // ----------------------------------------------------------------------------
 
+#ifndef __WXMICROWIN__
+
 // all image handlers are declared/defined in this file because the outside
 // world doesn't have to know about them (but only about wxBITMAP_TYPE_XXX ids)
 
@@ -173,6 +185,8 @@ private:
 // ----------------------------------------------------------------------------
 
 static wxSize GetHiconSize(HICON hicon);
+#endif
+    // __MICROWIN__
 
 // ============================================================================
 // implementation
@@ -288,18 +302,16 @@ void wxGDIImage::CleanUpHandlers()
 
 void wxGDIImage::InitStandardHandlers()
 {
+#ifndef __WXMICROWIN__
     AddHandler(new wxBMPResourceHandler);
     AddHandler(new wxBMPFileHandler);
-
-    // Not added by default: include xpmhand.h in your app
-    // and call these in your wxApp::OnInit.
-    //  AddHandler(new wxXPMFileHandler);
-    //  AddHandler(new wxXPMDataHandler);
-
     AddHandler(new wxICOResourceHandler);
     AddHandler(new wxICOFileHandler);
+#endif
 }
 
+#ifndef __WXMICROWIN__
+
 // ----------------------------------------------------------------------------
 // wxBitmap handlers
 // ----------------------------------------------------------------------------
@@ -318,7 +330,7 @@ bool wxBMPResourceHandler::LoadFile(wxBitmap *bitmap,
         BITMAP bm;
         if ( !::GetObject(GetHbitmapOf(*bitmap), sizeof(BITMAP), (LPSTR) &bm) )
         {
-            wxLogLastError("GetObject(HBITMAP)");
+            wxLogLastError(wxT("GetObject(HBITMAP)"));
         }
 
         data->m_width = bm.bmWidth;
@@ -343,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);
@@ -350,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
@@ -363,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;
@@ -378,7 +399,7 @@ bool wxBMPFileHandler::SaveFile(wxBitmap *bitmap,
 
 bool wxICOFileHandler::LoadIcon(wxIcon *icon,
                                 const wxString& name,
-                                long flags,
+                                long WXUNUSED(flags),
                                 int desiredWidth, int desiredHeight)
 {
 #if wxUSE_RESOURCE_LOADING_IN_MSW
@@ -388,7 +409,55 @@ bool wxICOFileHandler::LoadIcon(wxIcon *icon,
     wxSize size;
 
 #ifdef __WIN32__
-    HICON hicon = ::ExtractIcon(wxGetInstance(), name, 0 /* first */);
+    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.
+    int iconIndex = 0;
+    wxString nameReal(name);
+    wxString strIconIndex = name.AfterLast(wxT(';'));
+    if (strIconIndex != name)
+    {
+        iconIndex = wxAtoi(strIconIndex);
+        nameReal = name.BeforeLast(wxT(';'));
+    }
+
+    // were we asked for a large icon?
+    if ( desiredWidth == ::GetSystemMetrics(SM_CXICON) &&
+         desiredHeight == ::GetSystemMetrics(SM_CYICON) )
+    {
+        // get the specified large icon from file
+        if ( !::ExtractIconEx(nameReal, iconIndex, &hicon, NULL, 1) )
+        {
+            // it is not an error, but it might still be useful to be informed
+            // about it optionally
+            wxLogTrace(_T("iconload"),
+                       _T("No large icons found in the file '%s'."),
+                       name.c_str());
+        }
+    }
+    else if ( desiredWidth == ::GetSystemMetrics(SM_CXSMICON) &&
+              desiredHeight == ::GetSystemMetrics(SM_CYSMICON) )
+    {
+        // get the specified small icon from file
+        if ( !::ExtractIconEx(nameReal, iconIndex, NULL, &hicon, 1) )
+        {
+            wxLogTrace(_T("iconload"),
+                       _T("No small icons found in the file '%s'."),
+                       name.c_str());
+        }
+    }
+    //else: not standard size, load below
+
+    if ( !hicon )
+    {
+        // take any (the first one) icon from the file by default
+        hicon = ::ExtractIcon(wxGetInstance(), nameReal, 0 /* first */);
+    }
+
     if ( !hicon )
     {
         wxLogSysError(_T("Failed to load icon from the file '%s'"),
@@ -407,11 +476,10 @@ bool wxICOFileHandler::LoadIcon(wxIcon *icon,
     if ( (desiredWidth != -1 && desiredWidth != size.x) ||
          (desiredHeight != -1 && desiredHeight != size.y) )
     {
-        wxLogDebug(_T("Returning FALSE from wxICOFileHandler::Load because "
-                      "of the size mismatch: actual (%d, %d), "
-                      "requested (%d, %d)"),
-                      size.x, size.y,
-                      desiredWidth, desiredHeight);
+        wxLogTrace(_T("iconload"),
+                   _T("Returning FALSE from wxICOFileHandler::Load because of the size mismatch: actual (%d, %d), requested (%d, %d)"),
+                   size.x, size.y,
+                   desiredWidth, desiredHeight);
 
         ::DestroyIcon(hicon);
 
@@ -429,13 +497,22 @@ bool wxICOFileHandler::LoadIcon(wxIcon *icon,
 
 bool wxICOResourceHandler::LoadIcon(wxIcon *icon,
                                     const wxString& name,
-                                    long flags,
+                                    long WXUNUSED(flags),
                                     int desiredWidth, int desiredHeight)
 {
     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)
 #if defined(__WIN32__) && !defined(__SC__)
-    if ( desiredWidth != -1 && desiredHeight != -1 )
+    if ( hasSize )
     {
         hicon = (HICON)::LoadImage(wxGetInstance(), name, IMAGE_ICON,
                                     desiredWidth, desiredHeight,
@@ -447,6 +524,30 @@ bool wxICOResourceHandler::LoadIcon(wxIcon *icon,
         hicon = ::LoadIcon(wxGetInstance(), name);
     }
 
+    // next check if it's not a standard icon
+    if ( !hicon && !hasSize )
+    {
+        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);
 
@@ -476,7 +577,7 @@ static wxSize GetHiconSize(HICON hicon)
         ICONINFO info;
         if ( !::GetIconInfo(hicon, &info) )
         {
-            wxLogLastError("GetIconInfo");
+            wxLogLastError(wxT("GetIconInfo"));
         }
         else
         {
@@ -499,3 +600,5 @@ static wxSize GetHiconSize(HICON hicon)
 
     return size;
 }
+#endif
+    // __WXMICROWIN__