]> git.saurik.com Git - wxWidgets.git/commitdiff
1. fixed (to test) the bug with bitmaps without masks in wxImageList
authorVadim Zeitlin <vadim@wxwidgets.org>
Fri, 21 Jan 2000 21:38:51 +0000 (21:38 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Fri, 21 Jan 2000 21:38:51 +0000 (21:38 +0000)
2. reorganized wxImageList a bit, created a new wxInvertMask() function
3. an incredibly ugly fix (?) for "unsatisfied constraints" warnings
4. added wxIcon and wxBitmap ctors from XPM
5. XPM handler now creates bitmaps with mask
6. added wxPrinterDC::BitBlt() and DrawBitmap(), cleared the horrible mess in
   the wxDC methods with the same names

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@5571 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

16 files changed:
include/wx/layout.h
include/wx/log.h
include/wx/msw/bitmap.h
include/wx/msw/dc.h
include/wx/msw/dcprint.h
include/wx/msw/icon.h
include/wx/msw/private.h
include/wx/window.h
src/common/wincmn.cpp
src/msw/bitmap.cpp
src/msw/dc.cpp
src/msw/dcprint.cpp
src/msw/icon.cpp
src/msw/imaglist.cpp
src/msw/notebook.cpp
src/msw/xpmhand.cpp

index e3e5353ce7534b780a917619708aac442fd37338..0fcd64ecd8ff38766d60f02d9356345e41ba520a 100644 (file)
@@ -177,8 +177,8 @@ public:
     bool SatisfyConstraints(wxWindowBase *win, int *noChanges);
     bool AreSatisfied() const
     {
     bool SatisfyConstraints(wxWindowBase *win, int *noChanges);
     bool AreSatisfied() const
     {
-        return left.GetDone() && top.GetDone() && right.GetDone() &&
-               bottom.GetDone() && centreX.GetDone() && centreY.GetDone();
+        return left.GetDone() && top.GetDone() &&
+               width.GetDone() && height.GetDone();
     }
 };
 
     }
 };
 
index 507e646bfa47a95603cdf92e77e828489e149911..94d0beb5b6aef4d2216cd34f054900efdbe3e571 100644 (file)
@@ -480,15 +480,15 @@ DECLARE_LOG_FUNCTION2(SysError, long lErrCode);
     // make life easier for people using VC++ IDE: clicking on the message
     // will take us immediately to the place of the failed API
 #ifdef __VISUALC__
     // make life easier for people using VC++ IDE: clicking on the message
     // will take us immediately to the place of the failed API
 #ifdef __VISUALC__
-    #define wxLogApiError(api, rc)                                              \
-        wxLogDebug(wxT("%s(%d): '%s' failed with error 0x%08lx (%s)."),          \
-                   __TFILE__, __LINE__, api,                                    \
+    #define wxLogApiError(api, rc)                                            \
+        wxLogDebug(wxT("%s(%d): '%s' failed with error 0x%08lx (%s)."),       \
+                   __TFILE__, __LINE__, _T(api),                              \
                    rc, wxSysErrorMsg(rc))
 #else // !VC++
                    rc, wxSysErrorMsg(rc))
 #else // !VC++
-    #define wxLogApiError(api, rc)                                              \
-        wxLogDebug(wxT("In file %s at line %d: '%s' failed with "                \
-                      "error 0x%08lx (%s)."),                                   \
-                   __TFILE__, __LINE__, api,                                    \
+    #define wxLogApiError(api, rc)                                            \
+        wxLogDebug(wxT("In file %s at line %d: '%s' failed with "             \
+                      "error 0x%08lx (%s)."),                                 \
+                   __TFILE__, __LINE__, _T(api),                              \
                    rc, wxSysErrorMsg(rc))
 #endif // VC++/!VC++
 
                    rc, wxSysErrorMsg(rc))
 #endif // VC++/!VC++
 
index d71506f9447132aafe49f7e0b4ca98f458233fe5..cc0989f68b0e8d19d269d91c81292edc6b4af5e1 100644 (file)
@@ -78,7 +78,8 @@ public:
     wxBitmap(const char bits[], int width, int height, int depth = 1);
 
     // Initialize with XPM data
     wxBitmap(const char bits[], int width, int height, int depth = 1);
 
     // Initialize with XPM data
-    wxBitmap(char **data, wxControl *anItem = NULL);
+    wxBitmap(const char **data) { CreateFromXpm(data); }
+    wxBitmap(char **data) { CreateFromXpm((const char **)data); }
 
     // Load a file or resource
     wxBitmap(const wxString& name, long type = wxBITMAP_TYPE_BMP_RESOURCE);
 
     // Load a file or resource
     wxBitmap(const wxString& name, long type = wxBITMAP_TYPE_BMP_RESOURCE);
@@ -116,7 +117,7 @@ public:
 
     virtual ~wxBitmap();
 
 
     virtual ~wxBitmap();
 
-    // GRG, Dic/99
+    // get the given part of bitmap
     wxBitmap GetSubBitmap( const wxRect& rect ) const;
  
     // copies the contents and mask of the given (colour) icon to the bitmap
     wxBitmap GetSubBitmap( const wxRect& rect ) const;
  
     // copies the contents and mask of the given (colour) icon to the bitmap
@@ -182,6 +183,9 @@ protected:
     virtual wxGDIImageRefData *CreateData() const
         { return new wxBitmapRefData; }
 
     virtual wxGDIImageRefData *CreateData() const
         { return new wxBitmapRefData; }
 
+    // creates the bitmap from XPM data, supposed to be called from ctor
+    bool CreateFromXpm(const char **bits);
+
 private:
 #ifdef __WIN32__
     // common part of CopyFromIcon/CopyFromCursor for Win32
 private:
 #ifdef __WIN32__
     // common part of CopyFromIcon/CopyFromCursor for Win32
index c7a3700f08d5488710e0d6f9e3db8010ead46247..d9479093ea593ba06460f7eb889070fe98c8a602 100644 (file)
@@ -138,6 +138,9 @@ public:
         m_bOwnsDC = bOwnsDC;
     }
 
         m_bOwnsDC = bOwnsDC;
     }
 
+    const wxBitmap& GetSelectedBitmap() const { return m_selectedBitmap; }
+    wxBitmap& GetSelectedBitmap() { return m_selectedBitmap; }
+
 protected:
     virtual void DoFloodFill(wxCoord x, wxCoord y, const wxColour& col,
                              int style = wxFLOOD_SURFACE);
 protected:
     virtual void DoFloodFill(wxCoord x, wxCoord y, const wxColour& col,
                              int style = wxFLOOD_SURFACE);
index 4052a617a1b8f61224ab4ff1b598603819a8c1f7..0c3b02d5ad5b43126ca64956f0176b363585af53 100644 (file)
@@ -1,19 +1,19 @@
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
-// Name:        dcprint.h
+// Name:        wx/msw/dcprint.h
 // Purpose:     wxPrinterDC class
 // Author:      Julian Smart
 // Modified by:
 // Created:     01/02/97
 // RCS-ID:      $Id$
 // Copyright:   (c) Julian Smart
 // Purpose:     wxPrinterDC class
 // Author:      Julian Smart
 // Modified by:
 // Created:     01/02/97
 // RCS-ID:      $Id$
 // Copyright:   (c) Julian Smart
-// Licence:    wxWindows licence
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 #ifndef _WX_DCPRINT_H_
 #define _WX_DCPRINT_H_
 
 #ifdef __GNUG__
 /////////////////////////////////////////////////////////////////////////////
 
 #ifndef _WX_DCPRINT_H_
 #define _WX_DCPRINT_H_
 
 #ifdef __GNUG__
-#pragma interface "dcprint.h"
+    #pragma interface "dcprint.h"
 #endif
 
 #if wxUSE_PRINTING_ARCHITECTURE
 #endif
 
 #if wxUSE_PRINTING_ARCHITECTURE
@@ -36,12 +36,20 @@ DECLARE_CLASS(wxPrinterDC)
 
     ~wxPrinterDC(void);
 
 
     ~wxPrinterDC(void);
 
-    bool StartDoc(const wxString& message);
-    void EndDoc(void);
-    void StartPage(void);
-    void EndPage(void);
+    // override some base class virtuals
+    virtual bool StartDoc(const wxString& message);
+    virtual void EndDoc();
+    virtual void StartPage();
+    virtual void EndPage();
 
 protected:
 
 protected:
+    virtual void DoDrawBitmap(const wxBitmap &bmp, wxCoord x, wxCoord y,
+                              bool useMask = FALSE);
+    virtual bool DoBlit(wxCoord xdest, wxCoord ydest,
+                        wxCoord width, wxCoord height,
+                        wxDC *source, wxCoord xsrc, wxCoord ysrc,
+                        int rop = wxCOPY, bool useMask = FALSE);
+
     wxPrintData m_printData;
 };
 
     wxPrintData m_printData;
 };
 
index 6104c696eccb2f1166ad122aed6e57bc84d3bec9..101671a656860397cfa28d0d10d1b76b0f068578 100644 (file)
@@ -60,15 +60,23 @@ public:
 class WXDLLEXPORT wxIcon : public wxIconBase
 {
 public:
 class WXDLLEXPORT wxIcon : public wxIconBase
 {
 public:
-    wxIcon();
+    // ctors
+        // default
+    wxIcon() { }
 
 
-    // Copy constructors
+        // copy
     wxIcon(const wxIcon& icon) { Ref(icon); }
 
     wxIcon(const wxIcon& icon) { Ref(icon); }
 
+        // from raw data
     wxIcon(const char bits[], int width, int height);
     wxIcon(const char bits[], int width, int height);
+        // from XPM data
+    wxIcon(const char **data) { CreateIconFromXpm(data); }
+    wxIcon(char **data) { CreateIconFromXpm((const char **)data); }
+        // from resource/file
     wxIcon(const wxString& name,
            long type = wxBITMAP_TYPE_ICO_RESOURCE,
            int desiredWidth = -1, int desiredHeight = -1);
     wxIcon(const wxString& name,
            long type = wxBITMAP_TYPE_ICO_RESOURCE,
            int desiredWidth = -1, int desiredHeight = -1);
+
     virtual ~wxIcon();
 
     virtual bool LoadFile(const wxString& name,
     virtual ~wxIcon();
 
     virtual bool LoadFile(const wxString& name,
@@ -93,6 +101,12 @@ protected:
         return new wxIconRefData;
     }
 
         return new wxIconRefData;
     }
 
+    // create from XPM data
+    void CreateIconFromXpm(const char **data);
+
+    // create from bitmap (which should have a mask unless it's monochrome)
+    void CopyFromBitmap(const wxBitmap& bmp);
+
 private:
     DECLARE_DYNAMIC_CLASS(wxIcon)
 };
 private:
     DECLARE_DYNAMIC_CLASS(wxIcon)
 };
index 616f50aa7bd845defe0ca86412c71e19220e25a7..1f143400409de315294545fad8713ea4310e81e3 100644 (file)
@@ -231,6 +231,10 @@ inline void wxRGBToColour(wxColour& c, COLORREF rgb)
 extern void HIMETRICToPixel(LONG *x, LONG *y);
 extern void PixelToHIMETRIC(LONG *x, LONG *y);
 
 extern void HIMETRICToPixel(LONG *x, LONG *y);
 extern void PixelToHIMETRIC(LONG *x, LONG *y);
 
+// Windows convention of the mask is opposed to the wxWindows one, so we need
+// to invert the mask each time we pass one/get one to/from Windows
+extern HBITMAP wxInvertMask(HBITMAP hbmpMask, int w = 0, int h = 0);
+
 // ---------------------------------------------------------------------------
 // small helper classes
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 // small helper classes
 // ---------------------------------------------------------------------------
index b554906d5d6a75163105b37cc339c17bd439a3b0..f707a1c24ab53fcb8b20fe246818667730ffef18 100644 (file)
@@ -617,7 +617,7 @@ public:
     virtual void SetConstraintSizes(bool recurse = TRUE);
     virtual bool LayoutPhase1(int *noChanges);
     virtual bool LayoutPhase2(int *noChanges);
     virtual void SetConstraintSizes(bool recurse = TRUE);
     virtual bool LayoutPhase1(int *noChanges);
     virtual bool LayoutPhase2(int *noChanges);
-    virtual bool DoPhase(int);
+    virtual bool DoPhase(int phase);
 
         // these methods are virtual but normally won't be overridden
     virtual void SetSizeConstraint(int x, int y, int w, int h);
 
         // these methods are virtual but normally won't be overridden
     virtual void SetSizeConstraint(int x, int y, int w, int h);
