1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/msw/imaglist.cpp 
   3 // Purpose:     wxImageList implementation for Win32 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  20 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  21     #pragma implementation "imaglist.h" 
  24 // For compilers that support precompilation, includes "wx.h". 
  25 #include "wx/wxprec.h" 
  31 #if defined(__WIN95__) 
  34     #include "wx/window.h" 
  37     #include "wx/string.h" 
  38     #include "wx/dcmemory.h" 
  46 #include "wx/msw/imaglist.h" 
  47 #include "wx/msw/private.h" 
  49 #if defined(__WIN95__) && !(defined(__GNUWIN32_OLD__) && !defined(__CYGWIN10__)) 
  53 // ---------------------------------------------------------------------------- 
  55 // ---------------------------------------------------------------------------- 
  57 IMPLEMENT_DYNAMIC_CLASS(wxImageList
, wxObject
) 
  59 #define GetHImageList()     ((HIMAGELIST)m_hImageList) 
  61 // ---------------------------------------------------------------------------- 
  63 // ---------------------------------------------------------------------------- 
  65 // returns the mask if it's valid, otherwise the bitmap mask and, if it's not 
  66 // valid neither, a "solid" mask (no transparent zones at all) 
  67 static HBITMAP 
GetMaskForImage(const wxBitmap
& bitmap
, const wxBitmap
& mask
); 
  69 // ============================================================================ 
  71 // ============================================================================ 
  73 // ---------------------------------------------------------------------------- 
  74 // wxImageList creation/destruction 
  75 // ---------------------------------------------------------------------------- 
  77 wxImageList::wxImageList() 
  82 // Creates an image list 
  83 bool wxImageList::Create(int width
, int height
, bool mask
, int initial
) 
  87     // set appropriate color depth 
  88     int dd 
= wxDisplayDepth(); 
  92     if (dd 
<= 4)       flags 
|= ILC_COLOR
;      // 16 color 
  93     else if (dd 
<= 8)  flags 
|= ILC_COLOR8
;     // 256 color 
  94     else if (dd 
<= 16) flags 
|= ILC_COLOR16
;    // 64k hi-color 
  95     else if (dd 
<= 24) flags 
|= ILC_COLOR24
;    // 16m truecolor 
  96     else if (dd 
<= 32) flags 
|= ILC_COLOR32
;    // 16m truecolor 
 102     // Grow by 1, I guess this is reasonable behaviour most of the time 
 103     m_hImageList 
