Improve disabled buttons appearance in wxMSW when not using themes.

Owner drawn buttons were not drawn in the same way as normal ones when they
were disabled, use Win32 DrawState() to do it now to achieve the correct
appearance.

Closes #11746.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@75908 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2014-02-17 23:53:25 +00:00
parent 99d3a4f4d2
commit fd743aad4b

View File

@@ -831,6 +831,86 @@ void DrawButtonText(HDC hdc,
{
const wxString text = btn->GetLabel();
// To get a native look for owner-drawn button in disabled state (without
// theming) we must use DrawState() to draw the text label.
if ( !wxUxThemeEngine::GetIfActive() && !btn->IsEnabled() )
{
// However using DrawState() has some drawbacks:
// 1. It generally doesn't support alignment flags (except right
// alignment), so we need to align the text on our own.
// 2. It doesn't support multliline texts and there is necessary to
// draw/align multiline text line by line.
// Compute bounding rect for the whole text.
RECT rc;
::SetRectEmpty(&rc);
::DrawText(hdc, text.t_str(), text.length(), &rc, DT_CALCRECT);
const LONG h = rc.bottom - rc.top;
// Based on wxButton flags determine bottom edge of the drawing rect
// inside the entire button area.
int y0;
if ( btn->HasFlag(wxBU_BOTTOM) )
{
y0 = pRect->bottom - h;
}
else if ( !btn->HasFlag(wxBU_TOP) )
{
// DT_VCENTER
y0 = pRect->top + (pRect->bottom - pRect->top)/2 - h/2;
}
else // DT_TOP is the default
{
y0 = pRect->top;
}
UINT dsFlags = DSS_DISABLED;
if( flags & DT_HIDEPREFIX )
dsFlags |= (DSS_HIDEPREFIX | DST_PREFIXTEXT);
else
dsFlags |= DST_TEXT;
const wxArrayString lines = wxSplit(text, '\n', '\0');
const int hLine = h / lines.size();
for ( size_t lineNum = 0; lineNum < lines.size(); lineNum++ )
{
// Each line must be aligned in horizontal direction individually.
::SetRectEmpty(&rc);
::DrawText(hdc, lines[lineNum].t_str(), lines[lineNum].length(),
&rc, DT_CALCRECT);
const LONG w = rc.right - rc.left;
// Based on wxButton flags set horizontal position of the rect
// inside the entire button area. Text is always centered for
// multiline label.
if ( (!btn->HasFlag(wxBU_LEFT) && !btn->HasFlag(wxBU_RIGHT)) ||
lines.size() > 1 )
{
// DT_CENTER
rc.left = pRect->left + (pRect->right - pRect->left)/2 - w/2;
rc.right = rc.left + w;
}
else if ( btn->HasFlag(wxBU_RIGHT) )
{
rc.right = pRect->right;
rc.left = rc.right - w;
}
else // DT_LEFT is the default
{
rc.left = pRect->left;
rc.right = rc.left + w;
}
::OffsetRect(&rc, 0, y0 + lineNum * hLine);
::DrawState(hdc, NULL, NULL, wxMSW_CONV_LPARAM(lines[lineNum]),
lines[lineNum].length(),
rc.left, rc.top, rc.right, rc.bottom, dsFlags);
}
}
else // Button is enabled or using themes.
{
if ( text.find(wxT('\n')) != wxString::npos )
{
// draw multiline label
@@ -877,12 +957,13 @@ void DrawButtonText(HDC hdc,
}
//else: as above, DT_TOP is the default
// notice that we must have DT_SINGLELINE for vertical alignment flags
// to work
// notice that we must have DT_SINGLELINE for vertical alignment
// flags to work
::DrawText(hdc, text.t_str(), text.length(), pRect,
flags | DT_SINGLELINE );
}
}
}
void DrawRect(HDC hdc, const RECT& r)
{