diff --git a/include/wx/msw/uxtheme.h b/include/wx/msw/uxtheme.h index 036f8d0d03..b8d5f9612f 100644 --- a/include/wx/msw/uxtheme.h +++ b/include/wx/msw/uxtheme.h @@ -166,7 +166,7 @@ WXDLLIMPEXP_CORE bool wxUxThemeIsActive(); // wxUxThemeHandle: encapsulates ::Open/CloseThemeData() // ---------------------------------------------------------------------------- -class wxUxThemeHandle +class WXDLLIMPEXP_CORE wxUxThemeHandle { public: // For all factory functions, HWND doesn't need to be valid and may be @@ -218,6 +218,11 @@ public: // GetThemeColor() because we want to default the state. wxColour GetColour(int part, int prop, int state = 0) const; + // Draw theme background: if the caller already has a RECT, it can be + // provided directly, otherwise wxRect is converted to it. + void DrawBackground(HDC hdc, const RECT& rc, int part, int state = 0); + void DrawBackground(HDC hdc, const wxRect& rect, int part, int state = 0); + private: static const int STD_DPI = 96; diff --git a/src/aui/barartmsw.cpp b/src/aui/barartmsw.cpp index e9c8f8e82c..ef5029b813 100644 --- a/src/aui/barartmsw.cpp +++ b/src/aui/barartmsw.cpp @@ -77,18 +77,13 @@ void wxAuiMSWToolBarArt::DrawBackground( { if ( m_themed ) { - RECT r; - wxCopyRectToRECT(rect, r); - wxUxThemeHandle hTheme(wnd, L"Rebar"); - ::DrawThemeBackground( - hTheme, + hTheme.DrawBackground( GetHdcOf(dc.GetTempHDC()), - RP_BACKGROUND, - 0, - &r, - nullptr); + rect, + RP_BACKGROUND + ); } else wxAuiGenericToolBarArt::DrawBackground(dc, wnd, rect); @@ -111,9 +106,6 @@ void wxAuiMSWToolBarArt::DrawButton( { if ( m_themed ) { - RECT r; - wxCopyRectToRECT(rect, r); - wxUxThemeHandle hTheme(wnd, L"Toolbar"); int btnState; @@ -131,13 +123,12 @@ void wxAuiMSWToolBarArt::DrawButton( else btnState = TS_NORMAL; - ::DrawThemeBackground( - hTheme, + hTheme.DrawBackground( GetHdcOf(dc.GetTempHDC()), + rect, TP_BUTTON, - btnState, - &r, - nullptr); + btnState + ); int textWidth = 0, textHeight = 0; @@ -237,11 +228,6 @@ void wxAuiMSWToolBarArt::DrawDropDownButton( dc.GetTextExtent(item.GetLabel(), &textWidth, &ty); } - RECT btnR; - wxCopyRectToRECT(buttonRect, btnR); - RECT dropDownR; - wxCopyRectToRECT(dropDownRect, dropDownR); - int btnState; if ( item.GetState() & wxAUI_BUTTON_STATE_DISABLED ) btnState = TS_DISABLED; @@ -252,21 +238,23 @@ void wxAuiMSWToolBarArt::DrawDropDownButton( else btnState = TS_NORMAL; - ::DrawThemeBackground( - hTheme, - GetHdcOf(dc.GetTempHDC()), - TP_SPLITBUTTON, - btnState, - &btnR, - nullptr); + { + auto tempHDC = dc.GetTempHDC(); - ::DrawThemeBackground( - hTheme, - GetHdcOf(dc.GetTempHDC()), + hTheme.DrawBackground( + GetHdcOf(tempHDC), + buttonRect, + TP_SPLITBUTTON, + btnState + ); + + hTheme.DrawBackground( + GetHdcOf(tempHDC), + dropDownRect, TP_SPLITBUTTONDROPDOWN, - btnState, - &dropDownR, - nullptr); + btnState + ); + } // End of tempHDC scope. const wxBitmap& bmp = item.GetCurrentBitmapFor(wnd); if ( !bmp.IsOk() ) @@ -332,18 +320,13 @@ void wxAuiMSWToolBarArt::DrawSeparator( { if ( m_themed ) { - RECT r; - wxCopyRectToRECT(rect, r); - wxUxThemeHandle hTheme(wnd, L"Toolbar"); - ::DrawThemeBackground( - hTheme, + hTheme.DrawBackground( GetHdcOf(dc.GetTempHDC()), - (m_flags & wxAUI_TB_VERTICAL) ? TP_SEPARATORVERT : TP_SEPARATOR, - 0, - &r, - nullptr); + rect, + (m_flags & wxAUI_TB_VERTICAL) ? TP_SEPARATORVERT : TP_SEPARATOR + ); } else wxAuiGenericToolBarArt::DrawSeparator(dc, wnd, rect); @@ -356,18 +339,13 @@ void wxAuiMSWToolBarArt::DrawGripper( { if ( m_themed ) { - RECT r; - wxCopyRectToRECT(rect, r); - wxUxThemeHandle hTheme(wnd, L"Rebar"); - ::DrawThemeBackground( - hTheme, + hTheme.DrawBackground( GetHdcOf(dc.GetTempHDC()), - (m_flags & wxAUI_TB_VERTICAL) ? RP_GRIPPERVERT : RP_GRIPPER, - 0, - &r, - nullptr); + rect, + (m_flags & wxAUI_TB_VERTICAL) ? RP_GRIPPERVERT : RP_GRIPPER + ); } else wxAuiGenericToolBarArt::DrawGripper(dc, wnd, rect); @@ -381,26 +359,22 @@ void wxAuiMSWToolBarArt::DrawOverflowButton( { if ( m_themed ) { - RECT r; - wxCopyRectToRECT(rect, r); - wxUxThemeHandle hTheme(wnd, L"Rebar"); int chevState; if ( state & wxAUI_BUTTON_STATE_PRESSED ) chevState = CHEVS_PRESSED; else if ( state & wxAUI_BUTTON_STATE_HOVER ) - chevState = CHEVS_HOT; + chevState = CHEVS_HOT; else chevState = CHEVS_NORMAL; - ::DrawThemeBackground( - hTheme, + hTheme.DrawBackground( GetHdcOf(dc.GetTempHDC()), + rect, (m_flags & wxAUI_TB_VERTICAL) ? RP_CHEVRONVERT : RP_CHEVRON, - chevState, - &r, - nullptr); + chevState + ); } else wxAuiGenericToolBarArt::DrawOverflowButton(dc, wnd, rect, state); diff --git a/src/aui/tabartmsw.cpp b/src/aui/tabartmsw.cpp index f56b8d1593..0ecc39aa08 100644 --- a/src/aui/tabartmsw.cpp +++ b/src/aui/tabartmsw.cpp @@ -59,18 +59,13 @@ void wxAuiMSWTabArt::DrawBorder(wxDC& dc, wxWindow* wnd, const wxRect& rect) dc.SetPen(wxPen(wnd->GetBackgroundColour(), GetBorderWidth(wnd))); dc.DrawRectangle(topDrawRect); - RECT r; - wxCopyRectToRECT(drawRect, r); - wxUxThemeHandle hTheme(wnd, L"TAB"); - ::DrawThemeBackground( - hTheme, + hTheme.DrawBackground( GetHdcOf(dc.GetTempHDC()), - TABP_PANE, - 0, - &r, - nullptr); + drawRect, + TABP_PANE + ); } void wxAuiMSWTabArt::DrawBackground(wxDC& dc, @@ -99,18 +94,13 @@ void wxAuiMSWTabArt::DrawBackground(wxDC& dc, drawRect.Inflate(1, 0); - RECT r; - wxCopyRectToRECT(drawRect, r); - wxUxThemeHandle hTheme(wnd, L"TAB"); - ::DrawThemeBackground( - hTheme, + hTheme.DrawBackground( GetHdcOf(dc.GetTempHDC()), - TABP_PANE, - 0, - &r, - nullptr); + drawRect, + TABP_PANE + ); } void wxAuiMSWTabArt::DrawTab(wxDC& dc, @@ -175,25 +165,23 @@ void wxAuiMSWTabArt::DrawTab(wxDC& dc, tabState = TIS_NORMAL; wxUxThemeHandle hTabTheme(wnd, L"Tab"); - RECT tabR; - wxCopyRectToRECT(tabRect, tabR); - ::DrawThemeBackground(hTabTheme, GetHdcOf(dc.GetTempHDC()), TABP_TABITEM, - tabState, - &tabR, nullptr); + hTabTheme.DrawBackground( + GetHdcOf(dc.GetTempHDC()), + tabRect, + TABP_TABITEM, + tabState + ); // Apparently, in at least some Windows 10 installations the call above // does not draw the left edge of the first tab and it needs to be drawn // separately, or it wouldn't be drawn at all. if ( tabX == GetIndentSize() ) { - ::DrawThemeBackground - ( - hTabTheme, + hTabTheme.DrawBackground( GetHdcOf(dc.GetTempHDC()), + tabRect, TABP_TABITEMLEFTEDGE, - tabState, - &tabR, - nullptr + tabState ); } @@ -234,9 +222,12 @@ void wxAuiMSWTabArt::DrawTab(wxDC& dc, m_closeBtnSize.x, m_closeBtnSize.y); - RECT btnR; - wxCopyRectToRECT(rect, btnR); - ::DrawThemeBackground(hToolTipTheme, GetHdcOf(dc.GetTempHDC()), TTP_CLOSE, btnState, &btnR, nullptr); + hToolTipTheme.DrawBackground( + GetHdcOf(dc.GetTempHDC()), + rect, + TTP_CLOSE, + btnState + ); if ( out_button_rect ) *out_button_rect = rect; @@ -412,9 +403,12 @@ void wxAuiMSWTabArt::DrawButton(wxDC& dc, wxRect btnRect(rect); btnRect.width -= wnd->FromDIP(1); - RECT btnR; - wxCopyRectToRECT(btnRect, btnR); - ::DrawThemeBackground(hTheme, GetHdcOf(dc.GetTempHDC()), part, btnState, &btnR, nullptr); + hTheme.DrawBackground( + GetHdcOf(dc.GetTempHDC()), + rect, + part, + btnState + ); if ( out_rect ) *out_rect = rect; diff --git a/src/msw/anybutton.cpp b/src/msw/anybutton.cpp index 744482639f..bc8b9f9560 100644 --- a/src/msw/anybutton.cpp +++ b/src/msw/anybutton.cpp @@ -1288,8 +1288,7 @@ void DrawXPBackground(wxAnyButton *button, HDC hdc, RECT& rectBtn, UINT state) } // draw background - ::DrawThemeBackground(theme, hdc, BP_PUSHBUTTON, iState, - &rectBtn, nullptr); + theme.DrawBackground(hdc, rectBtn, BP_PUSHBUTTON, iState); // calculate content area margins, using the defaults in case we fail to // retrieve the current theme margins diff --git a/src/msw/combo.cpp b/src/msw/combo.cpp index 23f0cd4884..5c3dbbb3a0 100644 --- a/src/msw/combo.cpp +++ b/src/msw/combo.cpp @@ -429,7 +429,7 @@ void wxComboCtrl::OnPaintEvent( wxPaintEvent& WXUNUSED(event) ) // Draw the control background (including the border) if ( m_widthCustomBorder > 0 ) { - ::DrawThemeBackground( hTheme, hDc, comboBoxPart, bgState, rUseForBg, nullptr ); + hTheme.DrawBackground(hDc, *rUseForBg, comboBoxPart, bgState); } else { @@ -462,7 +462,7 @@ void wxComboCtrl::OnPaintEvent( wxPaintEvent& WXUNUSED(event) ) else butPart = CP_DROPDOWNBUTTONLEFT; - ::DrawThemeBackground( hTheme, hDc, butPart, butState, &rButton, nullptr ); + hTheme.DrawBackground(hDc, rButton, butPart, butState); } else if ( m_iFlags & wxCC_IFLAG_BUTTON_OUTSIDE ) { diff --git a/src/msw/menuitem.cpp b/src/msw/menuitem.cpp index 1903f2cd01..dd162341de 100644 --- a/src/msw/menuitem.cpp +++ b/src/msw/menuitem.cpp @@ -958,25 +958,19 @@ bool wxMenuItem::OnDrawItem(wxDC& dc, const wxRect& rc, if ( ::IsThemeBackgroundPartiallyTransparent(hTheme, MENU_POPUPITEM, state) ) { - ::DrawThemeBackground(hTheme, hdc, - MENU_POPUPBACKGROUND, - 0, &rect, nullptr); + hTheme.DrawBackground(hdc, rect, MENU_POPUPBACKGROUND); } - ::DrawThemeBackground(hTheme, hdc, MENU_POPUPGUTTER, - 0, &rcGutter, nullptr); + hTheme.DrawBackground(hdc, rcGutter, MENU_POPUPGUTTER); if ( IsSeparator() ) { rcSeparator.left = rcGutter.right; - ::DrawThemeBackground(hTheme, hdc, MENU_POPUPSEPARATOR, - 0, &rcSeparator, nullptr); + hTheme.DrawBackground(hdc, rcSeparator, MENU_POPUPSEPARATOR); return true; } - ::DrawThemeBackground(hTheme, hdc, MENU_POPUPITEM, - state, &rcSelection, nullptr); - + hTheme.DrawBackground(hdc, rcSelection, MENU_POPUPITEM, state); } else #endif // wxUSE_UXTHEME @@ -1192,8 +1186,7 @@ void wxMenuItem::DrawStdCheckMark(WXHDC hdc_, const RECT* rc, wxODStatus stat) ? MCB_DISABLED : MCB_NORMAL; - ::DrawThemeBackground(hTheme, hdc, MENU_POPUPCHECKBACKGROUND, - stateCheckBg, &rcBg, nullptr); + hTheme.DrawBackground(hdc, rcBg, MENU_POPUPCHECKBACKGROUND, stateCheckBg); POPUPCHECKSTATES stateCheck; if ( GetKind() == wxITEM_CHECK ) @@ -1207,8 +1200,7 @@ void wxMenuItem::DrawStdCheckMark(WXHDC hdc_, const RECT* rc, wxODStatus stat) : MC_BULLETNORMAL; } - ::DrawThemeBackground(hTheme, hdc, MENU_POPUPCHECK, - stateCheck, rc, nullptr); + hTheme.DrawBackground(hdc, *rc, MENU_POPUPCHECK, stateCheck); } else #endif // wxUSE_UXTHEME diff --git a/src/msw/notebook.cpp b/src/msw/notebook.cpp index 131f7c212f..a711cffd9b 100644 --- a/src/msw/notebook.cpp +++ b/src/msw/notebook.cpp @@ -1674,15 +1674,7 @@ WXHBRUSH wxNotebook::QueryBgBitmap() { SelectInHDC selectBmp(hDCMem, hBmp); - ::DrawThemeBackground - ( - theme, - hDCMem, - 9 /* TABP_PANE */, - 0, - &rc, - nullptr - ); + theme.DrawBackground(hDCMem, rc, 9 /* TABP_PANE */); } // deselect bitmap from the memory HDC before using it return (WXHBRUSH)::CreatePatternBrush(hBmp); @@ -1743,15 +1735,8 @@ bool wxNotebook::MSWPrintChild(WXHDC hDC, wxWindow *child) &rc, &rc ); - ::DrawThemeBackground - ( - theme, - (HDC) hDC, - 9 /* TABP_PANE */, - 0, - &rc, - nullptr - ); + + theme.DrawBackground((HDC) hDC, rc, 9 /* TABP_PANE */); return true; } } diff --git a/src/msw/renderer.cpp b/src/msw/renderer.cpp index 7a95ca16cd..cf84d9f0cd 100644 --- a/src/msw/renderer.cpp +++ b/src/msw/renderer.cpp @@ -300,7 +300,7 @@ private: // wrapper around DrawThemeBackground() translating flags to NORMAL/HOT/ // PUSHED/DISABLED states (and so suitable for drawing anything // button-like) - void DoDrawButtonLike(HTHEME htheme, + void DoDrawButtonLike(wxUxThemeHandle& hTheme, int part, wxDC& dc, const wxRect& rect, @@ -644,16 +644,7 @@ wxRendererXP::DrawComboBoxDropButton(wxWindow * win, else state = CBXS_NORMAL; - ::DrawThemeBackground - ( - hTheme, - GetHdcOf(dc.GetTempHDC()), - CP_DROPDOWNBUTTON, - state, - &r, - nullptr - ); - + hTheme.DrawBackground(GetHdcOf(dc.GetTempHDC()), r, CP_DROPDOWNBUTTON, state); } int @@ -681,15 +672,8 @@ wxRendererXP::DrawHeaderButton(wxWindow *win, state = HIS_HOT; else state = HIS_NORMAL; - ::DrawThemeBackground - ( - hTheme, - GetHdcOf(dc.GetTempHDC()), - HP_HEADERITEM, - state, - &r, - nullptr - ); + + hTheme.DrawBackground(GetHdcOf(dc.GetTempHDC()), r, HP_HEADERITEM, state); // NOTE: Using the theme to draw HP_HEADERSORTARROW doesn't do anything. // Why? If this can be fixed then draw the sort arrows using the theme @@ -718,15 +702,8 @@ wxRendererXP::DrawTreeItemButton(wxWindow *win, RECT r = ConvertToRECT(dc, rect); int state = flags & wxCONTROL_EXPANDED ? GLPS_OPENED : GLPS_CLOSED; - ::DrawThemeBackground - ( - hTheme, - GetHdcOf(dc.GetTempHDC()), - TVP_GLYPH, - state, - &r, - nullptr - ); + + hTheme.DrawBackground(GetHdcOf(dc.GetTempHDC()), r, TVP_GLYPH, state); } bool @@ -764,21 +741,13 @@ wxRendererXP::DoDrawCheckMark(int kind, if ( flags & wxCONTROL_DISABLED ) state = MC_CHECKMARKDISABLED; - ::DrawThemeBackground - ( - hTheme, - GetHdcOf(dc.GetTempHDC()), - kind, - state, - &r, - nullptr - ); + hTheme.DrawBackground(GetHdcOf(dc.GetTempHDC()), r, kind, state); return true; } void -wxRendererXP::DoDrawButtonLike(HTHEME htheme, +wxRendererXP::DoDrawButtonLike(wxUxThemeHandle& hTheme, int part, wxDC& dc, const wxRect& rect, @@ -820,15 +789,7 @@ wxRendererXP::DoDrawButtonLike(HTHEME htheme, else if ( part == BP_PUSHBUTTON && (flags & wxCONTROL_ISDEFAULT) ) state = PBS_DEFAULTED; - ::DrawThemeBackground - ( - htheme, - GetHdcOf(dc.GetTempHDC()), - part, - state, - &r, - nullptr - ); + hTheme.DrawBackground(GetHdcOf(dc.GetTempHDC()), r, part, state); } void @@ -948,15 +909,8 @@ DoDrawCollapseButton(wxWindow* win, HDC hdc, RECT r, int flags) if ( flags & wxCONTROL_EXPANDED ) state += 3; - ::DrawThemeBackground - ( - hTheme, - hdc, - TDLG_EXPANDOBUTTON, - state, - &r, - nullptr - ); + hTheme.DrawBackground(hdc, r, TDLG_EXPANDOBUTTON, state); + return true; } @@ -1046,7 +1000,7 @@ wxRendererXP::DrawItemSelectionRect(wxWindow *win, if ( ::IsThemeBackgroundPartiallyTransparent(hTheme, LVP_LISTITEM, itemState) ) ::DrawThemeParentBackground(GetHwndOf(win), GetHdcOf(dc.GetTempHDC()), &rc); - ::DrawThemeBackground(hTheme, GetHdcOf(dc.GetTempHDC()), LVP_LISTITEM, itemState, &rc, 0); + hTheme.DrawBackground(GetHdcOf(dc.GetTempHDC()), rc, LVP_LISTITEM, itemState); } else { @@ -1292,13 +1246,11 @@ void wxRendererXP::DrawGauge(wxWindow* win, RECT r = ConvertToRECT(dc, rect); - ::DrawThemeBackground( - hTheme, + hTheme.DrawBackground( GetHdcOf(dc.GetTempHDC()), - flags & wxCONTROL_SPECIAL ? PP_BARVERT : PP_BAR, - 0, - &r, - nullptr); + r, + flags & wxCONTROL_SPECIAL ? PP_BARVERT : PP_BAR + ); RECT contentRect; ::GetThemeBackgroundContentRect( @@ -1325,13 +1277,11 @@ void wxRendererXP::DrawGauge(wxWindow* win, max); } - ::DrawThemeBackground( - hTheme, + hTheme.DrawBackground( GetHdcOf(dc.GetTempHDC()), - flags & wxCONTROL_SPECIAL ? PP_CHUNKVERT : PP_CHUNK, - 0, - &contentRect, - nullptr); + contentRect, + flags & wxCONTROL_SPECIAL ? PP_CHUNKVERT : PP_CHUNK + ); } // ---------------------------------------------------------------------------- diff --git a/src/msw/uxtheme.cpp b/src/msw/uxtheme.cpp index 5428439020..7dc36f4e5d 100644 --- a/src/msw/uxtheme.cpp +++ b/src/msw/uxtheme.cpp @@ -82,6 +82,29 @@ wxColour wxUxThemeHandle::GetColour(int part, int prop, int state) const return wxRGBToColour(col); } + +void +wxUxThemeHandle::DrawBackground(HDC hdc, const RECT& rc, int part, int state) +{ + HRESULT hr = ::DrawThemeBackground(m_hTheme, hdc, part, state, &rc, nullptr); + if ( FAILED(hr) ) + { + wxLogApiError( + wxString::Format("DrawThemeBackground(%i, %i)", part, state), + hr + ); + } +} + +void +wxUxThemeHandle::DrawBackground(HDC hdc, const wxRect& rect, int part, int state) +{ + RECT rc; + wxCopyRectToRECT(rect, rc); + + DrawBackground(hdc, rc, part, state); +} + #else bool wxUxThemeIsActive() { diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 45a199c030..e1cabfe8e7 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -3970,7 +3970,7 @@ wxWindowMSW::MSWHandleMessage(WXLRESULT *result, } // Draw the border - ::DrawThemeBackground(hTheme, GetHdcOf(*impl), EP_EDITTEXT, nState, &rcBorder, nullptr); + hTheme.DrawBackground(GetHdcOf(*impl), rcBorder, EP_EDITTEXT, nState); } } break;