X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/0f767c96b244a7b37ac67c6e7e9bff17e50c28a9..0bd2681966523df88ad5cf8e505b532843e58d74:/src/msw/tbar95.cpp diff --git a/src/msw/tbar95.cpp b/src/msw/tbar95.cpp index eae78ec579..7966a6cd19 100644 --- a/src/msw/tbar95.cpp +++ b/src/msw/tbar95.cpp @@ -258,7 +258,7 @@ void wxToolBar::Init() m_defaultWidth = DEFAULTBITMAPX; m_defaultHeight = DEFAULTBITMAPY; - m_pInTool = 0; + m_pInTool = NULL; } bool wxToolBar::Create(wxWindow *parent, @@ -303,6 +303,11 @@ bool wxToolBar::MSWCreateToolbar(const wxPoint& pos, const wxSize& size) // toolbar-specific post initialisation ::SendMessage(GetHwnd(), TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0); +#ifdef TB_SETEXTENDEDSTYLE + if ( wxApp::GetComCtl32Version() >= 471 ) + ::SendMessage(GetHwnd(), TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_DRAWDDARROWS); +#endif + return true; } @@ -400,6 +405,17 @@ wxSize wxToolBar::DoGetBestSize() const sizeBest.y = size.cy; } + if (!IsVertical()) + { + // Without the extra height, DoGetBestSize can report a size that's + // smaller than the actual window, causing windows to overlap slightly + // in some circumstances, leading to missing borders (especially noticeable + // in AUI layouts). + if (!(GetWindowStyle() & wxTB_NODIVIDER)) + sizeBest.y += 2; + sizeBest.y ++; + } + CacheBestSize(sizeBest); return sizeBest; @@ -924,7 +940,7 @@ bool wxToolBar::Realize() DoToggleTool(tool, true); } } - else if (tool->IsToggled()) + else if ( tool->IsToggled() ) { wxToolBarToolsList::compatibility_iterator nodePrev = node->GetPrevious(); int prevIndex = i - 1; @@ -938,7 +954,7 @@ bool wxToolBar::Realize() if ( tool->Toggle(false) ) DoToggleTool(tool, false); - prevButton.fsState = TBSTATE_ENABLED; + prevButton.fsState &= TBSTATE_CHECKED; nodePrev = nodePrev->GetPrevious(); prevIndex--; } @@ -955,6 +971,10 @@ bool wxToolBar::Realize() button.fsStyle = TBSTYLE_BUTTON; break; + case wxITEM_DROPDOWN: + button.fsStyle = TBSTYLE_DROPDOWN; + break; + default: wxFAIL_MSG( _T("unexpected toolbar button kind") ); button.fsStyle = TBSTYLE_BUTTON; @@ -1197,11 +1217,38 @@ bool wxToolBar::MSWOnNotify(int WXUNUSED(idCtrl), WXLPARAM lParam, WXLPARAM *WXUNUSED(result)) { + LPNMHDR hdr = (LPNMHDR)lParam; + if ( hdr->code == TBN_DROPDOWN ) + { + LPNMTOOLBAR tbhdr = (LPNMTOOLBAR)lParam; + + wxCommandEvent evt(wxEVT_COMMAND_TOOL_DROPDOWN_CLICKED, tbhdr->iItem); + if ( GetEventHandler()->ProcessEvent(evt) ) + { + // Event got handled, don't display default popup menu + return false; + } + + const wxToolBarToolBase * const tool = FindById(tbhdr->iItem); + wxCHECK_MSG( tool, false, _T("drop down message for unknown tool") ); + + wxMenu * const menu = tool->GetDropdownMenu(); + if ( !menu ) + return false; + + // Display popup menu below button + RECT r; + if (::SendMessage(GetHwnd(), TB_GETITEMRECT, GetToolPos(tbhdr->iItem), (LPARAM)&r)) + PopupMenu(menu, r.left, r.bottom); + + return true; + } + + if( !HasFlag(wxTB_NO_TOOLTIPS) ) { #if wxUSE_TOOLTIPS // First check if this applies to us - NMHDR *hdr = (NMHDR *)lParam; // the tooltips control created by the toolbar is sometimes Unicode, even // in an ANSI application - this seems to be a bug in comctl32.dll v5 @@ -1452,9 +1499,14 @@ void wxToolBar::OnSysColourChanged(wxSysColourChangedEvent& event) void wxToolBar::OnMouseEvent(wxMouseEvent& event) { - if (event.Leaving() && m_pInTool) + if ( event.Leaving() ) { - OnMouseEnter( -1 ); + if ( m_pInTool ) + { + OnMouseEnter(wxID_ANY); + m_pInTool = NULL; + } + event.Skip(); return; } @@ -1481,6 +1533,9 @@ void wxToolBar::OnEraseBackground(wxEraseEvent& event) RECT rect = wxGetClientRect(GetHwnd()); HDC hdc = GetHdcOf((*event.GetDC())); + int majorVersion, minorVersion; + wxGetOsVersion(& majorVersion, & minorVersion); + #if wxUSE_UXTHEME // we may need to draw themed colour so that we appear correctly on // e.g. notebook page under XP with themes but only do it if the parent @@ -1501,6 +1556,30 @@ void wxToolBar::OnEraseBackground(wxEraseEvent& event) wxLogApiError(_T("DrawThemeParentBackground(toolbar)"), hr); } } + + // Only draw a rebar theme on Vista, since it doesn't jive so well with XP + if ( !UseBgCol() && majorVersion >= 6 ) + { + wxUxThemeEngine *theme = wxUxThemeEngine::GetIfActive(); + if ( theme ) + { + wxUxThemeHandle hTheme(this, L"REBAR"); + + RECT r; + wxRect rect = GetClientRect(); + wxCopyRectToRECT(rect, r); + + HRESULT hr = theme->DrawThemeBackground(hTheme, hdc, 0, 0, & r, NULL); + if ( hr == S_OK ) + return; + + // it can also return S_FALSE which seems to simply say that it + // didn't draw anything but no error really occurred + if ( FAILED(hr) ) + wxLogApiError(_T("DrawThemeParentBackground(toolbar)"), hr); + } + } + #endif // wxUSE_UXTHEME if ( UseBgCol() || (GetMSWToolbarStyle() & TBSTYLE_TRANSPARENT) ) @@ -1585,6 +1664,10 @@ bool wxToolBar::HandlePaint(WXWPARAM wParam, WXLPARAM lParam) // no controls, nothing to erase return false; + wxSize clientSize = GetClientSize(); + int majorVersion, minorVersion; + wxGetOsVersion(& majorVersion, & minorVersion); + // prepare the DC on which we'll be drawing wxClientDC dc(this); dc.SetBrush(wxBrush(GetBackgroundColour(), wxSOLID)); @@ -1654,20 +1737,53 @@ bool wxToolBar::HandlePaint(WXWPARAM wParam, WXLPARAM lParam) // does it intersect the control? wxRect rectItem; wxCopyRECTToRect(r, rectItem); - if ( rectCtrl.Intersects(rectItem) ) + if ( rectCtrl.Intersects(rectItem) || (staticText && rectStaticText.Intersects(rectItem))) { // yes, do erase it! - dc.DrawRectangle(rectItem); + bool haveRefreshed = false; + +#if wxUSE_UXTHEME + if ( !UseBgCol() && !GetParent()->UseBgCol() ) + { + // Don't use DrawThemeBackground + } + else if ( !UseBgCol() && majorVersion >= 6 ) + { + wxUxThemeEngine *theme = wxUxThemeEngine::GetIfActive(); + if ( theme ) + { + wxUxThemeHandle hTheme(this, L"REBAR"); + + RECT clipRect = r; + + // Draw the whole background since the pattern may be position sensitive; + // but clip it to the area of interest. + r.left = 0; + r.right = clientSize.x; + r.top = 0; + r.bottom = clientSize.y; + + HRESULT hr = theme->DrawThemeBackground(hTheme, (HDC) dc.GetHDC(), 0, 0, & r, & clipRect); + if ( hr == S_OK ) + haveRefreshed = true; + } + } +#endif + + if (!haveRefreshed) + dc.DrawRectangle(rectItem); + } + + if ( rectCtrl.Intersects(rectItem) ) + { // Necessary in case we use a no-paint-on-size // style in the parent: the controls can disappear control->Refresh(false); - } + } + if ( staticText && rectStaticText.Intersects(rectItem) ) { - // yes, do erase it! - dc.DrawRectangle(rectItem); - // Necessary in case we use a no-paint-on-size // style in the parent: the controls can disappear staticText->Refresh(false); @@ -1685,18 +1801,11 @@ void wxToolBar::HandleMouseMove(WXWPARAM WXUNUSED(wParam), WXLPARAM lParam) y = GET_Y_LPARAM(lParam); wxToolBarToolBase* tool = FindToolForPosition( x, y ); - // cursor left current tool - if ( tool != m_pInTool && !tool ) - { - m_pInTool = 0; - OnMouseEnter( -1 ); - } - - // cursor entered a tool - if ( tool != m_pInTool && tool ) + // has the current tool changed? + if ( tool != m_pInTool ) { m_pInTool = tool; - OnMouseEnter( tool->GetId() ); + OnMouseEnter(tool ? tool->GetId() : wxID_ANY); } }