X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/31dcbd12ef41de81f46e09f2a1694d5f83f08cff..86b8b3ac31b49ba93907c6088aac11ddb54f22bc:/src/msw/button.cpp diff --git a/src/msw/button.cpp b/src/msw/button.cpp index 50ea2ad9f2..433a71e73d 100644 --- a/src/msw/button.cpp +++ b/src/msw/button.cpp @@ -115,6 +115,10 @@ using namespace wxMSWImpl; #define BCM_SETSHIELD 0x160c #endif +#if wxUSE_UXTHEME +extern wxWindowMSW *wxWindowBeingErased; // From src/msw/window.cpp +#endif // wxUSE_UXTHEME + // ---------------------------------------------------------------------------- // button image data // ---------------------------------------------------------------------------- @@ -153,6 +157,7 @@ public: wxODButtonImageData(wxButton *btn, const wxBitmap& bitmap) { SetBitmap(bitmap, wxButton::State_Normal); + SetBitmap(bitmap.ConvertToDisabled(), wxButton::State_Disabled); m_dir = wxLEFT; @@ -221,10 +226,11 @@ public: wxButton::State_Max), m_hwndBtn(GetHwndOf(btn)) { - // initialize all bitmaps to normal state + // initialize all bitmaps except for the disabled one to normal state for ( int n = 0; n < wxButton::State_Max; n++ ) { - m_iml.Add(bitmap); + m_iml.Add(n == wxButton::State_Disabled ? bitmap.ConvertToDisabled() + : bitmap); } m_data.himl = GetHimagelistOf(&m_iml); @@ -987,6 +993,30 @@ wxBitmap wxButton::DoGetBitmap(State which) const void wxButton::DoSetBitmap(const wxBitmap& bitmap, State which) { +#if wxUSE_UXTHEME + wxXPButtonImageData *oldData = NULL; +#endif // wxUSE_UXTHEME + + // Check if we already had bitmaps of different size. + if ( m_imageData && + bitmap.GetSize() != m_imageData->GetBitmap(State_Normal).GetSize() ) + { + wxASSERT_MSG( which == State_Normal, + "Must set normal bitmap with the new size first" ); + +#if wxUSE_UXTHEME + if ( ShowsLabel() && wxUxThemeEngine::GetIfActive() ) + { + // We can't change the size of the images stored in wxImageList + // in wxXPButtonImageData::m_iml so force recreating it below but + // keep the current data to copy its values into the new one. + oldData = static_cast(m_imageData); + m_imageData = NULL; + } +#endif // wxUSE_UXTHEME + //else: wxODButtonImageData doesn't require anything special + } + // allocate the image data when the first bitmap is set if ( !m_imageData ) { @@ -998,6 +1028,20 @@ void wxButton::DoSetBitmap(const wxBitmap& bitmap, State which) if ( ShowsLabel() && wxUxThemeEngine::GetIfActive() ) { m_imageData = new wxXPButtonImageData(this, bitmap); + + if ( oldData ) + { + // Preserve the old values in case the user changed them. + m_imageData->SetBitmapPosition(oldData->GetBitmapPosition()); + + const wxSize oldMargins = oldData->GetBitmapMargins(); + m_imageData->SetBitmapMargins(oldMargins.x, oldMargins.y); + + // No need to preserve the bitmaps though as they were of wrong + // size anyhow. + + delete oldData; + } } else #endif // wxUSE_UXTHEME @@ -1277,7 +1321,20 @@ void DrawXPBackground(wxButton *button, HDC hdc, RECT& rectBtn, UINT state) iState ) ) { + // Set this button as the one whose background is being erased: this + // allows our WM_ERASEBKGND handler used by DrawThemeParentBackground() + // to correctly align the background brush with this window instead of + // the parent window to which WM_ERASEBKGND is sent. Notice that this + // doesn't work with custom user-defined EVT_ERASE_BACKGROUND handlers + // as they won't be aligned but unfortunately all the attempts to fix + // it by shifting DC origin before calling DrawThemeParentBackground() + // failed to work so we at least do this, even though this is far from + // being the perfect solution. + wxWindowBeingErased = button; + engine->DrawThemeParentBackground(GetHwndOf(button), hdc, &rectBtn); + + wxWindowBeingErased = NULL; } // draw background