bool wxNotebook::MSWPrintChild(WXHDC hDC, wxWindow *child) { // solid background colour overrides themed background drawing if ( !UseBgCol() && DoDrawBackground(hDC, child) ) return true; // If we're using a solid colour (for example if we've switched off // theming for this notebook), paint it if (UseBgCol()) { wxRect r = GetPageSize(); if ( r.IsEmpty() ) return false; RECT rc; wxCopyRectToRECT(r, rc); // map rect to the coords of the window we're drawing in if ( child ) ::MapWindowPoints(GetHwnd(), GetHwndOf(child), (POINT *)&rc, 2); wxBrush brush(GetBackgroundColour()); HBRUSH hbr = GetHbrushOf(brush); ::FillRect((HDC) hDC, &rc, hbr); return true; } return wxNotebookBase::MSWPrintChild(hDC, child); }
// helper for OnPaint(): really erase the background, i.e. do it even if we // don't have any non default brush for doing it (DoEraseBackground() doesn't // do anything in such case) void wxStaticBox::PaintBackground(wxDC& dc, const RECT& rc) { // note that we do not use the box background colour here, it shouldn't // apply to its interior for several reasons: // 1. wxGTK doesn't do it // 2. controls inside the box don't get correct bg colour because they // are not our children so we'd have some really ugly colour mix if // we did it // 3. this is backwards compatible behaviour and some people rely on it, // see http://groups.google.com/groups?selm=4252E932.3080801%40able.es wxWindow *parent = GetParent(); wxMSWDCImpl *impl = (wxMSWDCImpl*) dc.GetImpl(); HBRUSH hbr = (HBRUSH)parent->MSWGetBgBrush(impl->GetHDC(), this); // if there is no special brush for painting this control, just use the // solid background colour wxBrush brush; if ( !hbr ) { brush = wxBrush(parent->GetBackgroundColour()); hbr = GetHbrushOf(brush); } ::FillRect(GetHdcOf(*impl), &rc, hbr); }
WXLRESULT wxStaticBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) { if ( nMsg == WM_NCHITTEST ) { // This code breaks some other processing such as enter/leave tracking // so it's off by default. static int s_useHTClient = -1; if (s_useHTClient == -1) s_useHTClient = wxSystemOptions::GetOptionInt(wxT("msw.staticbox.htclient")); if (s_useHTClient == 1) { int xPos = GET_X_LPARAM(lParam); int yPos = GET_Y_LPARAM(lParam); ScreenToClient(&xPos, &yPos); // Make sure you can drag by the top of the groupbox, but let // other (enclosed) controls get mouse events also if ( yPos < 10 ) return (long)HTCLIENT; } } if ( nMsg == WM_PRINTCLIENT ) { // we have to process WM_PRINTCLIENT ourselves as otherwise child // windows' background (eg buttons in radio box) would never be drawn // unless we have a parent with non default background // so check first if we have one if ( !HandlePrintClient((WXHDC)wParam) ) { // no, we don't, erase the background ourselves // (don't use our own) - see PaintBackground for explanation wxBrush brush(GetParent()->GetBackgroundColour()); wxFillRect(GetHwnd(), (HDC)wParam, GetHbrushOf(brush)); } return 0; } return wxControl::MSWWindowProc(nMsg, wParam, lParam); }
void wxBitmapButton::DrawButtonDisable( WXHDC dc, int left, int top, int right, int bottom, bool with_marg ) { if ( !m_brushDisabled.Ok() ) { // draw a bitmap with two black and two background colour pixels wxBitmap bmp(2, 2); wxMemoryDC dc; dc.SelectObject(bmp); dc.SetPen(*wxBLACK_PEN); dc.DrawPoint(0, 0); dc.DrawPoint(1, 1); dc.SetPen(GetBackgroundColour()); dc.DrawPoint(0, 1); dc.DrawPoint(1, 0); m_brushDisabled = wxBrush(bmp); } SelectInHDC selectBrush((HDC)dc, GetHbrushOf(m_brushDisabled)); // ROP for "dest |= pattern" operation -- as it doesn't have a standard // name, give it our own static const DWORD PATTERNPAINT = 0xFA0089UL; if ( with_marg ) { left += m_marginX; top += m_marginY; right -= 2 * m_marginX; bottom -= 2 * m_marginY; } ::PatBlt( (HDC) dc, left, top, right, bottom, PATTERNPAINT); }
void wxNotebook::OnPaint(wxPaintEvent& WXUNUSED(event)) { wxPaintDC dc(this); wxMemoryDC memdc; RECT rc; ::GetClientRect(GetHwnd(), &rc); wxBitmap bmp(rc.right, rc.bottom); memdc.SelectObject(bmp); const wxLayoutDirection dir = dc.GetLayoutDirection(); memdc.SetLayoutDirection(dir); // if there is no special brush just use the solid background colour #if wxUSE_UXTHEME HBRUSH hbr = (HBRUSH)m_hbrBackground; #else HBRUSH hbr = 0; #endif wxBrush brush; if ( !hbr ) { brush = wxBrush(GetBackgroundColour()); hbr = GetHbrushOf(brush); } wxMSWDCImpl *impl = (wxMSWDCImpl*) memdc.GetImpl(); ::FillRect(GetHdcOf(*impl), &rc, hbr); MSWDefWindowProc(WM_PAINT, (WPARAM)(impl->GetHDC()), 0); // For some reason in RTL mode, source offset has to be -1, otherwise the // right border (physical) remains unpainted. const wxCoord ofs = dir == wxLayout_RightToLeft ? -1 : 0; dc.Blit(ofs, 0, rc.right, rc.bottom, &memdc, ofs, 0); }
void wxStaticBox::PaintForeground(wxDC& dc, const RECT& rc) { wxMSWDCImpl *impl = (wxMSWDCImpl*) dc.GetImpl(); MSWDefWindowProc(WM_PAINT, (WPARAM)GetHdcOf(*impl), 0); // when using XP themes, neither setting the text colour nor transparent // background mode doesn't change anything: the static box def window proc // still draws the label in its own colours, so we need to redraw the text // ourselves if we have a non default fg colour if ( m_hasFgCol && wxUxThemeEngine::GetIfActive() ) { // draw over the text in default colour in our colour HDC hdc = GetHdcOf(*impl); ::SetTextColor(hdc, GetForegroundColour().GetPixel()); const bool rtl = wxTheApp->GetLayoutDirection() == wxLayout_RightToLeft; if ( rtl ) ::SetTextAlign(hdc, TA_RTLREADING | TA_RIGHT); // Get dimensions of the label const wxString label = GetLabel(); // choose the correct font AutoHFONT font; SelectInHDC selFont; if ( m_hasFont ) { selFont.Init(hdc, GetHfontOf(GetFont())); } else // no font set, use the one set by the theme { wxUxThemeHandle hTheme(this, L"BUTTON"); if ( hTheme ) { wxUxThemeFont themeFont; if ( wxUxThemeEngine::Get()->GetThemeFont ( hTheme, hdc, BP_GROUPBOX, GBS_NORMAL, TMT_FONT, themeFont.GetPtr() ) == S_OK ) { font.Init(themeFont.GetLOGFONT()); if ( font ) selFont.Init(hdc, font); } } } // Get the font extent int width, height; dc.GetTextExtent(wxStripMenuCodes(label, wxStrip_Mnemonics), &width, &height); int x; int y = height; // first we need to correctly paint the background of the label // as Windows ignores the brush offset when doing it // // FIXME: value of x is hardcoded as this is what it is on my system, // no idea if it's true everywhere RECT dimensions = {0, 0, 0, y}; if ( !rtl ) { x = 9; dimensions.left = x; dimensions.right = x + width; } else { x = rc.right - 7; dimensions.left = x - width; dimensions.right = x; } // need to adjust the rectangle to cover all the label background dimensions.left -= 2; dimensions.right += 2; dimensions.bottom += 2; if ( UseBgCol() ) { // our own background colour should be used for the background of // the label: this is consistent with the behaviour under pre-XP // systems (i.e. without visual themes) and generally makes sense wxBrush brush = wxBrush(GetBackgroundColour()); wxMSWDCImpl *impl = (wxMSWDCImpl*) dc.GetImpl(); ::FillRect(GetHdcOf(*impl), &dimensions, GetHbrushOf(brush)); } else // paint parent background { PaintBackground(dc, dimensions); } UINT drawTextFlags = DT_SINGLELINE | DT_VCENTER; // determine the state of UI queues to draw the text correctly under XP // and later systems static const bool isXPorLater = wxGetWinVersion() >= wxWinVersion_XP; if ( isXPorLater ) { if ( ::SendMessage(GetHwnd(), WM_QUERYUISTATE, 0, 0) & UISF_HIDEACCEL ) { drawTextFlags |= DT_HIDEPREFIX; } } // now draw the text if ( !rtl ) { RECT rc2 = { x, 0, x + width, y }; ::DrawText(hdc, label.t_str(), label.length(), &rc2, drawTextFlags); } else // RTL { RECT rc2 = { x, 0, x - width, y }; ::DrawText(hdc, label.t_str(), label.length(), &rc2, drawTextFlags | DT_RTLREADING); } } }
WXLRESULT wxStaticBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) { if ( nMsg == WM_NCHITTEST ) { // This code breaks some other processing such as enter/leave tracking // so it's off by default. static int s_useHTClient = -1; if (s_useHTClient == -1) s_useHTClient = wxSystemOptions::GetOptionInt(wxT("msw.staticbox.htclient")); if (s_useHTClient == 1) { int xPos = GET_X_LPARAM(lParam); int yPos = GET_Y_LPARAM(lParam); ScreenToClient(&xPos, &yPos); // Make sure you can drag by the top of the groupbox, but let // other (enclosed) controls get mouse events also if ( yPos < 10 ) return (long)HTCLIENT; } } if ( nMsg == WM_PRINTCLIENT ) { // we have to process WM_PRINTCLIENT ourselves as otherwise child // windows' background (eg buttons in radio box) would never be drawn // unless we have a parent with non default background // so check first if we have one if ( !HandlePrintClient((WXHDC)wParam) ) { // no, we don't, erase the background ourselves // (don't use our own) - see PaintBackground for explanation wxBrush brush(GetParent()->GetBackgroundColour()); wxFillRect(GetHwnd(), (HDC)wParam, GetHbrushOf(brush)); } return 0; } if ( nMsg == WM_UPDATEUISTATE ) { // DefWindowProc() redraws just the static box text when it gets this // message and it does it using the standard (blue in standard theme) // colour and not our own label colour that we use in PaintForeground() // resulting in the label mysteriously changing the colour when e.g. // "Alt" is pressed anywhere in the window, see #12497. // // To avoid this we simply refresh the window forcing our own code // redrawing the label in the correct colour to be called. This is // inefficient but there doesn't seem to be anything else we can do. // // Notice that the problem is XP-specific and doesn't arise under later // systems. if ( m_hasFgCol && wxGetWinVersion() == wxWinVersion_XP ) Refresh(); } return wxControl::MSWWindowProc(nMsg, wParam, lParam); }
void wxStaticBox::PaintForeground(wxDC& dc, const RECT& rc) { wxMSWDCImpl *impl = (wxMSWDCImpl*) dc.GetImpl(); MSWDefWindowProc(WM_PAINT, (WPARAM)GetHdcOf(*impl), 0); // when using XP themes, neither setting the text colour nor transparent // background mode doesn't change anything: the static box def window proc // still draws the label in its own colours, so we need to redraw the text // ourselves if we have a non default fg colour if ( m_hasFgCol && wxUxThemeEngine::GetIfActive() ) { // draw over the text in default colour in our colour HDC hdc = GetHdcOf(*impl); ::SetTextColor(hdc, GetForegroundColour().GetPixel()); const bool rtl = wxTheApp->GetLayoutDirection() == wxLayout_RightToLeft; if ( rtl ) ::SetTextAlign(hdc, TA_RTLREADING | TA_RIGHT); // Get dimensions of the label const wxString label = GetLabel(); // choose the correct font AutoHFONT font; SelectInHDC selFont; if ( m_hasFont ) { selFont.Init(hdc, GetHfontOf(GetFont())); } else // no font set, use the one set by the theme { wxUxThemeHandle hTheme(this, L"BUTTON"); if ( hTheme ) { // GetThemeFont() expects its parameter to be LOGFONTW and not // LOGFONTA even in ANSI programs and will happily corrupt // memory after the struct end if we pass a LOGFONTA (which is // smaller) to it! LOGFONTW lfw; if ( wxUxThemeEngine::Get()->GetThemeFont ( hTheme, hdc, BP_GROUPBOX, GBS_NORMAL, TMT_FONT, (LOGFONT *)&lfw ) == S_OK ) { #if wxUSE_UNICODE // ok, no conversion necessary const LOGFONT& lf = lfw; #else // !wxUSE_UNICODE // most of the fields are the same in LOGFONTA and LOGFONTW LOGFONT lf; memcpy(&lf, &lfw, sizeof(lf)); // but the face name must be converted WideCharToMultiByte(CP_ACP, 0, lfw.lfFaceName, -1, lf.lfFaceName, sizeof(lf.lfFaceName), NULL, NULL); #endif // wxUSE_UNICODE/!wxUSE_UNICODE font.Init(lf); if ( font ) selFont.Init(hdc, font); } } } // Get the font extent int width, height; dc.GetTextExtent(wxStripMenuCodes(label, wxStrip_Mnemonics), &width, &height); int x; int y = height; // first we need to correctly paint the background of the label // as Windows ignores the brush offset when doing it // // FIXME: value of x is hardcoded as this is what it is on my system, // no idea if it's true everywhere RECT dimensions = {0, 0, 0, y}; if ( !rtl ) { x = 9; dimensions.left = x; dimensions.right = x + width; } else { x = rc.right - 7; dimensions.left = x - width; dimensions.right = x; } // need to adjust the rectangle to cover all the label background dimensions.left -= 2; dimensions.right += 2; dimensions.bottom += 2; if ( UseBgCol() ) { // our own background colour should be used for the background of // the label: this is consistent with the behaviour under pre-XP // systems (i.e. without visual themes) and generally makes sense wxBrush brush = wxBrush(GetBackgroundColour()); wxMSWDCImpl *impl = (wxMSWDCImpl*) dc.GetImpl(); ::FillRect(GetHdcOf(*impl), &dimensions, GetHbrushOf(brush)); } else // paint parent background { PaintBackground(dc, dimensions); } // now draw the text if ( !rtl ) { RECT rc2 = { x, 0, x + width, y }; ::DrawText(hdc, label.wx_str(), label.length(), &rc2, DT_SINGLELINE | DT_VCENTER); } else // RTL { RECT rc2 = { x, 0, x - width, y }; ::DrawText(hdc, label.wx_str(), label.length(), &rc2, DT_SINGLELINE | DT_VCENTER | DT_RTLREADING); } } }