setting foreground colour for wxCheckBox now works when using XP themes too
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@34150 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -31,6 +31,7 @@ wxMSW:
|
|||||||
- A control's text colour now reflects the system colour setting.
|
- A control's text colour now reflects the system colour setting.
|
||||||
- Fixed wxFileName::GetLongPath() to behave correctly during the first call too.
|
- Fixed wxFileName::GetLongPath() to behave correctly during the first call too.
|
||||||
- Fixed alpha blitting to take into account source position.
|
- Fixed alpha blitting to take into account source position.
|
||||||
|
- Setting foreground colour for wxCheckBox now works when using XP themes too
|
||||||
|
|
||||||
wxMac:
|
wxMac:
|
||||||
|
|
||||||
|
@@ -45,16 +45,44 @@ public:
|
|||||||
virtual void SetValue(bool value);
|
virtual void SetValue(bool value);
|
||||||
virtual bool GetValue() const;
|
virtual bool GetValue() const;
|
||||||
|
|
||||||
|
// override some base class virtuals
|
||||||
virtual bool MSWCommand(WXUINT param, WXWORD id);
|
virtual bool MSWCommand(WXUINT param, WXWORD id);
|
||||||
virtual void Command(wxCommandEvent& event);
|
virtual void Command(wxCommandEvent& event);
|
||||||
|
virtual bool SetForegroundColour(const wxColour& colour);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual wxSize DoGetBestSize() const;
|
virtual wxSize DoGetBestSize() const;
|
||||||
|
virtual bool MSWOnDraw(WXDRAWITEMSTRUCT *item);
|
||||||
|
|
||||||
virtual void DoSet3StateValue(wxCheckBoxState value);
|
virtual void DoSet3StateValue(wxCheckBoxState value);
|
||||||
virtual wxCheckBoxState DoGet3StateValue() const;
|
virtual wxCheckBoxState DoGet3StateValue() const;
|
||||||
|
|
||||||
|
// make the checkbox owner drawn or reset it to normal style
|
||||||
|
void MakeOwnerDrawn(bool ownerDrawn);
|
||||||
|
|
||||||
|
// return true if this checkbox is owner drawn
|
||||||
|
bool IsOwnerDrawn() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// common part of all ctors
|
||||||
|
void Init();
|
||||||
|
|
||||||
|
// event handlers used by owner-drawn checkbox
|
||||||
|
void OnMouseEnterOrLeave(wxMouseEvent& event);
|
||||||
|
void OnMouseLeft(wxMouseEvent& event);
|
||||||
|
void OnFocus(wxFocusEvent& event);
|
||||||
|
|
||||||
|
|
||||||
|
// current state of the checkbox
|
||||||
|
wxCheckBoxState m_state;
|
||||||
|
|
||||||
|
// true if the checkbox is currently pressed
|
||||||
|
bool m_isPressed;
|
||||||
|
|
||||||
|
// true if mouse is currently over the control
|
||||||
|
bool m_isHot;
|
||||||
|
|
||||||
|
|
||||||
DECLARE_DYNAMIC_CLASS_NO_COPY(wxCheckBox)
|
DECLARE_DYNAMIC_CLASS_NO_COPY(wxCheckBox)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -37,8 +37,13 @@
|
|||||||
#include "wx/settings.h"
|
#include "wx/settings.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "wx/msw/uxtheme.h"
|
||||||
#include "wx/msw/private.h"
|
#include "wx/msw/private.h"
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// constants
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
#ifndef BST_UNCHECKED
|
#ifndef BST_UNCHECKED
|
||||||
#define BST_UNCHECKED 0x0000
|
#define BST_UNCHECKED 0x0000
|
||||||
#endif
|
#endif
|
||||||
@@ -51,6 +56,44 @@
|
|||||||
#define BST_INDETERMINATE 0x0002
|
#define BST_INDETERMINATE 0x0002
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef DFCS_HOT
|
||||||
|
#define DFCS_HOT 0x1000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef DT_HIDEPREFIX
|
||||||
|
#define DT_HIDEPREFIX 0x00100000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BP_CHECKBOX
|
||||||
|
#define BP_CHECKBOX 3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// these values are defined in tmschema.h (except the first one)
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
CBS_INVALID,
|
||||||
|
CBS_UNCHECKEDNORMAL,
|
||||||
|
CBS_UNCHECKEDHOT,
|
||||||
|
CBS_UNCHECKEDPRESSED,
|
||||||
|
CBS_UNCHECKEDDISABLED,
|
||||||
|
CBS_CHECKEDNORMAL,
|
||||||
|
CBS_CHECKEDHOT,
|
||||||
|
CBS_CHECKEDPRESSED,
|
||||||
|
CBS_CHECKEDDISABLED,
|
||||||
|
CBS_MIXEDNORMAL,
|
||||||
|
CBS_MIXEDHOT,
|
||||||
|
CBS_MIXEDPRESSED,
|
||||||
|
CBS_MIXEDDISABLED
|
||||||
|
};
|
||||||
|
|
||||||
|
// these are our own
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
CBS_HOT_OFFSET = 1,
|
||||||
|
CBS_PRESSED_OFFSET = 2,
|
||||||
|
CBS_DISABLED_OFFSET = 3
|
||||||
|
};
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// implementation
|
// implementation
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -109,27 +152,14 @@ IMPLEMENT_DYNAMIC_CLASS(wxCheckBox, wxControl)
|
|||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxCheckBox
|
// wxCheckBox creation
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
bool wxCheckBox::MSWCommand(WXUINT WXUNUSED(param), WXWORD WXUNUSED(id))
|
void wxCheckBox::Init()
|
||||||
{
|
{
|
||||||
wxCommandEvent event(wxEVT_COMMAND_CHECKBOX_CLICKED, m_windowId);
|
m_state = wxCHK_UNCHECKED;
|
||||||
wxCheckBoxState state = Get3StateValue();
|
m_isPressed =
|
||||||
|
m_isHot = false;
|
||||||
// If the style flag to allow the user setting the undetermined state
|
|
||||||
// is not set, then skip the undetermined state and set it to unchecked.
|
|
||||||
if ( state == wxCHK_UNDETERMINED && !Is3rdStateAllowedForUser() )
|
|
||||||
{
|
|
||||||
state = wxCHK_UNCHECKED;
|
|
||||||
Set3StateValue(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
event.SetInt(state);
|
|
||||||
event.SetEventObject(this);
|
|
||||||
ProcessCommand(event);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxCheckBox::Create(wxWindow *parent,
|
bool wxCheckBox::Create(wxWindow *parent,
|
||||||
@@ -140,6 +170,8 @@ bool wxCheckBox::Create(wxWindow *parent,
|
|||||||
const wxValidator& validator,
|
const wxValidator& validator,
|
||||||
const wxString& name)
|
const wxString& name)
|
||||||
{
|
{
|
||||||
|
Init();
|
||||||
|
|
||||||
if ( !CreateControl(parent, id, pos, size, style, validator, name) )
|
if ( !CreateControl(parent, id, pos, size, style, validator, name) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -147,14 +179,14 @@ bool wxCheckBox::Create(wxWindow *parent,
|
|||||||
|
|
||||||
if ( style & wxCHK_3STATE )
|
if ( style & wxCHK_3STATE )
|
||||||
{
|
{
|
||||||
msStyle |= BS_AUTO3STATE;
|
msStyle |= BS_3STATE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wxASSERT_MSG( !Is3rdStateAllowedForUser(),
|
wxASSERT_MSG( !Is3rdStateAllowedForUser(),
|
||||||
wxT("Using wxCH_ALLOW_3RD_STATE_FOR_USER")
|
wxT("Using wxCH_ALLOW_3RD_STATE_FOR_USER")
|
||||||
wxT(" style flag for a 2-state checkbox is useless") );
|
wxT(" style flag for a 2-state checkbox is useless") );
|
||||||
msStyle |= BS_AUTOCHECKBOX;
|
msStyle |= BS_CHECKBOX;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( style & wxALIGN_RIGHT )
|
if ( style & wxALIGN_RIGHT )
|
||||||
@@ -165,6 +197,9 @@ bool wxCheckBox::Create(wxWindow *parent,
|
|||||||
return MSWCreateControl(wxT("BUTTON"), msStyle, pos, size, label, 0);
|
return MSWCreateControl(wxT("BUTTON"), msStyle, pos, size, label, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxCheckBox geometry
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
wxSize wxCheckBox::DoGetBestSize() const
|
wxSize wxCheckBox::DoGetBestSize() const
|
||||||
{
|
{
|
||||||
@@ -203,6 +238,10 @@ wxSize wxCheckBox::DoGetBestSize() const
|
|||||||
return best;
|
return best;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxCheckBox operations
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
void wxCheckBox::SetValue(bool val)
|
void wxCheckBox::SetValue(bool val)
|
||||||
{
|
{
|
||||||
Set3StateValue(val ? wxCHK_CHECKED : wxCHK_UNCHECKED);
|
Set3StateValue(val ? wxCHK_CHECKED : wxCHK_UNCHECKED);
|
||||||
@@ -230,12 +269,316 @@ wxCOMPILE_TIME_ASSERT(wxCHK_UNCHECKED == BST_UNCHECKED
|
|||||||
|
|
||||||
void wxCheckBox::DoSet3StateValue(wxCheckBoxState state)
|
void wxCheckBox::DoSet3StateValue(wxCheckBoxState state)
|
||||||
{
|
{
|
||||||
|
m_state = state;
|
||||||
|
if ( !IsOwnerDrawn() )
|
||||||
::SendMessage(GetHwnd(), BM_SETCHECK, (WPARAM) state, 0);
|
::SendMessage(GetHwnd(), BM_SETCHECK, (WPARAM) state, 0);
|
||||||
|
else // owner drawn buttons don't react to this message
|
||||||
|
Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
wxCheckBoxState wxCheckBox::DoGet3StateValue() const
|
wxCheckBoxState wxCheckBox::DoGet3StateValue() const
|
||||||
{
|
{
|
||||||
return (wxCheckBoxState) ::SendMessage(GetHwnd(), BM_GETCHECK, 0, 0);
|
return m_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxCheckBox::MSWCommand(WXUINT cmd, WXWORD WXUNUSED(id))
|
||||||
|
{
|
||||||
|
if ( cmd != BN_CLICKED && cmd != BN_DBLCLK )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// first update the value so that user event handler gets the new checkbox
|
||||||
|
// value
|
||||||
|
|
||||||
|
// ownerdrawn buttons don't manage their state themselves unlike usual
|
||||||
|
// auto checkboxes so do it ourselves in any case
|
||||||
|
wxCheckBoxState state;
|
||||||
|
if ( Is3rdStateAllowedForUser() )
|
||||||
|
{
|
||||||
|
state = (wxCheckBoxState)((m_state + 1) % 3);
|
||||||
|
}
|
||||||
|
else // 2 state checkbox (at least from users point of view)
|
||||||
|
{
|
||||||
|
// note that wxCHK_UNDETERMINED also becomes unchecked when clicked
|
||||||
|
state = m_state == wxCHK_UNCHECKED ? wxCHK_CHECKED : wxCHK_UNCHECKED;
|
||||||
|
}
|
||||||
|
|
||||||
|
DoSet3StateValue(state);
|
||||||
|
|
||||||
|
|
||||||
|
// generate the event
|
||||||
|
wxCommandEvent event(wxEVT_COMMAND_CHECKBOX_CLICKED, m_windowId);
|
||||||
|
|
||||||
|
event.SetInt(state);
|
||||||
|
event.SetEventObject(this);
|
||||||
|
ProcessCommand(event);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// owner drawn checkboxes stuff
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool wxCheckBox::SetForegroundColour(const wxColour& colour)
|
||||||
|
{
|
||||||
|
if ( !wxCheckBoxBase::SetForegroundColour(colour) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// the only way to change the checkbox foreground colour under Windows XP
|
||||||
|
// is to owner draw it
|
||||||
|
if ( wxUxThemeEngine::GetIfActive() )
|
||||||
|
MakeOwnerDrawn(colour.Ok());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxCheckBox::IsOwnerDrawn() const
|
||||||
|
{
|
||||||
|
return
|
||||||
|
(::GetWindowLong(GetHwnd(), GWL_STYLE) & BS_OWNERDRAW) == BS_OWNERDRAW;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxCheckBox::MakeOwnerDrawn(bool ownerDrawn)
|
||||||
|
{
|
||||||
|
long style = ::GetWindowLong(GetHwnd(), GWL_STYLE);
|
||||||
|
|
||||||
|
// note that BS_CHECKBOX & BS_OWNERDRAW != 0 so we can't operate on
|
||||||
|
// them as on independent style bits
|
||||||
|
if ( ownerDrawn )
|
||||||
|
{
|
||||||
|
style &= ~(BS_CHECKBOX | BS_3STATE);
|
||||||
|
style |= BS_OWNERDRAW;
|
||||||
|
|
||||||
|
Connect(wxEVT_ENTER_WINDOW,
|
||||||
|
wxMouseEventHandler(wxCheckBox::OnMouseEnterOrLeave));
|
||||||
|
Connect(wxEVT_LEAVE_WINDOW,
|
||||||
|
wxMouseEventHandler(wxCheckBox::OnMouseEnterOrLeave));
|
||||||
|
Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(wxCheckBox::OnMouseLeft));
|
||||||
|
Connect(wxEVT_LEFT_UP, wxMouseEventHandler(wxCheckBox::OnMouseLeft));
|
||||||
|
Connect(wxEVT_SET_FOCUS, wxFocusEventHandler(wxCheckBox::OnFocus));
|
||||||
|
Connect(wxEVT_KILL_FOCUS, wxFocusEventHandler(wxCheckBox::OnFocus));
|
||||||
|
}
|
||||||
|
else // reset to default colour
|
||||||
|
{
|
||||||
|
style &= ~BS_OWNERDRAW;
|
||||||
|
style |= HasFlag(wxCHK_3STATE) ? BS_3STATE : BS_CHECKBOX;
|
||||||
|
|
||||||
|
Disconnect(wxEVT_ENTER_WINDOW,
|
||||||
|
wxMouseEventHandler(wxCheckBox::OnMouseEnterOrLeave));
|
||||||
|
Disconnect(wxEVT_LEAVE_WINDOW,
|
||||||
|
wxMouseEventHandler(wxCheckBox::OnMouseEnterOrLeave));
|
||||||
|
Disconnect(wxEVT_LEFT_DOWN, wxMouseEventHandler(wxCheckBox::OnMouseLeft));
|
||||||
|
Disconnect(wxEVT_LEFT_UP, wxMouseEventHandler(wxCheckBox::OnMouseLeft));
|
||||||
|
Disconnect(wxEVT_SET_FOCUS, wxFocusEventHandler(wxCheckBox::OnFocus));
|
||||||
|
Disconnect(wxEVT_KILL_FOCUS, wxFocusEventHandler(wxCheckBox::OnFocus));
|
||||||
|
}
|
||||||
|
|
||||||
|
::SetWindowLong(GetHwnd(), GWL_STYLE, style);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxCheckBox::OnMouseEnterOrLeave(wxMouseEvent& event)
|
||||||
|
{
|
||||||
|
m_isHot = event.GetEventType() == wxEVT_ENTER_WINDOW;
|
||||||
|
if ( !m_isHot )
|
||||||
|
m_isPressed = false;
|
||||||
|
|
||||||
|
Refresh();
|
||||||
|
|
||||||
|
event.Skip();
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxCheckBox::OnMouseLeft(wxMouseEvent& event)
|
||||||
|
{
|
||||||
|
// TODO: we should capture the mouse here to be notified about left up
|
||||||
|
// event but this interferes with BN_CLICKED generation so if we
|
||||||
|
// want to do this we'd need to generate them ourselves
|
||||||
|
m_isPressed = event.GetEventType() == wxEVT_LEFT_DOWN;
|
||||||
|
Refresh();
|
||||||
|
|
||||||
|
event.Skip();
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxCheckBox::OnFocus(wxFocusEvent& event)
|
||||||
|
{
|
||||||
|
Refresh();
|
||||||
|
|
||||||
|
event.Skip();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxCheckBox::MSWOnDraw(WXDRAWITEMSTRUCT *item)
|
||||||
|
{
|
||||||
|
DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)item;
|
||||||
|
|
||||||
|
if ( !IsOwnerDrawn() || dis->CtlType != ODT_BUTTON )
|
||||||
|
return wxCheckBoxBase::MSWOnDraw(item);
|
||||||
|
|
||||||
|
// calculate the rectangles for the check mark itself and the label
|
||||||
|
HDC hdc = dis->hDC;
|
||||||
|
RECT& rect = dis->rcItem;
|
||||||
|
RECT rectCheck,
|
||||||
|
rectLabel;
|
||||||
|
rectCheck.top =
|
||||||
|
rectLabel.top = rect.top;
|
||||||
|
rectCheck.bottom =
|
||||||
|
rectLabel.bottom = rect.bottom;
|
||||||
|
const int checkSize = GetBestSize().y;
|
||||||
|
const int MARGIN = 3;
|
||||||
|
|
||||||
|
const bool isRightAligned = HasFlag(wxALIGN_RIGHT);
|
||||||
|
if ( isRightAligned )
|
||||||
|
{
|
||||||
|
rectCheck.right = rect.right;
|
||||||
|
rectCheck.left = rectCheck.right - checkSize;
|
||||||
|
|
||||||
|
rectLabel.right = rectCheck.left - MARGIN;
|
||||||
|
rectLabel.left = rect.left;
|
||||||
|
}
|
||||||
|
else // normal, left-aligned checkbox
|
||||||
|
{
|
||||||
|
rectCheck.left = rect.left;
|
||||||
|
rectCheck.right = rectCheck.left + checkSize;
|
||||||
|
|
||||||
|
rectLabel.left = rectCheck.right + MARGIN;
|
||||||
|
rectLabel.right = rect.right;
|
||||||
|
}
|
||||||
|
|
||||||
|
// show we draw a focus rect?
|
||||||
|
const bool isFocused = m_isPressed || FindFocus() == this;
|
||||||
|
|
||||||
|
|
||||||
|
// draw the checkbox itself: note that this should really, really be in
|
||||||
|
// wxRendererNative but unfortunately we can't add a new virtual function
|
||||||
|
// to it without breaking backwards compatibility
|
||||||
|
|
||||||
|
// classic Win32 version -- this can be useful when we move this into
|
||||||
|
#if 0
|
||||||
|
UINT state = DFCS_BUTTONCHECK;
|
||||||
|
if ( !IsEnabled() )
|
||||||
|
state |= DFCS_INACTIVE;
|
||||||
|
switch ( Get3StateValue() )
|
||||||
|
{
|
||||||
|
case wxCHK_CHECKED:
|
||||||
|
state |= DFCS_CHECKED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case wxCHK_UNDETERMINED:
|
||||||
|
state |= DFCS_PUSHED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
wxFAIL_MSG( _T("unexpected Get3StateValue() return value") );
|
||||||
|
// fall through
|
||||||
|
|
||||||
|
case wxCHK_UNCHECKED:
|
||||||
|
// no extra styles needed
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( wxFindWindowAtPoint(wxGetMousePosition()) == this )
|
||||||
|
state |= DFCS_HOT;
|
||||||
|
|
||||||
|
if ( !::DrawFrameControl(hdc, &rectCheck, DFC_BUTTON, state) )
|
||||||
|
{
|
||||||
|
wxLogLastError(_T("DrawFrameControl(DFC_BUTTON)"));
|
||||||
|
}
|
||||||
|
#else // XP version
|
||||||
|
wxUxThemeEngine *themeEngine = wxUxThemeEngine::GetIfActive();
|
||||||
|
if ( !themeEngine )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
wxUxThemeHandle theme(this, L"BUTTON");
|
||||||
|
if ( !theme )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int state;
|
||||||
|
switch ( Get3StateValue() )
|
||||||
|
{
|
||||||
|
case wxCHK_CHECKED:
|
||||||
|
state = CBS_CHECKEDNORMAL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case wxCHK_UNDETERMINED:
|
||||||
|
state = CBS_MIXEDNORMAL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
wxFAIL_MSG( _T("unexpected Get3StateValue() return value") );
|
||||||
|
// fall through
|
||||||
|
|
||||||
|
case wxCHK_UNCHECKED:
|
||||||
|
state = CBS_UNCHECKEDNORMAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !IsEnabled() )
|
||||||
|
state += CBS_DISABLED_OFFSET;
|
||||||
|
else if ( m_isPressed )
|
||||||
|
state += CBS_PRESSED_OFFSET;
|
||||||
|
else if ( m_isHot )
|
||||||
|
state += CBS_HOT_OFFSET;
|
||||||
|
|
||||||
|
HRESULT hr = themeEngine->DrawThemeBackground
|
||||||
|
(
|
||||||
|
theme,
|
||||||
|
hdc,
|
||||||
|
BP_CHECKBOX,
|
||||||
|
state,
|
||||||
|
&rectCheck,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
if ( FAILED(hr) )
|
||||||
|
{
|
||||||
|
wxLogApiError(_T("DrawThemeBackground(BP_CHECKBOX)"), hr);
|
||||||
|
}
|
||||||
|
#endif // 0/1
|
||||||
|
|
||||||
|
// draw the text
|
||||||
|
const wxString& label = GetLabel();
|
||||||
|
|
||||||
|
// first we need to measure it
|
||||||
|
UINT fmt = DT_NOCLIP;
|
||||||
|
|
||||||
|
// drawing underlying doesn't look well with focus rect (and the native
|
||||||
|
// control doesn't do it)
|
||||||
|
if ( isFocused )
|
||||||
|
fmt |= DT_HIDEPREFIX;
|
||||||
|
if ( isRightAligned )
|
||||||
|
fmt |= DT_RIGHT;
|
||||||
|
// TODO: also use DT_HIDEPREFIX if the system is configured so
|
||||||
|
|
||||||
|
// we need to get the label real size first if we have to draw a focus rect
|
||||||
|
// around it
|
||||||
|
if ( isFocused )
|
||||||
|
{
|
||||||
|
if ( !::DrawText(hdc, label, label.length(), &rectLabel,
|
||||||
|
fmt | DT_CALCRECT) )
|
||||||
|
{
|
||||||
|
wxLogLastError(_T("DrawText(DT_CALCRECT)"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !IsEnabled() )
|
||||||
|
{
|
||||||
|
::SetTextColor(hdc, ::GetSysColor(COLOR_GRAYTEXT));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !::DrawText(hdc, label, label.length(), &rectLabel, fmt) )
|
||||||
|
{
|
||||||
|
wxLogLastError(_T("DrawText()"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// finally draw the focus
|
||||||
|
if ( isFocused )
|
||||||
|
{
|
||||||
|
rectLabel.left--;
|
||||||
|
rectLabel.right++;
|
||||||
|
if ( !::DrawFocusRect(hdc, &rectLabel) )
|
||||||
|
{
|
||||||
|
wxLogLastError(_T("DrawFocusRect()"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // wxUSE_CHECKBOX
|
#endif // wxUSE_CHECKBOX
|
||||||
|
Reference in New Issue
Block a user