#include "wx/msw/private.h"
#include "wx/image.h"
-#include "wx/msw/uxtheme.h"
+
+#if wxUSE_UXTHEME
+ #include "wx/msw/uxtheme.h"
+
+ // no need to include tmschema.h
+ #ifndef BP_PUSHBUTTON
+ #define BP_PUSHBUTTON 1
+
+ #define PBS_NORMAL 1
+ #define PBS_HOT 2
+ #define PBS_PRESSED 3
+ #define PBS_DISABLED 4
+ #define PBS_DEFAULTED 5
+
+ #define TMT_CONTENTMARGINS 3602
+ #endif
+#endif // wxUSE_UXTHEME
+
+#ifndef ODS_NOFOCUSRECT
+ #define ODS_NOFOCUSRECT 0x0200
+#endif
// ----------------------------------------------------------------------------
// macros
parent->AddChild(this);
- m_backgroundColour = parent->GetBackgroundColour();
- m_foregroundColour = parent->GetForegroundColour();
m_windowStyle = style;
if ( style & wxBU_AUTODRAW )
wxBitmapButtonBase::OnSetBitmap();
}
+#if wxUSE_UXTHEME
+static
+void MSWDrawXPBackground(wxButton *button, WXDRAWITEMSTRUCT *wxdis)
+{
+ 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 )
+ {
+ 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;
+ }
+
+ // draw parent background if needed
+ if ( wxUxThemeEngine::Get()->IsThemeBackgroundPartiallyTransparent(theme,
+ BP_PUSHBUTTON,
+ iState) )
+ {
+ wxUxThemeEngine::Get()->DrawThemeParentBackground(GetHwndOf(button), hdc, &rectBtn);
+ }
+
+ // draw background
+ wxUxThemeEngine::Get()->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);
+ }
+
+ if ( button->UseBgCol() )
+ {
+ COLORREF colBg = wxColourToRGB(button->GetBackgroundColour());
+ HBRUSH hbrushBackground = ::CreateSolidBrush(colBg);
+
+ // don't overwrite the focus rect
+ ::InflateRect(&rectClient, -1, -1);
+ FillRect(hdc, &rectClient, hbrushBackground);
+ ::DeleteObject(hbrushBackground);
+ }
+}
+#endif // wxUSE_UXTHEME
+
// VZ: should be at the very least less than wxDEFAULT_BUTTON_MARGIN
#define FOCUS_MARGIN 3
int wBmp = bitmap->GetWidth();
int hBmp = bitmap->GetHeight();
+#if wxUSE_UXTHEME
+ if ( autoDraw && wxUxThemeEngine::GetIfActive() )
+ {
+ MSWDrawXPBackground(this, item);
+ wxUxThemeHandle theme(this, L"BUTTON");
+
+ // calculate content area margins
+ // assuming here that each state is the same size
+ MARGINS margins;
+ wxUxThemeEngine::Get()->GetThemeMargins(theme, NULL,
+ BP_PUSHBUTTON, PBS_NORMAL,
+ TMT_CONTENTMARGINS, NULL,
+ &margins);
+ int marginX = margins.cxLeftWidth + 1;
+ int marginY = margins.cyTopHeight + 1;
+ int x1,y1;
+
+ if ( m_windowStyle & wxBU_LEFT )
+ {
+ x1 = x + marginX;
+ }
+ else if ( m_windowStyle & wxBU_RIGHT )
+ {
+ x1 = x + (width - wBmp) - marginX;
+ }
+ else
+ {
+ x1 = x + (width - wBmp) / 2;
+ }
+
+ if ( m_windowStyle & wxBU_TOP )
+ {
+ y1 = y + marginY;
+ }
+ else if ( m_windowStyle & wxBU_BOTTOM )
+ {
+ y1 = y + (height - hBmp) - marginY;
+ }
+ else
+ {
+ y1 = y + (height - hBmp) / 2;
+ }
+
+ // draw the bitmap
+ wxClientDC dst;
+ dst.SetHDC((WXHDC) hDC, false);
+ dst.DrawBitmap(*bitmap, x1, y1, true);
+
+ return true;
+ }
+#endif // wxUSE_UXTHEME
+
int x1,y1;
if(m_windowStyle & wxBU_LEFT)
penLight = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_3DLIGHT));
penShadow = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_3DSHADOW));
penDkShadow = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_3DDKSHADOW));
- // brushFace = CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
- // Taking the background colour fits in better with
- // Windows XP themes.
- brushFace = CreateSolidBrush(m_backgroundColour.m_pixel);
+ brushFace = CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
// draw the rectangle
RECT rect;
{
if ( m_bmpNormal.Ok() )
{
+#if wxUSE_UXTHEME
+ if ( (GetWindowStyleFlag() & wxBU_AUTODRAW) && wxUxThemeEngine::GetIfActive() )
+ {
+ wxUxThemeHandle theme((wxBitmapButton *)this, L"BUTTON");
+
+ // calculate content area margins
+ // assuming here that each state is the same size
+ MARGINS margins;
+ wxUxThemeEngine::Get()->GetThemeMargins(theme, NULL,
+ BP_PUSHBUTTON, PBS_NORMAL,
+ TMT_CONTENTMARGINS, NULL,
+ &margins);
+ wxSize best(m_bmpNormal.GetWidth() + 2 * (margins.cxLeftWidth + 1),
+ m_bmpNormal.GetHeight() + 2* (margins.cyTopHeight + 1));
+ CacheBestSize(best);
+ return best;
+ }
+#endif // wxUSE_UXTHEME
+
wxSize best(m_bmpNormal.GetWidth() + 2*m_marginX,
m_bmpNormal.GetHeight() + 2*m_marginY);
CacheBestSize(best);
#include "wx/tokenzr.h"
#include "wx/msw/private.h"
+#if wxUSE_UXTHEME
+ #include "wx/msw/uxtheme.h"
+
+ // no need to include tmschema.h
+ #ifndef BP_PUSHBUTTON
+ #define BP_PUSHBUTTON 1
+
+ #define PBS_NORMAL 1
+ #define PBS_HOT 2
+ #define PBS_PRESSED 3
+ #define PBS_DISABLED 4
+ #define PBS_DEFAULTED 5
+
+ #define TMT_CONTENTMARGINS 3602
+ #endif
+#endif // wxUSE_UXTHEME
+
+#ifndef WM_THEMECHANGED
+ #define WM_THEMECHANGED 0x031A
+#endif
+
+#ifndef ODS_NOACCEL
+ #define ODS_NOACCEL 0x0100
+#endif
+
+#ifndef ODS_NOFOCUSRECT
+ #define ODS_NOFOCUSRECT 0x0200
+#endif
+
// ----------------------------------------------------------------------------
// macros
// ----------------------------------------------------------------------------
// and continue with processing the message normally as well
}
+#if wxUSE_UXTHEME
+ else if ( nMsg == WM_THEMECHANGED )
+ {
+ // need to recalculate the best size here
+ // as the theme size might have changed
+ InvalidateBestSize();
+ }
+ else if ( wxUxThemeEngine::GetIfActive() )
+ {
+ // 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 )
+ {
+ Refresh();
+ }
+ }
+#endif // wxUSE_UXTHEME
// let the base class do all real processing
return wxControl::MSWWindowProc(nMsg, wParam, lParam);
DeleteObject(hpenBlack);
}
-bool wxButton::MSWOnDraw(WXDRAWITEMSTRUCT *wxdis)
+#if wxUSE_UXTHEME
+static
+void MSWDrawXPBackground(wxButton *button, WXDRAWITEMSTRUCT *wxdis)
{
LPDRAWITEMSTRUCT lpDIS = (LPDRAWITEMSTRUCT)wxdis;
-
+ HDC hdc = lpDIS->hDC;
+ UINT state = lpDIS->itemState;
RECT rectBtn;
CopyRect(&rectBtn, &lpDIS->rcItem);
- COLORREF colBg = wxColourToRGB(GetBackgroundColour()),
- colFg = wxColourToRGB(GetForegroundColour());
+ wxUxThemeHandle theme(button, L"BUTTON");
+ int iState;
+
+ if ( state & ODS_SELECTED )
+ {
+ 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;
+ }
+ // draw parent background if needed
+ if ( wxUxThemeEngine::Get()->IsThemeBackgroundPartiallyTransparent(theme,
+ BP_PUSHBUTTON,
+ iState) )
+ {
+ wxUxThemeEngine::Get()->DrawThemeParentBackground(GetHwndOf(button), hdc, &rectBtn);
+ }
+
+ // draw background
+ wxUxThemeEngine::Get()->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);
+ }
+
+ if ( button->UseBgCol() )
+ {
+ COLORREF colBg = wxColourToRGB(button->GetBackgroundColour());
+ HBRUSH hbrushBackground = ::CreateSolidBrush(colBg);
+
+ // don't overwrite the focus rect
+ ::InflateRect(&rectClient, -1, -1);
+ FillRect(hdc, &rectClient, hbrushBackground);
+ ::DeleteObject(hbrushBackground);
+ }
+}
+#endif // wxUSE_UXTHEME
+
+bool wxButton::MSWOnDraw(WXDRAWITEMSTRUCT *wxdis)
+{
+ LPDRAWITEMSTRUCT lpDIS = (LPDRAWITEMSTRUCT)wxdis;
HDC hdc = lpDIS->hDC;
UINT state = lpDIS->itemState;
+ RECT rectBtn;
+ CopyRect(&rectBtn, &lpDIS->rcItem);
- // first, draw the background
- HBRUSH hbrushBackground = ::CreateSolidBrush(colBg);
+#if wxUSE_UXTHEME
+ if ( wxUxThemeEngine::GetIfActive() )
+ {
+ MSWDrawXPBackground(this, wxdis);
+ }
+ else
+#endif // wxUSE_UXTHEME
+ {
+ COLORREF colBg = wxColourToRGB(GetBackgroundColour());
- FillRect(hdc, &rectBtn, hbrushBackground);
+ // first, draw the background
+ HBRUSH hbrushBackground = ::CreateSolidBrush(colBg);
+ FillRect(hdc, &rectBtn, hbrushBackground);
+ ::DeleteObject(hbrushBackground);
- // draw the border for the current state
- bool selected = (state & ODS_SELECTED) != 0;
- if ( !selected )
- {
- wxPanel *panel = wxDynamicCast(GetParent(), wxPanel);
- if ( panel )
+ // draw the border for the current state
+ bool selected = (state & ODS_SELECTED) != 0;
+ if ( !selected )
{
- selected = panel->GetDefaultItem() == this;
+ wxPanel *panel = wxDynamicCast(GetParent(), wxPanel);
+ if ( panel )
+ {
+ selected = panel->GetDefaultItem() == this;
+ }
}
- }
- bool pushed = (SendMessage(GetHwnd(), BM_GETSTATE, 0, 0) & BST_PUSHED) != 0;
+ bool pushed = (SendMessage(GetHwnd(), BM_GETSTATE, 0, 0) & BST_PUSHED) != 0;
- DrawButtonFrame(hdc, rectBtn, selected, pushed);
+ DrawButtonFrame(hdc, rectBtn, selected, pushed);
- // draw the focus rect if needed
- if ( state & ODS_FOCUS )
- {
- RECT rectFocus;
- CopyRect(&rectFocus, &rectBtn);
+ // 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);
+ // I don't know where does this constant come from, but this is how
+ // Windows draws them
+ InflateRect(&rectFocus, -4, -4);
- DrawFocusRect(hdc, &rectFocus);
- }
+ DrawFocusRect(hdc, &rectFocus);
+ }
- if ( pushed )
- {
- // the label is shifted by 1 pixel to create "pushed" effect
- OffsetRect(&rectBtn, 1, 1);
+ if ( pushed )
+ {
+ // the label is shifted by 1 pixel to create "pushed" effect
+ OffsetRect(&rectBtn, 1, 1);
+ }
}
- DrawButtonText(hdc, &rectBtn, GetLabel(),
+ COLORREF colFg = wxColourToRGB(GetForegroundColour());
+ DrawButtonText(hdc, &rectBtn,
+ (state & ODS_NOACCEL ? wxStripMenuCodes(GetLabel())
+ : GetLabel()),
state & ODS_DISABLED ? GetSysColor(COLOR_GRAYTEXT)
: colFg);
- ::DeleteObject(hbrushBackground);
-
return true;
}