void wxRendererXP::DrawItemSelectionRect(wxWindow *win, wxDC& dc, const wxRect& rect, int flags) { wxUxThemeHandle hTheme(win, L"LISTVIEW"); const int itemState = GetListItemState(flags); wxUxThemeEngine* const te = wxUxThemeEngine::Get(); if ( te->IsThemePartDefined(hTheme, LVP_LISTITEM, itemState) ) { RECT rc; wxCopyRectToRECT(rect, rc); if ( te->IsThemeBackgroundPartiallyTransparent(hTheme, LVP_LISTITEM, itemState) ) te->DrawThemeParentBackground(GetHwndOf(win), GetHdcOf(dc.GetTempHDC()), &rc); te->DrawThemeBackground(hTheme, GetHdcOf(dc.GetTempHDC()), LVP_LISTITEM, itemState, &rc, 0); } else { m_rendererNative.DrawItemSelectionRect(win, dc, rect, flags); } }
void wxAuiMSWTabArt::InitSizes(wxWindow* wnd, wxDC& dc) { SIZE uxSize; // Borrow close button from tooltip (best fit on various backgrounds) wxUxThemeHandle hTooltipTheme(wnd, L"Tooltip"); ::GetThemePartSize(hTooltipTheme, GetHdcOf(dc.GetTempHDC()), TTP_CLOSE, 0, NULL, TS_TRUE, &uxSize); m_closeBtnSize.Set(uxSize.cx, uxSize.cy); wxUxThemeHandle hTabTheme(wnd, L"Tab"); ::GetThemePartSize(hTabTheme, GetHdcOf(dc.GetTempHDC()), TABP_TABITEM, 0, NULL, TS_TRUE, &uxSize); m_tabSize.Set(uxSize.cx, uxSize.cy); }
void wxAuiMSWTabArt::DrawBorder(wxDC& dc, wxWindow* wnd, const wxRect& rect) { if ( !IsThemed() ) { wxAuiGenericTabArt::DrawBorder(dc, wnd, rect); return; } wxRect drawRect(rect); drawRect.y += m_maxTabHeight + wnd->FromDIP(1); drawRect.height -= m_maxTabHeight; // Mask border not covered by native theme wxRect topDrawRect(rect); topDrawRect.height = drawRect.height; dc.SetPen(wxPen(wnd->GetBackgroundColour(), GetBorderWidth(wnd))); dc.DrawRectangle(topDrawRect); RECT r; wxCopyRectToRECT(drawRect, r); wxUxThemeHandle hTheme(wnd, L"TAB"); ::DrawThemeBackground( hTheme, GetHdcOf(dc.GetTempHDC()), TABP_PANE, 0, &r, NULL); }
void wxRendererMSW::DoDrawFrameControl(UINT type, UINT kind, wxWindow * WXUNUSED(win), wxDC& dc, const wxRect& rect, int flags) { wxCHECK_RET( dc.GetImpl(), wxT("Invalid wxDC") ); wxRect adjustedRect = dc.GetImpl()->MSWApplyGDIPlusTransform(rect); RECT r; wxCopyRectToRECT(adjustedRect, r); int style = kind; if ( flags & wxCONTROL_CHECKED ) style |= DFCS_CHECKED; if ( flags & wxCONTROL_DISABLED ) style |= DFCS_INACTIVE; if ( flags & wxCONTROL_FLAT ) style |= DFCS_MONO; if ( flags & wxCONTROL_PRESSED ) style |= DFCS_PUSHED; if ( flags & wxCONTROL_CURRENT ) style |= DFCS_HOT; if ( flags & wxCONTROL_UNDETERMINED ) // Using DFCS_BUTTON3STATE here doesn't work (as might be expected), // use the following two styles to get the same look of a check box // in the undetermined state. style |= DFCS_INACTIVE | DFCS_CHECKED; ::DrawFrameControl(GetHdcOf(dc.GetTempHDC()), &r, type, style); }
void wxRendererMSW::DoDrawFrameControl(UINT type, UINT kind, wxWindow * WXUNUSED(win), wxDC& dc, const wxRect& rect, int flags) { RECT r; wxCopyRectToRECT(rect, r); int style = kind; if ( flags & wxCONTROL_CHECKED ) style |= DFCS_CHECKED; if ( flags & wxCONTROL_DISABLED ) style |= DFCS_INACTIVE; if ( flags & wxCONTROL_FLAT ) style |= DFCS_MONO; if ( flags & wxCONTROL_PRESSED ) style |= DFCS_PUSHED; if ( flags & wxCONTROL_CURRENT ) style |= DFCS_HOT; ::DrawFrameControl(GetHdcOf(dc.GetTempHDC()), &r, type, style); }
void wxRendererXP::DrawTreeItemButton(wxWindow *win, wxDC& dc, const wxRect& rect, int flags) { wxUxThemeHandle hTheme(win, L"TREEVIEW"); if ( !hTheme ) { m_rendererNative.DrawTreeItemButton(win, dc, rect, flags); return; } RECT r; wxCopyRectToRECT(rect, r); int state = flags & wxCONTROL_EXPANDED ? GLPS_OPENED : GLPS_CLOSED; wxUxThemeEngine::Get()->DrawThemeBackground ( hTheme, GetHdcOf(dc.GetTempHDC()), TVP_GLYPH, state, &r, NULL ); }
void wxRendererXP::DrawTreeItemButton(wxWindow *win, wxDC& dc, const wxRect& rect, int flags) { wxUxThemeHandle hTheme(win, L"TREEVIEW"); if ( !hTheme ) { m_rendererNative.DrawTreeItemButton(win, dc, rect, flags); return; } wxCHECK_RET( dc.GetImpl(), wxT("Invalid wxDC") ); wxRect adjustedRect = dc.GetImpl()->MSWApplyGDIPlusTransform(rect); RECT r; wxCopyRectToRECT(adjustedRect, r); int state = flags & wxCONTROL_EXPANDED ? GLPS_OPENED : GLPS_CLOSED; wxUxThemeEngine::Get()->DrawThemeBackground ( hTheme, GetHdcOf(dc.GetTempHDC()), TVP_GLYPH, state, &r, NULL ); }
void wxAuiMSWToolBarArt::DrawOverflowButton( wxDC& dc, wxWindow* wnd, const wxRect& rect, int state) { 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; else chevState = CHEVS_NORMAL; wxUxThemeEngine::Get()->DrawThemeBackground( hTheme, GetHdcOf(dc.GetTempHDC()), (m_flags & wxAUI_TB_VERTICAL) ? RP_CHEVRONVERT : RP_CHEVRON, chevState, &r, NULL); } else wxAuiGenericToolBarArt::DrawOverflowButton(dc, wnd, rect, state); }
void wxRendererXP::DrawGauge(wxWindow* win, wxDC& dc, const wxRect& rect, int value, int max, int flags) { wxUxThemeHandle hTheme(win, L"PROGRESS"); if ( !hTheme ) { m_rendererNative.DrawGauge(win, dc, rect, value, max, flags); return; } RECT r; wxCopyRectToRECT(rect, r); wxUxThemeEngine::Get()->DrawThemeBackground( hTheme, GetHdcOf(dc.GetTempHDC()), PP_BAR, 0, &r, NULL); RECT contentRect; wxUxThemeEngine::Get()->GetThemeBackgroundContentRect( hTheme, GetHdcOf(dc.GetTempHDC()), PP_BAR, 0, &r, &contentRect); contentRect.right = contentRect.left + wxMulDivInt32(contentRect.right - contentRect.left, value, max); wxUxThemeEngine::Get()->DrawThemeBackground( hTheme, GetHdcOf(dc.GetTempHDC()), PP_CHUNK, 0, &contentRect, NULL); }
void wxRendererXP::DoDrawButtonLike(HTHEME htheme, int part, wxDC& dc, const wxRect& rect, int flags) { wxCHECK_RET( dc.GetImpl(), wxT("Invalid wxDC") ); wxRect adjustedRect = dc.GetImpl()->MSWApplyGDIPlusTransform(rect); RECT r; wxCopyRectToRECT(adjustedRect, r); // the base state is always 1, whether it is PBS_NORMAL, // {CBS,RBS}_UNCHECKEDNORMAL or CBS_NORMAL int state = 1; // XBS_XXX is followed by XBX_XXXHOT, then XBS_XXXPRESSED and DISABLED enum { NORMAL_OFFSET, HOT_OFFSET, PRESSED_OFFSET, DISABLED_OFFSET, STATES_COUNT }; // in both RBS_ and CBS_ enums CHECKED elements are offset by 4 from base // (UNCHECKED) ones and MIXED are offset by 4 again as there are all states // from the above enum in between them if ( flags & wxCONTROL_CHECKED ) state += STATES_COUNT; else if ( flags & wxCONTROL_UNDETERMINED ) state += 2*STATES_COUNT; if ( flags & wxCONTROL_DISABLED ) state += DISABLED_OFFSET; else if ( flags & wxCONTROL_PRESSED ) state += PRESSED_OFFSET; else if ( flags & wxCONTROL_CURRENT ) state += HOT_OFFSET; // wxCONTROL_ISDEFAULT flag is only valid for push buttons else if ( part == BP_PUSHBUTTON && (flags & wxCONTROL_ISDEFAULT) ) state = PBS_DEFAULTED; wxUxThemeEngine::Get()->DrawThemeBackground ( htheme, GetHdcOf(dc.GetTempHDC()), part, state, &r, NULL ); }
void wxRendererMSWBase::DrawFocusRect(wxWindow * WXUNUSED(win), wxDC& dc, const wxRect& rect, int WXUNUSED(flags)) { RECT rc; wxCopyRectToRECT(rect, rc); ::DrawFocusRect(GetHdcOf(dc.GetTempHDC()), &rc); }
void wxRendererMSW::DrawComboBoxDropButton(wxWindow * WXUNUSED(win), wxDC& dc, const wxRect& rect, int flags) { RECT r; wxCopyRectToRECT(rect, r); int style = DFCS_SCROLLCOMBOBOX; if ( flags & wxCONTROL_DISABLED ) style |= DFCS_INACTIVE; if ( flags & wxCONTROL_PRESSED ) style |= DFCS_PUSHED | DFCS_FLAT; ::DrawFrameControl(GetHdcOf(dc.GetTempHDC()), &r, DFC_SCROLL, style); }
int wxRendererXP::DrawHeaderButton(wxWindow *win, wxDC& dc, const wxRect& rect, int flags, wxHeaderSortIconType sortArrow, wxHeaderButtonParams* params) { wxUxThemeHandle hTheme(win, L"HEADER"); if ( !hTheme ) { return m_rendererNative.DrawHeaderButton(win, dc, rect, flags, sortArrow, params); } wxCHECK_MSG( dc.GetImpl(), -1, wxT("Invalid wxDC") ); wxRect adjustedRect = dc.GetImpl()->MSWApplyGDIPlusTransform(rect); RECT r; wxCopyRectToRECT(adjustedRect, r); int state; if ( flags & wxCONTROL_PRESSED ) state = HIS_PRESSED; else if ( flags & wxCONTROL_CURRENT ) state = HIS_HOT; else state = HIS_NORMAL; wxUxThemeEngine::Get()->DrawThemeBackground ( hTheme, GetHdcOf(dc.GetTempHDC()), HP_HEADERITEM, state, &r, NULL ); // 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 // and then clear those flags before calling DrawHeaderButtonContents. // Add any extras that are specified in flags and params return DrawHeaderButtonContents(win, dc, rect, flags, sortArrow, params); }
void wxRendererXP::DrawCollapseButton(wxWindow *win, wxDC& dc, const wxRect& rect, int flags) { wxUxThemeHandle hTheme(win, L"TASKDIALOG"); wxUxThemeEngine* const te = wxUxThemeEngine::Get(); int state; if (flags & wxCONTROL_PRESSED) state = TDLGEBS_PRESSED; else if (flags & wxCONTROL_CURRENT) state = TDLGEBS_HOVER; else state = TDLGEBS_NORMAL; if ( flags & wxCONTROL_EXPANDED ) state += 3; if ( te->IsThemePartDefined(hTheme, TDLG_EXPANDOBUTTON, state) ) { if (flags & wxCONTROL_EXPANDED) flags |= wxCONTROL_CHECKED; wxRect adjustedRect = dc.GetImpl()->MSWApplyGDIPlusTransform(rect); RECT r; wxCopyRectToRECT(adjustedRect, r); te->DrawThemeBackground ( hTheme, GetHdcOf(dc.GetTempHDC()), TDLG_EXPANDOBUTTON, state, &r, NULL ); } else m_rendererNative.DrawCollapseButton(win, dc, rect, flags); }
// NOTE: There is no guarantee that the button drawn fills the entire rect (XP // default theme, for example), so the caller should have cleared button's // background before this call. This is quite likely a wxMSW-specific thing. void wxRendererXP::DrawComboBoxDropButton(wxWindow * win, wxDC& dc, const wxRect& rect, int flags) { wxUxThemeHandle hTheme(win, L"COMBOBOX"); if ( !hTheme ) { m_rendererNative.DrawComboBoxDropButton(win, dc, rect, flags); return; } wxCHECK_RET( dc.GetImpl(), wxT("Invalid wxDC") ); wxRect adjustedRect = dc.GetImpl()->MSWApplyGDIPlusTransform(rect); RECT r; wxCopyRectToRECT(adjustedRect, r); int state; if ( flags & wxCONTROL_PRESSED ) state = CBXS_PRESSED; else if ( flags & wxCONTROL_CURRENT ) state = CBXS_HOT; else if ( flags & wxCONTROL_DISABLED ) state = CBXS_DISABLED; else state = CBXS_NORMAL; wxUxThemeEngine::Get()->DrawThemeBackground ( hTheme, GetHdcOf(dc.GetTempHDC()), CP_DROPDOWNBUTTON, state, &r, NULL ); }
void wxRendererMSW::DrawComboBoxDropButton(wxWindow * WXUNUSED(win), wxDC& dc, const wxRect& rect, int flags) { wxCHECK_RET( dc.GetImpl(), wxT("Invalid wxDC") ); wxRect adjustedRect = dc.GetImpl()->MSWApplyGDIPlusTransform(rect); RECT r; wxCopyRectToRECT(adjustedRect, r); int style = DFCS_SCROLLCOMBOBOX; if ( flags & wxCONTROL_DISABLED ) style |= DFCS_INACTIVE; if ( flags & wxCONTROL_PRESSED ) style |= DFCS_PUSHED | DFCS_FLAT; ::DrawFrameControl(GetHdcOf(dc.GetTempHDC()), &r, DFC_SCROLL, style); }
void wxAuiMSWTabArt::DrawBackground(wxDC& dc, wxWindow* wnd, const wxRect& rect) { if ( !IsThemed() ) { wxAuiGenericTabArt::DrawBackground(dc, wnd, rect); return; } int borderHeight = 2; wxRect drawRect = rect; drawRect.height -= borderHeight; // Draw background dc.SetBrush(wxBrush(wnd->GetBackgroundColour())); dc.SetPen(*wxTRANSPARENT_PEN); dc.DrawRectangle(drawRect); // Draw top border drawRect.y = drawRect.height; drawRect.height = borderHeight + 2; drawRect.Inflate(1, 0); RECT r; wxCopyRectToRECT(drawRect, r); wxUxThemeHandle hTheme(wnd, L"TAB"); ::DrawThemeBackground( hTheme, GetHdcOf(dc.GetTempHDC()), TABP_PANE, 0, &r, NULL); }
void wxAuiMSWToolBarArt::DrawGripper( wxDC& dc, wxWindow* wnd, const wxRect& rect) { if ( m_themed ) { RECT r; wxCopyRectToRECT(rect, r); wxUxThemeHandle hTheme(wnd, L"Rebar"); wxUxThemeEngine::Get()->DrawThemeBackground( hTheme, GetHdcOf(dc.GetTempHDC()), (m_flags & wxAUI_TB_VERTICAL) ? RP_GRIPPERVERT : RP_GRIPPER, 0, &r, NULL); } else wxAuiGenericToolBarArt::DrawGripper(dc, wnd, rect); }
void wxAuiMSWToolBarArt::DrawBackground( wxDC& dc, wxWindow* wnd, const wxRect& rect) { if ( m_themed ) { RECT r; wxCopyRectToRECT(rect, r); wxUxThemeHandle hTheme(wnd, L"Rebar"); wxUxThemeEngine::Get()->DrawThemeBackground( hTheme, GetHdcOf(dc.GetTempHDC()), RP_BACKGROUND, 0, &r, NULL); } else wxAuiGenericToolBarArt::DrawBackground(dc, wnd, rect); }
wxSize wxRendererXP::GetCollapseButtonSize(wxWindow *win, wxDC& dc) { wxUxThemeHandle hTheme(win, L"TASKDIALOG"); wxUxThemeEngine* const te = wxUxThemeEngine::Get(); // EXPANDOBUTTON scales ugly if not using the correct size, get size from theme if ( te->IsThemePartDefined(hTheme, TDLG_EXPANDOBUTTON, TDLGEBS_NORMAL) ) { SIZE s; te->GetThemePartSize(hTheme, GetHdcOf(dc.GetTempHDC()), TDLG_EXPANDOBUTTON, TDLGEBS_NORMAL, NULL, TS_TRUE, &s); return wxSize(s.cx, s.cy); } else return m_rendererNative.GetCollapseButtonSize(win, dc); }
void wxAuiMSWTabArt::DrawButton(wxDC& dc, wxWindow* wnd, const wxRect& in_rect, int bitmap_id, int button_state, int orientation, wxRect* out_rect) { if ( !IsThemed() ) { wxAuiGenericTabArt::DrawButton(dc, wnd, in_rect, bitmap_id, button_state, orientation, out_rect); return; } const wchar_t* themeId = NULL; int part = 0; switch (bitmap_id) { case wxAUI_BUTTON_CLOSE: themeId = L"Window"; part = WP_CLOSEBUTTON; break; case wxAUI_BUTTON_LEFT: themeId = L"Spin"; part = SPNP_DOWNHORZ; break; case wxAUI_BUTTON_RIGHT: themeId = L"Spin"; part = SPNP_UPHORZ; break; case wxAUI_BUTTON_WINDOWLIST: themeId = L"Combobox"; part = CP_DROPDOWNBUTTON; break; } wxRect rect = in_rect; if ( orientation == wxLEFT ) { rect.SetX(in_rect.x); rect.SetY(((in_rect.y + in_rect.height) / 2) - (m_closeBtnSize.GetHeight() / 2)); rect.SetWidth(m_closeBtnSize.GetWidth()); rect.SetHeight(m_closeBtnSize.GetHeight()); } else { rect = wxRect(in_rect.x + in_rect.width - m_closeBtnSize.GetWidth(), ((in_rect.y + in_rect.height) / 2) - (m_closeBtnSize.GetHeight() / 2), m_closeBtnSize.GetWidth(), m_closeBtnSize.GetHeight()); } if ( bitmap_id == wxAUI_BUTTON_LEFT || bitmap_id == wxAUI_BUTTON_RIGHT ) { rect.y = in_rect.y; rect.height = in_rect.height - wnd->FromDIP(7); } dc.SetPen(*wxTRANSPARENT_PEN); dc.SetBrush(wxBrush(m_baseColour)); dc.DrawRectangle(rect); int btnState; if ( button_state == wxAUI_BUTTON_STATE_DISABLED ) btnState = TTCS_PRESSED + 1; else if ( button_state == wxAUI_BUTTON_STATE_HOVER ) btnState = TTCS_HOT; else if ( button_state == wxAUI_BUTTON_STATE_PRESSED ) btnState = TTCS_PRESSED; else btnState = TTCS_NORMAL; wxUxThemeHandle hTheme(wnd, themeId); wxRect btnRect(rect); btnRect.width -= wnd->FromDIP(1); RECT btnR; wxCopyRectToRECT(btnRect, btnR); ::DrawThemeBackground(hTheme, GetHdcOf(dc.GetTempHDC()), part, btnState, &btnR, NULL); if ( out_rect ) *out_rect = rect; }
void wxAuiMSWToolBarArt::DrawDropDownButton( wxDC& dc, wxWindow* wnd, const wxAuiToolBarItem& item, const wxRect& rect) { if ( m_themed ) { wxUxThemeHandle hTheme(wnd, L"Toolbar"); wxUxThemeEngine* const te = wxUxThemeEngine::Get(); int dropDownWidth = 14; int textWidth = 0, textHeight = 0, textX = 0, textY = 0; int bmpX = 0, bmpY = 0; wxRect buttonRect = wxRect(rect.x, rect.y, rect.width - dropDownWidth, rect.height); wxRect dropDownRect = wxRect(rect.x + rect.width - dropDownWidth - 1, rect.y, dropDownWidth + 1, rect.height); if ( m_flags & wxAUI_TB_TEXT ) { dc.SetFont(m_font); int tx, ty; if ( m_flags & wxAUI_TB_TEXT ) { dc.GetTextExtent(wxT("ABCDHgj"), &tx, &textHeight); textWidth = 0; } 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; else if ( item.GetState() & wxAUI_BUTTON_STATE_PRESSED ) btnState = TS_PRESSED; else if ( item.GetState() & wxAUI_BUTTON_STATE_HOVER ) btnState = TS_HOT; else btnState = TS_NORMAL; te->DrawThemeBackground( hTheme, GetHdcOf(dc.GetTempHDC()), TP_SPLITBUTTON, btnState, &btnR, NULL); te->DrawThemeBackground( hTheme, GetHdcOf(dc.GetTempHDC()), TP_SPLITBUTTONDROPDOWN, btnState, &dropDownR, NULL); if ( m_textOrientation == wxAUI_TBTOOL_TEXT_BOTTOM ) { bmpX = buttonRect.x + (buttonRect.width / 2) - (item.GetBitmap().GetWidth() / 2); bmpY = buttonRect.y + ((buttonRect.height - textHeight) / 2) - (item.GetBitmap().GetHeight() / 2); textX = rect.x + (rect.width / 2) - (textWidth / 2) + 1; textY = rect.y + rect.height - textHeight - 1; } else if ( m_textOrientation == wxAUI_TBTOOL_TEXT_RIGHT ) { bmpX = rect.x + 3; bmpY = rect.y + (rect.height / 2) - (item.GetBitmap().GetHeight() / 2); textX = bmpX + 3 + item.GetBitmap().GetWidth(); textY = rect.y + (rect.height / 2) - (textHeight / 2); } wxBitmap bmp; if ( item.GetState() & wxAUI_BUTTON_STATE_DISABLED ) { bmp = item.GetDisabledBitmap(); } else { bmp = item.GetBitmap(); } if ( !bmp.IsOk() ) return; dc.DrawBitmap(bmp, bmpX, bmpY, true); // set the item's text color based on if it is disabled dc.SetTextForeground(*wxBLACK); if ( item.GetState() & wxAUI_BUTTON_STATE_DISABLED ) dc.SetTextForeground(DISABLED_TEXT_COLOR); if ( (m_flags & wxAUI_TB_TEXT) && !item.GetLabel().empty() ) { dc.DrawText(item.GetLabel(), textX, textY); } } else wxAuiGenericToolBarArt::DrawDropDownButton(dc, wnd, item, rect); }
void wxAuiMSWTabArt::DrawTab(wxDC& dc, wxWindow* wnd, const wxAuiNotebookPage& page, const wxRect& in_rect, int close_button_state, wxRect* out_tab_rect, wxRect* out_button_rect, int* x_extent) { if ( !IsThemed() ) { wxAuiGenericTabArt::DrawTab(dc, wnd, page, in_rect, close_button_state, out_tab_rect, out_button_rect, x_extent); return; } if ( !m_closeBtnSize.IsFullySpecified() ) InitSizes(wnd, dc); // figure out the size of the tab wxSize tabSize = GetTabSize(dc, wnd, page.caption, page.bitmap, page.active, close_button_state, x_extent); wxCoord tabHeight = tabSize.y; wxCoord tabWidth = tabSize.x; wxCoord tabX = in_rect.x; wxCoord tabY = 0; if (!page.active) { tabY += wnd->FromDIP(2); tabHeight -= wnd->FromDIP(2); } else { tabX -= wnd->FromDIP(2); tabWidth += wnd->FromDIP(4); tabHeight += 2; } int clipWidth = tabWidth; if ( tabX + clipWidth > in_rect.x + in_rect.width ) clipWidth = (in_rect.x + in_rect.width) - tabX; dc.SetClippingRegion(tabX - wnd->FromDIP(2), tabY, clipWidth + wnd->FromDIP(4), tabHeight); // draw tab wxRect tabRect(tabX, tabY, tabWidth, tabHeight); int tabState; if ( page.active ) tabState = TIS_SELECTED; else if ( page.hover ) tabState = TIS_HOT; else tabState = TIS_NORMAL; wxUxThemeHandle hTabTheme(wnd, L"Tab"); RECT tabR; wxCopyRectToRECT(tabRect, tabR); ::DrawThemeBackground(hTabTheme, GetHdcOf(dc.GetTempHDC()), TABP_TABITEM, tabState, &tabR, NULL); // 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, GetHdcOf(dc.GetTempHDC()), TABP_TABITEMLEFTEDGE, tabState, &tabR, NULL ); } wxRect textRect = tabRect; if ( !page.active ) textRect.Offset(0, wnd->FromDIP(1)); if ( close_button_state != wxAUI_BUTTON_STATE_HIDDEN ) textRect.width -= m_closeBtnSize.x + wnd->FromDIP(3); dc.SetFont(wnd->GetFont()); dc.DrawLabel(page.caption, page.bitmap, textRect, wxALIGN_CENTRE); // draw focus rectangle if ( page.active && (wnd->FindFocus() == wnd) ) { wxRect focusRect = tabRect; focusRect.Deflate(wnd->FromDIP(2)); wxRendererNative::Get().DrawFocusRect(wnd, dc, focusRect, 0); } // draw close button if ( close_button_state != wxAUI_BUTTON_STATE_HIDDEN ) { wxUxThemeHandle hToolTipTheme(wnd, L"TOOLTIP"); int btnState; if ( close_button_state == wxAUI_BUTTON_STATE_HOVER ) btnState = TTCS_HOT; else if ( close_button_state == wxAUI_BUTTON_STATE_PRESSED ) btnState = TTCS_PRESSED; else btnState = TTCS_NORMAL; int offsetY = tabY; if ( wxGetWinVersion() < wxWinVersion_Vista ) offsetY++; // WinXP theme needs a little more padding wxRect rect(tabX + tabWidth - m_closeBtnSize.x - wnd->FromDIP(4), offsetY + (tabHeight / 2) - (m_closeBtnSize.y / 2), m_closeBtnSize.x, m_closeBtnSize.y); RECT btnR; wxCopyRectToRECT(rect, btnR); ::DrawThemeBackground(hToolTipTheme, GetHdcOf(dc.GetTempHDC()), TTP_CLOSE, btnState, &btnR, NULL); if ( out_button_rect ) *out_button_rect = rect; } *out_tab_rect = wxRect(tabX, tabY, tabWidth, tabHeight); dc.DestroyClippingRegion(); }