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