index 9e96410e18f3ba41d9a2cdc8516e160edaeaddd8..a45c841cbdf1db1cfae86d02d79e1660dfab1d63 100644 (file)
@@ -932,10 +932,25 @@ bool wxWindowBase::Layout()
     }
     else
     {
     }
     else
     {
-        // Evaluate child constraints
+        wxLayoutConstraints *constr = GetConstraints();
+        bool wasOk = constr && constr->AreSatisfied();
+
         ResetConstraints();   // Mark all constraints as unevaluated
         ResetConstraints();   // Mark all constraints as unevaluated
-        DoPhase(1);           // Just one phase need if no sizers involved
-        DoPhase(2);
+
+        // if we're a top level panel (i.e. our parent is frame/dialog), our
+        // own constraints will never be satisfied any more unless we do it
+        // here
+        if ( wasOk )
+        {
+            int noChanges = 1;
+            while ( noChanges > 0 )
+            {
+                constr->SatisfyConstraints(this, &noChanges);
+            }
+        }
+
+        DoPhase(1);           // Layout children
+        DoPhase(2);           // Layout grand children
         SetConstraintSizes(); // Recursively set the real window sizes
     }
 
         SetConstraintSizes(); // Recursively set the real window sizes
     }
 
@@ -1039,8 +1054,7 @@ void wxWindowBase::ResetConstraints()
 void wxWindowBase::SetConstraintSizes(bool recurse)
 {
     wxLayoutConstraints *constr = GetConstraints();
 void wxWindowBase::SetConstraintSizes(bool recurse)
 {
     wxLayoutConstraints *constr = GetConstraints();
-    if ( constr && constr->left.GetDone() && constr->right.GetDone( ) &&
-            constr->width.GetDone() && constr->height.GetDone())
+    if ( constr && constr->AreSatisfied() )
     {
         int x = constr->left.GetValue();
         int y = constr->top.GetValue();
     {
         int x = constr->left.GetValue();
         int y = constr->top.GetValue();
@@ -1060,12 +1074,9 @@ void wxWindowBase::SetConstraintSizes(bool recurse)
     }
     else if ( constr )
     {
     }
     else if ( constr )
     {
-        wxString winName = GetName();
-        if ( !winName )
-            winName = wxT("unnamed");
-        wxLogDebug(wxT("Constraint not satisfied for %s, name '%s'."),
+        wxLogDebug(wxT("Constraints not satisfied for %s named '%s'."),
                    GetClassInfo()->GetClassName(),
                    GetClassInfo()->GetClassName(),
-                   winName.c_str());
+                   GetName().c_str());
     }
 
     if ( recurse )
     }
 
     if ( recurse )
index 6737631938fc25fd9f0113dcf43f97971fcba6a3..015b00e73249610b483b5482b14dac586d3e0587 100644 (file)
 // macros
 // ----------------------------------------------------------------------------
 
 // macros
 // ----------------------------------------------------------------------------
 
-    IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
-    IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
+IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
 
 
-    IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject)
 
 // ============================================================================
 // implementation
 
 // ============================================================================
 // implementation
@@ -131,26 +131,8 @@ bool wxBitmap::CopyFromIconOrCursor(const wxGDIImage& icon)
 
     // the mask returned by GetIconInfo() is inversed compared to the usual
     // wxWin convention
 
     // the mask returned by GetIconInfo() is inversed compared to the usual
     // wxWin convention
-    HBITMAP hbmpMask = ::CreateBitmap(w, h, 1, 1, 0);
-
-    // the icons mask is opposite to the usual wxWin convention
-    HDC dcSrc = ::CreateCompatibleDC(NULL);
-    HDC dcDst = ::CreateCompatibleDC(NULL);
-    (void)SelectObject(dcSrc, iconInfo.hbmMask);
-    (void)SelectObject(dcDst, hbmpMask);
-
-    HBRUSH brush = ::CreateSolidBrush(RGB(255, 255, 255));
-    RECT rect = { 0, 0, w, h };
-    FillRect(dcDst, &rect, brush);
-
-    BitBlt(dcDst, 0, 0, w, h, dcSrc, 0, 0, SRCINVERT);
-
-    SelectObject(dcDst, NULL);
-    SelectObject(dcSrc, NULL);
-    DeleteDC(dcDst);
-    DeleteDC(dcSrc);
-
-    refData->m_bitmapMask = new wxMask((WXHBITMAP)hbmpMask);
+    refData->m_bitmapMask = new wxMask((WXHBITMAP)
+                                        wxInvertMask(iconInfo.hbmMask, w, h));
 
 #if WXWIN_COMPATIBILITY_2
     refData->m_ok = TRUE;
 
 #if WXWIN_COMPATIBILITY_2
     refData->m_ok = TRUE;
@@ -293,52 +275,12 @@ wxBitmap::wxBitmap(const char bits[], int width, int height, int depth)
     SetHBITMAP((WXHBITMAP)hbmp);
 }
 
     SetHBITMAP((WXHBITMAP)hbmp);
 }
 
-// GRG, Dic/99
-wxBitmap wxBitmap::GetSubBitmap( const wxRect& rect) const
-{
-    wxCHECK_MSG( Ok() &&
-                 (rect.x >= 0) && (rect.y >= 0) &&
-                 (rect.x+rect.width <= GetWidth()) &&
-                 (rect.y+rect.height <= GetHeight()),
-                 wxNullBitmap, wxT("Invalid bitmap or bitmap region") );
-
-    wxBitmap ret( rect.width, rect.height, GetDepth() );
-    wxASSERT_MSG( ret.Ok(), wxT("GetSubBitmap error") );
-
-    // copy bitmap data
-    HDC dcSrc = ::CreateCompatibleDC(NULL);
-    HDC dcDst = ::CreateCompatibleDC(NULL);
-    SelectObject(dcSrc, (HBITMAP) GetHBITMAP());
-    SelectObject(dcDst, (HBITMAP) ret.GetHBITMAP());
-    BitBlt(dcDst, 0, 0, rect.width, rect.height, dcSrc, rect.x, rect.y, SRCCOPY);
-
-    // copy mask if there is one
-    if (GetMask())
-    {
-        HBITMAP hbmpMask = ::CreateBitmap(rect.width, rect.height, 1, 1, 0);
-
-        SelectObject(dcSrc, (HBITMAP) GetMask()->GetMaskBitmap());
-        SelectObject(dcDst, (HBITMAP) hbmpMask);
-        BitBlt(dcDst, 0, 0, rect.width, rect.height, dcSrc, rect.x, rect.y, SRCCOPY);
-
-        wxMask *mask = new wxMask((WXHBITMAP) hbmpMask);
-        ret.SetMask(mask);
-    }
-
-    SelectObject(dcDst, NULL);
-    SelectObject(dcSrc, NULL);
-    DeleteDC(dcDst);
-    DeleteDC(dcSrc);
-
-    return ret;
-}
-
 // Create from XPM data
 // Create from XPM data
-wxBitmap::wxBitmap(char **data, wxControl *WXUNUSED(anItem))
+bool wxBitmap::CreateFromXpm(const char **data)
 {
     Init();
 
 {
     Init();
 
-    (void)Create((void *)data, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0);
+    return Create((void *)data, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0);
 }
 
 wxBitmap::wxBitmap(int w, int h, int d)
 }
 
 wxBitmap::wxBitmap(int w, int h, int d)
@@ -465,6 +407,49 @@ bool wxBitmap::SaveFile(const wxString& filename, int type, const wxPalette *pal
     }
 }
 
     }
 }
 
+// ----------------------------------------------------------------------------
+// sub bitmap extraction
+// ----------------------------------------------------------------------------
+
+wxBitmap wxBitmap::GetSubBitmap( const wxRect& rect) const
+{
+    wxCHECK_MSG( Ok() &&
+                 (rect.x >= 0) && (rect.y >= 0) &&
+                 (rect.x+rect.width <= GetWidth()) &&
+                 (rect.y+rect.height <= GetHeight()),
+                 wxNullBitmap, wxT("Invalid bitmap or bitmap region") );
+
+    wxBitmap ret( rect.width, rect.height, GetDepth() );
+    wxASSERT_MSG( ret.Ok(), wxT("GetSubBitmap error") );
+
+    // copy bitmap data
+    HDC dcSrc = ::CreateCompatibleDC(NULL);
+    HDC dcDst = ::CreateCompatibleDC(NULL);
+    SelectObject(dcSrc, (HBITMAP) GetHBITMAP());
+    SelectObject(dcDst, (HBITMAP) ret.GetHBITMAP());
+    BitBlt(dcDst, 0, 0, rect.width, rect.height, dcSrc, rect.x, rect.y, SRCCOPY);
+
+    // copy mask if there is one
+    if (GetMask())
+    {
+        HBITMAP hbmpMask = ::CreateBitmap(rect.width, rect.height, 1, 1, 0);
+
+        SelectObject(dcSrc, (HBITMAP) GetMask()->GetMaskBitmap());
+        SelectObject(dcDst, (HBITMAP) hbmpMask);
+        BitBlt(dcDst, 0, 0, rect.width, rect.height, dcSrc, rect.x, rect.y, SRCCOPY);
+
+        wxMask *mask = new wxMask((WXHBITMAP) hbmpMask);
+        ret.SetMask(mask);
+    }
+
+    SelectObject(dcDst, NULL);
+    SelectObject(dcSrc, NULL);
+    DeleteDC(dcDst);
+    DeleteDC(dcSrc);
+
+    return ret;
+}
+
 // ----------------------------------------------------------------------------
 // wxBitmap accessors
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 // wxBitmap accessors
 // ----------------------------------------------------------------------------
@@ -506,7 +491,7 @@ void wxBitmap::SetMask(wxMask *mask)
 wxBitmap wxBitmap::GetBitmapForDC(wxDC& dc) const
 {
     wxMemoryDC      memDC;
 wxBitmap wxBitmap::GetBitmapForDC(wxDC& dc) const
 {
     wxMemoryDC      memDC;
-    wxBitmap        tmpBitmap(this->GetWidth(), this->GetHeight(), dc.GetDepth());
+    wxBitmap        tmpBitmap(GetWidth(), GetHeight(), dc.GetDepth());
     HPALETTE        hPal = (HPALETTE) NULL;
     LPBITMAPINFO    lpDib;
     void            *lpBits = (void*) NULL;
     HPALETTE        hPal = (HPALETTE) NULL;
     LPBITMAPINFO    lpDib;
     void            *lpBits = (void*) NULL;
@@ -643,38 +628,59 @@ bool wxMask::Create(const wxBitmap& bitmap, int paletteIndex)
 // the transparent area
 bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour)
 {
 // the transparent area
 bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour)
 {
+    wxCHECK_MSG( bitmap.Ok(), FALSE, _T("invalid bitmap in wxMask::Create") );
+
     if ( m_maskBitmap )
     {
         ::DeleteObject((HBITMAP) m_maskBitmap);
         m_maskBitmap = 0;
     }
     if ( m_maskBitmap )
     {
         ::DeleteObject((HBITMAP) m_maskBitmap);
         m_maskBitmap = 0;
     }
-    if (!bitmap.Ok())
+
+    int width = bitmap.GetWidth(),
+        height = bitmap.GetHeight();
+
+    // scan the bitmap for the transparent colour and set the corresponding
+    // pixels in the mask to BLACK and the rest to WHITE
+    COLORREF maskColour = wxColourToRGB(colour);
+    m_maskBitmap = (WXHBITMAP)::CreateBitmap(width, height, 1, 1, 0);
+
+    HDC srcDC = ::CreateCompatibleDC(NULL);
+    HDC destDC = ::CreateCompatibleDC(NULL);
+    if ( !srcDC || !destDC )
+    {
+        wxLogLastError("CreateCompatibleDC");
+    }
+
+    if ( !::SelectObject(srcDC, GetHbitmapOf(bitmap)) )
     {
     {
-        return FALSE;
+        wxLogLastError("SelectObject");
+    }
+    if ( !::SelectObject(destDC, (HBITMAP)m_maskBitmap) )
+    {
+        wxLogLastError("SelectObject");
     }
 
     }
 
-    // scan the bitmap for the transparent colour and set
-    // the corresponding pixels in the mask to BLACK and
-    // the rest to WHITE
-    COLORREF maskColour = RGB(colour.Red(), colour.Green(), colour.Blue());
-    m_maskBitmap = (WXHBITMAP) ::CreateBitmap(
-            bitmap.GetWidth(),
-            bitmap.GetHeight(),
-            1, 1, 0
-                                             );
-    HDC srcDC = ::CreateCompatibleDC(0);
-    ::SelectObject(srcDC, (HBITMAP) bitmap.GetHBITMAP());
-    HDC destDC = ::CreateCompatibleDC(0);
-    ::SelectObject(destDC, (HBITMAP) m_maskBitmap);
-
-    // this is not very efficient, but I can't think
-    // of a better way of doing it
-    for (int w = 0; w < bitmap.GetWidth(); w++)
+    // this is not very efficient, but I can't think of a better way of doing
+    // it
+    for ( int w = 0; w < width; w++ )
     {
     {
-        for (int h = 0; h < bitmap.GetHeight(); h++)
+        for ( int h = 0; h < height; h++ )
         {
             COLORREF col = GetPixel(srcDC, w, h);
         {
             COLORREF col = GetPixel(srcDC, w, h);
-            if (col == maskColour)
+            if ( col == CLR_INVALID )
+            {
+                wxLogLastError("GetPixel");
+
+                // doesn't make sense to continue
+                ::SelectObject(srcDC, 0);
+                ::DeleteDC(srcDC);
+                ::SelectObject(destDC, 0);
+                ::DeleteDC(destDC);
+
+                return FALSE;
+            }
+
+            if ( col == maskColour )
             {
                 ::SetPixel(destDC, w, h, RGB(0, 0, 0));
             }
             {
                 ::SetPixel(destDC, w, h, RGB(0, 0, 0));
             }
@@ -684,10 +690,12 @@ bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour)
             }
         }
     }
             }
         }
     }
