]> git.saurik.com Git - wxWidgets.git/blob - src/msw/bitmap.cpp
corrected serious bug in SetHBITMAP
[wxWidgets.git] / src / msw / bitmap.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: bitmap.cpp
3 // Purpose: wxBitmap
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21 #pragma implementation "bitmap.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 <stdio.h>
33
34 #include "wx/list.h"
35 #include "wx/utils.h"
36 #include "wx/app.h"
37 #include "wx/palette.h"
38 #include "wx/dcmemory.h"
39 #include "wx/bitmap.h"
40 #include "wx/icon.h"
41 #endif
42
43 #include "wx/msw/private.h"
44 #include "wx/log.h"
45
46 #include "wx/msw/dib.h"
47
48 // ----------------------------------------------------------------------------
49 // macros
50 // ----------------------------------------------------------------------------
51
52 #if !USE_SHARED_LIBRARIES
53 IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
54 IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
55 #endif
56
57 // ============================================================================
58 // implementation
59 // ============================================================================
60
61 // ----------------------------------------------------------------------------
62 // wxBitmapRefData
63 // ----------------------------------------------------------------------------
64
65 wxBitmapRefData::wxBitmapRefData()
66 {
67 m_ok = FALSE;
68 m_width = 0;
69 m_height = 0;
70 m_depth = 0;
71 m_quality = 0;
72 m_hBitmap = 0 ;
73 m_selectedInto = NULL;
74 m_numColors = 0;
75 m_bitmapMask = NULL;
76 }
77
78 wxBitmapRefData::~wxBitmapRefData()
79 {
80 if (m_selectedInto)
81 {
82 wxChar buf[200];
83 wxSprintf(buf, wxT("Bitmap was deleted without selecting out of wxMemoryDC %lX."), (unsigned long) m_selectedInto);
84 wxFatalError(buf);
85 }
86 if (m_hBitmap)
87 {
88 DeleteObject((HBITMAP) m_hBitmap);
89 }
90 m_hBitmap = 0 ;
91
92 if (m_bitmapMask)
93 delete m_bitmapMask;
94 m_bitmapMask = NULL;
95
96 }
97
98 // ----------------------------------------------------------------------------
99 // wxBitmap
100 // ----------------------------------------------------------------------------
101
102 wxList wxBitmap::sm_handlers;
103
104 wxBitmap::wxBitmap()
105 {
106 if ( wxTheBitmapList )
107 wxTheBitmapList->AddBitmap(this);
108 }
109
110 wxBitmap::wxBitmap(const wxBitmap& bitmap)
111 {
112 wxIcon *icon = wxDynamicCast(&bitmap, wxIcon);
113 if ( icon )
114 {
115 HDC hdc = ::CreateCompatibleDC(NULL); // screen DC
116 HBITMAP hbitmap = ::CreateCompatibleBitmap(hdc,
117 icon->GetWidth(),
118 icon->GetHeight());
119 ::SelectObject(hdc, hbitmap);
120 ::DrawIcon(hdc, 0, 0, (HICON)icon->GetHICON());
121
122 ::DeleteDC(hdc);
123
124 SetHBITMAP((WXHBITMAP)hbitmap);
125 }
126 else
127 {
128 Ref(bitmap);
129 }
130
131 if ( wxTheBitmapList )
132 wxTheBitmapList->AddBitmap(this);
133 }
134
135 wxBitmap::~wxBitmap()
136 {
137 if (wxTheBitmapList)
138 wxTheBitmapList->DeleteObject(this);
139 }
140
141 bool wxBitmap::FreeResource(bool WXUNUSED(force))
142 {
143 if ( !M_BITMAPDATA )
144 return FALSE;
145
146 if (M_BITMAPDATA->m_selectedInto)
147 {
148 wxChar buf[200];
149 wxSprintf(buf, wxT("Bitmap %lX was deleted without selecting out of wxMemoryDC %lX."), (unsigned long) this, (unsigned long) M_BITMAPDATA->m_selectedInto);
150 wxFatalError(buf);
151 }
152 if (M_BITMAPDATA->m_hBitmap)
153 {
154 DeleteObject((HBITMAP) M_BITMAPDATA->m_hBitmap);
155 }
156 M_BITMAPDATA->m_hBitmap = 0 ;
157
158 /*
159 if (M_BITMAPDATA->m_bitmapPalette)
160 delete M_BITMAPDATA->m_bitmapPalette;
161
162 M_BITMAPDATA->m_bitmapPalette = NULL ;
163 */
164
165 return TRUE;
166 }
167
168
169 wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits)
170 {
171 m_refData = new wxBitmapRefData;
172
173 M_BITMAPDATA->m_width = the_width ;
174 M_BITMAPDATA->m_height = the_height ;
175 M_BITMAPDATA->m_depth = no_bits ;
176 M_BITMAPDATA->m_numColors = 0;
177
178 M_BITMAPDATA->m_hBitmap = (WXHBITMAP) CreateBitmap(the_width, the_height, 1, no_bits, bits);
179
180 if (M_BITMAPDATA->m_hBitmap)
181 M_BITMAPDATA->m_ok = TRUE;
182 else
183 M_BITMAPDATA->m_ok = FALSE;
184
185 M_BITMAPDATA->m_selectedInto = NULL;
186
187 if ( wxTheBitmapList )
188 wxTheBitmapList->AddBitmap(this);
189 }
190
191 // Create from XPM data
192 wxBitmap::wxBitmap(char **data, wxControl *WXUNUSED(anItem))
193 {
194 (void) Create((void *)data, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0);
195 }
196
197 wxBitmap::wxBitmap(int w, int h, int d)
198 {
199 (void)Create(w, h, d);
200
201 if ( wxTheBitmapList )
202 wxTheBitmapList->AddBitmap(this);
203 }
204
205 wxBitmap::wxBitmap(void *data, long type, int width, int height, int depth)
206 {
207 (void) Create(data, type, width, height, depth);
208
209 if ( wxTheBitmapList )
210 wxTheBitmapList->AddBitmap(this);
211 }
212
213 wxBitmap::wxBitmap(const wxString& filename, long type)
214 {
215 LoadFile(filename, (int)type);
216
217 if ( wxTheBitmapList )
218 wxTheBitmapList->AddBitmap(this);
219 }
220
221 bool wxBitmap::Create(int w, int h, int d)
222 {
223 UnRef();
224
225 m_refData = new wxBitmapRefData;
226
227 M_BITMAPDATA->m_width = w;
228 M_BITMAPDATA->m_height = h;
229 M_BITMAPDATA->m_depth = d;
230
231 if (d > 0)
232 {
233 M_BITMAPDATA->m_hBitmap = (WXHBITMAP) CreateBitmap(w, h, 1, d, NULL);
234 }
235 else
236 {
237 HDC dc = GetDC((HWND) NULL);
238 M_BITMAPDATA->m_hBitmap = (WXHBITMAP) CreateCompatibleBitmap(dc, w, h);
239 ReleaseDC((HWND) NULL, dc);
240 M_BITMAPDATA->m_depth = wxDisplayDepth();
241 }
242 if (M_BITMAPDATA->m_hBitmap)
243 M_BITMAPDATA->m_ok = TRUE;
244 else
245 M_BITMAPDATA->m_ok = FALSE;
246 return M_BITMAPDATA->m_ok;
247 }
248
249 bool wxBitmap::LoadFile(const wxString& filename, long type)
250 {
251 UnRef();
252
253 m_refData = new wxBitmapRefData;
254
255 wxBitmapHandler *handler = FindHandler(type);
256
257 if ( handler == NULL ) {
258 wxLogWarning(wxT("no bitmap handler for type %d defined."), type);
259
260 return FALSE;
261 }
262
263 return handler->LoadFile(this, filename, type, -1, -1);
264 }
265
266 bool wxBitmap::Create(void *data, long type, int width, int height, int depth)
267 {
268 UnRef();
269
270 m_refData = new wxBitmapRefData;
271
272 wxBitmapHandler *handler = FindHandler(type);
273
274 if ( handler == NULL ) {
275 wxLogWarning(wxT("no bitmap handler for type %d defined."), type);
276
277 return FALSE;
278 }
279
280 return handler->Create(this, data, type, width, height, depth);
281 }
282
283 bool wxBitmap::SaveFile(const wxString& filename, int type, const wxPalette *palette)
284 {
285 wxBitmapHandler *handler = FindHandler(type);
286
287 if ( handler == NULL ) {
288 wxLogWarning(wxT("no bitmap handler for type %d defined."), type);
289
290 return FALSE;
291 }
292
293 return handler->SaveFile(this, filename, type, palette);
294 }
295
296 void wxBitmap::SetWidth(int w)
297 {
298 if (!M_BITMAPDATA)
299 m_refData = new wxBitmapRefData;
300
301 M_BITMAPDATA->m_width = w;
302 }
303
304 void wxBitmap::SetHeight(int h)
305 {
306 if (!M_BITMAPDATA)
307 m_refData = new wxBitmapRefData;
308
309 M_BITMAPDATA->m_height = h;
310 }
311
312 void wxBitmap::SetDepth(int d)
313 {
314 if (!M_BITMAPDATA)
315 m_refData = new wxBitmapRefData;
316
317 M_BITMAPDATA->m_depth = d;
318 }
319
320 void wxBitmap::SetQuality(int q)
321 {
322 if (!M_BITMAPDATA)
323 m_refData = new wxBitmapRefData;
324
325 M_BITMAPDATA->m_quality = q;
326 }
327
328 void wxBitmap::SetOk(bool isOk)
329 {
330 if (!M_BITMAPDATA)
331 m_refData = new wxBitmapRefData;
332
333 M_BITMAPDATA->m_ok = isOk;
334 }
335
336 void wxBitmap::SetPalette(const wxPalette& palette)
337 {
338 if (!M_BITMAPDATA)
339 m_refData = new wxBitmapRefData;
340
341 M_BITMAPDATA->m_bitmapPalette = palette ;
342 }
343
344 void wxBitmap::SetMask(wxMask *mask)
345 {
346 if (!M_BITMAPDATA)
347 m_refData = new wxBitmapRefData;
348
349 M_BITMAPDATA->m_bitmapMask = mask ;
350 }
351
352 void wxBitmap::SetHBITMAP(WXHBITMAP bmp)
353 {
354 if (!M_BITMAPDATA)
355 m_refData = new wxBitmapRefData;
356
357 M_BITMAPDATA->m_hBitmap = bmp;
358 M_BITMAPDATA->m_ok = bmp != 0;
359 }
360
361 void wxBitmap::AddHandler(wxBitmapHandler *handler)
362 {
363 sm_handlers.Append(handler);
364 }
365
366 void wxBitmap::InsertHandler(wxBitmapHandler *handler)
367 {
368 sm_handlers.Insert(handler);
369 }
370
371 bool wxBitmap::RemoveHandler(const wxString& name)
372 {
373 wxBitmapHandler *handler = FindHandler(name);
374 if ( handler )
375 {
376 sm_handlers.DeleteObject(handler);
377 return TRUE;
378 }
379 else
380 return FALSE;
381 }
382
383 wxBitmapHandler *wxBitmap::FindHandler(const wxString& name)
384 {
385 wxNode *node = sm_handlers.First();
386 while ( node )
387 {
388 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
389 if ( (handler->GetName().Cmp(name) == 0) )
390 return handler;
391 node = node->Next();
392 }
393 return NULL;
394 }
395
396 wxBitmapHandler *wxBitmap::FindHandler(const wxString& extension, long bitmapType)
397 {
398 wxNode *node = sm_handlers.First();
399 while ( node )
400 {
401 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
402 if ( (handler->GetExtension().Cmp(extension) == 0) &&
403 (bitmapType == -1 || (handler->GetType() == bitmapType)) )
404 return handler;
405 node = node->Next();
406 }
407 return NULL;
408 }
409
410 wxBitmapHandler *wxBitmap::FindHandler(long bitmapType)
411 {
412 wxNode *node = sm_handlers.First();
413 while ( node )
414 {
415 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
416 if (handler->GetType() == bitmapType)
417 return handler;
418 node = node->Next();
419 }
420 return NULL;
421 }
422
423 // New Create/FreeDIB functions since ones in dibutils.cpp are confusing
424 static long createDIB(long xSize, long ySize, long bitsPerPixel,
425 HPALETTE hPal, LPBITMAPINFO* lpDIBHeader);
426 static long freeDIB(LPBITMAPINFO lpDIBHeader);
427
428 // Creates a bitmap that matches the device context, from
429 // an arbitray bitmap. At present, the original bitmap must have an
430 // associated palette. TODO: use a default palette if no palette exists.
431 // Contributed by Frederic Villeneuve <frederic.villeneuve@natinst.com>
432 wxBitmap wxBitmap::GetBitmapForDC(wxDC& dc) const
433 {
434 wxMemoryDC memDC;
435 wxBitmap tmpBitmap(this->GetWidth(), this->GetHeight(), dc.GetDepth());
436 HPALETTE hPal = (HPALETTE) NULL;
437 LPBITMAPINFO lpDib;
438 void *lpBits = (void*) NULL;
439
440 /*
441 wxASSERT( this->GetPalette() && this->GetPalette()->Ok() && (this->GetPalette()->GetHPALETTE() != 0) );
442
443 tmpBitmap.SetPalette(this->GetPalette());
444 memDC.SelectObject(tmpBitmap);
445 memDC.SetPalette(this->GetPalette());
446
447 hPal = (HPALETTE) this->GetPalette()->GetHPALETTE();
448 */
449 if( this->GetPalette() && this->GetPalette()->Ok() && (this->GetPalette()->GetHPALETTE() != 0) )
450 {
451 tmpBitmap.SetPalette(* this->GetPalette());
452 memDC.SelectObject(tmpBitmap);
453 memDC.SetPalette(* this->GetPalette());
454 hPal = (HPALETTE) this->GetPalette()->GetHPALETTE();
455 }
456 else
457 {
458 hPal = (HPALETTE) ::GetStockObject(DEFAULT_PALETTE);
459 wxPalette palette;
460 palette.SetHPALETTE( (WXHPALETTE)hPal );
461 tmpBitmap.SetPalette( palette );
462 memDC.SelectObject(tmpBitmap);
463 memDC.SetPalette( palette );
464 }
465
466 // set the height negative because in a DIB the order of the lines is reversed
467 createDIB(this->GetWidth(), -this->GetHeight(), this->GetDepth(), hPal, &lpDib);
468
469 lpBits = malloc(lpDib->bmiHeader.biSizeImage);
470
471 ::GetBitmapBits((HBITMAP)GetHBITMAP(), lpDib->bmiHeader.biSizeImage, lpBits);
472
473 ::SetDIBitsToDevice((HDC) memDC.GetHDC(), 0, 0, this->GetWidth(), this->GetHeight(),
474 0, 0, 0, this->GetHeight(), lpBits, lpDib, DIB_RGB_COLORS);
475
476 free(lpBits);
477
478 freeDIB(lpDib);
479 return (tmpBitmap);
480 }
481
482 /*
483 * wxMask
484 */
485
486 wxMask::wxMask()
487 {
488 m_maskBitmap = 0;
489 }
490
491 // Construct a mask from a bitmap and a colour indicating
492 // the transparent area
493 wxMask::wxMask(const wxBitmap& bitmap, const wxColour& colour)
494 {
495 m_maskBitmap = 0;
496 Create(bitmap, colour);
497 }
498
499 // Construct a mask from a bitmap and a palette index indicating
500 // the transparent area
501 wxMask::wxMask(const wxBitmap& bitmap, int paletteIndex)
502 {
503 m_maskBitmap = 0;
504 Create(bitmap, paletteIndex);
505 }
506
507 // Construct a mask from a mono bitmap (copies the bitmap).
508 wxMask::wxMask(const wxBitmap& bitmap)
509 {
510 m_maskBitmap = 0;
511 Create(bitmap);
512 }
513
514 wxMask::~wxMask()
515 {
516 if ( m_maskBitmap )
517 ::DeleteObject((HBITMAP) m_maskBitmap);
518 }
519
520 // Create a mask from a mono bitmap (copies the bitmap).
521 bool wxMask::Create(const wxBitmap& bitmap)
522 {
523 if ( m_maskBitmap )
524 {
525 ::DeleteObject((HBITMAP) m_maskBitmap);
526 m_maskBitmap = 0;
527 }
528 if (!bitmap.Ok() || bitmap.GetDepth() != 1)
529 {
530 return FALSE;
531 }
532 m_maskBitmap = (WXHBITMAP) CreateBitmap(
533 bitmap.GetWidth(),
534 bitmap.GetHeight(),
535 1, 1, 0
536 );
537 HDC srcDC = CreateCompatibleDC(0);
538 SelectObject(srcDC, (HBITMAP) bitmap.GetHBITMAP());
539 HDC destDC = CreateCompatibleDC(0);
540 SelectObject(destDC, (HBITMAP) m_maskBitmap);
541 BitBlt(destDC, 0, 0, bitmap.GetWidth(), bitmap.GetHeight(), srcDC, 0, 0, SRCCOPY);
542 SelectObject(srcDC, 0);
543 DeleteDC(srcDC);
544 SelectObject(destDC, 0);
545 DeleteDC(destDC);
546 return TRUE;
547 }
548
549 // Create a mask from a bitmap and a palette index indicating
550 // the transparent area
551 bool wxMask::Create(const wxBitmap& bitmap, int paletteIndex)
552 {
553 if ( m_maskBitmap )
554 {
555 ::DeleteObject((HBITMAP) m_maskBitmap);
556 m_maskBitmap = 0;
557 }
558 if (bitmap.Ok() && bitmap.GetPalette()->Ok())
559 {
560 unsigned char red, green, blue;
561 if (bitmap.GetPalette()->GetRGB(paletteIndex, &red, &green, &blue))
562 {
563 wxColour transparentColour(red, green, blue);
564 return Create(bitmap, transparentColour);
565 }
566 }
567 return FALSE;
568 }
569
570 // Create a mask from a bitmap and a colour indicating
571 // the transparent area
572 bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour)
573 {
574 if ( m_maskBitmap )
575 {
576 ::DeleteObject((HBITMAP) m_maskBitmap);
577 m_maskBitmap = 0;
578 }
579 if (!bitmap.Ok())
580 {
581 return FALSE;
582 }
583
584 // scan the bitmap for the transparent colour and set
585 // the corresponding pixels in the mask to BLACK and
586 // the rest to WHITE
587 COLORREF maskColour = RGB(colour.Red(), colour.Green(), colour.Blue());
588 m_maskBitmap = (WXHBITMAP) ::CreateBitmap(
589 bitmap.GetWidth(),
590 bitmap.GetHeight(),
591 1, 1, 0
592 );
593 HDC srcDC = ::CreateCompatibleDC(0);
594 ::SelectObject(srcDC, (HBITMAP) bitmap.GetHBITMAP());
595 HDC destDC = ::CreateCompatibleDC(0);
596 ::SelectObject(destDC, (HBITMAP) m_maskBitmap);
597
598 // this is not very efficient, but I can't think
599 // of a better way of doing it
600 for (int w = 0; w < bitmap.GetWidth(); w++)
601 {
602 for (int h = 0; h < bitmap.GetHeight(); h++)
603 {
604 COLORREF col = GetPixel(srcDC, w, h);
605 if (col == maskColour)
606 {
607 ::SetPixel(destDC, w, h, RGB(0, 0, 0));
608 }
609 else
610 {
611 ::SetPixel(destDC, w, h, RGB(255, 255, 255));
612 }
613 }
614 }
615 ::SelectObject(srcDC, 0);
616 ::DeleteDC(srcDC);
617 ::SelectObject(destDC, 0);
618 ::DeleteDC(destDC);
619 return TRUE;
620 }
621
622 /*
623 * wxBitmapHandler
624 */
625
626 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject)
627
628 bool wxBitmapHandler::Create(wxBitmap *WXUNUSED(bitmap), void *WXUNUSED(data), long WXUNUSED(type), int WXUNUSED(width), int WXUNUSED(height), int WXUNUSED(depth))
629 {
630 return FALSE;
631 }
632
633 bool wxBitmapHandler::LoadFile(wxBitmap *WXUNUSED(bitmap), const wxString& WXUNUSED(name), long WXUNUSED(type),
634 int WXUNUSED(desiredWidth), int WXUNUSED(desiredHeight))
635 {
636 return FALSE;
637 }
638
639 bool wxBitmapHandler::SaveFile(wxBitmap *WXUNUSED(bitmap), const wxString& WXUNUSED(name), int WXUNUSED(type), const wxPalette *WXUNUSED(palette))
640 {
641 return FALSE;
642 }
643
644 /*
645 * Standard handlers
646 */
647
648 class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler
649 {
650 DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler)
651 public:
652 inline wxBMPResourceHandler()
653 {
654 m_name = "Windows bitmap resource";
655 m_extension = "";
656 m_type = wxBITMAP_TYPE_BMP_RESOURCE;
657 };
658
659 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
660 int desiredWidth, int desiredHeight);
661 };
662 IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler)
663
664 bool wxBMPResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long WXUNUSED(flags),
665 int WXUNUSED(desiredWidth), int WXUNUSED(desiredHeight))
666 {
667 // TODO: load colourmap.
668 M_BITMAPHANDLERDATA->m_hBitmap = (WXHBITMAP) ::LoadBitmap(wxGetInstance(), name);
669 if (M_BITMAPHANDLERDATA->m_hBitmap)
670 {
671 M_BITMAPHANDLERDATA->m_ok = TRUE;
672 BITMAP bm;
673 GetObject((HBITMAP) M_BITMAPHANDLERDATA->m_hBitmap, sizeof(BITMAP), (LPSTR) &bm);
674 M_BITMAPHANDLERDATA->m_width = bm.bmWidth;
675 M_BITMAPHANDLERDATA->m_height = bm.bmHeight;
676 M_BITMAPHANDLERDATA->m_depth = bm.bmBitsPixel;
677
678 if ( bitmap->IsKindOf(CLASSINFO(wxIcon)) )
679 {
680 }
681
682 return TRUE;
683 }
684
685 // it's probably not found
686 wxLogError(wxT("Can't load bitmap '%s' from resources! Check .rc file."), name.c_str());
687
688 return FALSE;
689 }
690
691 class WXDLLEXPORT wxBMPFileHandler: public wxBitmapHandler
692 {
693 DECLARE_DYNAMIC_CLASS(wxBMPFileHandler)
694 public:
695 inline wxBMPFileHandler()
696 {
697 m_name = "Windows bitmap file";
698 m_extension = "bmp";
699 m_type = wxBITMAP_TYPE_BMP;
700 };
701
702 virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
703 int desiredWidth, int desiredHeight);
704 virtual bool SaveFile(wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette = NULL);
705 };
706 IMPLEMENT_DYNAMIC_CLASS(wxBMPFileHandler, wxBitmapHandler)
707
708 bool wxBMPFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long WXUNUSED(flags),
709 int WXUNUSED(desiredWidth), int WXUNUSED(desiredHeight))
710 {
711 #if wxUSE_IMAGE_LOADING_IN_MSW
712 wxPalette *palette = NULL;
713 bool success = FALSE;
714 /*
715 if (type & wxBITMAP_DISCARD_COLOURMAP)
716 success = wxLoadIntoBitmap(WXSTRINGCAST name, bitmap);
717 else
718 */
719 success = (wxLoadIntoBitmap(WXSTRINGCAST name, bitmap, &palette) != 0);
720 if (!success && palette)
721 {
722 delete palette;
723 palette = NULL;
724 }
725 if (palette)
726 {
727 M_BITMAPHANDLERDATA->m_bitmapPalette = *palette;
728 delete palette;
729 }
730 return success;
731 #else
732 return FALSE;
733 #endif
734 }
735
736 bool wxBMPFileHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int WXUNUSED(type), const wxPalette *pal)
737 {
738 #if wxUSE_IMAGE_LOADING_IN_MSW
739 wxPalette *actualPalette = (wxPalette *)pal;
740 if (!actualPalette && (!M_BITMAPHANDLERDATA->m_bitmapPalette.IsNull()))
741 actualPalette = & (M_BITMAPHANDLERDATA->m_bitmapPalette);
742 return (wxSaveBitmap(WXSTRINGCAST name, bitmap, actualPalette) != 0);
743 #else
744 return FALSE;
745 #endif
746 }
747
748 void wxBitmap::CleanUpHandlers()
749 {
750 wxNode *node = sm_handlers.First();
751 while ( node )
752 {
753 wxBitmapHandler *handler = (wxBitmapHandler *)node->Data();
754 wxNode *next = node->Next();
755 delete handler;
756 delete node;
757 node = next;
758 }
759 }
760
761 void wxBitmap::InitStandardHandlers()
762 {
763 AddHandler(new wxBMPResourceHandler);
764 AddHandler(new wxBMPFileHandler);
765
766 // Not added by default: include xpmhand.h in your app
767 // and call these in your wxApp::OnInit.
768 // AddHandler(new wxXPMFileHandler);
769 // AddHandler(new wxXPMDataHandler);
770
771 AddHandler(new wxICOResourceHandler);
772 AddHandler(new wxICOFileHandler);
773 }
774
775 static long createDIB(long xSize, long ySize, long bitsPerPixel,
776 HPALETTE hPal, LPBITMAPINFO* lpDIBHeader)
777 {
778 unsigned long i, headerSize;
779 LPBITMAPINFO lpDIBheader = NULL;
780 LPPALETTEENTRY lpPe = NULL;
781
782
783 // Allocate space for a DIB header
784 headerSize = (sizeof(BITMAPINFOHEADER) + (256 * sizeof(PALETTEENTRY)));
785 lpDIBheader = (BITMAPINFO *) malloc(headerSize);
786 lpPe = (PALETTEENTRY *)((BYTE*)lpDIBheader + sizeof(BITMAPINFOHEADER));
787
788 GetPaletteEntries(hPal, 0, 256, lpPe);
789
790
791 memset(lpDIBheader, 0x00, sizeof(BITMAPINFOHEADER));
792
793
794 // Fill in the static parts of the DIB header
795 lpDIBheader->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
796 lpDIBheader->bmiHeader.biWidth = xSize;
797 lpDIBheader->bmiHeader.biHeight = ySize;
798 lpDIBheader->bmiHeader.biPlanes = 1;
799
800 // this value must be 1, 4, 8 or 24 so PixelDepth can only be
801 lpDIBheader->bmiHeader.biBitCount = (WORD)(bitsPerPixel);
802 lpDIBheader->bmiHeader.biCompression = BI_RGB;
803 lpDIBheader->bmiHeader.biSizeImage = xSize * abs(ySize) * bitsPerPixel >>
804 3;
805 lpDIBheader->bmiHeader.biClrUsed = 256;
806
807
808 // Initialize the DIB palette
809 for (i = 0; i < 256; i++) {
810 lpDIBheader->bmiColors[i].rgbReserved = lpPe[i].peFlags;
811 lpDIBheader->bmiColors[i].rgbRed = lpPe[i].peRed;
812 lpDIBheader->bmiColors[i].rgbGreen = lpPe[i].peGreen;
813 lpDIBheader->bmiColors[i].rgbBlue = lpPe[i].peBlue;
814 }
815
816 *lpDIBHeader = lpDIBheader;
817
818
819 return (0);
820
821 }
822
823
824
825 static long freeDIB(LPBITMAPINFO lpDIBHeader)
826 {
827
828 if (lpDIBHeader != NULL) {
829 free(lpDIBHeader);
830 }
831
832 return (0);
833 }
834
835