= (WXHIMAGELIST
) ImageList_Create(width
, height
, flags
, 
 107         wxLogLastError(wxT("ImageList_Create()")); 
 110     return m_hImageList 
!= 0; 
 113 wxImageList::~wxImageList() 
 117         ImageList_Destroy(GetHImageList()); 
 122 // ---------------------------------------------------------------------------- 
 123 // wxImageList attributes 
 124 // ---------------------------------------------------------------------------- 
 126 // Returns the number of images in the image list. 
 127 int wxImageList::GetImageCount() const 
 129     wxASSERT_MSG( m_hImageList
, _T("invalid image list") ); 
 131     return ImageList_GetImageCount(GetHImageList()); 
 134 // Returns the size (same for all images) of the images in the list 
 135 bool wxImageList::GetSize(int WXUNUSED(index
), int &width
, int &height
) const 
 137     wxASSERT_MSG( m_hImageList
, _T("invalid image list") ); 
 139     return ImageList_GetIconSize(GetHImageList(), &width
, &height
) != 0; 
 142 // ---------------------------------------------------------------------------- 
 143 // wxImageList operations 
 144 // ---------------------------------------------------------------------------- 
 146 // Adds a bitmap, and optionally a mask bitmap. 
 147 // Note that wxImageList creates new bitmaps, so you may delete 
 148 // 'bitmap' and 'mask'. 
 149 int wxImageList::Add(const wxBitmap
& bitmap
, const wxBitmap
& mask
) 
 151     HBITMAP hbmpMask 
= GetMaskForImage(bitmap
, mask
); 
 153     int index 
= ImageList_Add(GetHImageList(), GetHbitmapOf(bitmap
), hbmpMask
); 
 156         wxLogError(_("Couldn't add an image to the image list.")); 
 159     ::DeleteObject(hbmpMask
); 
 164 // Adds a bitmap, using the specified colour to create the mask bitmap 
 165 // Note that wxImageList creates new bitmaps, so you may delete 
 167 int wxImageList::Add(const wxBitmap
& bitmap
, const wxColour
& maskColour
) 
 169     int index 
= ImageList_AddMasked(GetHImageList(), 
 170                                     GetHbitmapOf(bitmap
), 
 171                                     wxColourToRGB(maskColour
)); 
 174         wxLogError(_("Couldn't add an image to the image list.")); 
 180 // Adds a bitmap and mask from an icon. 
 181 int wxImageList::Add(const wxIcon
& icon
) 
 183     int index 
= ImageList_AddIcon(GetHImageList(), GetHiconOf(icon
)); 
 186         wxLogError(_("Couldn't add an image to the image list.")); 
 192 // Replaces a bitmap, optionally passing a mask bitmap. 
 193 // Note that wxImageList creates new bitmaps, so you may delete 
 194 // 'bitmap' and 'mask'. 
 195 bool wxImageList::Replace(int index
, 
 196                           const wxBitmap
& bitmap
, const wxBitmap
& mask
) 
 198     HBITMAP hbmpMask 
= GetMaskForImage(bitmap
, mask
); 
 200     bool ok 
= ImageList_Replace(GetHImageList(), index
, 
 201                                 GetHbitmapOf(bitmap
), hbmpMask
) != 0; 
 204         wxLogLastError(wxT("ImageList_Add()")); 
 207     ::DeleteObject(hbmpMask
); 
 212 // Replaces a bitmap and mask from an icon. 
 213 bool wxImageList::Replace(int i
, const wxIcon
& icon
) 
 215     bool ok 
= ImageList_ReplaceIcon(GetHImageList(), i
, GetHiconOf(icon
)) != 0; 
 218         wxLogLastError(wxT("ImageList_ReplaceIcon()")); 
 224 // Removes the image at the given index. 
 225 bool wxImageList::Remove(int index
) 
 227     bool ok 
= ImageList_Remove(GetHImageList(), index
) != 0; 
 230         wxLogLastError(wxT("ImageList_Remove()")); 
 237 bool wxImageList::RemoveAll() 
 239     // don't use ImageList_RemoveAll() because mingw32 headers don't have it 
 240     int count 
= ImageList_GetImageCount(GetHImageList()); 
 241     for ( int i 
= 0; i 
< count
; i
++ ) 
 243         // the image indexes are shifted, so we should always remove the first 
 251 // Draws the given image on a dc at the specified position. 
 252 // If 'solidBackground' is TRUE, Draw sets the image list background 
 253 // colour to the background colour of the wxDC, to speed up 
 254 // drawing by eliminating masked drawing where possible. 
 255 bool wxImageList::Draw(int index
, 
 259                        bool solidBackground
) 
 261     HDC hDC 
= GetHdcOf(dc
); 
 262     wxCHECK_MSG( hDC
, FALSE
, _T("invalid wxDC in wxImageList::Draw") ); 
 264     COLORREF clr 
= CLR_NONE
;    // transparent by default 
 265     if ( solidBackground 
) 
 267         wxBrush 
*brush 
= & dc
.GetBackground(); 
 268         if ( brush 
&& brush
->Ok() ) 
 270             clr 
= wxColourToRGB(brush
->GetColour()); 
 274     ImageList_SetBkColor(GetHImageList(), clr
); 
 277     if ( flags 
& wxIMAGELIST_DRAW_NORMAL 
) 
 279     if ( flags 
& wxIMAGELIST_DRAW_TRANSPARENT 
) 
 280         style 
|= ILD_TRANSPARENT
; 
 281     if ( flags 
& wxIMAGELIST_DRAW_SELECTED 
) 
 282         style 
|= ILD_SELECTED
; 
 283     if ( flags 
& wxIMAGELIST_DRAW_FOCUSED 
) 
 286     bool ok 
= ImageList_Draw(GetHImageList(), index
, hDC
, x
, y
, style
) != 0; 
 289         wxLogLastError(wxT("ImageList_Draw()")); 
 295 // ---------------------------------------------------------------------------- 
 297 // ---------------------------------------------------------------------------- 
 299 static HBITMAP 
GetMaskForImage(const wxBitmap
& bitmap
, const wxBitmap
& mask
) 
 303     bool deleteMask 
= FALSE
; 
 307         hbmpMask 
= GetHbitmapOf(mask
); 
 312         pMask 
= bitmap
.GetMask(); 
 315             // use the light grey count as transparent: the trouble here is 
 316             // that the light grey might have been changed by Windows behind 
 317             // our back, so use the standard colour map to get its real value 
 318             wxCOLORMAP 
*cmap 
= wxGetStdColourMap(); 
 320             wxRGBToColour(col
, cmap
[wxSTD_COL_BTNFACE
].from
); 
 322             pMask 
= new wxMask(bitmap
, col
); 
 327         hbmpMask 
= (HBITMAP
)pMask
->GetMaskBitmap(); 
 330     // windows mask convention is opposite to the wxWindows one 
 331     HBITMAP hbmpMaskInv 
= wxInvertMask(hbmpMask
);