]> git.saurik.com Git - wxWidgets.git/blame - src/msw/artmsw.cpp
Correct erasing of background behind controls in a toolbar in wxMSW.
[wxWidgets.git] / src / msw / artmsw.cpp
CommitLineData
7abd9a03
VS
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/msw/artmsw.cpp
3// Purpose: stock wxArtProvider instance with native MSW stock icons
4// Author: Vaclav Slavik
5// Modified by:
6// Created: 2008-10-15
7abd9a03
VS
7// Copyright: (c) Vaclav Slavik, 2008
8// Licence: wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
10
11// ---------------------------------------------------------------------------
12// headers
13// ---------------------------------------------------------------------------
14
15// For compilers that support precompilation, includes "wx.h".
16#include "wx/wxprec.h"
17
18#if defined(__BORLANDC__)
19 #pragma hdrstop
20#endif
21
22#include "wx/artprov.h"
023f2738 23#include "wx/image.h"
f29b59b7
VZ
24#include "wx/dynlib.h"
25#include "wx/volume.h"
26#include "wx/msw/private.h"
7abd9a03
VS
27#include "wx/msw/wrapwin.h"
28
f29b59b7
VZ
29#ifdef SHGSI_ICON
30 #define wxHAS_SHGetStockIconInfo
31#endif
32
33namespace
34{
35
36#ifdef wxHAS_SHGetStockIconInfo
37
38SHSTOCKICONID MSWGetStockIconIdForArtProviderId(const wxArtID& art_id)
39{
40 // try to find an equivalent MSW stock icon id for wxArtID
41 if ( art_id == wxART_ERROR) return SIID_ERROR;
42 else if ( art_id == wxART_QUESTION ) return SIID_HELP;
43 else if ( art_id == wxART_WARNING ) return SIID_WARNING;
44 else if ( art_id == wxART_INFORMATION ) return SIID_INFO;
45 else if ( art_id == wxART_HELP ) return SIID_HELP;
46 else if ( art_id == wxART_FOLDER ) return SIID_FOLDER;
47 else if ( art_id == wxART_FOLDER_OPEN ) return SIID_FOLDEROPEN;
48 else if ( art_id == wxART_DELETE ) return SIID_DELETE;
49 else if ( art_id == wxART_FIND ) return SIID_FIND;
50 else if ( art_id == wxART_HARDDISK ) return SIID_DRIVEFIXED;
51 else if ( art_id == wxART_FLOPPY ) return SIID_DRIVE35;
52 else if ( art_id == wxART_CDROM ) return SIID_DRIVECD;
53 else if ( art_id == wxART_REMOVABLE ) return SIID_DRIVEREMOVE;
54
55 return SIID_INVALID;
56};
57
58
59// try to load SHGetStockIconInfo dynamically, so this code runs
60// even on pre-Vista Windows versions
61HRESULT
62MSW_SHGetStockIconInfo(SHSTOCKICONID siid,
63 UINT uFlags,
64 SHSTOCKICONINFO *psii)
65{
66 typedef HRESULT (WINAPI *PSHGETSTOCKICONINFO)(SHSTOCKICONID, UINT, SHSTOCKICONINFO *);
67 static PSHGETSTOCKICONINFO pSHGetStockIconInfo = (PSHGETSTOCKICONINFO)-1;
68
69 if ( pSHGetStockIconInfo == (PSHGETSTOCKICONINFO)-1 )
70 {
71 wxDynamicLibrary shell32(wxT("shell32.dll"));
72
73 pSHGetStockIconInfo = (PSHGETSTOCKICONINFO)shell32.RawGetSymbol( wxT("SHGetStockIconInfo") );
74 }
75
76 if ( !pSHGetStockIconInfo )
77 return E_FAIL;
78
79 return pSHGetStockIconInfo(siid, uFlags, psii);
80}
81
82#endif // #ifdef wxHAS_SHGetStockIconInfo
83
84wxBitmap
85MSWGetBitmapForPath(const wxString& path, const wxSize& size, DWORD uFlags = 0)
86{
87 SHFILEINFO fi;
88 wxZeroMemory(fi);
89
90 uFlags |= SHGFI_USEFILEATTRIBUTES | SHGFI_ICON;
91 if ( size != wxDefaultSize )
92 {
93 if ( size.x <= 16 )
94 uFlags |= SHGFI_SMALLICON;
95 else if ( size.x >= 64 )
96 uFlags |= SHGFI_LARGEICON;
97 }
98
99 if ( !SHGetFileInfo(path.t_str(), FILE_ATTRIBUTE_DIRECTORY,
100 &fi, sizeof(SHFILEINFO), uFlags) )
101 return wxNullBitmap;
102
103 wxIcon icon;
104 icon.CreateFromHICON((WXHICON)fi.hIcon);
105
106 wxBitmap bitmap(icon);
107 ::DestroyIcon(fi.hIcon);
108
109 return bitmap;
110}
111
112#if wxUSE_FSVOLUME
113
114wxBitmap
115GetDriveBitmapForVolumeType(const wxFSVolumeKind& volKind, const wxSize& size)
116{
117 // get all volumes and try to find one with a matching type
118 wxArrayString volumes = wxFSVolume::GetVolumes();
119 for ( size_t i = 0; i < volumes.Count(); i++ )
120 {
121 wxFSVolume vol( volumes[i] );
122 if ( vol.GetKind() == volKind )
123 {
124 return MSWGetBitmapForPath(volumes[i], size);
125 }
126 }
127
128 return wxNullBitmap;
129}
130
131#endif // wxUSE_FSVOLUME
132
133} // anonymous namespace
7abd9a03
VS
134
135// ----------------------------------------------------------------------------
136// wxWindowsArtProvider
137// ----------------------------------------------------------------------------
138
139class wxWindowsArtProvider : public wxArtProvider
140{
141protected:
142 virtual wxBitmap CreateBitmap(const wxArtID& id, const wxArtClient& client,
143 const wxSize& size);
144};
145
023f2738
VS
146static wxBitmap CreateFromStdIcon(const char *iconName,
147 const wxArtClient& client)
7abd9a03
VS
148{
149 wxIcon icon(iconName);
150 wxBitmap bmp;
151 bmp.CopyFromIcon(icon);
023f2738
VS
152
153#if wxUSE_IMAGE
154 // The standard native message box icons are in message box size (32x32).
155 // If they are requested in any size other than the default or message
156 // box size, they must be rescaled first.
157 if ( client != wxART_MESSAGE_BOX && client != wxART_OTHER )
158 {
159 const wxSize size = wxArtProvider::GetNativeSizeHint(client);
160 if ( size != wxDefaultSize )
161 {
162 wxImage img = bmp.ConvertToImage();
163 img.Rescale(size.x, size.y);
164 bmp = wxBitmap(img);
165 }
166 }
167#endif // wxUSE_IMAGE
168
7abd9a03
VS
169 return bmp;
170}
171
172wxBitmap wxWindowsArtProvider::CreateBitmap(const wxArtID& id,
023f2738 173 const wxArtClient& client,
f29b59b7 174 const wxSize& size)
7abd9a03 175{
f29b59b7
VZ
176 wxBitmap bitmap;
177
178#ifdef wxHAS_SHGetStockIconInfo
179 // first try to use SHGetStockIconInfo, available only on Vista and higher
180 SHSTOCKICONID stockIconId = MSWGetStockIconIdForArtProviderId( id );
181 if ( stockIconId != SIID_INVALID )
182 {
183 WinStruct<SHSTOCKICONINFO> sii;
184
185 UINT uFlags = SHGSI_ICON;
186 if ( size != wxDefaultSize )
187 {
188 if ( size.x <= 16 )
189 uFlags |= SHGSI_SMALLICON;
190 else if ( size.x >= 64 )
191 uFlags |= SHGSI_LARGEICON;
192 }
193
194 HRESULT res = MSW_SHGetStockIconInfo(stockIconId, uFlags, &sii);
195 if ( res == S_OK )
196 {
197 wxIcon icon;
198 icon.CreateFromHICON( (WXHICON)sii.hIcon );
199
200 wxBitmap bitmap( icon );
201 ::DestroyIcon(sii.hIcon);
202
203 if ( bitmap.IsOk() )
204 return bitmap;
205 }
206 }
207#endif // wxHAS_SHGetStockIconInfo
208
209
210#if wxUSE_FSVOLUME
211 // now try SHGetFileInfo
212 wxFSVolumeKind volKind = wxFS_VOL_OTHER;
213 if ( id == wxART_HARDDISK )
214 volKind = wxFS_VOL_DISK;
215 else if ( id == wxART_FLOPPY )
216 volKind = wxFS_VOL_FLOPPY;
217 else if ( id == wxART_CDROM )
218 volKind = wxFS_VOL_CDROM;
219
220 if ( volKind != wxFS_VOL_OTHER )
221 {
222 bitmap = GetDriveBitmapForVolumeType(volKind, size);
223 if ( bitmap.IsOk() )
224 return bitmap;
225 }
226#endif // wxUSE_FSVOLUME
227
228 // notice that the directory used here doesn't need to exist
229 if ( id == wxART_FOLDER )
230 bitmap = MSWGetBitmapForPath("C:\\wxdummydir\\", size );
231 else if ( id == wxART_FOLDER_OPEN )
232 bitmap = MSWGetBitmapForPath("C:\\wxdummydir\\", size, SHGFI_OPENICON );
233
234 if ( !bitmap.IsOk() )
235 {
236 // handle message box icons specially (wxIcon ctor treat these names
237 // as special cases via wxICOResourceHandler::LoadIcon):
238 const char *name = NULL;
239 if ( id == wxART_ERROR )
240 name = "wxICON_ERROR";
241 else if ( id == wxART_INFORMATION )
242 name = "wxICON_INFORMATION";
243 else if ( id == wxART_WARNING )
244 name = "wxICON_WARNING";
245 else if ( id == wxART_QUESTION )
246 name = "wxICON_QUESTION";
247
248 if ( name )
249 return CreateFromStdIcon(name, client);
250 }
7abd9a03
VS
251
252 // for anything else, fall back to generic provider:
f29b59b7 253 return bitmap;
7abd9a03
VS
254}
255
256// ----------------------------------------------------------------------------
257// wxArtProvider::InitNativeProvider()
258// ----------------------------------------------------------------------------
259
260/*static*/ void wxArtProvider::InitNativeProvider()
261{
0d68cd13 262 PushBack(new wxWindowsArtProvider);
7abd9a03
VS
263}
264
265// ----------------------------------------------------------------------------
266// wxArtProvider::GetNativeSizeHint()
267// ----------------------------------------------------------------------------
268
269/*static*/
270wxSize wxArtProvider::GetNativeSizeHint(const wxArtClient& client)
271{
272 if ( client == wxART_TOOLBAR )
273 {
274 return wxSize(24, 24);
275 }
276 else if ( client == wxART_MENU )
277 {
278 return wxSize(16, 16);
279 }
280 else if ( client == wxART_FRAME_ICON )
281 {
282 return wxSize(::GetSystemMetrics(SM_CXSMICON),
283 ::GetSystemMetrics(SM_CYSMICON));
284 }
285 else if ( client == wxART_CMN_DIALOG ||
286 client == wxART_MESSAGE_BOX )
287 {
288 return wxSize(::GetSystemMetrics(SM_CXICON),
289 ::GetSystemMetrics(SM_CYICON));
290 }
291 else if (client == wxART_BUTTON)
292 {
293 return wxSize(16, 16);
294 }
66d9eb61
VZ
295 else if (client == wxART_LIST)
296 {
297 return wxSize(16, 16);
298 }
7abd9a03
VS
299
300 return wxDefaultSize;
301}