+
     ::SelectObject(srcDC, 0);
     ::DeleteDC(srcDC);
     ::SelectObject(destDC, 0);
     ::DeleteDC(destDC);
     ::SelectObject(srcDC, 0);
     ::DeleteDC(srcDC);
     ::SelectObject(destDC, 0);
     ::DeleteDC(destDC);
+
     return TRUE;
 }
 
     return TRUE;
 }
 
@@ -803,4 +811,47 @@ void wxFreeDIB(LPBITMAPINFO lpDIBHeader)
     free(lpDIBHeader);
 }
 
     free(lpDIBHeader);
 }
 
+// ----------------------------------------------------------------------------
+// other helper functions
+// ----------------------------------------------------------------------------
+
+extern HBITMAP wxInvertMask(HBITMAP hbmpMask, int w, int h)
+{
+    wxCHECK_MSG( hbmpMask, 0, _T("invalid bitmap in wxInvertMask") );
+
+    // get width/height from the bitmap if not given
+    if ( !w || !h )
+    {
+        BITMAP bm;
+        ::GetObject(hbmpMask, sizeof(BITMAP), (LPVOID)&bm);
+        w = bm.bmWidth;
+        h = bm.bmHeight;
+    }
+
+    HDC hdcSrc = ::CreateCompatibleDC(NULL);
+    HDC hdcDst = ::CreateCompatibleDC(NULL);
+    if ( !hdcSrc || !hdcDst )
+    {
+        wxLogLastError("CreateCompatibleDC");
+    }
+
+    HBITMAP hbmpInvMask = ::CreateBitmap(w, h, 1, 1, 0);
+    if ( !hbmpInvMask )
+    {
+        wxLogLastError("CreateBitmap");
+    }
+
+    ::SelectObject(hdcSrc, hbmpMask);
+    ::SelectObject(hdcDst, hbmpInvMask);
+    if ( !::BitBlt(hdcDst, 0, 0, w, h,
+                   hdcSrc, 0, 0,
+                   NOTSRCCOPY) )
+    {
+        wxLogLastError("BitBlt");
+    }
 
 
+    ::DeleteDC(hdcSrc);
+    ::DeleteDC(hdcDst);
+
+    return hbmpInvMask;
+}
index d6be602027d299e1eb4bba0baa6ae21f9c578172..c280a0573ad35dd7d72d9ad55dc6e761fb88de3e 100644 (file)
@@ -583,112 +583,55 @@ void wxDC::DoDrawEllipticArc(wxCoord x,wxCoord y,wxCoord w,wxCoord h,double sa,d
 
 void wxDC::DoDrawIcon(const wxIcon& icon, wxCoord x, wxCoord y)
 {
 
 void wxDC::DoDrawIcon(const wxIcon& icon, wxCoord x, wxCoord y)
 {
-#if defined(__WIN32__) && !defined(__SC__) && !defined(__TWIN32__)
-    ::DrawIconEx(GetHdc(), XLOG2DEV(x), YLOG2DEV(y), (HICON) icon.GetHICON(),
-        icon.GetWidth(), icon.GetHeight(), 0, 0, DI_NORMAL);
-#else
-    ::DrawIcon(GetHdc(), XLOG2DEV(x), YLOG2DEV(y), (HICON) icon.GetHICON());
-#endif
+    wxCHECK_RET( icon.Ok(), wxT("invalid icon in DrawIcon") );
+
+    ::DrawIcon(GetHdc(), XLOG2DEV(x), YLOG2DEV(y), GetHiconOf(icon));
 
     CalcBoundingBox(x, y);
 
     CalcBoundingBox(x, y);
-    CalcBoundingBox(x+icon.GetWidth(), y+icon.GetHeight());
+    CalcBoundingBox(x + icon.GetWidth(), y + icon.GetHeight());
 }
 
 void wxDC::DoDrawBitmap( const wxBitmap &bmp, wxCoord x, wxCoord y, bool useMask )
 {
 }
 
 void wxDC::DoDrawBitmap( const wxBitmap &bmp, wxCoord x, wxCoord y, bool useMask )
 {
-    if (!bmp.Ok())
-        return;
-    
-    bool needsPixelCopy = FALSE ;
-    bool isPrinter = FALSE ;
-    if (IsKindOf(CLASSINFO(wxPrinterDC)) )
-    {
-        isPrinter = TRUE ;
-        if ( ::GetDeviceCaps((HDC) m_hDC, RASTERCAPS) & RC_STRETCHDIB )
-               {
-        }
-               else
-               {
-            needsPixelCopy = TRUE ;
-               }
-    }
-    // If we're not drawing transparently, and not drawing to a printer,
-    // optimize this function to use Windows functions.
-    if (!useMask && !needsPixelCopy)
+    wxCHECK_RET( bmp.Ok(), _T("invalid bitmap in wxDC::DrawBitmap") );
+
+    int width = bmp.GetWidth(),
+        height = bmp.GetHeight();
+
+    if ( !useMask )
     {
     {
-        if ( isPrinter )
+        HDC cdc = GetHdc();
+        HDC memdc = ::CreateCompatibleDC( cdc );
+        HBITMAP hbitmap = (HBITMAP) bmp.GetHBITMAP( );
+
+        wxASSERT_MSG( hbitmap, wxT("bitmap is ok but HBITMAP is NULL?") );
+
+        COLORREF old_textground = ::GetTextColor(GetHdc());
+        COLORREF old_background = ::GetBkColor(GetHdc());
+        if (m_textForegroundColour.Ok())
         {
         {
-            BITMAPINFO *info = (BITMAPINFO *) malloc( sizeof( BITMAPINFOHEADER ) + 256 * sizeof(RGBQUAD ) ) ;
-            int iBitsSize = ((bmp.GetWidth() + 3 ) & ~3 ) * bmp.GetHeight() ;
-            
-            void* bits = malloc( iBitsSize ) ;
-            
-            memset( info , 0 , sizeof( BITMAPINFOHEADER ) ) ;
-            
-            info->bmiHeader.biSize = sizeof( BITMAPINFOHEADER ) ;
-            info->bmiHeader.biWidth = bmp.GetWidth() ;
-            info->bmiHeader.biHeight = bmp.GetHeight() ;
-            info->bmiHeader.biPlanes = 1 ;
-            info->bmiHeader.biBitCount = 8 ;
-            info->bmiHeader.biCompression = BI_RGB ;
-            
-            HDC display = GetDC( NULL ) ;
-            if ( GetDIBits( display , (HBITMAP) bmp.GetHBITMAP( ) , 0 , bmp.GetHeight() , bits , info , DIB_RGB_COLORS ) )
-            {
-                StretchDIBits( (HDC) m_hDC, 
-                    x, y, bmp.GetWidth(), bmp.GetHeight() , 
-                    0 , 0 ,bmp.GetWidth(), bmp.GetHeight() , 
-                    bits , info , DIB_RGB_COLORS , SRCCOPY ) ;
-            }
-            ReleaseDC( NULL , display ) ;
-            free ( bits ) ;
-            free( info ) ;
+            ::SetTextColor(GetHdc(), m_textForegroundColour.GetPixel() );
         }
         }
-        else
+        if (m_textBackgroundColour.Ok())
         {
         {
-            HDC cdc = GetHdc();
-            HDC memdc = ::CreateCompatibleDC( cdc );
-            HBITMAP hbitmap = (HBITMAP) bmp.GetHBITMAP( );
-            
-            wxASSERT_MSG( hbitmap, wxT("bitmap is ok but HBITMAP is NULL?") );
-            
-            COLORREF old_textground = ::GetTextColor(GetHdc());
-            COLORREF old_background = ::GetBkColor(GetHdc());
-            if (m_textForegroundColour.Ok())
-            {
-                ::SetTextColor(GetHdc(), m_textForegroundColour.GetPixel() );
-            }
-            if (m_textBackgroundColour.Ok())
-            {
-                ::SetBkColor(GetHdc(), m_textBackgroundColour.GetPixel() );
-            }
+            ::SetBkColor(GetHdc(), m_textBackgroundColour.GetPixel() );
+        }
 
 
-            ::SelectObject( memdc, hbitmap );
-            ::BitBlt( cdc, x, y, bmp.GetWidth(), bmp.GetHeight(), memdc, 0, 0, SRCCOPY);
-            ::DeleteDC( memdc );
+        ::SelectObject( memdc, hbitmap );
+        ::BitBlt( cdc, x, y, width, height, memdc, 0, 0, SRCCOPY);
+        ::DeleteDC( memdc );
 
 
-            ::SetTextColor(GetHdc(), old_textground);
-            ::SetBkColor(GetHdc(), old_background);
-        }
+        ::SetTextColor(GetHdc(), old_textground);
+        ::SetBkColor(GetHdc(), old_background);
     }
     else
     {
         // Rather than reproduce wxDC::Blit, let's do it at the wxWin API level
         wxMemoryDC memDC;
         memDC.SelectObject(bmp);
     }
     else
     {
         // Rather than reproduce wxDC::Blit, let's do it at the wxWin API level
         wxMemoryDC memDC;
         memDC.SelectObject(bmp);
-        
-        /* Not sure if we need this. The mask should leave the
-        * masked areas as per the original background of this DC.
-        */
-        /*
-        // There might be transparent areas, so make these
-        // the same colour as this DC
-        memDC.SetBackground(* GetBackground());
-        memDC.Clear();
-        */
-        
-        Blit(x, y, bmp.GetWidth(), bmp.GetHeight(), & memDC, 0, 0, wxCOPY, useMask);
-        
+
+        Blit(x, y, width, height, &memDC, 0, 0, wxCOPY, useMask);
+
         memDC.SelectObject(wxNullBitmap);
     }
 }
         memDC.SelectObject(wxNullBitmap);
     }
 }
@@ -981,7 +924,7 @@ void wxDC::SetBackgroundMode(int mode)
     if (m_backgroundMode == wxTRANSPARENT)
         ::SetBkMode(GetHdc(), TRANSPARENT);
     else
     if (m_backgroundMode == wxTRANSPARENT)
         ::SetBkMode(GetHdc(), TRANSPARENT);
     else
-       ::SetBkMode(GetHdc(), OPAQUE);
+        ::SetBkMode(GetHdc(), OPAQUE);
 */
 }
 
 */
 }
 
@@ -1237,13 +1180,21 @@ wxCoord wxDCBase::LogicalToDeviceYRel(wxCoord y) const
 // ---------------------------------------------------------------------------
 // bit blit
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 // bit blit
 // ---------------------------------------------------------------------------
-bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
-                  wxDC *source, wxCoord xsrc, wxCoord ysrc, int rop, bool useMask)
+
+bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest,
+                  wxCoord width, wxCoord height,
+                  wxDC *source, wxCoord xsrc, wxCoord ysrc,
+                  int rop, bool useMask)
 {
 {
-    wxCoord xdest1 = xdest;
-    wxCoord ydest1 = ydest;
-    wxCoord xsrc1 = xsrc;
-    wxCoord ysrc1 = ysrc;
+    wxMask *mask = NULL;
+    if ( useMask )
+    {
+        const wxBitmap& bmp = source->m_selectedBitmap;
+        mask = bmp.GetMask();
+
+        wxCHECK_MSG( bmp.Ok() && mask, FALSE,
+                     _T("can't blit with mask without mask") );
+    }
 
     COLORREF old_textground = ::GetTextColor(GetHdc());
     COLORREF old_background = ::GetBkColor(GetHdc());
 
     COLORREF old_textground = ::GetTextColor(GetHdc());
     COLORREF old_background = ::GetBkColor(GetHdc());
@@ -1257,201 +1208,107 @@ bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
     }
 
     DWORD dwRop = rop == wxCOPY ? SRCCOPY :
     }
 
     DWORD dwRop = rop == wxCOPY ? SRCCOPY :
-    rop == wxCLEAR ? WHITENESS :
-    rop == wxSET ? BLACKNESS :
-    rop == wxINVERT ? DSTINVERT :
-    rop == wxAND ? MERGECOPY :
-    rop == wxOR ? MERGEPAINT :
-    rop == wxSRC_INVERT ? NOTSRCCOPY :
-    rop == wxXOR ? SRCINVERT :
-    rop == wxOR_REVERSE ? MERGEPAINT :
-    rop == wxAND_REVERSE ? SRCERASE :
-    rop == wxSRC_OR ? SRCPAINT :
-    rop == wxSRC_AND ? SRCAND :
-    SRCCOPY;
-
-    bool success = TRUE;
-    bool needsPixelCopy = FALSE ;
-    bool isPrinter = FALSE ;
-
-    if (IsKindOf(CLASSINFO(wxPrinterDC)) )
-    {
-        isPrinter = TRUE ;
-        if ( ::GetDeviceCaps((HDC) m_hDC, RASTERCAPS) & RC_STRETCHDIB )
-               {
-        }
-               else
-               {
-            needsPixelCopy = TRUE ;
-               }
-    }
-    if (useMask && !source->m_selectedBitmap.Ok())
-        return FALSE;
-
-    if (useMask && !source->m_selectedBitmap.GetMask())
-        useMask = FALSE;
+                  rop == wxCLEAR ? WHITENESS :
+                  rop == wxSET ? BLACKNESS :
+                  rop == wxINVERT ? DSTINVERT :
+                  rop == wxAND ? MERGECOPY :
+                  rop == wxOR ? MERGEPAINT :
+                  rop == wxSRC_INVERT ? NOTSRCCOPY :
+                  rop == wxXOR ? SRCINVERT :
+                  rop == wxOR_REVERSE ? MERGEPAINT :
+                  rop == wxAND_REVERSE ? SRCERASE :
+                  rop == wxSRC_OR ? SRCPAINT :
+                  rop == wxSRC_AND ? SRCAND :
+                  SRCCOPY;
+
+    bool success;
 
     if (useMask)
     {
 
     if (useMask)
     {
-
-#if 0 // __WIN32__
-        // Not implemented under Win95 (or maybe a specific device?)
-        if (MaskBlt(GetHdc(), xdest1, ydest1, (int)width, (int)height,
-            (HDC) source->m_hDC, xsrc1, ysrc1, (HBITMAP) source->m_selectedBitmap.GetMask()->GetMaskBitmap(),
-            0, 0, 0xAACC0020))
+#ifdef __WIN32__
+        if ( ::MaskBlt(GetHdc(), xdest, ydest,
+                       (int)width, (int)height,
+                       GetHdcOf(*source), xsrc, ysrc,
+                       (HBITMAP) mask->GetMaskBitmap(),
+                       0, 0, MAKEROP4(SRCCOPY, PATCOPY)) != 0 )
         {
             // Success
         {
             // Success
+            success = TRUE;
         }
         else
         }
         else
-#endif
+#endif // Win32
         {
         {
-            // New code from Chris Breeze, 15/7/98
             // Blit bitmap with mask
 
             // Blit bitmap with mask
 
-            if (isPrinter)
+            // create a temp buffer bitmap and DCs to access it and the mask
+            HDC dc_mask = ::CreateCompatibleDC(GetHdcOf(*source));
+            HDC dc_buffer = ::CreateCompatibleDC(GetHdc());
+            HBITMAP buffer_bmap = ::CreateCompatibleBitmap(GetHdc(), width, height);
+            ::SelectObject(dc_mask, (HBITMAP) mask->GetMaskBitmap());
+            ::SelectObject(dc_buffer, buffer_bmap);
+
+            // copy dest to buffer
+            if ( !::BitBlt(dc_buffer, 0, 0, (int)width, (int)height,
+                           GetHdc(), xdest, ydest, SRCCOPY) )
             {
             {
-                // If we are printing source colours are screen colours
-                // not printer colours and so we need copy the bitmap
-                // pixel by pixel.
-                RECT rect;
-                HDC dc_mask = ::CreateCompatibleDC((HDC) source->m_hDC);
-                HDC dc_src = (HDC) source->m_hDC;
-
-                ::SelectObject(dc_mask, (HBITMAP) source->m_selectedBitmap.GetMask()->GetMaskBitmap());
-                for (int x = 0; x < width; x++)
-                {
-                    for (int y = 0; y < height; y++)
-                    {
-                        COLORREF cref = ::GetPixel(dc_mask, x, y);
-                        if (cref)
-                        {
-                            HBRUSH brush = ::CreateSolidBrush(::GetPixel(dc_src, x, y));
-                            rect.left = xdest1 + x; rect.right = rect.left + 1;
-                            rect.top = ydest1 + y;  rect.bottom = rect.top + 1;
-                            ::FillRect(GetHdc(), &rect, brush);
-                            ::DeleteObject(brush);
-                        }
-                    }
-                }
-                ::SelectObject(dc_mask, 0);
-                ::DeleteDC(dc_mask);
+                wxLogLastError("BitBlt");
             }
             }
-            else
+
+            // copy src to buffer using selected raster op
+            if ( !::BitBlt(dc_buffer, 0, 0, (int)width, (int)height,
+                           GetHdcOf(*source), xsrc, ysrc, dwRop) )
             {
             {
-                // create a temp buffer bitmap and DCs to access it and the mask
-                HDC dc_mask = ::CreateCompatibleDC((HDC) source->m_hDC);
-                HDC dc_buffer = ::CreateCompatibleDC(GetHdc());
-                HBITMAP buffer_bmap = ::CreateCompatibleBitmap(GetHdc(), width, height);
-                ::SelectObject(dc_mask, (HBITMAP) source->m_selectedBitmap.GetMask()->GetMaskBitmap());
-                ::SelectObject(dc_buffer, buffer_bmap);
-
-                // copy dest to buffer
-                ::BitBlt(dc_buffer, 0, 0, (int)width, (int)height,
-                    GetHdc(), xdest1, ydest1, SRCCOPY);
-
-                // copy src to buffer using selected raster op
-                ::BitBlt(dc_buffer, 0, 0, (int)width, (int)height,
-                    (HDC) source->m_hDC, xsrc1, ysrc1, dwRop);
-
-                // set masked area in buffer to BLACK (pixel value 0)
-                COLORREF prevBkCol = ::SetBkColor(GetHdc(), RGB(255, 255, 255));
-                COLORREF prevCol = ::SetTextColor(GetHdc(), RGB(0, 0, 0));
-                ::BitBlt(dc_buffer, 0, 0, (int)width, (int)height,
-                    dc_mask, xsrc1, ysrc1, SRCAND);
-
-                // set unmasked area in dest to BLACK
-                ::SetBkColor(GetHdc(), RGB(0, 0, 0));
-                ::SetTextColor(GetHdc(), RGB(255, 255, 255));
-                ::BitBlt(GetHdc(), xdest1, ydest1, (int)width, (int)height,
-                    dc_mask, xsrc1, ysrc1, SRCAND);
-                ::SetBkColor(GetHdc(), prevBkCol);   // restore colours to original values
-                ::SetTextColor(GetHdc(), prevCol);
-
-                // OR buffer to dest
-                success = (::BitBlt(GetHdc(), xdest1, ydest1, (int)width, (int)height,
-                    dc_buffer, 0, 0, SRCPAINT) != 0);
-
-                // tidy up temporary DCs and bitmap
-                ::SelectObject(dc_mask, 0);
-                ::DeleteDC(dc_mask);
-                ::SelectObject(dc_buffer, 0);
-                ::DeleteDC(dc_buffer);
-                ::DeleteObject(buffer_bmap);
+                wxLogLastError("BitBlt");
             }
             }
+
+            // set masked area in buffer to BLACK (pixel value 0)
+            COLORREF prevBkCol = ::SetBkColor(GetHdc(), RGB(255, 255, 255));
+            COLORREF prevCol = ::SetTextColor(GetHdc(), RGB(0, 0, 0));
+            if ( !::BitBlt(dc_buffer, 0, 0, (int)width, (int)height,
+                           dc_mask, xsrc, ysrc, SRCAND) )
+            {
+                wxLogLastError("BitBlt");
+            }
+
+            // set unmasked area in dest to BLACK
+            ::SetBkColor(GetHdc(), RGB(0, 0, 0));
+            ::SetTextColor(GetHdc(), RGB(255, 255, 255));
+            if ( !::BitBlt(GetHdc(), xdest, ydest, (int)width, (int)height,
+                           dc_mask, xsrc, ysrc, SRCAND) )
+            {
+                wxLogLastError("BitBlt");
+            }
+            ::SetBkColor(GetHdc(), prevBkCol);   // restore colours to original values
+            ::SetTextColor(GetHdc(), prevCol);
+
+            // OR buffer to dest
+            success = ::BitBlt(GetHdc(), xdest, ydest,
+                               (int)width, (int)height,
+                               dc_buffer, 0, 0, SRCPAINT) != 0;
+            if ( !success )
+            {
+                wxLogLastError("BitBlt");
+            }
+
+            // tidy up temporary DCs and bitmap
+            ::SelectObject(dc_mask, 0);
+            ::DeleteDC(dc_mask);
+            ::SelectObject(dc_buffer, 0);
+            ::DeleteDC(dc_buffer);
+            ::DeleteObject(buffer_bmap);
         }
     }
         }
     }
-    else if (needsPixelCopy) // not masked, but we need pixel copy. Only true if it's a printer
-    {
-        // If we are printing, source colours are screen colours
-        // not printer colours and so we need copy the bitmap
-        // pixel by pixel.
-        if (isPrinter)
-        {
-            HDC dc_src = (HDC) source->m_hDC;
-               RECT rect;
-               for (int y = 0; y < height; y++)
-               {
-                // This is Stefan Csomor's optimisation, where
-                // identical adjacent pixels are drawn together.
-                   for (int x = 0; x < width; x++)
-                   {
-                       COLORREF col = ::GetPixel(dc_src, x, y) ;
-                       HBRUSH brush = ::CreateSolidBrush( col );
-
-                       rect.left = xdest1 + x;
-                       rect.top = ydest1 + y;
-                       while( (x + 1 < width) && (::GetPixel(dc_src, x + 1, y) == col ) )
-                       {
-                               ++x ;
-                       }
-                       rect.right = xdest1 + x + 1;
-                       rect.bottom = rect.top + 1;
-                       ::FillRect((HDC) m_hDC, &rect, brush);
-                       ::DeleteObject(brush);
-                }
-               }
-           }
-        else
-        {
-            wxFAIL_MSG( "If needsPixelCopy is true, isPrinter should be true also." );
-        }
-    }
-    else if (isPrinter) // not masked, not pixel copy
+    else // no mask, just BitBlt() it
     {
     {
-        wxBitmap& bmp = source->m_selectedBitmap ;
-        BITMAPINFO *info = (BITMAPINFO *) malloc( sizeof( BITMAPINFOHEADER ) + 256 * sizeof(RGBQUAD ) ) ;
-        int iBitsSize = ((bmp.GetWidth() + 3 ) & ~3 ) * bmp.GetHeight() ;
-            
-        void* bits = malloc( iBitsSize ) ;
-            
-        memset( info , 0 , sizeof( BITMAPINFOHEADER ) ) ;
-            
-        info->bmiHeader.biSize = sizeof( BITMAPINFOHEADER ) ;
-        info->bmiHeader.biWidth = bmp.GetWidth() ;
-        info->bmiHeader.biHeight = bmp.GetHeight() ;
-        info->bmiHeader.biPlanes = 1 ;
-        info->bmiHeader.biBitCount = 8 ;
-        info->bmiHeader.biCompression = BI_RGB ;
-            
-        HDC display = GetDC( NULL ) ;
-        if ( GetDIBits( display , (HBITMAP) bmp.GetHBITMAP( ) , 0 , bmp.GetHeight() , bits , info , DIB_RGB_COLORS ) )
+        success = ::BitBlt(GetHdc(), xdest, ydest,
+                           (int)width, (int)height,
+                           GetHdcOf(*source), xsrc, ysrc, dwRop) != 0;
+        if ( !success )
         {
         {
-            success = (GDI_ERROR != StretchDIBits( (HDC) m_hDC,
-                    xdest1, ydest1, bmp.GetWidth(), bmp.GetHeight() ,
-                    xsrc1 , ysrc1 ,bmp.GetWidth(), bmp.GetHeight() ,
-                    bits , info , DIB_RGB_COLORS , SRCCOPY )) ;
+            wxLogLastError("BitBlt");
         }
         }
-        else
-            success = FALSE;
-        ReleaseDC( NULL , display ) ;
-        free ( bits ) ;
-        free( info ) ;
-    }
-    else // Not masked, not printer, not pixel copy
-    {
-        success = (BitBlt(GetHdc(), xdest1, ydest1, (int)width, (int)height, (HDC) source->m_hDC,
-             xsrc1, ysrc1, dwRop) != 0);
     }
     }
