]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/tbar95.cpp
let the popup listbox process the kbd messages in wxComboBox
[wxWidgets.git] / src / msw / tbar95.cpp
index 758426c5a53c6f525d9e2c7c83687c71274d08ec..fe3e60ea8e730803bdc00a39e252f650eaf3c943 100644 (file)
@@ -36,6 +36,7 @@
     #include "wx/settings.h"
     #include "wx/bitmap.h"
     #include "wx/dcmemory.h"
+    #include "wx/control.h"
 #endif
 
 #if wxUSE_TOOLBAR && defined(__WIN95__) && wxUSE_TOOLBAR_NATIVE
 #ifndef TBSTYLE_FLAT
     #define TBSTYLE_LIST            0x1000
     #define TBSTYLE_FLAT            0x0800
+#endif
+
+#ifndef TBSTYLE_TRANSPARENT
     #define TBSTYLE_TRANSPARENT     0x8000
 #endif
- // use TBSTYLE_TRANSPARENT if you use TBSTYLE_FLAT
 
 // Messages
 #ifndef TB_GETSTYLE
@@ -232,8 +235,17 @@ bool wxToolBar::Create(wxWindow *parent,
 
     if (style & wxTB_FLAT)
     {
-        if (wxTheApp->GetComCtl32Version() > 400)
-            msflags |= TBSTYLE_FLAT;
+        // static as it doesn't change during the program lifetime
+        static int s_verComCtl = wxTheApp->GetComCtl32Version();
+
+        // comctl32.dll 4.00 doesn't support the flat toolbars and using this
+        // style with 6.00 (part of Windows XP) leads to the toolbar with
+        // incorrect background colour - and not using it still results in the
+        // correct (flat) toolbar, so don't use it there
+        if ( s_verComCtl > 400 && s_verComCtl < 600 )
+        {
+            msflags |= TBSTYLE_FLAT | TBSTYLE_TRANSPARENT;
+        }
     }
 
     // MSW-specific initialisation
@@ -244,9 +256,7 @@ bool wxToolBar::Create(wxWindow *parent,
     ::SendMessage(GetHwnd(), TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
 
     // set up the colors and fonts
-    wxRGBToColour(m_backgroundColour, GetSysColor(COLOR_BTNFACE));
-    m_foregroundColour = *wxBLACK;
-
+    SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_MENUBAR));
     SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
 
     // position it
@@ -438,12 +448,12 @@ bool wxToolBar::Realize()
         wxToolBarToolBase *tool = node->GetData();
         if ( tool->IsButton() )
         {
-            const wxBitmap& bmp = tool->GetBitmap1();
+            const wxBitmap& bmp = tool->GetNormalBitmap();
             if ( bmp.Ok() )
             {
 #if USE_BITMAP_MASKS
                 // notice the last parameter: do use mask
-                dcAllButtons.DrawBitmap(tool->GetBitmap1(), x, 0, TRUE);
+                dcAllButtons.DrawBitmap(bmp, x, 0, TRUE);
 #else // !USE_BITMAP_MASKS
                 HBITMAP hbmp = GetHbitmapOf(bmp);
                 HBITMAP oldBitmap2 = (HBITMAP)::SelectObject(memoryDC2, hbmp);
@@ -1030,69 +1040,184 @@ void wxToolBar::OnMouseEvent(wxMouseEvent& event)
     }
 }
 
-long wxToolBar::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
+bool wxToolBar::HandleSize(WXWPARAM wParam, WXLPARAM lParam)
 {
-    if ( nMsg == WM_SIZE )
+    // calculate our minor dimenstion ourselves - we're confusing the standard
+    // logic (TB_AUTOSIZE) with our horizontal toolbars and other hacks
+    RECT r;
+    if ( ::SendMessage(GetHwnd(), TB_GETITEMRECT, 0, (LPARAM)&r) )
     {
-        // calculate our minor dimenstion ourselves - we're confusing the
-        // standard logic (TB_AUTOSIZE) with our horizontal toolbars and other
-        // hacks
-        RECT r;
-        if ( ::SendMessage(GetHwnd(), TB_GETITEMRECT, 0, (LPARAM)&r) )
+        int w, h;
+
+        if ( GetWindowStyle() & wxTB_VERTICAL )
+        {
+            w = r.right - r.left;
+            if ( m_maxRows )
+            {
+                w *= (m_nButtons + m_maxRows - 1)/m_maxRows;
+            }
+            h = HIWORD(lParam);
+        }
+        else
+        {
+            w = LOWORD(lParam);
+            h = r.bottom - r.top;
+            if ( m_maxRows )
+            {
+                // FIXME: 6 is hardcoded separator line height...
+                h += 6;
+                h *= m_maxRows;
+            }
+        }
+
+        if ( MAKELPARAM(w, h) != lParam )
+        {
+            // size really changed
+            SetSize(w, h);
+        }
+
+        // message processed
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+bool wxToolBar::HandlePaint(WXWPARAM wParam, WXLPARAM lParam)
+{
+    // erase any dummy separators which we used for aligning the controls if
+    // any here
+
+    // first of all, do we have any controls at all?
+    wxToolBarToolsList::Node *node;
+    for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
+    {
+        if ( node->GetData()->IsControl() )
+            break;
+    }
+
+    if ( !node )
+    {
+        // no controls, nothing to erase
+        return FALSE;
+    }
+
+    // prepare the DC on which we'll be drawing
+    wxClientDC dc(this);
+    dc.SetBrush(wxBrush(GetBackgroundColour(), wxSOLID));
+    dc.SetPen(*wxTRANSPARENT_PEN);
+
+    RECT r;
+    if ( !GetUpdateRect(GetHwnd(), &r, FALSE) )
+    {
+        // nothing to redraw anyhow
+        return FALSE;
+    }
+
+    wxRect rectUpdate;
+    wxCopyRECTToRect(r, rectUpdate);
+
+    dc.SetClippingRegion(rectUpdate);
+
+    // draw the toolbar tools, separators &c normally
+    wxControl::MSWWindowProc(WM_PAINT, wParam, lParam);
+
+    // for each control in the toolbar find all the separators intersecting it
+    // and erase them
+    //
+    // NB: this is really the only way to do it as we don't know if a separator
+    //     corresponds to a control (i.e. is a dummy one) or a real one
+    //     otherwise
+    for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
+    {
+        wxToolBarToolBase *tool = node->GetData();
+        if ( tool->IsControl() )
         {
-            int w, h;
+            // get the control rect in our client coords
+            wxControl *control = tool->GetControl();
+            wxRect rectCtrl = control->GetRect();
 
-            if ( GetWindowStyle() & wxTB_VERTICAL )
+            // iterate over all buttons
+            TBBUTTON tbb;
+            int count = ::SendMessage(GetHwnd(), TB_BUTTONCOUNT, 0, 0);
+            for ( int n = 0; n < count; n++ )
             {
-                w = r.right - r.left;
-                if ( m_maxRows )
+                // is it a separator?
+                if ( !::SendMessage(GetHwnd(), TB_GETBUTTON,
+                                    n, (LPARAM)&tbb) )
                 {
-                    w *= (m_nButtons + m_maxRows - 1)/m_maxRows;
+                    wxLogDebug(_T("TB_GETBUTTON failed?"));
+
+                    continue;
                 }
-                h = HIWORD(lParam);
-            }
-            else
-            {
-                w = LOWORD(lParam);
-                h = r.bottom - r.top;
-                if ( m_maxRows )
+
+                if ( tbb.fsStyle != TBSTYLE_SEP )
+                    continue;
+
+                // get the bounding rect of the separator
+                RECT r;
+                if ( !::SendMessage(GetHwnd(), TB_GETITEMRECT,
+                                    n, (LPARAM)&r) )
                 {
-                    h += 6; // FIXME: this is the separator line height...
-                    h *= m_maxRows;
+                    wxLogDebug(_T("TB_GETITEMRECT failed?"));
+
+                    continue;
                 }
-            }
 
-            if ( MAKELPARAM(w, h) != lParam )
-            {
-                // size really changed
-                SetSize(w, h);
+                // does it intersect the control?
+                wxRect rectItem;
+                wxCopyRECTToRect(r, rectItem);
+                if ( rectCtrl.Intersects(rectItem) )
+                {
+                    // yes, do erase it!
+                    dc.DrawRectangle(rectItem);
+                }
             }
-
-            // message processed
-            return 0;
         }
     }
-    else if ( nMsg == WM_MOUSEMOVE )
+
+    return TRUE;
+}
+
+void wxToolBar::HandleMouseMove(WXWPARAM wParam, WXLPARAM lParam)
+{
+    wxCoord x = GET_X_LPARAM(lParam),
+            y = GET_Y_LPARAM(lParam);
+    wxToolBarToolBase* tool = FindToolForPosition( x, y );
+
+    // cursor left current tool
+    if( tool != m_pInTool && !tool )
     {
-        wxCoord x = GET_X_LPARAM(lParam), y = GET_Y_LPARAM(lParam);
-        wxToolBarToolBase* tool = FindToolForPosition( x, y );
+        m_pInTool = 0;
+        OnMouseEnter( -1 );
+    }
 
-        // cursor left current tool
-        if( tool != m_pInTool && !tool )
-        {
-            m_pInTool = 0;
-            OnMouseEnter( -1 );
-        }
+    // cursor entered a tool
+    if( tool != m_pInTool && tool )
+    {
+        m_pInTool = tool;
+        OnMouseEnter( tool->GetId() );
+    }
+}
 
-        // cursor entered a tool
-        if( tool != m_pInTool && tool )
-        {
-            m_pInTool = tool;
-            OnMouseEnter( tool->GetId() );
-        }
+long wxToolBar::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
+{
+    switch ( nMsg )
+    {
+        case WM_SIZE:
+            if ( HandleSize(wParam, lParam) )
+                return 0;
+            break;
+
+        case WM_MOUSEMOVE:
+            // we don't handle mouse moves, so always pass the message to
+            // wxControl::MSWWindowProc
+            HandleMouseMove(wParam, lParam);
+            break;
 
-        // we don't handle mouse moves, so fall through
-        // to wxControl::MSWWindowProc
+        case WM_PAINT:
+            if ( HandlePaint(wParam, lParam) )
+                return 0;
     }
 
     return wxControl::MSWWindowProc(nMsg, wParam, lParam);