]> git.saurik.com Git - wxWidgets.git/commitdiff
0. extracted toolbar colour mapping stuff to its own function
authorVadim Zeitlin <vadim@wxwidgets.org>
Sun, 13 Jan 2002 23:04:11 +0000 (23:04 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sun, 13 Jan 2002 23:04:11 +0000 (23:04 +0000)
1. wxToolBar adjusts the colours properly when the system colours change
2. wxImageList uses light grey as the transparent colour for the bitmaps

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

docs/changes.txt
include/wx/msw/colours.bmp
include/wx/msw/private.h
src/msw/imaglist.cpp
src/msw/tbar95.cpp
src/msw/window.cpp

index 17af5d58870b9873c57827574de6001d3d80189c..afa2e6179af0de3f6312d6f89354dedc0d7b8546 100644 (file)
@@ -86,6 +86,8 @@ wxMSW:
 - huge (40*) speed up in wxMask::Create() (=> much faster toolbar creation)
 - fixed flicker in wxTreeCtrl::SetItemXXX()
 - fixed redraw problems in dynamically resized wxStaticText
 - huge (40*) speed up in wxMask::Create() (=> much faster toolbar creation)
 - fixed flicker in wxTreeCtrl::SetItemXXX()
 - fixed redraw problems in dynamically resized wxStaticText
+- improvements to wxWindows applications behaviour when the system colours
+  are changed
 - fixed wxProgressDialog for ranges > 65535
 - wxFontEnumerator now returns all fonts, not only TrueType ones
 - wxTextCtrl with wxTE_RICH flag scrolls to the end when text is appended to it
 - fixed wxProgressDialog for ranges > 65535
 - wxFontEnumerator now returns all fonts, not only TrueType ones
 - wxTextCtrl with wxTE_RICH flag scrolls to the end when text is appended to it
index 62d1f8045fecec3f0b54c57c0e885b4d6e464624..7d391ad144a486bc3b54dc00e0f19624cf4fc6b3 100644 (file)
Binary files a/include/wx/msw/colours.bmp and b/include/wx/msw/colours.bmp differ
index e61c66cc7cfd551d74f776031fb437e7246ac5f4..67bf32de92d5c9069bf642ac266d0876c6eaa7d6 100644 (file)
@@ -212,6 +212,31 @@ inline void wxRGBToColour(wxColour& c, COLORREF rgb)
     c.Set(GetRValue(rgb), GetGValue(rgb), GetBValue(rgb));
 }
 
     c.Set(GetRValue(rgb), GetGValue(rgb), GetBValue(rgb));
 }
 
