1 ///////////////////////////////////////////////////////////////////////////////
2 // Name:        src/msw/gdiimage.cpp
3 // Purpose:     wxGDIImage implementation
4 // Author:      Vadim Zeitlin
5 // Modified by:
6 // Created:     20.11.99
7 // Copyright:   (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
8 // Licence:     wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
10 
11 // ============================================================================
12 // declarations
13 // ============================================================================
14 
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18 
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
21 
22 #ifdef __BORLANDC__
23     #pragma hdrstop
24 #endif
25 
26 #ifndef WX_PRECOMP
27     #include "wx/string.h"
28     #include "wx/log.h"
29     #include "wx/app.h"
30     #include "wx/bitmap.h"
31 #endif // WX_PRECOMP
32 
33 #include "wx/msw/private.h"
34 
35 #include "wx/msw/gdiimage.h"
36 
37 #if wxUSE_WXDIB
38 #include "wx/msw/dib.h"
39 #endif
40 
41 // By default, use PNG resource handler if we can, i.e. have support for
42 // loading PNG images in the library. This symbol could be predefined as 0 to
43 // avoid doing this if anybody ever needs to do it for some reason.
44 #if !defined(wxUSE_PNG_RESOURCE_HANDLER) && wxUSE_LIBPNG && wxUSE_IMAGE
45     #define wxUSE_PNG_RESOURCE_HANDLER 1
46 #endif
47 
48 #if wxUSE_PNG_RESOURCE_HANDLER
49     #include "wx/image.h"
50     #include "wx/utils.h"       // For wxLoadUserResource()
51 #endif
52 
53 #ifdef __WXWINCE__
54 #include <winreg.h>
55 #include <shellapi.h>
56 #endif
57 
58 #include "wx/file.h"
59 
60 #include "wx/listimpl.cpp"
61 WX_DEFINE_LIST(wxGDIImageHandlerList)
62 
63 // ----------------------------------------------------------------------------
64 // private classes
65 // ----------------------------------------------------------------------------
66 
67 #ifndef __WXMICROWIN__
68 
69 // all image handlers are declared/defined in this file because the outside
70 // world doesn't have to know about them (but only about wxBITMAP_TYPE_XXX ids)
71 
72 class WXDLLEXPORT wxBMPFileHandler : public wxBitmapHandler
73 {
74 public:
wxBMPFileHandler()75     wxBMPFileHandler() : wxBitmapHandler(wxT("Windows bitmap file"), wxT("bmp"),
76                                          wxBITMAP_TYPE_BMP)
77     {
78     }
79 
80     virtual bool LoadFile(wxBitmap *bitmap,
81                           const wxString& name, wxBitmapType flags,
82                           int desiredWidth, int desiredHeight);
83     virtual bool SaveFile(const wxBitmap *bitmap,
84                           const wxString& name, wxBitmapType type,
85                           const wxPalette *palette = NULL) const;
86 
87 private:
88     DECLARE_DYNAMIC_CLASS(wxBMPFileHandler)
89 };
90 
91 class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler
92 {
93 public:
wxBMPResourceHandler()94     wxBMPResourceHandler() : wxBitmapHandler(wxT("Windows bitmap resource"),
95                                              wxEmptyString,
96                                              wxBITMAP_TYPE_BMP_RESOURCE)
97     {
98     }
99 
100     virtual bool LoadFile(wxBitmap *bitmap,
101                           const wxString& name, wxBitmapType flags,
102                           int desiredWidth, int desiredHeight);
103 
104 private:
105     DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler)
106 };
107 
108 class WXDLLEXPORT wxIconHandler : public wxGDIImageHandler
109 {
110 public:
wxIconHandler(const wxString & name,const wxString & ext,wxBitmapType type)111     wxIconHandler(const wxString& name, const wxString& ext, wxBitmapType type)
112         : wxGDIImageHandler(name, ext, type)
113     {
114     }
115 
116     // creating and saving icons is not supported
Create(wxGDIImage * WXUNUSED (image),const void * WXUNUSED (data),wxBitmapType WXUNUSED (flags),int WXUNUSED (width),int WXUNUSED (height),int WXUNUSED (depth)=1)117     virtual bool Create(wxGDIImage *WXUNUSED(image),
118                         const void* WXUNUSED(data),
119                         wxBitmapType WXUNUSED(flags),
120                         int WXUNUSED(width),
121                         int WXUNUSED(height),
122                         int WXUNUSED(depth) = 1)
123     {
124         return false;
125     }
126 
Save(const wxGDIImage * WXUNUSED (image),const wxString & WXUNUSED (name),wxBitmapType WXUNUSED (type)) const127     virtual bool Save(const wxGDIImage *WXUNUSED(image),
128                       const wxString& WXUNUSED(name),
129                       wxBitmapType WXUNUSED(type)) const
130     {
131         return false;
132     }
133 
Load(wxGDIImage * image,const wxString & name,wxBitmapType flags,int desiredWidth,int desiredHeight)134     virtual bool Load(wxGDIImage *image,
135                       const wxString& name,
136                       wxBitmapType flags,
137                       int desiredWidth, int desiredHeight)
138     {
139         wxIcon *icon = wxDynamicCast(image, wxIcon);
140         wxCHECK_MSG( icon, false, wxT("wxIconHandler only works with icons") );
141 
142         return LoadIcon(icon, name, flags, desiredWidth, desiredHeight);
143     }
144 
145 protected:
146     virtual bool LoadIcon(wxIcon *icon,
147                           const wxString& name, wxBitmapType flags,
148                           int desiredWidth = -1, int desiredHeight = -1) = 0;
149 };
150 
151 class WXDLLEXPORT wxICOFileHandler : public wxIconHandler
152 {
153 public:
wxICOFileHandler()154     wxICOFileHandler() : wxIconHandler(wxT("ICO icon file"),
155                                        wxT("ico"),
156                                        wxBITMAP_TYPE_ICO)
157     {
158     }
159 
160 protected:
161     virtual bool LoadIcon(wxIcon *icon,
162                           const wxString& name, wxBitmapType flags,
163                           int desiredWidth = -1, int desiredHeight = -1);
164 
165 private:
166     DECLARE_DYNAMIC_CLASS(wxICOFileHandler)
167 };
168 
169 class WXDLLEXPORT wxICOResourceHandler: public wxIconHandler
170 {
171 public:
wxICOResourceHandler()172     wxICOResourceHandler() : wxIconHandler(wxT("ICO resource"),
173                                            wxT("ico"),
174                                            wxBITMAP_TYPE_ICO_RESOURCE)
175     {
176     }
177 
178 protected:
179     virtual bool LoadIcon(wxIcon *icon,
180                           const wxString& name, wxBitmapType flags,
181                           int desiredWidth = -1, int desiredHeight = -1);
182 
183 private:
184     DECLARE_DYNAMIC_CLASS(wxICOResourceHandler)
185 };
186 
187 #if wxUSE_PNG_RESOURCE_HANDLER
188 
189 class WXDLLEXPORT wxPNGResourceHandler : public wxBitmapHandler
190 {
191 public:
wxPNGResourceHandler()192     wxPNGResourceHandler() : wxBitmapHandler(wxS("Windows PNG resource"),
193                                              wxString(),
194                                              wxBITMAP_TYPE_PNG_RESOURCE)
195     {
196     }
197 
198     virtual bool LoadFile(wxBitmap *bitmap,
199                           const wxString& name, wxBitmapType flags,
200                           int desiredWidth, int desiredHeight);
201 
202 private:
203     wxDECLARE_DYNAMIC_CLASS(wxPNGResourceHandler);
204 };
205 
206 #endif // wxUSE_PNG_RESOURCE_HANDLER
207 
208 // ----------------------------------------------------------------------------
209 // wxWin macros
210 // ----------------------------------------------------------------------------
211 
212 IMPLEMENT_DYNAMIC_CLASS(wxBMPFileHandler, wxBitmapHandler)
213 IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler)
214 IMPLEMENT_DYNAMIC_CLASS(wxICOFileHandler, wxObject)
215 IMPLEMENT_DYNAMIC_CLASS(wxICOResourceHandler, wxObject)
216 #if wxUSE_PNG_RESOURCE_HANDLER
217 IMPLEMENT_DYNAMIC_CLASS(wxPNGResourceHandler, wxBitmapHandler)
218 #endif // wxUSE_PNG_RESOURCE_HANDLER
219 
220 // ----------------------------------------------------------------------------
221 // private functions
222 // ----------------------------------------------------------------------------
223 
224 #endif
225     // __MICROWIN__
226 
227 // ============================================================================
228 // implementation
229 // ============================================================================
230 
231 wxGDIImageHandlerList wxGDIImage::ms_handlers;
232 
233 // ----------------------------------------------------------------------------
234 // wxGDIImage functions forwarded to wxGDIImageRefData
235 // ----------------------------------------------------------------------------
236 
FreeResource(bool WXUNUSED (force))237 bool wxGDIImage::FreeResource(bool WXUNUSED(force))
238 {
239     if ( !IsNull() )
240     {
241         GetGDIImageData()->Free();
242         GetGDIImageData()->m_handle = 0;
243     }
244 
245     return true;
246 }
247 
GetResourceHandle() const248 WXHANDLE wxGDIImage::GetResourceHandle() const
249 {
250     return GetHandle();
251 }
252 
253 // ----------------------------------------------------------------------------
254 // wxGDIImage handler stuff
255 // ----------------------------------------------------------------------------
256 
AddHandler(wxGDIImageHandler * handler)257 void wxGDIImage::AddHandler(wxGDIImageHandler *handler)
258 {
259     ms_handlers.Append(handler);
260 }
261 
InsertHandler(wxGDIImageHandler * handler)262 void wxGDIImage::InsertHandler(wxGDIImageHandler *handler)
263 {
264     ms_handlers.Insert(handler);
265 }
266 
RemoveHandler(const wxString & name)267 bool wxGDIImage::RemoveHandler(const wxString& name)
268 {
269     wxGDIImageHandler *handler = FindHandler(name);
270     if ( handler )
271     {
272         ms_handlers.DeleteObject(handler);
273         return true;
274     }
275     else
276         return false;
277 }
278 
FindHandler(const wxString & name)279 wxGDIImageHandler *wxGDIImage::FindHandler(const wxString& name)
280 {
281     wxGDIImageHandlerList::compatibility_iterator node = ms_handlers.GetFirst();
282     while ( node )
283     {
284         wxGDIImageHandler *handler = node->GetData();
285         if ( handler->GetName() == name )
286             return handler;
287         node = node->GetNext();
288     }
289 
290     return NULL;
291 }
292 
FindHandler(const wxString & extension,long type)293 wxGDIImageHandler *wxGDIImage::FindHandler(const wxString& extension,
294                                            long type)
295 {
296     wxGDIImageHandlerList::compatibility_iterator node = ms_handlers.GetFirst();
297     while ( node )
298     {
299         wxGDIImageHandler *handler = node->GetData();
300         if ( (handler->GetExtension() == extension) &&
301              (type == -1 || handler->GetType() == type) )
302         {
303             return handler;
304         }
305 
306         node = node->GetNext();
307     }
308     return NULL;
309 }
310 
FindHandler(long type)311 wxGDIImageHandler *wxGDIImage::FindHandler(long type)
312 {
313     wxGDIImageHandlerList::compatibility_iterator node = ms_handlers.GetFirst();
314     while ( node )
315     {
316         wxGDIImageHandler *handler = node->GetData();
317         if ( handler->GetType() == type )
318             return handler;
319 
320         node = node->GetNext();
321     }
322 
323     return NULL;
324 }
325 
CleanUpHandlers()326 void wxGDIImage::CleanUpHandlers()
327 {
328     wxGDIImageHandlerList::compatibility_iterator node = ms_handlers.GetFirst();
329     while ( node )
330     {
331         wxGDIImageHandler *handler = node->GetData();
332         wxGDIImageHandlerList::compatibility_iterator next = node->GetNext();
333         delete handler;
334         ms_handlers.Erase( node );
335         node = next;
336     }
337 }
338 
InitStandardHandlers()339 void wxGDIImage::InitStandardHandlers()
340 {
341 #ifndef __WXMICROWIN__
342     AddHandler(new wxBMPResourceHandler);
343     AddHandler(new wxBMPFileHandler);
344     AddHandler(new wxICOFileHandler);
345     AddHandler(new wxICOResourceHandler);
346 #if wxUSE_PNG_RESOURCE_HANDLER
347     AddHandler(new wxPNGResourceHandler);
348 #endif // wxUSE_PNG_RESOURCE_HANDLER
349 #endif
350 }
351 
352 #ifndef __WXMICROWIN__
353 
354 // ----------------------------------------------------------------------------
355 // wxBitmap handlers
356 // ----------------------------------------------------------------------------
357 
LoadFile(wxBitmap * bitmap,const wxString & name,wxBitmapType WXUNUSED (flags),int WXUNUSED (desiredWidth),int WXUNUSED (desiredHeight))358 bool wxBMPResourceHandler::LoadFile(wxBitmap *bitmap,
359                                     const wxString& name, wxBitmapType WXUNUSED(flags),
360                                     int WXUNUSED(desiredWidth),
361                                     int WXUNUSED(desiredHeight))
362 {
363     // TODO: load colourmap.
364     bitmap->SetHBITMAP((WXHBITMAP)::LoadBitmap(wxGetInstance(), name.t_str()));
365 
366     if ( !bitmap->IsOk() )
367     {
368         // it's probably not found
369         wxLogError(wxT("Can't load bitmap '%s' from resources! Check .rc file."),
370                    name.c_str());
371 
372         return false;
373     }
374 
375     BITMAP bm;
376     if ( !::GetObject(GetHbitmapOf(*bitmap), sizeof(BITMAP), (LPSTR) &bm) )
377     {
378         wxLogLastError(wxT("GetObject(HBITMAP)"));
379     }
380 
381     bitmap->SetWidth(bm.bmWidth);
382     bitmap->SetHeight(bm.bmHeight);
383     bitmap->SetDepth(bm.bmBitsPixel);
384 
385     // use 0xc0c0c0 as transparent colour by default
386     bitmap->SetMask(new wxMask(*bitmap, *wxLIGHT_GREY));
387 
388     return true;
389 }
390 
LoadFile(wxBitmap * bitmap,const wxString & name,wxBitmapType WXUNUSED (flags),int WXUNUSED (desiredWidth),int WXUNUSED (desiredHeight))391 bool wxBMPFileHandler::LoadFile(wxBitmap *bitmap,
392                                 const wxString& name, wxBitmapType WXUNUSED(flags),
393                                 int WXUNUSED(desiredWidth),
394                                 int WXUNUSED(desiredHeight))
395 {
396     wxCHECK_MSG( bitmap, false, wxT("NULL bitmap in LoadFile") );
397 
398 #if wxUSE_WXDIB
399     // Try loading using native Windows LoadImage() first.
400     wxDIB dib(name);
401     if ( dib.IsOk() )
402         return bitmap->CopyFromDIB(dib);
403 #endif // wxUSE_WXDIB
404 
405     // Some valid bitmap files are not supported by LoadImage(), e.g. those
406     // with negative height. Try to use our own bitmap loading code which does
407     // support them.
408 #if wxUSE_IMAGE
409     wxImage img(name, wxBITMAP_TYPE_BMP);
410     if ( img.IsOk() )
411     {
412         *bitmap = wxBitmap(img);
413         return true;
414     }
415 #endif // wxUSE_IMAGE
416 
417     return false;
418 }
419 
SaveFile(const wxBitmap * bitmap,const wxString & name,wxBitmapType WXUNUSED (type),const wxPalette * WXUNUSED (pal)) const420 bool wxBMPFileHandler::SaveFile(const wxBitmap *bitmap,
421                                 const wxString& name,
422                                 wxBitmapType WXUNUSED(type),
423                                 const wxPalette * WXUNUSED(pal)) const
424 {
425 #if wxUSE_WXDIB
426     wxCHECK_MSG( bitmap, false, wxT("NULL bitmap in SaveFile") );
427 
428     wxDIB dib(*bitmap);
429 
430     return dib.Save(name);
431 #else
432     return false;
433 #endif
434 }
435 
436 // ----------------------------------------------------------------------------
437 // wxIcon handlers
438 // ----------------------------------------------------------------------------
439 
LoadIcon(wxIcon * icon,const wxString & name,wxBitmapType WXUNUSED (flags),int desiredWidth,int desiredHeight)440 bool wxICOFileHandler::LoadIcon(wxIcon *icon,
441                                 const wxString& name,
442                                 wxBitmapType WXUNUSED(flags),
443                                 int desiredWidth, int desiredHeight)
444 {
445     icon->UnRef();
446 
447     HICON hicon = NULL;
448 
449     // Parse the filename: it may be of the form "filename;n" in order to
450     // specify the nth icon in the file.
451     //
452     // For the moment, ignore the issue of possible semicolons in the
453     // filename.
454     int iconIndex = 0;
455     wxString nameReal(name);
456     wxString strIconIndex = name.AfterLast(wxT(';'));
457     if (strIconIndex != name)
458     {
459         iconIndex = wxAtoi(strIconIndex);
460         nameReal = name.BeforeLast(wxT(';'));
461     }
462 
463 #if 0
464     // If we don't know what size icon we're looking for,
465     // try to find out what's there.
466     // Unfortunately this doesn't work, because ExtractIconEx
467     // will scale the icon to the 'desired' size, even if that
468     // size of icon isn't explicitly stored. So we would have
469     // to parse the icon file outselves.
470     if ( desiredWidth == -1 &&
471          desiredHeight == -1)
472     {
473         // Try loading a large icon first
474         if ( ::ExtractIconEx(nameReal, iconIndex, &hicon, NULL, 1) == 1)
475         {
476         }
477         // Then try loading a small icon
478         else if ( ::ExtractIconEx(nameReal, iconIndex, NULL, &hicon, 1) == 1)
479         {
480         }
481     }
482     else
483 #endif
484         // were we asked for a large icon?
485     if ( desiredWidth == ::GetSystemMetrics(SM_CXICON) &&
486          desiredHeight == ::GetSystemMetrics(SM_CYICON) )
487     {
488         // get the specified large icon from file
489         if ( !::ExtractIconEx(nameReal.t_str(), iconIndex, &hicon, NULL, 1) )
490         {
491             // it is not an error, but it might still be useful to be informed
492             // about it optionally
493             wxLogTrace(wxT("iconload"),
494                        wxT("No large icons found in the file '%s'."),
495                        name.c_str());
496         }
497     }
498     else if ( desiredWidth == ::GetSystemMetrics(SM_CXSMICON) &&
499               desiredHeight == ::GetSystemMetrics(SM_CYSMICON) )
500     {
501         // get the specified small icon from file
502         if ( !::ExtractIconEx(nameReal.t_str(), iconIndex, NULL, &hicon, 1) )
503         {
504             wxLogTrace(wxT("iconload"),
505                        wxT("No small icons found in the file '%s'."),
506                        name.c_str());
507         }
508     }
509     //else: not standard size, load below
510 
511 #ifndef __WXWINCE__
512     if ( !hicon )
513     {
514         // take any size icon from the file by index
515         hicon = ::ExtractIcon(wxGetInstance(), nameReal.t_str(), iconIndex);
516     }
517 #endif
518 
519     if ( !hicon )
520     {
521         wxLogSysError(wxT("Failed to load icon from the file '%s'"),
522                       name.c_str());
523 
524         return false;
525     }
526 
527     if ( !icon->CreateFromHICON(hicon) )
528         return false;
529 
530     if ( (desiredWidth != -1 && desiredWidth != icon->GetWidth()) ||
531          (desiredHeight != -1 && desiredHeight != icon->GetHeight()) )
532     {
533         wxLogTrace(wxT("iconload"),
534                    wxT("Returning false from wxICOFileHandler::Load because of the size mismatch: actual (%d, %d), requested (%d, %d)"),
535                    icon->GetWidth(), icon->GetHeight(),
536                    desiredWidth, desiredHeight);
537 
538         icon->UnRef();
539 
540         return false;
541     }
542 
543     return true;
544 }
545 
LoadIcon(wxIcon * icon,const wxString & name,wxBitmapType WXUNUSED (flags),int desiredWidth,int desiredHeight)546 bool wxICOResourceHandler::LoadIcon(wxIcon *icon,
547                                     const wxString& name,
548                                     wxBitmapType WXUNUSED(flags),
549                                     int desiredWidth, int desiredHeight)
550 {
551     HICON hicon;
552 
553     // do we need the icon of the specific size or would any icon do?
554     bool hasSize = desiredWidth != -1 || desiredHeight != -1;
555 
556     wxASSERT_MSG( !hasSize || (desiredWidth != -1 && desiredHeight != -1),
557                   wxT("width and height should be either both -1 or not") );
558 
559     // try to load the icon from this program first to allow overriding the
560     // standard icons (although why one would want to do it considering that
561     // we already have wxApp::GetStdIcon() is unclear)
562 
563     // note that we can't just always call LoadImage() because it seems to do
564     // some icon rescaling internally which results in very ugly 16x16 icons
565     if ( hasSize )
566     {
567         hicon = (HICON)::LoadImage(wxGetInstance(), name.t_str(), IMAGE_ICON,
568                                     desiredWidth, desiredHeight,
569                                     LR_DEFAULTCOLOR);
570     }
571     else
572     {
573         hicon = ::LoadIcon(wxGetInstance(), name.t_str());
574     }
575 
576     // next check if it's not a standard icon
577 #ifndef __WXWINCE__
578     if ( !hicon && !hasSize )
579     {
580         static const struct
581         {
582             const wxChar *name;
583             LPTSTR id;
584         } stdIcons[] =
585         {
586             { wxT("wxICON_QUESTION"),   IDI_QUESTION    },
587             { wxT("wxICON_WARNING"),    IDI_EXCLAMATION },
588             { wxT("wxICON_ERROR"),      IDI_HAND        },
589             { wxT("wxICON_INFORMATION"),       IDI_ASTERISK    },
590         };
591 
592         for ( size_t nIcon = 0; !hicon && nIcon < WXSIZEOF(stdIcons); nIcon++ )
593         {
594             if ( name == stdIcons[nIcon].name )
595             {
596                 hicon = ::LoadIcon((HINSTANCE)NULL, stdIcons[nIcon].id);
597                 break;
598             }
599         }
600     }
601 #endif
602 
603     return icon->CreateFromHICON((WXHICON)hicon);
604 }
605 
606 #if wxUSE_PNG_RESOURCE_HANDLER
607 
608 // ----------------------------------------------------------------------------
609 // PNG handler
610 // ----------------------------------------------------------------------------
611 
LoadFile(wxBitmap * bitmap,const wxString & name,wxBitmapType WXUNUSED (flags),int WXUNUSED (desiredWidth),int WXUNUSED (desiredHeight))612 bool wxPNGResourceHandler::LoadFile(wxBitmap *bitmap,
613                                     const wxString& name,
614                                     wxBitmapType WXUNUSED(flags),
615                                     int WXUNUSED(desiredWidth),
616                                     int WXUNUSED(desiredHeight))
617 {
618     const void* pngData = NULL;
619     size_t pngSize = 0;
620 
621     // Currently we hardcode RCDATA resource type as this is what is usually
622     // used for the embedded images. We could allow specifying the type as part
623     // of the name in the future (e.g. "type:name" or something like this) if
624     // really needed.
625     if ( !wxLoadUserResource(&pngData, &pngSize,
626                              name,
627                              RT_RCDATA,
628                              wxGetInstance()) )
629     {
630         // Notice that this message is not translated because only the
631         // programmer (and not the end user) can make any use of it.
632         wxLogError(wxS("Bitmap in PNG format \"%s\" not found, check ")
633                    wxS("that the resource file contains \"RCDATA\" ")
634                    wxS("resource with this name."),
635                    name);
636 
637         return false;
638     }
639 
640     *bitmap = wxBitmap::NewFromPNGData(pngData, pngSize);
641     if ( !bitmap->IsOk() )
642     {
643         wxLogError(wxS("Couldn't load resource bitmap \"%s\" as a PNG. "),
644                    wxS("Have you registered PNG image handler?"),
645                    name);
646 
647         return false;
648     }
649 
650     return true;
651 }
652 
653 #endif // wxUSE_PNG_RESOURCE_HANDLER
654 
655 // ----------------------------------------------------------------------------
656 // private functions
657 // ----------------------------------------------------------------------------
658 
wxGetHiconSize(HICON WXUNUSED_IN_WINCE (hicon))659 wxSize wxGetHiconSize(HICON WXUNUSED_IN_WINCE(hicon))
660 {
661     wxSize size;
662 
663 #ifndef __WXWINCE__
664     if ( hicon )
665     {
666         ICONINFO info;
667         if ( !::GetIconInfo(hicon, &info) )
668         {
669             wxLogLastError(wxT("GetIconInfo"));
670         }
671         else
672         {
673             HBITMAP hbmp = info.hbmMask;
674             if ( hbmp )
675             {
676                 BITMAP bm;
677                 if ( ::GetObject(hbmp, sizeof(BITMAP), (LPSTR) &bm) )
678                 {
679                     size = wxSize(bm.bmWidth, bm.bmHeight);
680                 }
681 
682                 ::DeleteObject(info.hbmMask);
683             }
684             if ( info.hbmColor )
685                 ::DeleteObject(info.hbmColor);
686         }
687     }
688 
689     if ( !size.x )
690 #endif // !__WXWINCE__
691     {
692         // use default icon size on this hardware
693         size.x = ::GetSystemMetrics(SM_CXICON);
694         size.y = ::GetSystemMetrics(SM_CYICON);
695     }
696 
697     return size;
698 }
699 
700 #endif // __WXMICROWIN__
701