+
     ::SetTextColor(GetHdc(), old_textground);
     ::SetBkColor(GetHdc(), old_background);
 
     ::SetTextColor(GetHdc(), old_textground);
     ::SetBkColor(GetHdc(), old_background);
 
index 35c9be54be32ce76eb13192b1646ca4b576b6857..8105eec4413e8a4ed55a9ed49d04b0443554db28 100644 (file)
@@ -1,51 +1,70 @@
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
-// Name:        dcprint.cpp
+// Name:        src/msw/dcprint.cpp
 // Purpose:     wxPrinterDC class
 // Author:      Julian Smart
 // Modified by:
 // Created:     01/02/97
 // RCS-ID:      $Id$
 // Copyright:   (c) Julian Smart and Markus Holzem
 // Purpose:     wxPrinterDC class
 // Author:      Julian Smart
 // Modified by:
 // Created:     01/02/97
 // RCS-ID:      $Id$
 // Copyright:   (c) Julian Smart and Markus Holzem
-// Licence:    wxWindows licence
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 /////////////////////////////////////////////////////////////////////////////
 
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
 #ifdef __GNUG__
 #ifdef __GNUG__
-#pragma implementation "dcprint.h"
+    #pragma implementation "dcprint.h"
 #endif
 
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
 #ifdef __BORLANDC__
 #endif
 
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
 #ifdef __BORLANDC__
-#pragma hdrstop
+    #pragma hdrstop
 #endif
 
 #ifndef WX_PRECOMP
 #endif
 
 #ifndef WX_PRECOMP
+    #include "wx/string.h"
+    #include "wx/log.h"
+    #include "wx/window.h"
 #endif
 
 #endif
 
-#include "wx/string.h"
-#include "wx/log.h"
-#include "wx/window.h"
 #include "wx/msw/private.h"
 #include "wx/dcprint.h"
 #include "math.h"
 
 #if wxUSE_COMMON_DIALOGS || defined(__WXWINE__)
 #include "wx/msw/private.h"
 #include "wx/dcprint.h"
 #include "math.h"
 
 #if wxUSE_COMMON_DIALOGS || defined(__WXWINE__)
-#include <commdlg.h>
+    #include <commdlg.h>
 #endif
 
 #ifndef __WIN32__
 #endif
 
 #ifndef __WIN32__
-#include <print.h>
+    #include <print.h>
 #endif
 
 #endif
 
+// ----------------------------------------------------------------------------
+// wxWin macros
+// ----------------------------------------------------------------------------
 IMPLEMENT_CLASS(wxPrinterDC, wxDC)
 
 IMPLEMENT_CLASS(wxPrinterDC, wxDC)
 
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// wxPrinterDC construction
+// ----------------------------------------------------------------------------
+
 // This form is deprecated
 wxPrinterDC::wxPrinterDC(const wxString& driver_name, const wxString& device_name, const wxString& file, bool interactive, int orientation)
 {
     m_isInteractive = interactive;
 
 // This form is deprecated
 wxPrinterDC::wxPrinterDC(const wxString& driver_name, const wxString& device_name, const wxString& file, bool interactive, int orientation)
 {
     m_isInteractive = interactive;
 
-    if (!file.IsNull() && file != wxT(""))
+    if ( !!file )
         m_printData.SetFilename(file);
 
 #if wxUSE_COMMON_DIALOGS
         m_printData.SetFilename(file);
 
 #if wxUSE_COMMON_DIALOGS
@@ -79,7 +98,7 @@ wxPrinterDC::wxPrinterDC(const wxString& driver_name, const wxString& device_nam
         //     m_dontDelete = TRUE;
     }
     else
         //     m_dontDelete = TRUE;
     }
     else
-#endif
+#endif // wxUSE_COMMON_DIALOGS
         if ((!driver_name.IsNull() && driver_name != wxT("")) &&
             (!device_name.IsNull() && device_name != wxT("")) &&
             (!file.IsNull() && file != wxT("")))
         if ((!driver_name.IsNull() && driver_name != wxT("")) &&
             (!device_name.IsNull() && device_name != wxT("")) &&
             (!file.IsNull() && file != wxT("")))
@@ -138,10 +157,14 @@ wxPrinterDC::wxPrinterDC(WXHDC theDC)
     SetPen(*wxBLACK_PEN);
 }
 
     SetPen(*wxBLACK_PEN);
 }
 
-wxPrinterDC::~wxPrinterDC(void)
+wxPrinterDC::~wxPrinterDC()
 {
 }
 
 {
 }
 
+// ----------------------------------------------------------------------------
+// wxPrinterDC {Start/End}{Page/Doc} methods
+// ----------------------------------------------------------------------------
+
 bool wxPrinterDC::StartDoc(const wxString& message)
 {
     DOCINFO docinfo;
 bool wxPrinterDC::StartDoc(const wxString& message)
 {
     DOCINFO docinfo;
@@ -163,20 +186,7 @@ bool wxPrinterDC::StartDoc(const wxString& message)
     if (!m_hDC)
         return FALSE;
 
     if (!m_hDC)
         return FALSE;
 
-    int ret =
-#ifndef __WIN32__
-        ::StartDoc((HDC) m_hDC, &docinfo);
-#else
-#ifdef UNICODE
-    ::StartDocW((HDC) m_hDC, &docinfo);
-#else
-#ifdef __TWIN32__
-    ::StartDoc((HDC) m_hDC, &docinfo);
-#else
-    ::StartDocA((HDC) m_hDC, &docinfo);
-#endif
-#endif
-#endif
+    int ret = ::StartDoc(GetHdc(), &docinfo);
 
 #ifndef __WIN16__
     if (ret <= 0)
 
 #ifndef __WIN16__
     if (ret <= 0)
@@ -189,18 +199,18 @@ bool wxPrinterDC::StartDoc(const wxString& message)
     return (ret > 0);
 }
 
     return (ret > 0);
 }
 
-void wxPrinterDC::EndDoc(void)
+void wxPrinterDC::EndDoc()
 {
     if (m_hDC) ::EndDoc((HDC) m_hDC);
 }
 
 {
     if (m_hDC) ::EndDoc((HDC) m_hDC);
 }
 
-void wxPrinterDC::StartPage(void)
+void wxPrinterDC::StartPage()
 {
     if (m_hDC)
         ::StartPage((HDC) m_hDC);
 }
 
 {
     if (m_hDC)
         ::StartPage((HDC) m_hDC);
 }
 
-void wxPrinterDC::EndPage(void)
+void wxPrinterDC::EndPage()
 {
     if (m_hDC)
         ::EndPage((HDC) m_hDC);
 {
     if (m_hDC)
         ::EndPage((HDC) m_hDC);
@@ -350,13 +360,13 @@ WXHDC WXDLLEXPORT wxGetPrinterDC(const wxPrintData& printDataConst)
     wxChar* driverName = (wxChar*) NULL;
 
     wxString devNameStr = printData.GetPrinterName();
     wxChar* driverName = (wxChar*) NULL;
 
     wxString devNameStr = printData.GetPrinterName();
-    wxChar* deviceName;
     wxChar* portName = (wxChar*) NULL; // Obsolete in WIN32
 
     wxChar* portName = (wxChar*) NULL; // Obsolete in WIN32
 
-    if (devNameStr == wxT(""))
+    const wxChar* deviceName;
+    if ( !devNameStr )
         deviceName = (wxChar*) NULL;
     else
         deviceName = (wxChar*) NULL;
     else
-        deviceName = WXSTRINGCAST devNameStr;
+        deviceName = devNameStr.c_str();
 
     LPDEVMODE lpDevMode = (LPDEVMODE) NULL;
 
 
     LPDEVMODE lpDevMode = (LPDEVMODE) NULL;
 
@@ -365,7 +375,7 @@ WXHDC WXDLLEXPORT wxGetPrinterDC(const wxPrintData& printDataConst)
     if ( hDevMode )
         lpDevMode = (DEVMODE*) GlobalLock(hDevMode);
 
     if ( hDevMode )
         lpDevMode = (DEVMODE*) GlobalLock(hDevMode);
 
-    if (devNameStr == wxT(""))
+    if ( !devNameStr )
     {
         // Retrieve the default device name
         wxString portName;
     {
         // Retrieve the default device name
         wxString portName;
@@ -378,7 +388,7 @@ WXHDC WXDLLEXPORT wxGetPrinterDC(const wxPrintData& printDataConst)
 
         wxASSERT_MSG( ret, wxT("Could not get default device name.") );
 
 
         wxASSERT_MSG( ret, wxT("Could not get default device name.") );
 
-        deviceName = WXSTRINGCAST devNameStr;
+        deviceName = devNameStr.c_str();
     }
 
 #ifdef __WIN32__
     }
 
 #ifdef __WIN32__
@@ -393,3 +403,180 @@ WXHDC WXDLLEXPORT wxGetPrinterDC(const wxPrintData& printDataConst)
     return (WXHDC) hDC;
 }
 
     return (WXHDC) hDC;
 }
 