+// get the standard colour map for some standard colours - see comment in this
+// function to understand why is it needed and when should it be used
+//
+// it returns a wxCOLORMAP (can't use COLORMAP itself here as comctl32.dll
+// might be not included/available) array of size wxSTD_COLOUR_MAX
+//
+// NB: if you change these colours, update wxBITMAP_STD_COLOURS in the
+//     resources as well: it must have the same number of pixels!
+enum wxSTD_COLOUR
+{
+    wxSTD_COL_BTNTEXT,
+    wxSTD_COL_BTNSHADOW,
+    wxSTD_COL_BTNFACE,
+    wxSTD_COL_BTNHIGHLIGHT,
+    wxSTD_COL_MAX,
+};
+
+struct WXDLLEXPORT wxCOLORMAP
+{
+    COLORREF from, to;
+};
+
+// this function is implemented in src/msw/window.cpp
+extern wxCOLORMAP *wxGetStdColourMap();
+
 // copy Windows RECT to our wxRect
 inline void wxCopyRECTToRect(const RECT& r, wxRect& rect)
 {
 // copy Windows RECT to our wxRect
 inline void wxCopyRECTToRect(const RECT& r, wxRect& rect)
 {
index 5140135aebb0edbfa60d7c9eb6b72d905a83e9e1..46cb341d1252fa74c183098af3fc1d90e148e4b5 100644 (file)
@@ -315,37 +315,41 @@ bool wxImageList::Draw(int index,
 static HBITMAP GetMaskForImage(const wxBitmap& bitmap, const wxBitmap& mask)
 {
     HBITMAP hbmpMask;
 static HBITMAP GetMaskForImage(const wxBitmap& bitmap, const wxBitmap& mask)
 {
     HBITMAP hbmpMask;
-    wxBitmap *bmpMask = NULL;
+    wxMask *pMask;
+    bool deleteMask = FALSE;
 
     if ( mask.Ok() )
     {
         hbmpMask = GetHbitmapOf(mask);
 
     if ( mask.Ok() )
     {
         hbmpMask = GetHbitmapOf(mask);
+        pMask = NULL;
     }
     else
     {
     }
     else
     {
-        wxMask *pMask = bitmap.GetMask();
-        if ( pMask )
+        pMask = bitmap.GetMask();
+        if ( !pMask )
         {
         {
-            hbmpMask = (HBITMAP)pMask->GetMaskBitmap();
-        }
-        else
-        {
-            // create a non transparent mask - apparently, this is needed under
-            // Win9x (it doesn't behave correctly if it's passed 0 mask)
-            bmpMask = new wxBitmap(bitmap.GetWidth(), bitmap.GetHeight(), 1);
+            // use the light grey count as transparent: the trouble here is
+            // that the light grey might have been changed by Windows behind
+            // our back, so use the standard colour map to get its real value
+            wxCOLORMAP *cmap = wxGetStdColourMap();
+            wxColour col;
+            wxRGBToColour(col, cmap[wxSTD_COL_BTNFACE].from);
 
 
-            wxMemoryDC dcMem;
-            dcMem.SelectObject(*bmpMask);
-            dcMem.Clear();
-            dcMem.SelectObject(wxNullBitmap);
+            pMask = new wxMask(bitmap, col);
 
 
-            hbmpMask = GetHbitmapOf(*bmpMask);
+            deleteMask = TRUE;
         }
         }
+
+        hbmpMask = (HBITMAP)pMask->GetMaskBitmap();
     }
 
     // windows mask convention is opposite to the wxWindows one
     HBITMAP hbmpMaskInv = wxInvertMask(hbmpMask);
     }
 
     // windows mask convention is opposite to the wxWindows one
     HBITMAP hbmpMaskInv = wxInvertMask(hbmpMask);
-    delete bmpMask;
+
+    if ( deleteMask )
+    {
+        delete pMask;
+    }
 
     return hbmpMaskInv;
 }
 
     return hbmpMaskInv;
 }
index 025fc91265df255608eaa8b218d503087f466508..758426c5a53c6f525d9e2c7c83687c71274d08ec 100644 (file)
@@ -1104,74 +1104,6 @@ long wxToolBar::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
 
 WXHBITMAP wxToolBar::MapBitmap(WXHBITMAP bitmap, int width, int height)
 {
 
 WXHBITMAP wxToolBar::MapBitmap(WXHBITMAP bitmap, int width, int height)
 {
-    // number of the colours we map: if you change this, update
-    // wxBITMAP_STD_COLOURS in the resources as well: it must have the same number
-    // of pixels
-    static const size_t NUM_OF_MAPPED_COLOURS = 4;
-
-    static bool s_coloursInit = FALSE;
-    static long s_stdColours[NUM_OF_MAPPED_COLOURS];
-
-    if (!s_coloursInit)
-    {
-        // When a bitmap is loaded, the RGB values can change (apparently
-        // because Windows adjusts them to care for the old programs always
-        // using 0xc0c0c0 while the transparent colour for the new Windows
-        // versions is different). But we do this adjustment ourselves so we
-        // want to avoid Windows' "help" and for this we need to have a
-        // reference bitmap which can tell us what the RGB values change to.
-        wxBitmap stdColourBitmap(_T("wxBITMAP_STD_COLOURS"));
-        if (stdColourBitmap.Ok())
-        {
-            wxMemoryDC memDC;
-            memDC.SelectObject(stdColourBitmap);
-
-            wxColour colour;
-            for ( size_t i = 0; i < WXSIZEOF(s_stdColours); i++ )
-            {
-                memDC.GetPixel(i, 0, &colour);
-                s_stdColours[i] = wxColourToRGB(colour);
-            }
-        }
-        else
-        {
-            s_stdColours[0] = RGB(000,000,000) ;
-            s_stdColours[1] = RGB(128,128,128) ;
-            s_stdColours[2] = RGB(192,192,192) ;
-            s_stdColours[3] = RGB(255,255,255) ;
-            //s_stdColours[4] = RGB(000,000,255) ;
-            //s_stdColours[5] = RGB(255,000,255) ;
-        }
-
-        s_coloursInit = TRUE;
-    }
-
-    COLORMAP ColorMap[NUM_OF_MAPPED_COLOURS];
-
-    // black        (0, 0 0)
-    ColorMap[0].from = s_stdColours[0];
-    ColorMap[0].to = COLOR_BTNTEXT;
-    // dark grey    (128, 128, 128)
-    ColorMap[1].from = s_stdColours[1];
-    ColorMap[1].to = COLOR_BTNSHADOW;
-    // bright grey  (192, 192, 192)
-    ColorMap[2].from = s_stdColours[2];
-    ColorMap[2].to = COLOR_BTNFACE;
-    // white        (255, 255, 255)
-    ColorMap[3].from = s_stdColours[3];
-    ColorMap[3].to = COLOR_BTNHIGHLIGHT;
-    // blue         (0, 0, 255)
-    //  ColorMap[4].from = s_stdColours[4];
-    //  ColorMap[4].to = COLOR_HIGHLIGHT;
-    // magenta      (255, 0, 255)
-    //  ColorMap[4].from = s_stdColours[5];
-    //  ColorMap[4].to = COLOR_WINDOW;
-
-    for ( size_t n = 0; n < WXSIZEOF(ColorMap); n++ )
-    {
-        ColorMap[n].to = ::GetSysColor(ColorMap[n].to);
-    }
-
     MemoryHDC hdcMem;
 
     if ( !hdcMem )
     MemoryHDC hdcMem;
 
     if ( !hdcMem )
@@ -1190,20 +1122,22 @@ WXHBITMAP wxToolBar::MapBitmap(WXHBITMAP bitmap, int width, int height)
         return bitmap;
     }
 
         return bitmap;
     }
 
+    wxCOLORMAP *cmap = wxGetStdColourMap();
+
     for ( int i = 0; i < width; i++ )
     {
         for ( int j = 0; j < height; j++ )
         {
             COLORREF pixel = ::GetPixel(hdcMem, i, j);
 
     for ( int i = 0; i < width; i++ )
     {
         for ( int j = 0; j < height; j++ )
         {
             COLORREF pixel = ::GetPixel(hdcMem, i, j);
 
-            for ( size_t k = 0; k < WXSIZEOF(ColorMap); k++ )
+            for ( size_t k = 0; k < wxSTD_COL_MAX; k++ )
             {
             {
-                COLORREF col = ColorMap[k].from;
+                COLORREF col = cmap[k].from;
                 if ( abs(GetRValue(pixel) - GetRValue(col)) < 10 &&
                      abs(GetGValue(pixel) - GetGValue(col)) < 10 &&
                      abs(GetBValue(pixel) - GetBValue(col)) < 10 )
                 {
                 if ( abs(GetRValue(pixel) - GetRValue(col)) < 10 &&
                      abs(GetGValue(pixel) - GetGValue(col)) < 10 &&
                      abs(GetBValue(pixel) - GetBValue(col)) < 10 )
                 {
-                    ::SetPixel(hdcMem, i, j, ColorMap[k].to);
+                    ::SetPixel(hdcMem, i, j, cmap[k].to);
                     break;
                 }
             }
                     break;
                 }
             }
index 733c8c7824d2d3c5bc6630bb1c51ab1f4084c154..ea58c880b23e2cbe9eadcc932a63165f89303c68 100644 (file)
 // global variables
 // ---------------------------------------------------------------------------
 
 // global variables
 // ---------------------------------------------------------------------------
 
-// the last Windows message we got (MT-UNSAFE)
+// the last Windows message we got (FIXME-MT)
 extern MSG s_currentMsg;
 
 #if wxUSE_MENUS_NATIVE
 extern MSG s_currentMsg;
 
 #if wxUSE_MENUS_NATIVE
@@ -131,6 +131,10 @@ wxMenu *wxCurrentPopupMenu = NULL;
 
 extern const wxChar *wxCanvasClassName;
 
 
 extern const wxChar *wxCanvasClassName;
 
+// true if we had already created the std colour map, used by
+// wxGetStdColourMap() and wxWindow::OnSysColourChanged()           (FIXME-MT)
+static bool gs_hasStdCmap = FALSE;
+
 // ---------------------------------------------------------------------------
 // private functions
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 // private functions
 // ---------------------------------------------------------------------------
@@ -2493,8 +2497,8 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam
             break;
 #endif // !__WXMICROWIN__
 
             break;
 #endif // !__WXMICROWIN__
 
-            // the return value for this message is ignored
         case WM_SYSCOLORCHANGE:
         case WM_SYSCOLORCHANGE:
+            // the return value for this message is ignored
             processed = HandleSysColorChange();
             break;
 
             processed = HandleSysColorChange();
             break;
 
@@ -3350,6 +3354,14 @@ bool wxWindowMSW::HandleQueryNewPalette()
 // Responds to colour changes: passes event on to children.
 void wxWindowMSW::OnSysColourChanged(wxSysColourChangedEvent& event)
 {
 // Responds to colour changes: passes event on to children.
 void wxWindowMSW::OnSysColourChanged(wxSysColourChangedEvent& event)
 {
+    // the top level window also reset the standard colour map as it might have
+    // changed (there is no need to do it for the non top level windows as we
+    // only have to do it once)
+    if ( IsTopLevel() )
+    {
+        // FIXME-MT
+        gs_hasStdCmap = FALSE;
+    }
     wxWindowList::Node *node = GetChildren().GetFirst();
     while ( node )
     {
     wxWindowList::Node *node = GetChildren().GetFirst();
     while ( node )
     {
@@ -3382,6 +3394,72 @@ void wxWindowMSW::OnSysColourChanged(wxSysColourChangedEvent& event)
     }
 }
 
     }
 }
 
+extern wxCOLORMAP *wxGetStdColourMap()
+{
+    static COLORREF s_stdColours[wxSTD_COL_MAX];
+    static wxCOLORMAP s_cmap[wxSTD_COL_MAX];
+
+    if ( !gs_hasStdCmap )
+    {
+        static bool s_coloursInit = FALSE;
+
+        if ( !s_coloursInit )
+        {
+            // When a bitmap is loaded, the RGB values can change (apparently
+            // because Windows adjusts them to care for the old programs always
+            // using 0xc0c0c0 while the transparent colour for the new Windows
+            // versions is different). But we do this adjustment ourselves so
+            // we want to avoid Windows' "help" and for this we need to have a
+            // reference bitmap which can tell us what the RGB values change
+            // to.
+            wxBitmap stdColourBitmap(_T("wxBITMAP_STD_COLOURS"));
+            if ( stdColourBitmap.Ok() )
+            {
+                // the pixels in the bitmap must correspond to wxSTD_COL_XXX!
+                wxASSERT_MSG( stdColourBitmap.GetWidth() == wxSTD_COL_MAX,
+                              _T("forgot to update wxBITMAP_STD_COLOURS!") );
+
+                wxMemoryDC memDC;
+                memDC.SelectObject(stdColourBitmap);
+
+                wxColour colour;
+                for ( size_t i = 0; i < WXSIZEOF(s_stdColours); i++ )
+                {
+                    memDC.GetPixel(i, 0, &colour);
+                    s_stdColours[i] = wxColourToRGB(colour);
+                }
+            }
+            else // wxBITMAP_STD_COLOURS couldn't be loaded
+            {
+                s_stdColours[0] = RGB(000,000,000);     // black
+                s_stdColours[1] = RGB(128,128,128);     // dark grey
+                s_stdColours[2] = RGB(192,192,192);     // light grey
+                s_stdColours[3] = RGB(255,255,255);     // white
+                //s_stdColours[4] = RGB(000,000,255);     // blue
+                //s_stdColours[5] = RGB(255,000,255);     // magenta
+            }
+
+            s_coloursInit = TRUE;
+        }
+
+        gs_hasStdCmap = TRUE;
+
+        // create the colour map
+#define INIT_CMAP_ENTRY(col) \
+            s_cmap[wxSTD_COL_##col].from = s_stdColours[wxSTD_COL_##col]; \
+            s_cmap[wxSTD_COL_##col].to = ::GetSysColor(COLOR_##col)
+
+        INIT_CMAP_ENTRY(BTNTEXT);
+        INIT_CMAP_ENTRY(BTNSHADOW);
+        INIT_CMAP_ENTRY(BTNFACE);
+        INIT_CMAP_ENTRY(BTNHIGHLIGHT);
+
+#undef INIT_CMAP_ENTRY
+    }
+
+    return s_cmap;
+}
+
 // ---------------------------------------------------------------------------
 // painting
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 // painting
 // ---------------------------------------------------------------------------