]> git.saurik.com Git - wxWidgets.git/blame - src/msw/gdiimage.cpp
Misc small mods
[wxWidgets.git] / src / msw / gdiimage.cpp
CommitLineData
0d0512bd
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: msw/gdiimage.cpp
3// Purpose: wxGDIImage implementation
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 20.11.99
7// RCS-ID: $Id$
8// Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9// Licence: wxWindows license
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20#ifdef __GNUG__
21 #pragma implementation "gdiimage.h"
22#endif
23
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
27#ifdef __BORLANDC__
28 #pragma hdrstop
29#endif
30
31#ifndef WX_PRECOMP
32 #include "wx/string.h"
33#endif // WX_PRECOMP
34
e42a6c18
VZ
35#include "wx/msw/private.h"
36
0d0512bd
VZ
37#include "wx/app.h"
38
39#include "wx/msw/dib.h"
40#include "wx/msw/gdiimage.h"
41
8f177c8e
VZ
42#ifdef __WIN16__
43 #include "wx/msw/curico.h"
44#endif // __WIN16__
45
0d0512bd
VZ
46// ----------------------------------------------------------------------------
47// private classes
48// ----------------------------------------------------------------------------
49
50// all image handlers are declared/defined in this file because the outside
51// world doesn't have to know about them (but only about wxBITMAP_TYPE_XXX ids)
52
53class WXDLLEXPORT wxBMPFileHandler : public wxBitmapHandler
54{
55public:
56 wxBMPFileHandler() : wxBitmapHandler(_T("Windows bitmap file"), _T("bmp"),
57 wxBITMAP_TYPE_BMP)
58 {
59 }
60
61 virtual bool LoadFile(wxBitmap *bitmap,
62 const wxString& name, long flags,
63 int desiredWidth, int desiredHeight);
64 virtual bool SaveFile(wxBitmap *bitmap,
65 const wxString& name, int type,
66 const wxPalette *palette = NULL);
67
68private:
69 DECLARE_DYNAMIC_CLASS(wxBMPFileHandler)
70};
71
72class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler
73{
74public:
75 wxBMPResourceHandler() : wxBitmapHandler(_T("Windows bitmap resource"),
76 wxEmptyString,
77 wxBITMAP_TYPE_BMP_RESOURCE)
78 {
79 }
80
81 virtual bool LoadFile(wxBitmap *bitmap,
82 const wxString& name, long flags,
83 int desiredWidth, int desiredHeight);
84
85private:
86 DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler)
87};
88
89class WXDLLEXPORT wxIconHandler : public wxGDIImageHandler
90{
91public:
92 wxIconHandler(const wxString& name, const wxString& ext, long type)
93 : wxGDIImageHandler(name, ext, type)
94 {
95 }
96
97 // creating and saving icons is not supported
98 virtual bool Create(wxGDIImage *WXUNUSED(image),
99 void *WXUNUSED(data),
100 long WXUNUSED(flags),
101 int WXUNUSED(width),
102 int WXUNUSED(height),
103 int WXUNUSED(depth) = 1)
104 {
105 return FALSE;
106 }
107
108 virtual bool Save(wxGDIImage *WXUNUSED(image),
109 const wxString& WXUNUSED(name),
110 int WXUNUSED(type))
111 {
112 return FALSE;
113 }
114
115 virtual bool Load(wxGDIImage *image,
116 const wxString& name,
117 long flags,
118 int desiredWidth, int desiredHeight)
119 {
120 wxIcon *icon = wxDynamicCast(image, wxIcon);
121 wxCHECK_MSG( icon, FALSE, _T("wxIconHandler only works with icons") );
122
123 return LoadIcon(icon, name, flags, desiredWidth, desiredHeight);
124 }
125
126protected:
127 virtual bool LoadIcon(wxIcon *icon,
128 const wxString& name, long flags,
129 int desiredWidth = -1, int desiredHeight = -1) = 0;
130};
131
132class WXDLLEXPORT wxICOFileHandler : public wxIconHandler
133{
134public:
135 wxICOFileHandler() : wxIconHandler(_T("ICO icon file"),
136 _T("ico"),
137 wxBITMAP_TYPE_ICO)
138 {
139 }
140
141 virtual bool LoadIcon(wxIcon *icon,
142 const wxString& name, long flags,
143 int desiredWidth = -1, int desiredHeight = -1);
144
145private:
146 DECLARE_DYNAMIC_CLASS(wxICOFileHandler)
147};
148
149class WXDLLEXPORT wxICOResourceHandler: public wxIconHandler
150{
151public:
152 wxICOResourceHandler() : wxIconHandler(_T("ICO resource"),
153 _T("ico"),
154 wxBITMAP_TYPE_ICO_RESOURCE)
155 {
156 }
157
158 virtual bool LoadIcon(wxIcon *icon,
159 const wxString& name, long flags,
160 int desiredWidth = -1, int desiredHeight = -1);
161
162private:
163 DECLARE_DYNAMIC_CLASS(wxICOResourceHandler)
164};
165
166// ----------------------------------------------------------------------------
167// wxWin macros
168// ----------------------------------------------------------------------------
169
0d0512bd
VZ
170 IMPLEMENT_DYNAMIC_CLASS(wxBMPFileHandler, wxBitmapHandler)
171 IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler)
172 IMPLEMENT_DYNAMIC_CLASS(wxICOFileHandler, wxGDIImageHandler)
173 IMPLEMENT_DYNAMIC_CLASS(wxICOResourceHandler, wxGDIImageHandler)
0d0512bd
VZ
174
175// ----------------------------------------------------------------------------
176// private functions
177// ----------------------------------------------------------------------------
178
179static wxSize GetHiconSize(HICON hicon);
180
181// ============================================================================
182// implementation
183// ============================================================================
184
185wxList wxGDIImage::ms_handlers;
186
187// ----------------------------------------------------------------------------
188// wxGDIImage functions forwarded to wxGDIImageRefData
189// ----------------------------------------------------------------------------
190
191bool wxGDIImage::FreeResource(bool WXUNUSED(force))
192{
193 if ( !IsNull() )
194 {
195 GetGDIImageData()->Free();
196 GetGDIImageData()->m_handle = 0;
197 }
198
199 return TRUE;
200}
201
202WXHANDLE wxGDIImage::GetResourceHandle()
203{
204 return GetHandle();
205}
206
207// ----------------------------------------------------------------------------
208// wxGDIImage handler stuff
209// ----------------------------------------------------------------------------
210
211void wxGDIImage::AddHandler(wxGDIImageHandler *handler)
212{
213 ms_handlers.Append(handler);
214}
215
216void wxGDIImage::InsertHandler(wxGDIImageHandler *handler)
217{
218 ms_handlers.Insert(handler);
219}
220
221bool wxGDIImage::RemoveHandler(const wxString& name)
222{
223 wxGDIImageHandler *handler = FindHandler(name);
224 if ( handler )
225 {
226 ms_handlers.DeleteObject(handler);
227 return TRUE;
228 }
229 else
230 return FALSE;
231}
232
233wxGDIImageHandler *wxGDIImage::FindHandler(const wxString& name)
234{
235 wxNode *node = ms_handlers.First();
236 while ( node )
237 {
238 wxGDIImageHandler *handler = (wxGDIImageHandler *)node->Data();
239 if ( handler->GetName() == name )
240 return handler;
241 node = node->Next();
242 }
243
244 return NULL;
245}
246
247wxGDIImageHandler *wxGDIImage::FindHandler(const wxString& extension,
248 long type)
249{
250 wxNode *node = ms_handlers.First();
251 while ( node )
252 {
253 wxGDIImageHandler *handler = (wxGDIImageHandler *)node->Data();
254 if ( (handler->GetExtension() = extension) &&
255 (type == -1 || handler->GetType() == type) )
256 {
257 return handler;
258 }
259
260 node = node->Next();
261 }
262 return NULL;
263}
264
265wxGDIImageHandler *wxGDIImage::FindHandler(long type)
266{
267 wxNode *node = ms_handlers.First();
268 while ( node )
269 {
270 wxGDIImageHandler *handler = (wxGDIImageHandler *)node->Data();
271 if ( handler->GetType() == type )
272 return handler;
273
274 node = node->Next();
275 }
276
277 return NULL;
278}
279
280void wxGDIImage::CleanUpHandlers()
281{
282 wxNode *node = ms_handlers.First();
283 while ( node )
284 {
285 wxGDIImageHandler *handler = (wxGDIImageHandler *)node->Data();
286 wxNode *next = node->Next();
287 delete handler;
288 delete node;
289 node = next;
290 }
291}
292
293void wxGDIImage::InitStandardHandlers()
294{
295 AddHandler(new wxBMPResourceHandler);
296 AddHandler(new wxBMPFileHandler);
297
298 // Not added by default: include xpmhand.h in your app
299 // and call these in your wxApp::OnInit.
300 // AddHandler(new wxXPMFileHandler);
301 // AddHandler(new wxXPMDataHandler);
302
303 AddHandler(new wxICOResourceHandler);
304 AddHandler(new wxICOFileHandler);
305}
306
307// ----------------------------------------------------------------------------
308// wxBitmap handlers
309// ----------------------------------------------------------------------------
310
311bool wxBMPResourceHandler::LoadFile(wxBitmap *bitmap,
312 const wxString& name, long WXUNUSED(flags),
313 int WXUNUSED(desiredWidth),
314 int WXUNUSED(desiredHeight))
315{
316 // TODO: load colourmap.
317 bitmap->SetHBITMAP((WXHBITMAP)::LoadBitmap(wxGetInstance(), name));
318
319 wxBitmapRefData *data = bitmap->GetBitmapData();
320 if ( bitmap->Ok() )
321 {
322 BITMAP bm;
323 if ( !::GetObject(GetHbitmapOf(*bitmap), sizeof(BITMAP), (LPSTR) &bm) )
324 {
325 wxLogLastError("GetObject(HBITMAP)");
326 }
327
328 data->m_width = bm.bmWidth;
329 data->m_height = bm.bmHeight;
330 data->m_depth = bm.bmBitsPixel;
331 }
332 else
333 {
334 // it's probably not found
335 wxLogError(wxT("Can't load bitmap '%s' from resources! Check .rc file."),
336 name.c_str());
337 }
338
339 return bitmap->Ok();
340}
341
342bool wxBMPFileHandler::LoadFile(wxBitmap *bitmap,
343 const wxString& name, long WXUNUSED(flags),
344 int WXUNUSED(desiredWidth),
345 int WXUNUSED(desiredHeight))
346{
347#if wxUSE_IMAGE_LOADING_IN_MSW
348 wxPalette *palette = NULL;
349 bool success = wxLoadIntoBitmap(WXSTRINGCAST name, bitmap, &palette) != 0;
350 if ( success && palette )
351 {
352 bitmap->SetPalette(*palette);
353 }
354
355 // it was copied by the bitmap if it was loaded successfully
356 delete palette;
357
358 return success;
359#else
360 return FALSE;
361#endif
362}
363
364bool wxBMPFileHandler::SaveFile(wxBitmap *bitmap,
365 const wxString& name,
366 int WXUNUSED(type),
367 const wxPalette *pal)
368{
369#if wxUSE_IMAGE_LOADING_IN_MSW
370 wxPalette *actualPalette = (wxPalette *)pal;
371 if ( !actualPalette )
372 actualPalette = bitmap->GetPalette();
373 return wxSaveBitmap(WXSTRINGCAST name, bitmap, actualPalette) != 0;
374#else
375 return FALSE;
376#endif
377}
378
379// ----------------------------------------------------------------------------
380// wxIcon handlers
381// ----------------------------------------------------------------------------
382
383bool wxICOFileHandler::LoadIcon(wxIcon *icon,
384 const wxString& name,
385 long flags,
386 int desiredWidth, int desiredHeight)
387{
388#if wxUSE_RESOURCE_LOADING_IN_MSW
389 icon->UnRef();
390
391 // actual size
392 wxSize size;
393
394#ifdef __WIN32__
395 HICON hicon = ::ExtractIcon(wxGetInstance(), name, 0 /* first */);
396 if ( !hicon )
397 {
398 wxLogSysError(_T("Failed to load icon from the file '%s'"),
399 name.c_str());
400
401 return FALSE;
402 }
403
404 size = GetHiconSize(hicon);
405#else // Win16
406 HICON hicon = ReadIconFile((wxChar *)name.c_str(),
407 wxGetInstance(),
408 &size.x, &size.y);
409#endif // Win32/Win16
410
411 if ( (desiredWidth != -1 && desiredWidth != size.x) ||
412 (desiredHeight != -1 && desiredHeight != size.y) )
413 {
414 wxLogDebug(_T("Returning FALSE from wxICOFileHandler::Load because "
415 "of the size mismatch: actual (%d, %d), "
416 "requested (%d, %d)"),
417 size.x, size.y,
418 desiredWidth, desiredHeight);
419
420 ::DestroyIcon(hicon);
421
422 return FALSE;
423 }
424
425 icon->SetHICON((WXHICON)hicon);
426 icon->SetSize(size.x, size.y);
427
428 return icon->Ok();
429#else
430 return FALSE;
431#endif
432}
433
434bool wxICOResourceHandler::LoadIcon(wxIcon *icon,
435 const wxString& name,
436 long flags,
437 int desiredWidth, int desiredHeight)
438{
439 HICON hicon;
440
441#if defined(__WIN32__) && !defined(__SC__)
442 if ( desiredWidth != -1 && desiredHeight != -1 )
443 {
444 hicon = (HICON)::LoadImage(wxGetInstance(), name, IMAGE_ICON,
445 desiredWidth, desiredHeight,
446 LR_DEFAULTCOLOR);
447 }
448 else
449#endif // Win32
450 {
451 hicon = ::LoadIcon(wxGetInstance(), name);
452 }
453
454 wxSize size = GetHiconSize(hicon);
455 icon->SetSize(size.x, size.y);
456
457 // Override the found values with desired values
458 if ( desiredWidth > -1 && desiredHeight > -1 )
459 {
460 icon->SetSize(desiredWidth, desiredHeight);
461 }
462
463 icon->SetHICON((WXHICON)hicon);
464
465 return icon->Ok();
466}
467
468// ----------------------------------------------------------------------------
469// private functions
470// ----------------------------------------------------------------------------
471
472static wxSize GetHiconSize(HICON hicon)
473{
474 wxSize size(32, 32); // default
475
476#ifdef __WIN32__
477 // Win32s doesn't have GetIconInfo function...
478 if ( hicon && wxGetOsVersion() != wxWIN32S )
479 {
480 ICONINFO info;
481 if ( !::GetIconInfo(hicon, &info) )
482 {
483 wxLogLastError("GetIconInfo");
484 }
485 else
486 {
487 HBITMAP hbmp = info.hbmMask;
488 if ( hbmp )
489 {
490 BITMAP bm;
491 if ( ::GetObject(hbmp, sizeof(BITMAP), (LPSTR) &bm) )
492 {
493 size = wxSize(bm.bmWidth, bm.bmHeight);
494 }
495
496 ::DeleteObject(info.hbmMask);
497 }
498 if ( info.hbmColor )
499 ::DeleteObject(info.hbmColor);
500 }
501 }
502#endif
503
504 return size;
505}