X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/233f10bf15c7201e8733426cffdeb6595df539ae..b85b06e13d22e7fc1604ec1a49caa1227a1b3d36:/src/msw/button.cpp diff --git a/src/msw/button.cpp b/src/msw/button.cpp index ead9214d2c..b789a6ccc2 100644 --- a/src/msw/button.cpp +++ b/src/msw/button.cpp @@ -43,6 +43,9 @@ #include "wx/stockitem.h" #include "wx/msw/private.h" #include "wx/msw/private/button.h" +#include "wx/msw/private/dc.h" + +using namespace wxMSWImpl; #if wxUSE_UXTHEME #include "wx/msw/uxtheme.h" @@ -109,6 +112,7 @@ class wxButtonImageData { public: wxButtonImageData() { } + virtual ~wxButtonImageData() { } virtual wxBitmap GetBitmap(wxButton::State which) const = 0; virtual void SetBitmap(const wxBitmap& bitmap, wxButton::State which) = 0; @@ -116,7 +120,7 @@ public: virtual wxSize GetBitmapMargins() const = 0; virtual void SetBitmapMargins(wxCoord x, wxCoord y) = 0; - virtual bool IsHorizontal() const = 0; + virtual wxDirection GetBitmapPosition() const = 0; virtual void SetBitmapPosition(wxDirection dir) = 0; private: @@ -126,10 +130,27 @@ private: namespace { +// the gap between button edge and the interior area used by Windows for the +// standard buttons +const int OD_BUTTON_MARGIN = 4; + class wxODButtonImageData : public wxButtonImageData { public: - wxODButtonImageData() { m_dir = wxLEFT; } + wxODButtonImageData(wxButton *btn, const wxBitmap& bitmap) + { + SetBitmap(bitmap, wxButton::State_Normal); + + m_dir = wxLEFT; + + // we use margins when we have both bitmap and text, but when we have + // only the bitmap it should take up the entire button area + if ( !btn->GetLabel().empty() ) + { + m_margin.x = btn->GetCharWidth(); + m_margin.y = btn->GetCharHeight() / 2; + } + } virtual wxBitmap GetBitmap(wxButton::State which) const { @@ -151,9 +172,9 @@ public: m_margin = wxSize(x, y); } - virtual bool IsHorizontal() const + virtual wxDirection GetBitmapPosition() const { - return m_dir == wxLEFT || m_dir == wxRIGHT; + return m_dir; } virtual void SetBitmapPosition(wxDirection dir) @@ -173,15 +194,26 @@ private: #if wxUSE_UXTHEME +// somehow the margin is one pixel greater than the value returned by +// GetThemeMargins() call +const int XP_BUTTON_EXTRA_MARGIN = 1; + class wxXPButtonImageData : public wxButtonImageData { public: // we must be constructed with the size of our images as we need to create // the image list - wxXPButtonImageData(wxButton *btn, const wxSize& size) - : m_iml(size.x, size.y, true /* use mask */, wxButton::State_Max), + wxXPButtonImageData(wxButton *btn, const wxBitmap& bitmap) + : m_iml(bitmap.GetWidth(), bitmap.GetHeight(), true /* use mask */, + wxButton::State_Max), m_hwndBtn(GetHwndOf(btn)) { + // initialize all bitmaps to normal state + for ( int n = 0; n < wxButton::State_Max; n++ ) + { + m_iml.Add(bitmap); + } + m_data.himl = GetHimagelistOf(&m_iml); // use default margins @@ -192,6 +224,8 @@ public: // and default alignment m_data.uAlign = BUTTON_IMAGELIST_ALIGN_LEFT; + + UpdateImageInfo(); } virtual wxBitmap GetBitmap(wxButton::State which) const @@ -201,22 +235,7 @@ public: virtual void SetBitmap(const wxBitmap& bitmap, wxButton::State which) { - const int imagesToAdd = which - m_iml.GetImageCount(); - if ( imagesToAdd >= 0 ) - { - if ( imagesToAdd > 0 ) - { - const wxBitmap bmpNormal = GetBitmap(wxButton::State_Normal); - for ( int n = 0; n < imagesToAdd; n++ ) - m_iml.Add(bmpNormal); - } - - m_iml.Add(bitmap); - } - else // we already have this bitmap - { - m_iml.Replace(which, bitmap); - } + m_iml.Replace(which, bitmap); UpdateImageInfo(); } @@ -240,10 +259,26 @@ public: } } - virtual bool IsHorizontal() const + virtual wxDirection GetBitmapPosition() const { - return m_data.uAlign == BUTTON_IMAGELIST_ALIGN_LEFT || - m_data.uAlign == BUTTON_IMAGELIST_ALIGN_RIGHT; + switch ( m_data.uAlign ) + { + default: + wxFAIL_MSG( "invalid image alignment" ); + // fall through + + case BUTTON_IMAGELIST_ALIGN_LEFT: + return wxLEFT; + + case BUTTON_IMAGELIST_ALIGN_RIGHT: + return wxRIGHT; + + case BUTTON_IMAGELIST_ALIGN_TOP: + return wxTOP; + + case BUTTON_IMAGELIST_ALIGN_BOTTOM: + return wxBOTTOM; + } } virtual void SetBitmapPosition(wxDirection dir) @@ -537,11 +572,20 @@ void wxButton::SetLabel(const wxString& label) wxSize wxButton::DoGetBestSize() const { - wxSize size = wxMSWButton::ComputeBestSize(const_cast(this)); + wxSize size; + + // account for the text part + if ( !GetLabel().empty() ) + { + size = wxMSWButton::ComputeBestSize(const_cast(this)); + } + if ( m_imageData ) { + // account for the bitmap size const wxSize sizeBmp = m_imageData->GetBitmap(State_Normal).GetSize(); - if ( m_imageData->IsHorizontal() ) + const wxDirection dirBmp = m_imageData->GetBitmapPosition(); + if ( dirBmp == wxLEFT || dirBmp == wxRIGHT ) { size.x += sizeBmp.x; if ( sizeBmp.y > size.y ) @@ -554,8 +598,46 @@ wxSize wxButton::DoGetBestSize() const size.x = sizeBmp.x; } + // account for the user-specified margins size += 2*m_imageData->GetBitmapMargins(); + // and also for the margins we always add internally + int marginH = 0, + marginV = 0; +#if wxUSE_UXTHEME + if ( wxUxThemeEngine::GetIfActive() ) + { + wxUxThemeHandle theme(const_cast(this), L"BUTTON"); + + MARGINS margins; + wxUxThemeEngine::Get()->GetThemeMargins(theme, NULL, + BP_PUSHBUTTON, PBS_NORMAL, + TMT_CONTENTMARGINS, NULL, + &margins); + + // XP doesn't draw themed buttons correctly when the client area is + // smaller than 8x8 - enforce this minimum size for small bitmaps + size.IncTo(wxSize(8, 8)); + + // don't add margins for the borderless buttons, they don't need + // them and it just makes them appear larger than needed + if ( !HasFlag(wxBORDER_NONE) ) + { + marginH = margins.cxLeftWidth + margins.cxRightWidth + + 2*XP_BUTTON_EXTRA_MARGIN; + marginV = margins.cyTopHeight + margins.cyBottomHeight + + 2*XP_BUTTON_EXTRA_MARGIN; + } + } + else +#endif // wxUSE_UXTHEME + { + marginH = + marginV = OD_BUTTON_MARGIN; + } + + size.IncBy(marginH, marginV); + CacheBestSize(size); } @@ -820,20 +902,26 @@ WXLRESULT wxButton::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) // as the theme size might have changed InvalidateBestSize(); } - else if ( wxUxThemeEngine::GetIfActive() ) +#endif // wxUSE_UXTHEME + // must use m_mouseInWindow here instead of IsMouseInWindow() + // since we need to know the first time the mouse enters the window + // and IsMouseInWindow() would return true in this case + else if ( (nMsg == WM_MOUSEMOVE && !m_mouseInWindow) || + nMsg == WM_MOUSELEAVE ) { - // we need to Refresh() if mouse has entered or left window - // so we can update the hot tracking state - // must use m_mouseInWindow here instead of IsMouseInWindow() - // since we need to know the first time the mouse enters the window - // and IsMouseInWindow() would return true in this case - if ( ( nMsg == WM_MOUSEMOVE && !m_mouseInWindow ) || - nMsg == WM_MOUSELEAVE ) + if ( + IsEnabled() && + ( +#if wxUSE_UXTHEME + wxUxThemeEngine::GetIfActive() || +#endif // wxUSE_UXTHEME + m_imageData && m_imageData->GetBitmap(State_Current).IsOk() + ) + ) { Refresh(); } } -#endif // wxUSE_UXTHEME // let the base class do all real processing return wxControl::MSWWindowProc(nMsg, wParam, lParam); @@ -854,18 +942,36 @@ void wxButton::DoSetBitmap(const wxBitmap& bitmap, State which) if ( !m_imageData ) { #if wxUSE_UXTHEME - if ( wxUxThemeEngine::GetIfActive() ) - m_imageData = new wxXPButtonImageData(this, bitmap.GetSize()); + // using image list doesn't work correctly if we don't have any label + // (even if we use BUTTON_IMAGELIST_ALIGN_CENTER alignment and + // BS_BITMAP style), at least under Windows 2003 so use owner drawn + // strategy for bitmap-only buttons + if ( !GetLabel().empty() && wxUxThemeEngine::GetIfActive() ) + { + m_imageData = new wxXPButtonImageData(this, bitmap); + } else #endif // wxUSE_UXTHEME - m_imageData = new wxODButtonImageData; + { + m_imageData = new wxODButtonImageData(this, bitmap); + MakeOwnerDrawn(); + } // if a bitmap was assigned to the bitmap, its best size must be // changed to account for it InvalidateBestSize(); } + else + { + m_imageData->SetBitmap(bitmap, which); + } + + Refresh(); +} - m_imageData->SetBitmap(bitmap, which); +wxSize wxButton::DoGetBitmapMargins() const +{ + return m_imageData ? m_imageData->GetBitmapMargins() : wxSize(0, 0); } void wxButton::DoSetBitmapMargins(wxCoord x, wxCoord y) @@ -887,15 +993,36 @@ void wxButton::DoSetBitmapPosition(wxDirection dir) // ---------------------------------------------------------------------------- // drawing helpers +namespace +{ + +// return the button state using both the ODS_XXX flags specified in state +// parameter and the current button state +wxButton::State GetButtonState(wxButton *btn, UINT state) +{ + if ( state & ODS_DISABLED ) + return wxButton::State_Disabled; -static void DrawButtonText(HDC hdc, - RECT *pRect, - const wxString& text, - COLORREF col, - int flags) + if ( state & ODS_SELECTED ) + return wxButton::State_Pressed; + + if ( btn->HasCapture() || btn->IsMouseInWindow() ) + return wxButton::State_Current; + + if ( state & ODS_FOCUS ) + return wxButton::State_Focused; + + return wxButton::State_Normal; +} + +void DrawButtonText(HDC hdc, + RECT *pRect, + const wxString& text, + COLORREF col, + int flags) { - COLORREF colOld = SetTextColor(hdc, col); - int modeOld = SetBkMode(hdc, TRANSPARENT); + wxTextColoursChanger changeFg(hdc, col, CLR_INVALID); + wxBkModeChanger changeBkMode(hdc, wxBRUSHSTYLE_TRANSPARENT); // center text horizontally in any case flags |= DT_CENTER; @@ -927,12 +1054,9 @@ static void DrawButtonText(HDC hdc, ::DrawText(hdc, text.wx_str(), text.length(), pRect, flags | DT_SINGLELINE | DT_VCENTER); } - - SetBkMode(hdc, modeOld); - SetTextColor(hdc, colOld); } -static void DrawRect(HDC hdc, const RECT& r) +void DrawRect(HDC hdc, const RECT& r) { wxDrawLine(hdc, r.left, r.top, r.right, r.top); wxDrawLine(hdc, r.right, r.top, r.right, r.bottom); @@ -940,47 +1064,6 @@ static void DrawRect(HDC hdc, const RECT& r) wxDrawLine(hdc, r.left, r.bottom, r.left, r.top); } -void wxButton::MakeOwnerDrawn() -{ - long style = GetWindowLong(GetHwnd(), GWL_STYLE); - if ( (style & BS_OWNERDRAW) != BS_OWNERDRAW ) - { - // make it so - style |= BS_OWNERDRAW; - SetWindowLong(GetHwnd(), GWL_STYLE, style); - } -} - -bool wxButton::SetBackgroundColour(const wxColour &colour) -{ - if ( !wxControl::SetBackgroundColour(colour) ) - { - // nothing to do - return false; - } - - MakeOwnerDrawn(); - - Refresh(); - - return true; -} - -bool wxButton::SetForegroundColour(const wxColour &colour) -{ - if ( !wxControl::SetForegroundColour(colour) ) - { - // nothing to do - return false; - } - - MakeOwnerDrawn(); - - Refresh(); - - return true; -} - /* The button frame looks like this normally: @@ -1016,19 +1099,18 @@ bool wxButton::SetForegroundColour(const wxColour &colour) BGGGGGGGGGGGGGGGGGB BBBBBBBBBBBBBBBBBBB */ - -static void DrawButtonFrame(HDC hdc, const RECT& rectBtn, - bool selected, bool pushed) +void DrawButtonFrame(HDC hdc, RECT& rectBtn, + bool selected, bool pushed) { RECT r; CopyRect(&r, &rectBtn); - HPEN hpenBlack = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DDKSHADOW)), - hpenGrey = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DSHADOW)), - hpenLightGr = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DLIGHT)), - hpenWhite = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DHILIGHT)); + AutoHPEN hpenBlack(GetSysColor(COLOR_3DDKSHADOW)), + hpenGrey(GetSysColor(COLOR_3DSHADOW)), + hpenLightGr(GetSysColor(COLOR_3DLIGHT)), + hpenWhite(GetSysColor(COLOR_3DHILIGHT)); - HPEN hpenOld = (HPEN)SelectObject(hdc, hpenBlack); + SelectInHDC selectPen(hdc, hpenBlack); r.right--; r.bottom--; @@ -1067,98 +1149,126 @@ static void DrawButtonFrame(HDC hdc, const RECT& rectBtn, wxDrawLine(hdc, r.right - 1, r.bottom - 1, r.right - 1, r.top); } - (void)SelectObject(hdc, hpenOld); - DeleteObject(hpenWhite); - DeleteObject(hpenLightGr); - DeleteObject(hpenGrey); - DeleteObject(hpenBlack); + InflateRect(&rectBtn, -OD_BUTTON_MARGIN, -OD_BUTTON_MARGIN); } #if wxUSE_UXTHEME -static -void MSWDrawXPBackground(wxButton *button, WXDRAWITEMSTRUCT *wxdis) +void DrawXPBackground(wxButton *button, HDC hdc, RECT& rectBtn, UINT state) { - LPDRAWITEMSTRUCT lpDIS = (LPDRAWITEMSTRUCT)wxdis; - HDC hdc = lpDIS->hDC; - UINT state = lpDIS->itemState; - RECT rectBtn; - CopyRect(&rectBtn, &lpDIS->rcItem); - wxUxThemeHandle theme(button, L"BUTTON"); - int iState; - if ( state & ODS_SELECTED ) + // this array is indexed by wxButton::State values and so must be kept in + // sync with it + static const int uxStates[] = { - iState = PBS_PRESSED; - } - else if ( button->HasCapture() || button->IsMouseInWindow() ) - { - iState = PBS_HOT; - } - else if ( state & ODS_FOCUS ) - { - iState = PBS_DEFAULTED; - } - else if ( state & ODS_DISABLED ) - { - iState = PBS_DISABLED; - } - else - { - iState = PBS_NORMAL; - } + PBS_NORMAL, PBS_HOT, PBS_PRESSED, PBS_DISABLED, PBS_DEFAULTED + }; + + int iState = uxStates[GetButtonState(button, state)]; + + wxUxThemeEngine * const engine = wxUxThemeEngine::Get(); // draw parent background if needed - if ( wxUxThemeEngine::Get()->IsThemeBackgroundPartiallyTransparent(theme, - BP_PUSHBUTTON, - iState) ) + if ( engine->IsThemeBackgroundPartiallyTransparent + ( + theme, + BP_PUSHBUTTON, + iState + ) ) { - wxUxThemeEngine::Get()->DrawThemeParentBackground(GetHwndOf(button), hdc, &rectBtn); + engine->DrawThemeParentBackground(GetHwndOf(button), hdc, &rectBtn); } // draw background - wxUxThemeEngine::Get()->DrawThemeBackground(theme, hdc, BP_PUSHBUTTON, iState, - &rectBtn, NULL); + engine->DrawThemeBackground(theme, hdc, BP_PUSHBUTTON, iState, + &rectBtn, NULL); // calculate content area margins MARGINS margins; - wxUxThemeEngine::Get()->GetThemeMargins(theme, hdc, BP_PUSHBUTTON, iState, - TMT_CONTENTMARGINS, &rectBtn, &margins); - RECT rectClient; - ::CopyRect(&rectClient, &rectBtn); - ::InflateRect(&rectClient, -margins.cxLeftWidth, -margins.cyTopHeight); - - // if focused and !nofocus rect - if ( (state & ODS_FOCUS) && !(state & ODS_NOFOCUSRECT) ) - { - DrawFocusRect(hdc, &rectClient); - } + engine->GetThemeMargins(theme, hdc, BP_PUSHBUTTON, iState, + TMT_CONTENTMARGINS, &rectBtn, &margins); + ::InflateRect(&rectBtn, -margins.cxLeftWidth, -margins.cyTopHeight); + ::InflateRect(&rectBtn, -XP_BUTTON_EXTRA_MARGIN, -XP_BUTTON_EXTRA_MARGIN); if ( button->UseBgCol() ) { COLORREF colBg = wxColourToRGB(button->GetBackgroundColour()); - HBRUSH hbrushBackground = ::CreateSolidBrush(colBg); + AutoHBRUSH hbrushBackground(colBg); // don't overwrite the focus rect + RECT rectClient; + ::CopyRect(&rectClient, &rectBtn); ::InflateRect(&rectClient, -1, -1); FillRect(hdc, &rectClient, hbrushBackground); - ::DeleteObject(hbrushBackground); } } #endif // wxUSE_UXTHEME +} // anonymous namespace + +// ---------------------------------------------------------------------------- +// owner drawn buttons support +// ---------------------------------------------------------------------------- + +void wxButton::MakeOwnerDrawn() +{ + long style = GetWindowLong(GetHwnd(), GWL_STYLE); + if ( (style & BS_OWNERDRAW) != BS_OWNERDRAW ) + { + // make it so + style |= BS_OWNERDRAW; + SetWindowLong(GetHwnd(), GWL_STYLE, style); + } +} + +bool wxButton::SetBackgroundColour(const wxColour &colour) +{ + if ( !wxControl::SetBackgroundColour(colour) ) + { + // nothing to do + return false; + } + + MakeOwnerDrawn(); + + Refresh(); + + return true; +} + +bool wxButton::SetForegroundColour(const wxColour &colour) +{ + if ( !wxControl::SetForegroundColour(colour) ) + { + // nothing to do + return false; + } + + MakeOwnerDrawn(); + + Refresh(); + + return true; +} + bool wxButton::MSWOnDraw(WXDRAWITEMSTRUCT *wxdis) { LPDRAWITEMSTRUCT lpDIS = (LPDRAWITEMSTRUCT)wxdis; HDC hdc = lpDIS->hDC; + UINT state = lpDIS->itemState; + bool pushed = (SendMessage(GetHwnd(), BM_GETSTATE, 0, 0) & BST_PUSHED) != 0; + RECT rectBtn; CopyRect(&rectBtn, &lpDIS->rcItem); + const wxString label = GetLabel(); + + // draw the button background #if wxUSE_UXTHEME if ( wxUxThemeEngine::GetIfActive() ) { - MSWDrawXPBackground(this, wxdis); + DrawXPBackground(this, hdc, rectBtn, state); } else #endif // wxUSE_UXTHEME @@ -1166,53 +1276,106 @@ bool wxButton::MSWOnDraw(WXDRAWITEMSTRUCT *wxdis) COLORREF colBg = wxColourToRGB(GetBackgroundColour()); // first, draw the background - HBRUSH hbrushBackground = ::CreateSolidBrush(colBg); + AutoHBRUSH hbrushBackground(colBg); FillRect(hdc, &rectBtn, hbrushBackground); - ::DeleteObject(hbrushBackground); // draw the border for the current state bool selected = (state & ODS_SELECTED) != 0; if ( !selected ) { - wxTopLevelWindow *tlw = wxDynamicCast(wxGetTopLevelParent(this), wxTopLevelWindow); + wxTopLevelWindow * + tlw = wxDynamicCast(wxGetTopLevelParent(this), wxTopLevelWindow); if ( tlw ) { selected = tlw->GetDefaultItem() == this; } } - bool pushed = (SendMessage(GetHwnd(), BM_GETSTATE, 0, 0) & BST_PUSHED) != 0; DrawButtonFrame(hdc, rectBtn, selected, pushed); + } - // if focused and !nofocus rect - if ( (state & ODS_FOCUS) && !(state & ODS_NOFOCUSRECT) ) - { - RECT rectFocus; - CopyRect(&rectFocus, &rectBtn); - - // I don't know where does this constant come from, but this is how - // Windows draws them - InflateRect(&rectFocus, -4, -4); + // draw the focus rectangle if we need it + if ( (state & ODS_FOCUS) && !(state & ODS_NOFOCUSRECT) ) + { + DrawFocusRect(hdc, &rectBtn); - DrawFocusRect(hdc, &rectFocus); +#if wxUSE_UXTHEME + if ( !wxUxThemeEngine::GetIfActive() ) +#endif // wxUSE_UXTHEME + { + if ( pushed ) + { + // the label is shifted by 1 pixel to create "pushed" effect + OffsetRect(&rectBtn, 1, 1); + } } + } + - if ( pushed ) + // draw the image, if any + if ( m_imageData ) + { + wxBitmap bmp = m_imageData->GetBitmap(GetButtonState(this, state)); + if ( !bmp.IsOk() ) + bmp = m_imageData->GetBitmap(State_Normal); + + const wxSize sizeBmp = bmp.GetSize(); + const wxSize margin = m_imageData->GetBitmapMargins(); + const wxSize sizeBmpWithMargins(sizeBmp + 2*margin); + wxRect rectButton(wxRectFromRECT(rectBtn)); + + // for simplicity, we start with centred rectangle and then move it to + // the appropriate edge + wxRect rectBitmap = wxRect(sizeBmp).CentreIn(rectButton); + switch ( m_imageData->GetBitmapPosition() ) { - // the label is shifted by 1 pixel to create "pushed" effect - OffsetRect(&rectBtn, 1, 1); + default: + wxFAIL_MSG( "invalid direction" ); + // fall through + + case wxLEFT: + rectBitmap.x = rectButton.x + margin.x; + rectButton.x += sizeBmpWithMargins.x; + rectButton.width -= sizeBmpWithMargins.x; + break; + + case wxRIGHT: + rectBitmap.x = rectButton.GetRight() - sizeBmp.x - margin.x; + rectButton.width -= sizeBmpWithMargins.x; + break; + + case wxTOP: + rectBitmap.y = rectButton.y + margin.y; + rectButton.y += sizeBmpWithMargins.y; + rectButton.height -= sizeBmpWithMargins.y; + break; + + case wxBOTTOM: + rectBitmap.y = rectButton.GetBottom() - sizeBmp.y - margin.y; + rectButton.height -= sizeBmpWithMargins.y; + break; } + + wxDCTemp dst((WXHDC)hdc); + dst.DrawBitmap(bmp, rectBitmap.GetPosition(), true); + + wxCopyRectToRECT(rectButton, rectBtn); } - COLORREF colFg = state & ODS_DISABLED - ? ::GetSysColor(COLOR_GRAYTEXT) - : wxColourToRGB(GetForegroundColour()); - // notice that DT_HIDEPREFIX doesn't work on old (pre-Windows 2000) systems - // but by happy coincidence ODS_NOACCEL is not used under them neither so - // DT_HIDEPREFIX should never be used there - DrawButtonText(hdc, &rectBtn, GetLabel(), colFg, - state & ODS_NOACCEL ? DT_HIDEPREFIX : 0); + // finally draw the label + if ( !label.empty() ) + { + COLORREF colFg = state & ODS_DISABLED + ? ::GetSysColor(COLOR_GRAYTEXT) + : wxColourToRGB(GetForegroundColour()); + + // notice that DT_HIDEPREFIX doesn't work on old (pre-Windows 2000) + // systems but by happy coincidence ODS_NOACCEL is not used under them + // neither so DT_HIDEPREFIX should never be used there + DrawButtonText(hdc, &rectBtn, label, colFg, + state & ODS_NOACCEL ? DT_HIDEPREFIX : 0); + } return true; }