From 7509fa8caa43a1327175dd5fa8b7caf6b647e81b Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 15 Mar 2002 23:42:42 +0000 Subject: [PATCH] erase separators shown behind the controls added to the toolbar git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@14623 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 1 + include/wx/msw/tbar95.h | 7 +- src/msw/tbar95.cpp | 209 +++++++++++++++++++++++++++++++--------- 3 files changed, 170 insertions(+), 47 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index bfa4564868..6a1be269f6 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -135,6 +135,7 @@ wxMSW: - showing a dialog from EVT_RADIOBUTTON handler doesn't lead to an infinite recursion any more - wxTextCtrl with wxTE_RICH flag scrolls to the end when text is appended to it +- the separators are not seen behind the controls added to the toolbar any more - wxWindowDC and wxClientDC::GetSize() works correctly now wxGTK: diff --git a/include/wx/msw/tbar95.h b/include/wx/msw/tbar95.h index 01949b91cb..f032a86039 100644 --- a/include/wx/msw/tbar95.h +++ b/include/wx/msw/tbar95.h @@ -92,9 +92,14 @@ protected: // should be called whenever the toolbar size changes void UpdateSize(); - // override WndProc to process WM_SIZE + // override WndProc mainly to process WM_SIZE virtual long MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam); + // handlers for various events + bool HandleSize(WXWPARAM wParam, WXLPARAM lParam); + bool HandlePaint(WXWPARAM wParam, WXLPARAM lParam); + void HandleMouseMove(WXWPARAM wParam, WXLPARAM lParam); + // the big bitmap containing all bitmaps of the toolbar buttons WXHBITMAP m_hBitmap; diff --git a/src/msw/tbar95.cpp b/src/msw/tbar95.cpp index b734360d7b..e0c800a45a 100644 --- a/src/msw/tbar95.cpp +++ b/src/msw/tbar95.cpp @@ -1040,69 +1040,186 @@ 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 ) { - int w, h; + // 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); - if ( GetWindowStyle() & wxTB_VERTICAL ) + // 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() ) + { + // get the control rect in our client coords + wxControl *control = tool->GetControl(); + wxRect rectCtrl = control->GetRect(); + control->ClientToScreen(&rectCtrl.x, &rectCtrl.y); + ScreenToClient(&rectCtrl.x, &rectCtrl.y); + + // 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); -- 2.45.2