+// ----------------------------------------------------------------------------
+// wxPrinterDC bit blitting/bitmap drawing
+// ----------------------------------------------------------------------------
+
+void wxPrinterDC::DoDrawBitmap(const wxBitmap &bmp,
+                               wxCoord x, wxCoord y,
+                               bool useMask)
+{
+    wxCHECK_RET( bmp.Ok(), _T("invalid bitmap in wxPrinterDC::DrawBitmap") );
+
+    int width = bmp.GetWidth(),
+        height = bmp.GetHeight();
+
+    if ( ::GetDeviceCaps(GetHdc(), RASTERCAPS) & RC_STRETCHDIB )
+    {
+        BITMAPINFO *info = (BITMAPINFO *) malloc( sizeof( BITMAPINFOHEADER ) + 256 * sizeof(RGBQUAD ) );
+        memset( info, 0, sizeof( BITMAPINFOHEADER ) );
+
+        int iBitsSize = ((width + 3 ) & ~3 ) * height;
+
+        void* bits = malloc( iBitsSize );
+
+        info->bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
+        info->bmiHeader.biWidth = width;
+        info->bmiHeader.biHeight = height;
+        info->bmiHeader.biPlanes = 1;
+        info->bmiHeader.biBitCount = 8;
+        info->bmiHeader.biCompression = BI_RGB;
+
+        ScreenHDC display;
+        if ( GetDIBits(display, GetHbitmapOf(bmp), 0,
+                       bmp.GetHeight(), bits, info,
+                       DIB_RGB_COLORS) )
+        {
+            if ( ::StretchDIBits(GetHdc(), x, y,
+                                 width, height,
+                                 0 , 0, width, height,
+                                 bits, info,
+                                 DIB_RGB_COLORS, SRCCOPY) == GDI_ERROR )
+            {
+                wxLogLastError("StretchDIBits");
+            }
+        }
+
+        free(bits);
+        free(info);
+    }
+    else // no support for StretchDIBits()
+    {
+        wxMemoryDC memDC;
+        memDC.SelectObject(bmp);
+
+        Blit(x, y, width, height, &memDC, 0, 0, wxCOPY, useMask);
+
+        memDC.SelectObject(wxNullBitmap);
+    }
+}
+
+bool wxPrinterDC::DoBlit(wxCoord xdest, wxCoord ydest,
+                         wxCoord width, wxCoord height,
+                         wxDC *source,
+                         wxCoord xsrc, wxCoord ysrc,
+                         int rop, bool useMask)
+{
+    bool success = TRUE;
+
+    if ( useMask )
+    {
+        // If we are printing source colours are screen colours
+        // not printer colours and so we need copy the bitmap
+        // pixel by pixel.
+        RECT rect;
+        HDC dc_src = GetHdcOf(*source);
+        HDC dc_mask = ::CreateCompatibleDC(dc_src);
+
+        ::SelectObject(dc_mask, (HBITMAP) source->GetSelectedBitmap().GetMask()->GetMaskBitmap());
+        for (int x = 0; x < width; x++)
+        {
+            for (int y = 0; y < height; y++)
+            {
+                COLORREF cref = ::GetPixel(dc_mask, x, y);
+                if (cref)
+                {
+                    HBRUSH brush = ::CreateSolidBrush(::GetPixel(dc_src, x, y));
+                    rect.left = xdest + x;
+                    rect.right = rect.left + 1;
+                    rect.top = ydest + y; 
+                    rect.bottom = rect.top + 1;
+                    ::FillRect(GetHdc(), &rect, brush);
+                    ::DeleteObject(brush);
+                }
+            }
+        }
+        ::SelectObject(dc_mask, 0);
+        ::DeleteDC(dc_mask);
+    }
+    else // no mask
+    {
+        if ( ::GetDeviceCaps(GetHdc(), RASTERCAPS) & RC_STRETCHDIB )
+        {
+            wxBitmap& bmp = source->GetSelectedBitmap();
+            int width = bmp.GetWidth(),
+                height = bmp.GetHeight();
+
+            BITMAPINFO *info = (BITMAPINFO *) malloc( sizeof( BITMAPINFOHEADER ) + 256 * sizeof(RGBQUAD ) );
+            int iBitsSize = ((width + 3 ) & ~3 ) * height;
+
+            void* bits = malloc( iBitsSize );
+
+            memset( info , 0 , sizeof( BITMAPINFOHEADER ) );
+
+            info->bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
+            info->bmiHeader.biWidth = width;
+            info->bmiHeader.biHeight = height;
+            info->bmiHeader.biPlanes = 1;
+            info->bmiHeader.biBitCount = 8;
+            info->bmiHeader.biCompression = BI_RGB;
+
+            ScreenHDC display;
+            if ( !::GetDIBits(display, GetHbitmapOf(bmp), 0,
+                              height, bits, info, DIB_RGB_COLORS) )
+            {
+                wxLogLastError("GetDIBits");
+
+                success = FALSE;
+            }
+
+            if ( success )
+            {
+                success = ::StretchDIBits(GetHdc(), xdest, ydest,
+                                          width, height,
+                                          xsrc, ysrc,
+                                          width, height,
+                                          bits, info ,
+                                          DIB_RGB_COLORS,
+                                          SRCCOPY) != GDI_ERROR;
+                if ( !success )
+                {
+                    wxLogLastError("StretchDIBits");
+                }
+            }
+
+            free(bits);
+            free(info);
+        }
+        else // no support for StretchDIBits
+        {
+            // as we are printing, source colours are screen colours not printer
+            // colours and so we need copy the bitmap pixel by pixel.
+            HDC dc_src = GetHdcOf(*source);
+            RECT rect;
+            for (int y = 0; y < height; y++)
+            {
+                // This is Stefan Csomor's optimisation, where identical adjacent
+                // pixels are drawn together.
+                for (int x = 0; x < width; x++)
+                {
+                    COLORREF col = ::GetPixel(dc_src, x, y);
+                    HBRUSH brush = ::CreateSolidBrush( col );
+
+                    rect.left = xdest + x;
+                    rect.top = ydest + y;
+                    while( (x + 1 < width) && (::GetPixel(dc_src, x + 1, y) == col ) )
+                    {
+                        ++x;
+                    }
+                    rect.right = xdest + x + 1;
+                    rect.bottom = rect.top + 1;
+                    ::FillRect((HDC) m_hDC, &rect, brush);
+                    ::DeleteObject(brush);
+                }
+            }
+        }
+    }
+
+    return success;
+}
index 00b0741ab76d9f730dc0de70a8dcff846b000972..5d615ffa30d60c727453e94889838d23c666a36e 100644 (file)
@@ -47,7 +47,7 @@
 // wxWin macros
 // ----------------------------------------------------------------------------
 
 // wxWin macros
 // ----------------------------------------------------------------------------
 
-    IMPLEMENT_DYNAMIC_CLASS(wxIcon, wxIconBase)
+IMPLEMENT_DYNAMIC_CLASS(wxIcon, wxIconBase)
 
 // ============================================================================
 // implementation
 
 // ============================================================================
 // implementation
@@ -71,14 +71,10 @@ void wxIconRefData::Free()
 // wxIcon
 // ----------------------------------------------------------------------------
 
 // wxIcon
 // ----------------------------------------------------------------------------
 
-wxIcon::wxIcon()
-{
-}
-
-wxIcon::wxIcon(const char WXUNUSED(bits)[],
-               int WXUNUSED(width),
-               int WXUNUSED(height))
+wxIcon::wxIcon(const char bits[], int width, int height)
 {
 {
+    wxBitmap bmp(bits, width, height);
+    CopyFromBitmap(bmp);
 }
 
 wxIcon::wxIcon(const wxString& iconfile,
 }
 
 wxIcon::wxIcon(const wxString& iconfile,
@@ -94,6 +90,51 @@ wxIcon::~wxIcon()
 {
 }
 
 {
 }
 
+void wxIcon::CopyFromBitmap(const wxBitmap& bmp)
+{
+#ifdef __WIN32__
+    wxMask *mask = bmp.GetMask();
+    if ( !mask )
+    {
+        // we must have a mask for an icon, so even if it's probably incorrect,
+        // do create it (grey is the "standard" transparent colour)
+        mask = new wxMask(bmp, *wxLIGHT_GREY);
+    }
+
+    ICONINFO iconInfo;
+    iconInfo.fIcon = TRUE;  // we want an icon, not a cursor
+    iconInfo.hbmMask = wxInvertMask((HBITMAP)mask->GetMaskBitmap());
+    iconInfo.hbmColor = GetHbitmapOf(bmp);
+
+    HICON hicon = ::CreateIconIndirect(&iconInfo);
+    if ( !hicon )
+    {
+        wxLogLastError("CreateIconIndirect");
+    }
+    else
+    {
+        SetHICON((WXHICON)hicon);
+        SetSize(bmp.GetWidth(), bmp.GetHeight());
+    }
+
+    if ( !bmp.GetMask() )
+    {
+        // we created the mask, now delete it
+        delete mask;
+    }
+#else // Win16
+    // there are some functions in curico.cpp which probably could be used
+    // here...
+    wxFAIL_MSG("not implemented");
+#endif // Win32/16
+}
+
+void wxIcon::CreateIconFromXpm(const char **data)
+{
+    wxBitmap bmp(data);
+    CopyFromBitmap(bmp);
+}
+
 bool wxIcon::LoadFile(const wxString& filename,
                       long type,
                       int desiredWidth, int desiredHeight)
 bool wxIcon::LoadFile(const wxString& filename,
                       long type,
                       int desiredWidth, int desiredHeight)
index 642fc9290c2619630096d6f67a308b7a597cdc53..c80c8b8e7a423085fb68da10239e02df1916764e 100644 (file)
@@ -1,34 +1,42 @@
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
-// Name:        imaglist.cpp
-// Purpose:     wxImageList
+// Name:        src/msw/imaglist.cpp
+// Purpose:     wxImageList implementation for Win32
 // Author:      Julian Smart
 // Modified by:
 // Created:     04/01/98
 // RCS-ID:      $Id$
 // Copyright:   (c) Julian Smart and Markus Holzem
 // Author:      Julian Smart
 // Modified by:
 // Created:     04/01/98
 // RCS-ID:      $Id$
 // Copyright:   (c) Julian Smart and Markus Holzem
-// Licence:    wxWindows license
+// Licence:     wxWindows license
 /////////////////////////////////////////////////////////////////////////////
 
 /////////////////////////////////////////////////////////////////////////////
 
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
 #ifdef __GNUG__
 #ifdef __GNUG__
-#pragma implementation "imaglist.h"
+    #pragma implementation "imaglist.h"
 #endif
 
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
 #ifdef __BORLANDC__
 #endif
 
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
 #ifdef __BORLANDC__
-#pragma hdrstop
+    #pragma hdrstop
 #endif
 
 #if defined(__WIN95__)
 
 #ifndef WX_PRECOMP
 #endif
 
 #if defined(__WIN95__)
 
 #ifndef WX_PRECOMP
-#include <stdio.h>
-#include "wx/setup.h"
-#include "wx/window.h"
-#include "wx/icon.h"
-#include "wx/dc.h"
-#include "wx/string.h"
+    #include "wx/window.h"
+    #include "wx/icon.h"
+    #include "wx/dc.h"
+    #include "wx/string.h"
+
+    #include <stdio.h>
 #endif
 
 #include "wx/log.h"
 #endif
 
 #include "wx/log.h"
 #include "wx/msw/imaglist.h"
 #include "wx/msw/private.h"
 
 #include "wx/msw/imaglist.h"
 #include "wx/msw/private.h"
 
-#if (defined(__WIN95__) && !defined(__GNUWIN32__)) || defined(__TWIN32__) || defined(wxUSE_NORLANDER_HEADERS)
-#include <commctrl.h>
+#if !defined(__GNUWIN32_OLD__) && !defined(__TWIN32__)
+    #include <commctrl.h>
 #endif
 
 #endif
 
+// ----------------------------------------------------------------------------
+// wxWin macros
+// ----------------------------------------------------------------------------
+
 IMPLEMENT_DYNAMIC_CLASS(wxImageList, wxObject)
 
 IMPLEMENT_DYNAMIC_CLASS(wxImageList, wxObject)
 
-wxImageList::wxImageList(void)
+#define GetHImageList()     ((HIMAGELIST)m_hImageList)
+
+// ----------------------------------------------------------------------------
+// private functions
+// ----------------------------------------------------------------------------
+
+// returns the mask if it's valid, otherwise the bitmap mask and, if it's not
+// valid neither, a "solid" mask (no transparent zones at all)
+static wxBitmap GetMaskForImage(const wxBitmap& bitmap, const wxBitmap& mask);
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// wxImageList creation/destruction
+// ----------------------------------------------------------------------------
+
+wxImageList::wxImageList()
 {
     m_hImageList = 0;
 }
 
 {
     m_hImageList = 0;
 }
 
-wxImageList::~wxImageList(void)
+// Creates an image list
+bool wxImageList::Create(int width, int height, bool mask, int initial)
 {
 {
-       if ( m_hImageList )
-               ImageList_Destroy((HIMAGELIST) m_hImageList);
-       m_hImageList = 0;
-}
-
+    UINT flags = 0; // TODO shouldallow to specify ILC_COLORxxx here
+    if ( mask )
+        flags |= ILC_MASK;
+
+    // Grow by 1, I guess this is reasonable behaviour most of the time
+    m_hImageList = (WXHIMAGELIST) ImageList_Create(width, height, flags,
+                                                   initial, 1);
+    if ( !m_hImageList )
+    {
+        wxLogLastError("ImageList_Create()");
+    }
 
 
-// Attributes
-////////////////////////////////////////////////////////////////////////////
+    return m_hImageList != 0;
+}
 
 
-// Returns the number of images in the image list.
-int wxImageList::GetImageCount(void) const
+wxImageList::~wxImageList()
 {
 {
-       return ImageList_GetImageCount((HIMAGELIST) m_hImageList);
+    if ( m_hImageList )
+    {
+        ImageList_Destroy(GetHImageList());
+        m_hImageList = 0;
+    }
 }
 
 }
 
-// Operations
-////////////////////////////////////////////////////////////////////////////
+// ----------------------------------------------------------------------------
+// wxImageList attributes
+// ----------------------------------------------------------------------------
 
 
-// Creates an image list
-bool wxImageList::Create(int width, int height, bool mask, int initial)
+// Returns the number of images in the image list.
+int wxImageList::GetImageCount() const
 {
 {
-       UINT flags = 0;
-       if ( mask )
-               flags |= ILC_MASK;
+    wxASSERT_MSG( m_hImageList, _T("invalid image list") );
 
 
-       // Grow by 1, I guess this is reasonable behaviour most of the time
-       m_hImageList = (WXHIMAGELIST) ImageList_Create(width, height, flags, initial, 1);
-       return (m_hImageList != 0);
+    return ImageList_GetImageCount(GetHImageList());
 }
 
 }
 
+// ----------------------------------------------------------------------------
+// wxImageList operations
+// ----------------------------------------------------------------------------
+
 // Adds a bitmap, and optionally a mask bitmap.
 // Note that wxImageList creates new bitmaps, so you may delete
 // 'bitmap' and 'mask'.
 int wxImageList::Add(const wxBitmap& bitmap, const wxBitmap& mask)
 {
 // Adds a bitmap, and optionally a mask bitmap.
 // Note that wxImageList creates new bitmaps, so you may delete
 // 'bitmap' and 'mask'.
 int wxImageList::Add(const wxBitmap& bitmap, const wxBitmap& mask)
 {
-       HBITMAP hBitmap1 = (HBITMAP) bitmap.GetHBITMAP();
-       HBITMAP hBitmap2 = 0;
-       if ( mask.Ok() )
-           hBitmap2 = (HBITMAP) mask.GetHBITMAP();
-    else if (bitmap.GetMask())
-        hBitmap2 = (HBITMAP) bitmap.GetMask()->GetMaskBitmap();
-
-    HBITMAP hBitmapI=0;
-    if(hBitmap2!=0) {
-        // Microsoft imagelist masks are inverted from wxWindows mask standard (white is mask color)
-        BITMAP bm;
-        ::GetObject(hBitmap2,sizeof(BITMAP),(LPVOID)&bm);
-        int w=bm.bmWidth;
-        int h=bm.bmHeight;
-        HDC hdc = ::CreateCompatibleDC(NULL);   
-        HDC hdci = ::CreateCompatibleDC(NULL);  
-        hBitmapI = ::CreateCompatibleBitmap(hdci, w, h);
-        ::SelectObject(hdc, hBitmap2);
-        ::SelectObject(hdci, hBitmapI);
-        ::BitBlt(hdci, 0, 0, w, h, hdc, 0, 0, NOTSRCCOPY);
-        ::DeleteDC(hdc);
-        ::DeleteDC(hdci);
-    }
+    wxBitmap bmpMask = GetMaskForImage(bitmap, mask);
+    HBITMAP hbmpMask = wxInvertMask(GetHbitmapOf(bmpMask));
 
 
-    int index = ImageList_Add((HIMAGELIST) GetHIMAGELIST(), hBitmap1, hBitmapI);
-       if ( index == -1 )
+    int index = ImageList_Add(GetHImageList(), GetHbitmapOf(bitmap), hbmpMask);
+    if ( index == -1 )
     {
         wxLogError(_("Couldn't add an image to the image list."));
     }
 
     {
         wxLogError(_("Couldn't add an image to the image list."));
     }
 
-    // Clean up inverted mask
-    if(hBitmapI!=0)
-        ::DeleteObject(hBitmapI);
+    ::DeleteObject(hbmpMask);
 
     return index;
 }
 
     return index;
 }
@@ -128,126 +146,184 @@ int wxImageList::Add(const wxBitmap& bitmap, const wxBitmap& mask)
 int wxImageList::Add(const wxBitmap& bitmap, const wxColour& maskColour)
 {
 #ifdef __TWIN32__
 int wxImageList::Add(const wxBitmap& bitmap, const wxColour& maskColour)
 {
 #ifdef __TWIN32__
-        wxFAIL_MSG("ImageList_AddMasked not implemented in TWIN32");
-        return -1;
+    wxFAIL_MSG(_T("ImageList_AddMasked not implemented in TWIN32"));
+    return -1;
 #else
 #else
-       HBITMAP hBitmap1 = (HBITMAP) bitmap.GetHBITMAP();
-       COLORREF colorRef = PALETTERGB(maskColour.Red(), maskColour.Green(), maskColour.Blue());
-       return ImageList_AddMasked((HIMAGELIST) GetHIMAGELIST(), hBitmap1, colorRef);
+    int index = ImageList_AddMasked(GetHImageList(),
+                                    GetHbitmapOf(bitmap),
+                                    wxColourToRGB(maskColour));
+    if ( index == -1 )
+    {
+        wxLogError(_("Couldn't add an image to the image list."));
+    }
+
+    return index;
 #endif
 }
 
 // Adds a bitmap and mask from an icon.
 int wxImageList::Add(const wxIcon& icon)
 {
 #endif
 }
 
 // Adds a bitmap and mask from an icon.
 int wxImageList::Add(const wxIcon& icon)
 {
-       HICON hIcon = (HICON) icon.GetHICON();
-       return ImageList_AddIcon((HIMAGELIST) GetHIMAGELIST(), hIcon);
+    int index = ImageList_AddIcon(GetHImageList(), GetHiconOf(icon));
+    if ( index == -1 )
+    {
+        wxLogError(_("Couldn't add an image to the image list."));
+    }
+
+    return index;
 }
 
 // Replaces a bitmap, optionally passing a mask bitmap.
 // Note that wxImageList creates new bitmaps, so you may delete
 // 'bitmap' and 'mask'.
 }
 
 // Replaces a bitmap, optionally passing a mask bitmap.
 // Note that wxImageList creates new bitmaps, so you may delete
 // 'bitmap' and 'mask'.
-bool wxImageList::Replace(int index, const wxBitmap& bitmap, const wxBitmap& mask)
+bool wxImageList::Replace(int index,
+                          const wxBitmap& bitmap, const wxBitmap& mask)
 {
 #ifdef __TWIN32__
 {
 #ifdef __TWIN32__
-        wxFAIL_MSG("ImageList_Replace not implemented in TWIN32");
-        return FALSE;
+    wxFAIL_MSG(_T("ImageList_Replace not implemented in TWIN32"));
+    return FALSE;
 #else
 #else
-       HBITMAP hBitmap1 = (HBITMAP) bitmap.GetHBITMAP();
-       HBITMAP hBitmap2 = 0;
-       if ( mask.Ok() )
-           hBitmap2 = (HBITMAP) mask.GetHBITMAP();
-       return (ImageList_Replace((HIMAGELIST) GetHIMAGELIST(), index, hBitmap1, hBitmap2) != 0);
-#endif
-}
+    wxBitmap bmpMask = GetMaskForImage(bitmap, mask);
+    HBITMAP hbmpMask = wxInvertMask(GetHbitmapOf(bmpMask));
 
 
-/* Not supported by Win95
-// Replacing a bitmap, using the specified colour to create the mask bitmap
-// Note that wxImageList creates new bitmaps, so you may delete
-// 'bitmap'.
-bool wxImageList::Replace(int index, const wxBitmap& bitmap, const wxColour& maskColour)
-{
-       HBITMAP hBitmap1 = (HBITMAP) bitmap.GetHBITMAP();
-       COLORREF colorRef = PALETTERGB(maskColour.Red(), maskColour.Green(), maskColour.Blue());
-       return (bool) ImageList_ReplaceMasked((HIMAGELIST) GetHIMAGELIST(), index, hBitmap1, colorRef);
+    bool ok = ImageList_Replace(GetHImageList(), index,
+                                GetHbitmapOf(bitmap), hbmpMask) != 0;
+    if ( !ok )
+    {
+        wxLogLastError("ImageList_Add()");
+    }
+
+    ::DeleteObject(hbmpMask);
+
+    return ok;
+#endif
 }
 }
-*/
 
 // Replaces a bitmap and mask from an icon.
 
 // Replaces a bitmap and mask from an icon.
-bool wxImageList::Replace(int index, const wxIcon& icon)
+bool wxImageList::Replace(int i, const wxIcon& icon)
 {
 {
-       HICON hIcon = (HICON) icon.GetHICON();
-       return (ImageList_ReplaceIcon((HIMAGELIST) GetHIMAGELIST(), index, hIcon) != 0);
+    bool ok = ImageList_ReplaceIcon(GetHImageList(), i, GetHiconOf(icon)) != 0;
+    if ( !ok )
+    {
+        wxLogLastError("ImageList_ReplaceIcon()");
+    }
+
+    return ok;
 }
 
 // Removes the image at the given index.
 bool wxImageList::Remove(int index)
 {
 #ifdef __TWIN32__
 }
 
 // Removes the image at the given index.
 bool wxImageList::Remove(int index)
 {
 #ifdef __TWIN32__
-        wxFAIL_MSG("ImageList_Replace not implemented in TWIN32");
-        return FALSE;
+    wxFAIL_MSG(_T("ImageList_Replace not implemented in TWIN32"));
+    return FALSE;
 #else
 #else
-       return (ImageList_Remove((HIMAGELIST) GetHIMAGELIST(), index) != 0);
+    bool ok = ImageList_Remove(GetHImageList(), index) != 0;
+    if ( !ok )
+    {
+        wxLogLastError("ImageList_Remove()");
+    }
+
+    return ok;
 #endif
 }
 
 // Remove all images
 #endif
 }
 
 // Remove all images
-bool wxImageList::RemoveAll(void)
+bool wxImageList::RemoveAll()
 {
 {
-       // TODO: Is this correct?
-       while ( GetImageCount() > 0 )
-       {
-               Remove(0);
-       }
-       return TRUE;
+    bool ok = ImageList_RemoveAll(GetHImageList()) != 0;
+    if ( !ok )
+    {
+        wxLogLastError("ImageList_RemoveAll()");
+    }
+
+    return ok;
 }
 
 // Draws the given image on a dc at the specified position.
 // If 'solidBackground' is TRUE, Draw sets the image list background
 // colour to the background colour of the wxDC, to speed up
 // drawing by eliminating masked drawing where possible.
 }
 
 // Draws the given image on a dc at the specified position.
 // If 'solidBackground' is TRUE, Draw sets the image list background
 // colour to the background colour of the wxDC, to speed up
 // drawing by eliminating masked drawing where possible.
-bool wxImageList::Draw(int index, wxDC& dc, int x, int y,
-    int flags, bool solidBackground)
+bool wxImageList::Draw(int index,
+                       wxDC& dc,
+                       int x, int y,
+                       int flags,
+                       bool solidBackground)
 {
 #ifdef __TWIN32__
 {
 #ifdef __TWIN32__
-        wxFAIL_MSG("ImageList_Replace not implemented in TWIN32");
-        return FALSE;
+    wxFAIL_MSG(_T("ImageList_Replace not implemented in TWIN32"));
+    return FALSE;
 #else
 #else
-       HDC hDC = (HDC) dc.GetHDC();
-       if ( !hDC )
-               return FALSE;
-
-       if ( solidBackground )
-       {
-               wxBrush *brush = & dc.GetBackground();
-               if ( brush && brush->Ok())
-               {
-                       wxColour col(brush->GetColour());
-                       ImageList_SetBkColor((HIMAGELIST) GetHIMAGELIST(),
-                                       PALETTERGB(col.Red(), col.Green(), col.Blue()));
-               }
-               else
-                       ImageList_SetBkColor((HIMAGELIST) GetHIMAGELIST(),
-                               CLR_NONE);
-       }
-       else
-               ImageList_SetBkColor((HIMAGELIST) GetHIMAGELIST(),
-                               CLR_NONE);
+    HDC hDC = GetHdcOf(dc);
+    wxCHECK_MSG( hDC, FALSE, _T("invalid wxDC in wxImageList::Draw") );
+
+    COLORREF clr = CLR_NONE;    // transparent by default
+    if ( solidBackground )
+    {
+        wxBrush *brush = & dc.GetBackground();
+        if ( brush && brush->Ok() )
+        {
+            clr = wxColourToRGB(brush->GetColour());
+        }
+    }
+
+    ImageList_SetBkColor(GetHImageList(), clr);
 
     UINT style = 0;
 
     UINT style = 0;
-       if ( flags & wxIMAGELIST_DRAW_NORMAL )
-               style |= ILD_NORMAL;
-       if ( flags & wxIMAGELIST_DRAW_TRANSPARENT )
-               style |= ILD_TRANSPARENT;
-       if ( flags & wxIMAGELIST_DRAW_SELECTED )
-               style |= ILD_SELECTED;
-       if ( flags & wxIMAGELIST_DRAW_FOCUSED )
-               style |= ILD_FOCUS;
-
-       return (ImageList_Draw((HIMAGELIST) GetHIMAGELIST(), index, hDC,
-               x, y, style) != 0);
+    if ( flags & wxIMAGELIST_DRAW_NORMAL )
+        style |= ILD_NORMAL;
+    if ( flags & wxIMAGELIST_DRAW_TRANSPARENT )
+        style |= ILD_TRANSPARENT;
+    if ( flags & wxIMAGELIST_DRAW_SELECTED )
+        style |= ILD_SELECTED;
+    if ( flags & wxIMAGELIST_DRAW_FOCUSED )
+        style |= ILD_FOCUS;
+
+    bool ok = ImageList_Draw(GetHImageList(), index, hDC, x, y, style) != 0;
+    if ( !ok )
+    {
+        wxLogLastError("ImageList_Draw()");
+    }
+
+    return ok;
 #endif
 }
 
 #endif
 }
 
-#endif
+// ----------------------------------------------------------------------------
+// helpers
+// ----------------------------------------------------------------------------
+
+static wxBitmap GetMaskForImage(const wxBitmap& bitmap, const wxBitmap& mask)
+{
+    wxBitmap bmpMask;
+
+    if ( mask.Ok() )
+    {
+        bmpMask = mask;
+    }
+    else
+    {
+        wxMask *pMask = bitmap.GetMask();
+        if ( pMask )
+        {
+            bmpMask.SetHBITMAP(pMask->GetMaskBitmap());
+        }
+    }
+
+    if ( !bmpMask.Ok() )
+    {
+        // create a non transparent mask - apparently, this is needed under
+        // Win9x (it doesn't behave correctly if it's passed 0 mask)
+        bmpMask.Create(bitmap.GetWidth(), bitmap.GetHeight(), 1);
+
+        wxMemoryDC dcMem;
+        dcMem.SelectObject(bmpMask);
+        dcMem.Clear();
+        dcMem.SelectObject(wxNullBitmap);
+    }
+
+    return bmpMask;
+}
+
+#endif // Win95
 
 
index 185a915c58371ac75858c62ce13781887ced3fe4..b187fa931ea1b8de2d8e9101616ad8f740632df0 100644 (file)
@@ -144,7 +144,7 @@ bool wxNotebook::Create(wxWindow *parent,
 
   // colors and font
   m_backgroundColour = wxColour(GetSysColor(COLOR_BTNFACE));
 
   // colors and font
   m_backgroundColour = wxColour(GetSysColor(COLOR_BTNFACE));
-  m_foregroundColour = *wxBLACK ;
+  m_foregroundColour = *wxBLACK;
 
   // style
   m_windowStyle = style | wxTAB_TRAVERSAL;
 
   // style
   m_windowStyle = style | wxTAB_TRAVERSAL;
@@ -450,10 +450,13 @@ void wxNotebook::OnSize(wxSizeEvent& event)
   GetSize((int *)&rc.right, (int *)&rc.bottom);
 
   TabCtrl_AdjustRect(m_hwnd, FALSE, &rc);
   GetSize((int *)&rc.right, (int *)&rc.bottom);
 
   TabCtrl_AdjustRect(m_hwnd, FALSE, &rc);
+
+  int width = rc.right - rc.left,
+      height = rc.bottom - rc.top;
   size_t nCount = m_aPages.Count();
   for ( size_t nPage = 0; nPage < nCount; nPage++ ) {
     wxNotebookPage *pPage = m_aPages[nPage];
   size_t nCount = m_aPages.Count();
   for ( size_t nPage = 0; nPage < nCount; nPage++ ) {
     wxNotebookPage *pPage = m_aPages[nPage];
-    pPage->SetSize(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top);
+    pPage->SetSize(rc.left, rc.top, width, height);
   }
 
   event.Skip();
   }
 
   event.Skip();
@@ -513,13 +516,13 @@ void wxNotebook::OnNavigationKey(wxNavigationKeyEvent& event)
 
 // override these 2 functions to do nothing: everything is done in OnSize
 
 
 // override these 2 functions to do nothing: everything is done in OnSize
 
-void wxNotebook::SetConstraintSizes(bool /* recurse */)
+void wxNotebook::SetConstraintSizes(bool WXUNUSED(recurse))
 {
   // don't set the sizes of the pages - their correct size is not yet known
   wxControl::SetConstraintSizes(FALSE);
 }
 
 {
   // don't set the sizes of the pages - their correct size is not yet known
   wxControl::SetConstraintSizes(FALSE);
 }
 
-bool wxNotebook::DoPhase(int /* nPhase */)
+bool wxNotebook::DoPhase(int WXUNUSED(nPhase))
 {
   return TRUE;
 }
 {
   return TRUE;
 }
index 5a1b6ab7426af7cf113a1e357627d466ca94dc69..7c3a590ffc77672336e8d29ebb1c193c259fac99 100644 (file)
@@ -50,6 +50,7 @@ static void XpmToBitmap(wxBitmap *bitmap,
     wxBitmapRefData *refData = bitmap->GetBitmapData();
     refData->m_hBitmap = (WXHBITMAP)ximage->bitmap;
 
     wxBitmapRefData *refData = bitmap->GetBitmapData();
     refData->m_hBitmap = (WXHBITMAP)ximage->bitmap;
 
+    // first set the bitmap width, height, depth...
     BITMAP bm;
     if ( !::GetObject(GetHbitmapOf(*bitmap), sizeof(bm), (LPSTR) & bm) )
     {
     BITMAP bm;
     if ( !::GetObject(GetHbitmapOf(*bitmap), sizeof(bm), (LPSTR) & bm) )
     {
@@ -60,6 +61,26 @@ static void XpmToBitmap(wxBitmap *bitmap,
     refData->m_height = bm.bmHeight;
     refData->m_depth = bm.bmPlanes * bm.bmBitsPixel;
     refData->m_numColors = xpmAttr.npixels;
     refData->m_height = bm.bmHeight;
     refData->m_depth = bm.bmPlanes * bm.bmBitsPixel;
     refData->m_numColors = xpmAttr.npixels;
+
+    // next get the mask, if any
+    if ( xpmAttr.mask_pixel != XpmUndefPixel )
+    {
+        int red, green, blue;
+        const char *clrString = xpmAttr.colorTable[xpmAttr.mask_pixel].c_color;
+        if ( strcmp(clrString, "None") == 0 )
+        {
+            // TODO what to do here??
+            red = green = 0;
+            blue = 1;
+        }
+        else
+        {
+            sscanf(clrString, "#%02x%02x%02x", &red, &green, &blue);
+        }
+
+        wxMask *mask = new wxMask(*bitmap, wxColour(red, green, blue));
+        bitmap->SetMask(mask);
+    }
 }
 
 #endif // wxUSE_XPM_IN_MSW
 }
 
 #endif // wxUSE_XPM_IN_MSW
@@ -79,24 +100,29 @@ bool wxXPMFileHandler::LoadFile(wxBitmap *bitmap,
     dc = CreateCompatibleDC(NULL);
     if (dc)
     {
     dc = CreateCompatibleDC(NULL);
     if (dc)
     {
-      xpmAttr.valuemask = XpmReturnPixels;
-      int errorStatus = XpmReadFileToImage(&dc, wxMBSTRINGCAST name.fn_str(), &ximage, (XImage **) NULL, &xpmAttr);
-      DeleteDC(dc);
-      if (errorStatus == XpmSuccess)
-      {
-        XpmToBitmap(bitmap, ximage, xpmAttr);
+        xpmAttr.valuemask = XpmReturnPixels | XpmColorTable;
+        int errorStatus = XpmReadFileToImage(&dc,
+                                             wxMBSTRINGCAST name.fn_str(),
+                                             &ximage,
+                                             (XImage **)NULL,
+                                             &xpmAttr);
+        DeleteDC(dc);
+        if (errorStatus == XpmSuccess)
+        {
+            XpmToBitmap(bitmap, ximage, xpmAttr);
 
 
-        XpmFreeAttributes(&xpmAttr);
-        XImageFree(ximage);
-      }
+            XpmFree(xpmAttr.pixels);
+            XpmFreeAttributes(&xpmAttr);
+            XImageFree(ximage);
+        }
 
 #if WXWIN_COMPATIBILITY_2
 
 #if WXWIN_COMPATIBILITY_2
-      bitmap->SetOk(errorStatus == XpmSuccess);
+        bitmap->SetOk(errorStatus == XpmSuccess);
 #endif // WXWIN_COMPATIBILITY_2
 
 #endif // WXWIN_COMPATIBILITY_2
 
-      return bitmap->Ok();
+        return bitmap->Ok();
     }
     }
-#endif
+#endif // wxUSE_XPM_IN_MSW
 
     return FALSE;
 }
 
     return FALSE;
 }
@@ -107,11 +133,9 @@ bool wxXPMFileHandler::SaveFile(wxBitmap *bitmap,
                                 const wxPalette *palette)
 {
 #if wxUSE_XPM_IN_MSW
                                 const wxPalette *palette)
 {
 #if wxUSE_XPM_IN_MSW
-    HDC     dc = NULL;
+    XImage ximage;
 
 
-    XImage  ximage;
-
-    dc = CreateCompatibleDC(NULL);
+    HDC dc = CreateCompatibleDC(NULL);
     if (dc)
     {
         if ( SelectObject(dc, GetHbitmapOf(*bitmap)) )
     if (dc)
     {
         if ( SelectObject(dc, GetHbitmapOf(*bitmap)) )
@@ -132,13 +156,11 @@ bool wxXPMFileHandler::SaveFile(wxBitmap *bitmap,
 
             if (errorStatus == XpmSuccess)
                 return TRUE;    /* no error */
 
             if (errorStatus == XpmSuccess)
                 return TRUE;    /* no error */
-            else
-                return FALSE;
-        } else return FALSE;
-    } else return FALSE;
-#else
+        }
+    }
+#endif // !wxUSE_XPM_IN_MSW
+
     return FALSE;
     return FALSE;
-#endif
 }
 
 IMPLEMENT_DYNAMIC_CLASS(wxXPMDataHandler, wxBitmapHandler)
 }
 
 IMPLEMENT_DYNAMIC_CLASS(wxXPMDataHandler, wxBitmapHandler)
@@ -152,41 +174,35 @@ bool wxXPMDataHandler::Create(wxBitmap *bitmap,
 {
 #if wxUSE_XPM_IN_MSW
   XImage *ximage;
 {
 #if wxUSE_XPM_IN_MSW
   XImage *ximage;
-  int     ErrorStatus;
   XpmAttributes xpmAttr;
   XpmAttributes xpmAttr;
-  HDC     dc;
 
 
-  dc = CreateCompatibleDC(NULL);  /* memory DC */
+  HDC dc = CreateCompatibleDC(NULL);  /* memory DC */
 
   if (dc)
   {
 
   if (dc)
   {
-    xpmAttr.valuemask = XpmReturnInfos; /* get infos back */
-    ErrorStatus = XpmCreateImageFromData(&dc, (char **)data,
-                                         &ximage, (XImage **) NULL, &xpmAttr);
-
-    if (ErrorStatus == XpmSuccess)
-    {
-        XpmToBitmap(bitmap, ximage, xpmAttr);
-
-      XpmFreeAttributes(&xpmAttr);
+      xpmAttr.valuemask = XpmReturnInfos | XpmColorTable;
+      int errorStatus = XpmCreateImageFromData(&dc, (char **)data,
+                                               &ximage,
+                                               (XImage **) NULL,
+                                               &xpmAttr);
+      DeleteDC(dc);
 
 
-      XImageFree(ximage); // releases the malloc, but does not detroy
-                          // the bitmap
-    }
-    else
-    {
-      //    XpmDebugError(ErrorStatus, NULL);
-    }
+      if ( errorStatus == XpmSuccess )
+      {
+          XpmToBitmap(bitmap, ximage, xpmAttr);
 
 
-    DeleteDC(dc);
+          XpmFree(xpmAttr.pixels);
+          XpmFreeAttributes(&xpmAttr);
+          XImageFree(ximage); // releases the malloc, but does not destroy bitmap
+      }
 
 #if WXWIN_COMPATIBILITY_2
       bitmap->SetOk(errorStatus == XpmSuccess);
 #endif // WXWIN_COMPATIBILITY_2
 
 
 #if WXWIN_COMPATIBILITY_2
       bitmap->SetOk(errorStatus == XpmSuccess);
 #endif // WXWIN_COMPATIBILITY_2
 
-    return bitmap->Ok();
+      return bitmap->Ok();
   }
   }
-#endif
+#endif // wxUSE_XPM_IN_MSW
 
   return FALSE;
 }
 
   return FALSE;
 }