simplifications and corrections to background drawing:

1. removed ApplyParentThemeBackground() not used any longer
2. removed ProvidesBackground() which is synonymous with
   !HasTransparentBackground()
3. removed a whole bunch of unused MSWXXX() methods
4. moved MSWControlColor() from wxWindow up to wxControl

results:

1. the gradient is still shown properly for static/radio boxes in notebooks
2. correct background colour is used for the static boxes
3. code is shorter and better commented


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@33474 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2005-04-10 15:23:08 +00:00
parent 47561b0dc5
commit c3732409ac
32 changed files with 340 additions and 496 deletions

View File

@ -61,10 +61,6 @@ public:
int GetMarginX() const { return m_marginX; }
int GetMarginY() const { return m_marginY; }
virtual void ApplyParentThemeBackground(const wxColour& bg)
{ SetBackgroundColour(bg); }
protected:
// function called when any of the bitmaps changes
virtual void OnSetBitmap() { InvalidateBestSize(); Refresh(); }

View File

@ -179,11 +179,6 @@ public:
}
}
// override some base class virtuals
virtual void ApplyParentThemeBackground(const wxColour& bg)
{ SetBackgroundColour(bg); }
virtual bool ProvidesBackground() const { return true; }
protected:
// remove the page and return a pointer to it
virtual wxWindow *DoRemovePage(size_t page) = 0;

View File

@ -80,12 +80,8 @@ public:
#ifdef __WXUNIVERSAL__
virtual bool IsCanvasWindow() const { return true; }
virtual bool ProvidesBackground() const { return true; }
#endif
virtual void ApplyParentThemeBackground(const wxColour& bg)
{ SetBackgroundColour(bg); }
WX_DECLARE_CONTROL_CONTAINER();

View File

@ -54,13 +54,6 @@ public:
virtual WXLRESULT MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
virtual bool MSWCommand(WXUINT param, WXWORD id);
virtual void ApplyParentThemeBackground(const wxColour& bg)
{
// avoide switching into owner-drawn mode
wxControl::SetBackgroundColour(bg);
}
#ifdef __WIN32__
// coloured buttons support
virtual bool SetBackgroundColour(const wxColour &colour);
virtual bool SetForegroundColour(const wxColour &colour);
@ -69,7 +62,6 @@ public:
private:
void MakeOwnerDrawn();
#endif // __WIN32__
protected:
// send a notification event, return true if processed

View File

@ -50,7 +50,6 @@ public:
protected:
virtual wxSize DoGetBestSize() const;
virtual WXHBRUSH MSWGetDefaultBgBrush();
virtual void DoSet3StateValue(wxCheckBoxState value);
virtual wxCheckBoxState DoGet3StateValue() const;

View File

@ -70,6 +70,10 @@ public:
const wxArrayLong& GetSubcontrols() const { return m_subControls; }
// default handling of WM_CTLCOLORxxx: this is public so that wxWindow
// could call it
virtual WXHBRUSH MSWControlColor(WXHDC pDC);
protected:
// choose the default border for this window
virtual wxBorder GetDefaultBorder() const;
@ -116,34 +120,15 @@ protected:
// default style for the control include WS_TABSTOP if it AcceptsFocus()
virtual WXDWORD MSWGetStyle(long style, WXDWORD *exstyle) const;
// default handling of WM_CTLCOLORxxx
virtual WXHBRUSH MSWControlColor(WXHDC pDC);
// call this from the derived class MSWControlColor() if you want to show
// the control greyed out (and opaque)
WXHBRUSH MSWControlColorDisabled(WXHDC pDC);
// call this from the derived class MSWControlColor() if you want to always
// paint the background (as all opaque controls do)
WXHBRUSH MSWControlColorSolid(WXHDC pDC)
{
return DoMSWControlColor(pDC, GetBackgroundColour());
}
// common part of the 3 functions above: pass wxNullColour to use the
// appropriate background colour (meaning ours or our parents) or a fixed
// one
virtual WXHBRUSH DoMSWControlColor(WXHDC pDC, wxColour colBg);
// another WM_CTLCOLOR-related function: override this to return the brush
// which should be used to paint the control background by default
//
// for most controls, the default behaviour of returning 0 and letting the
// system do it is correct, but for some -- e.g. checkboxes -- we actually
// have to return transparent brush from here to prevent the system from
// overwriting background with solid colour
virtual WXHBRUSH MSWGetDefaultBgBrush() { return 0; }
// this is a helper for the derived class GetClassDefaultAttributes()
// implementation: it returns the right colours for the classes which
// contain something else (e.g. wxListBox, wxTextCtrl, ...) instead of

View File

@ -143,11 +143,6 @@ public:
protected:
WXDWORD MSWGetStyle(long style, WXDWORD *exstyle) const;
virtual WXHBRUSH MSWControlColor(WXHDC pDC)
{
return MSWControlColorSolid(pDC);
}
// free memory (common part of Clear() and dtor)
void Free();

View File

@ -183,9 +183,6 @@ public:
return true;
}
virtual WXHBRUSH MSWGetBgBrushForChild(WXHDC hDC, wxWindow *win);
virtual wxColour MSWGetBgColourForChild(wxWindow *win);
#endif // wxUSE_UXTHEME
protected:
@ -198,6 +195,11 @@ protected:
// remove one page from the notebook, without deleting
virtual wxNotebookPage *DoRemovePage(size_t nPage);
// get the page rectangle for the current notebook size
//
// returns empty rectangle if an error occurs, do test for it
wxRect GetPageSize() const;
// set the size of the given page to fit in the notebook
void AdjustPageSize(wxNotebookPage *page);
@ -208,8 +210,16 @@ protected:
// creates the brush to be used for drawing the tab control background
void UpdateBgBrush();
// paint themed children background here
virtual bool MSWPrintChild(wxWindow *win, WXWPARAM wParam, WXLPARAM lParam);
// return the themed brush for painting our children
virtual WXHBRUSH MSWGetBgBrushForChild(WXHDC hDC, wxWindow *win);
// draw child background
virtual bool MSWPrintChild(WXHDC hDC, wxWindow *win);
// common part of QueryBgBitmap() and MSWPrintChild()
//
// if child == NULL, draw background for the entire notebook itself
bool DoDrawBackground(WXHDC hDC, wxWindow *child = NULL);
#endif // wxUSE_UXTHEME
// the current selection (-1 if none)

View File

@ -722,6 +722,14 @@ extern WXDLLEXPORT wxSize wxGetHiconSize(HICON hicon);
// Lines are drawn differently for WinCE and regular WIN32
WXDLLEXPORT void wxDrawLine(HDC hdc, int x1, int y1, int x2, int y2);
// fill the client rect of the given window on the provided dc using this brush
inline void wxFillRect(HWND hwnd, HDC hdc, HBRUSH hbr)
{
RECT rc;
::GetClientRect(hwnd, &rc);
::FillRect(hdc, &rc, hbr);
}
// ----------------------------------------------------------------------------
// 32/64 bit helpers
// ----------------------------------------------------------------------------

View File

@ -144,10 +144,9 @@ protected:
int sizeFlags = wxSIZE_AUTO);
virtual wxSize DoGetBestSize() const;
#ifndef __WXWINCE__
virtual WXHRGN MSWGetRegionWithoutChildren();
virtual WXLRESULT MSWWindowProc(WXUINT nMsg,
WXWPARAM wParam,
WXLPARAM lParam);
#endif // __WXWINCE__
// the buttons we contain

View File

@ -52,9 +52,7 @@ public:
// implementation only from now on
virtual bool MSWCommand(WXUINT param, WXWORD id);
virtual void Command(wxCommandEvent& event);
virtual void ApplyParentThemeBackground(const wxColour& bg)
{ SetBackgroundColour(bg); }
virtual bool HasTransparentBackground() { return true; }
protected:
virtual wxSize DoGetBestSize() const;

View File

@ -49,6 +49,8 @@ protected:
virtual wxBorder GetDefaultBorder() const;
virtual WXDWORD MSWGetStyle(long style, WXDWORD *exstyle) const;
#ifndef __WXWINCE__
virtual WXLRESULT MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
// return the region with all the windows inside this static box excluded
@ -58,12 +60,13 @@ protected:
// region which is embedded in a rectangle (0, 0)-(w, h)
virtual void MSWGetRegionWithoutSelf(WXHRGN hrgn, int w, int h);
// paint the given rectangle with our background colour
// paint the given rectangle with our background brush/colour
void PaintBackground(wxDC& dc, const struct tagRECT& rc);
void OnPaint(wxPaintEvent& event);
DECLARE_DYNAMIC_CLASS_NO_COPY(wxStaticBox)
#endif // !__WXWINCE__
};
#endif // _WX_MSW_STATBOX_H_

View File

@ -51,7 +51,7 @@ protected:
int sizeFlags = wxSIZE_AUTO);
virtual wxSize DoGetBestSize() const;
virtual WXDWORD MSWGetStyle(long flags, WXDWORD *exstyle = NULL) const;
virtual WXHBRUSH DoMSWControlColor(WXHDC pDC, wxColour colBg);
DECLARE_DYNAMIC_CLASS_NO_COPY(wxStaticText)
};

View File

@ -358,55 +358,32 @@ public:
// called when the window is about to be destroyed
virtual void MSWDestroyWindow();
// this function should return the brush to paint the window background
// with or 0 for the default brush
virtual WXHBRUSH MSWControlColor(WXHDC hDC);
// this function should return the brush to paint the children controls
// background or 0 if this window doesn't impose any particular background
// on its children
//
// the base class version uses MSWGetBgColourForChild() and returns a solid
// brush if we have a non default background colour or 0 otherwise
virtual WXHBRUSH MSWGetBgBrushForChild(WXHDC WXUNUSED(hDC), wxWindow *child)
// the base class version returns a solid brush if we have a non default
// background colour or 0 otherwise
virtual WXHBRUSH MSWGetBgBrushForChild(WXHDC hDC, wxWindow *child);
// return the background brush to use for painting the given window by
// quering the parent windows via their MSWGetBgBrushForChild() recursively
//
// winToPaint is normally NULL meaning this window itself, but it can also
// be a child of this window which is used by the static box and could be
// potentially useful for other transparent controls
WXHBRUSH MSWGetBgBrush(WXHDC hDC, wxWindow *winToPaint = NULL);
// gives the parent the possibility to draw its children background, e.g.
// this is used by wxNotebook to do it using DrawThemeBackground()
//
// return true if background was drawn, false otherwise
virtual bool MSWPrintChild(WXHDC WXUNUSED(hDC), wxWindow * WXUNUSED(child))
{
return MSWGetSolidBgBrushForChild(child);
return false;
}
// return the background colour of this window under the given child
// (possible grand child)
//
// this is a hack as if the background is themed, there is no single colour
// representing it, but sometimes we can't use the pattern brush returned
// by MSWGetBgBrushForChild() anyhow and then this function is used as
// fallback
//
// the base class version returns bg colour if it had been explicitely set
// or wxNullColour otherwise
virtual wxColour MSWGetBgColourForChild(wxWindow *child);
// convenience function: returns a solid brush of the colour returned by
// MSWGetBgColourForChild() or 0
WXHBRUSH MSWGetSolidBgBrushForChild(wxWindow *child);
// normally just calls MSWGetBgBrushForChild() on the parent window but may
// be overridden if the default background brush is not suitable for some
// reason (e.g. wxStaticBox uses MSWGetSolidBgBrushForChild() instead)
virtual WXHBRUSH MSWGetBgBrushForSelf(wxWindow *parent, WXHDC hDC);
// return the background brush to use for this window by quering the parent
// windows via their MSWGetBgBrushForChild() recursively
WXHBRUSH MSWGetBgBrush(WXHDC hDC);
// overriding this method gives the parent window the opportunity to
// process WM_PRINTCLIENT for its children: this is currently used by
// wxNotebook to draw themed background for them
//
// return true if the message was processed or false to use default logic
// for it (currently this means handling it just as WM_PAINT i.e. render
// the control into the provided DC)
virtual bool MSWPrintChild(wxWindow *win, WXWPARAM wParam, WXLPARAM lParam);
// Responds to colour changes: passes event on to children.
void OnSysColourChanged(wxSysColourChangedEvent& event);
@ -422,7 +399,7 @@ public:
// virtual function for implementing internal idle
// behaviour
virtual void OnInternalIdle() ;
virtual void OnInternalIdle();
protected:
// the window handle
@ -485,8 +462,8 @@ protected:
// default OnEraseBackground() implementation, return true if we did erase
// the background, false otherwise
bool DoEraseBackground(wxDC& dc);
// the background, false otherwise (i.e. the system should erase it)
bool DoEraseBackground(WXHDC hDC);
private:
// common part of all ctors

View File

@ -55,12 +55,6 @@ public:
// send a notification event, return true if processed
bool SendClickEvent();
virtual void ApplyParentThemeBackground(const wxColour& bg)
{
// avoide switching into owner-drawn mode
wxControl::SetBackgroundColour(bg);
}
protected:
// default button handling

View File

@ -137,9 +137,6 @@ public:
int GetNumVer() const;
int GetNumHor() const;
virtual void ApplyParentThemeBackground(const wxColour& bg)
{ SetBackgroundColour(bg); }
protected:
// we can't compute our best size before the items are added to the control
virtual void SetInitialBestSize(const wxSize& WXUNUSED(size)) { }

View File

@ -56,10 +56,6 @@ public:
// send a notification event, return true if processed
bool SendClickEvent();
virtual void ApplyParentThemeBackground(const wxColour& bg)
{ SetBackgroundColour(bg); }
protected:
virtual wxSize DoGetBestSize() const;

View File

@ -80,9 +80,6 @@ public:
virtual int GetSelStart() const { return GetMax(); }
virtual void SetSelection(int WXUNUSED(min), int WXUNUSED(max)) { }
virtual void ApplyParentThemeBackground(const wxColour& bg)
{ SetBackgroundColour(bg); }
protected:
// adjust value according to wxSL_INVERSE style

View File

@ -48,8 +48,6 @@ public:
// overriden base class virtuals
virtual bool AcceptsFocus() const { return false; }
virtual void ApplyParentThemeBackground(const wxColour& bg)
{ SetBackgroundColour(bg); }
protected:
// set the right size for the right dimension

View File

@ -191,7 +191,6 @@ public:
virtual bool Destroy();
virtual bool IsTopLevel() const { return true; }
virtual wxSize GetMaxSize() const;
virtual bool ProvidesBackground() const { return true; }
// event handlers
void OnCloseWindow(wxCloseEvent& event);

View File

@ -189,10 +189,6 @@ public:
void SetSelectionBackground(const wxColour& col);
virtual void ApplyParentThemeBackground(const wxColour& WXUNUSED(bg))
{ /* do nothing */ }
virtual wxVisualAttributes GetDefaultAttributes() const
{
return GetClassDefaultAttributes(GetWindowVariant());

View File

@ -482,14 +482,6 @@ public:
virtual void SetThemeEnabled(bool enableTheme) { m_themeEnabled = enableTheme; }
virtual bool GetThemeEnabled() const { return m_themeEnabled; }
// Returns true if this class should have the background colour
// changed to match the parent window's theme. For example when a
// page is added to a notebook it and its children may need to have
// the colours adjusted depending on the current theme settings, but
// not all windows/controls can do this without looking wrong.
virtual void ApplyParentThemeBackground(const wxColour& WXUNUSED(bg))
{ /* do nothing */ }
// focus and keyboard handling
// ---------------------------
@ -768,13 +760,6 @@ public:
return m_hasBgCol;
}
// if the window shouldn't inherit its colour from the parent, override
// this function to return true
//
// this is currently only used by wxMSW and wxUniv but should be useful for
// the other ports too
virtual bool ProvidesBackground() const { return false; }
virtual bool SetForegroundColour(const wxColour& colour);
void SetOwnForegroundColour(const wxColour& colour)
{

View File

@ -142,29 +142,31 @@ void wxTimerScheduler::NotifyTimers()
bool oneShot;
volatile bool timerDeleted;
wxTimerTick_t now = GetMillisecondsTime();
wxTimerDesc *desc;
while ( m_timers && m_timers->shotTime <= now )
for ( wxTimerDesc *desc = m_timers; desc; desc = desc->next )
{
desc = m_timers;
oneShot = desc->timer->IsOneShot();
RemoveTimer(desc);
timerDeleted = false;
desc->deleteFlag = &timerDeleted;
desc->timer->Notify();
if ( !timerDeleted )
if ( desc->running && desc->shotTime <= now )
{
wxLogTrace( wxT("timer"),
wxT("notified timer %p sheduled for %")
wxTimerTickFmtSpec,
desc->timer,
wxTimerTickPrintfArg(desc->shotTime) );
desc = m_timers;
oneShot = desc->timer->IsOneShot();
RemoveTimer(desc);
desc->deleteFlag = NULL;
if ( !oneShot )
QueueTimer(desc, now + desc->timer->GetInterval());
timerDeleted = false;
desc->deleteFlag = &timerDeleted;
desc->timer->Notify();
if ( !timerDeleted )
{
wxLogTrace( wxT("timer"),
wxT("notified timer %p sheduled for %")
wxTimerTickFmtSpec,
desc->timer,
wxTimerTickPrintfArg(desc->shotTime) );
desc->deleteFlag = NULL;
if ( !oneShot )
QueueTimer(desc, now + desc->timer->GetInterval());
}
}
}
}

View File

@ -201,26 +201,14 @@ wxSize wxCheckBox::DoGetBestSize() const
return wxSize(wCheckbox, hCheckbox);
}
WXHBRUSH wxCheckBox::MSWGetDefaultBgBrush()
{
return ::GetStockObject(NULL_BRUSH);
}
void wxCheckBox::SetValue(bool val)
{
if (val)
{
Set3StateValue(wxCHK_CHECKED);
}
else
{
Set3StateValue(wxCHK_UNCHECKED);
}
Set3StateValue(val ? wxCHK_CHECKED : wxCHK_UNCHECKED);
}
bool wxCheckBox::GetValue() const
{
return (Get3StateValue() != wxCHK_UNCHECKED);
return Get3StateValue() != wxCHK_UNCHECKED;
}
void wxCheckBox::Command(wxCommandEvent& event)
@ -245,13 +233,7 @@ void wxCheckBox::DoSet3StateValue(wxCheckBoxState state)
wxCheckBoxState wxCheckBox::DoGet3StateValue() const
{
#ifdef __WIN32__
return (wxCheckBoxState) ::SendMessage(GetHwnd(), BM_GETCHECK, 0, 0);
#else
return (wxCheckBoxState) ((::SendMessage(GetHwnd(), BM_GETCHECK, 0, 0)
& 0x001) == 0x001);
#endif
}
#endif // wxUSE_CHECKBOX

View File

@ -639,7 +639,7 @@ WXHBRUSH wxChoice::MSWControlColor(WXHDC hDC)
if ( !IsEnabled() )
return MSWControlColorDisabled(hDC);
return wxChoiceBase::MSWControlColorSolid(hDC);
return wxChoiceBase::MSWControlColor(hDC);
}
#endif // wxUSE_CHOICE && !(__SMARTPHONE__ && __WXWINCE__)

View File

@ -340,8 +340,19 @@ WXHBRUSH wxControl::DoMSWControlColor(WXHDC pDC, wxColour colBg)
::SetTextColor(hdc, wxColourToRGB(GetForegroundColour()));
}
WXHBRUSH hbr = 0;
if ( !colBg.Ok() )
{
hbr = MSWGetBgBrush(pDC);
// if the control doesn't have any bg colour, foreground colour will be
// ignored as the return value would be 0 -- so forcefully give it a
// non default background brush in this case
if ( !hbr && m_hasFgCol )
colBg = GetBackgroundColour();
}
// use the background colour override if a valid colour is given
WXHBRUSH hbr;
if ( colBg.Ok() )
{
::SetBkColor(hdc, wxColourToRGB(colBg));
@ -351,22 +362,20 @@ WXHBRUSH wxControl::DoMSWControlColor(WXHDC pDC, wxColour colBg)
hbr = (WXHBRUSH)brush->GetResourceHandle();
}
else // use our own background colour and recurse upwards if necessary
{
hbr = MSWGetBgBrush(pDC);
}
return hbr;
}
WXHBRUSH wxControl::MSWControlColor(WXHDC pDC)
{
// by default consider that the controls text shouldn't erase the
// background under it (this is true for all static controls, check boxes,
// radio buttons, ...)
::SetBkMode((HDC)pDC, TRANSPARENT);
wxColour colBg;
return DoMSWControlColor(pDC, wxNullColour);
if ( HasTransparentBackground() )
::SetBkMode((HDC)pDC, TRANSPARENT);
else // if the control is opaque it shouldn't use the parents background
colBg = GetBackgroundColour();
return DoMSWControlColor(pDC, colBg);
}
WXHBRUSH wxControl::MSWControlColorDisabled(WXHDC pDC)

View File

@ -180,25 +180,6 @@ IMPLEMENT_DYNAMIC_CLASS(wxNotebookPageInfo, wxObject )
#endif
IMPLEMENT_DYNAMIC_CLASS(wxNotebookEvent, wxNotifyEvent)
// ----------------------------------------------------------------------------
// local functions
// ----------------------------------------------------------------------------
#ifndef __WXWINCE__
// apparently DrawThemeBackground() modifies the rect passed to it and if we
// don't call this function there are some drawing artifacts which are only
// visible with some non default themes; so modify the rect here so that it
// still paints the correct area
static void AdjustRectForThemeBg(RECT& rc)
{
// magic numbers needed to compensate for DrawThemeBackground()
rc.left -= 2;
rc.top -= 2;
rc.right += 4;
rc.bottom += 5;
}
#endif
// ============================================================================
// implementation
// ============================================================================
@ -264,7 +245,7 @@ bool wxNotebook::Create(wxWindow *parent,
if (style & wxNB_FLAT)
style |= wxBORDER_SUNKEN;
#endif
// comctl32.dll 6.0 doesn't support non-top tabs with visual styles (the
// control is simply not rendered correctly), so disable them in this case
const int verComCtl32 = wxApp::GetComCtl32Version();
@ -361,7 +342,7 @@ WXDWORD wxNotebook::MSWGetStyle(long style, WXDWORD *exstyle) const
else if ( style & wxNB_LEFT )
tabStyle |= TCS_VERTICAL;
else if ( style & wxNB_RIGHT )
tabStyle |= TCS_VERTICAL | TCS_RIGHT;
tabStyle |= TCS_VERTICAL | TCS_RIGHT;
// ex style
if ( exstyle )
@ -485,6 +466,29 @@ void wxNotebook::SetImageList(wxImageList* imageList)
// wxNotebook size settings
// ----------------------------------------------------------------------------
wxRect wxNotebook::GetPageSize() const
{
wxRect r;
RECT rc;
::GetClientRect(GetHwnd(), &rc);
// This check is to work around a bug in TabCtrl_AdjustRect which will
// cause a crash on win2k, or on XP with themes disabled, if the
// wxNB_MULTILINE style is used and the rectangle is very small, (such as
// when the notebook is first created.) The value of 20 is just
// arbitrarily chosen, if there is a better way to determine this value
// then please do so. --RD
if ( !HasFlag(wxNB_MULTILINE) || (rc.right > 20 && rc.bottom > 20) )
{
TabCtrl_AdjustRect(m_hwnd, false, &rc);
wxCopyRECTToRect(rc, r);
}
return r;
}
void wxNotebook::SetPageSize(const wxSize& size)
{
// transform the page size into the notebook size
@ -543,23 +547,10 @@ void wxNotebook::AdjustPageSize(wxNotebookPage *page)
{
wxCHECK_RET( page, _T("NULL page in wxNotebook::AdjustPageSize") );
RECT rc;
rc.left =
rc.top = 0;
// get the page size from the notebook size
GetSize((int *)&rc.right, (int *)&rc.bottom);
// This check is to work around a bug in TabCtrl_AdjustRect which will
// cause a crash on win2k, or on XP with themes disabled, if the
// wxNB_MULTILINE style is used and the rectangle is very small, (such as
// when the notebook is first created.) The value of 20 is just
// arbitrarily chosen, if there is a better way to determine this value
// then please do so. --RD
if (rc.right > 20 && rc.bottom > 20)
const wxRect r = GetPageSize();
if ( !r.IsEmpty() )
{
TabCtrl_AdjustRect(m_hwnd, false, &rc);
page->SetSize(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top);
page->SetSize(r);
}
}
@ -969,35 +960,63 @@ void wxNotebook::OnNavigationKey(wxNavigationKeyEvent& event)
#if wxUSE_UXTHEME
bool wxNotebook::DoDrawBackground(WXHDC hDC, wxWindow *child)
{
wxUxThemeHandle theme(child ? child : this, L"TAB");
if ( !theme )
return false;
// get the notebook client rect (we're not interested in drawing tabs
// themselves)
wxRect r = GetPageSize();
if ( r.IsEmpty() )
return false;
RECT rc;
wxCopyRectToRECT(r, rc);
// map rect to the coords of the window we're drawing in
if ( child )
::MapWindowPoints(GetHwnd(), GetHwndOf(child), (POINT *)&rc, 2);
// apparently DrawThemeBackground() modifies the rect passed to it and if we
// don't do these adjustments, there are some drawing artifacts which are
// only visible with some non default themes; so modify the rect here using
// the magic numbers below so that it still paints the correct area
rc.left -= 2;
rc.top -= 2;
rc.right += 4;
rc.bottom += 5;
wxUxThemeEngine::Get()->DrawThemeBackground
(
theme,
hDC,
9 /* TABP_PANE */,
0,
&rc,
NULL
);
return true;
}
WXHBRUSH wxNotebook::QueryBgBitmap()
{
RECT rc;
::GetClientRect(GetHwnd(), &rc);
// adjust position
TabCtrl_AdjustRect(GetHwnd(), false, &rc);
wxRect r = GetPageSize();
if ( r.IsEmpty() )
return 0;
WindowHDC hDC(GetHwnd());
MemoryHDC hDCMem(hDC);
CompatibleBitmap hBmp(hDC, rc.right, rc.bottom);
CompatibleBitmap hBmp(hDC, r.x + r.width, r.y + r.height);
SelectInHDC selectBmp(hDCMem, hBmp);
wxUxThemeHandle theme(this, L"TAB");
if ( theme )
{
AdjustRectForThemeBg(rc);
wxUxThemeEngine::Get()->DrawThemeBackground
(
theme,
(WXHDC)hDCMem,
9 /* TABP_PANE */,
0,
&rc,
NULL
);
}
if ( !DoDrawBackground((WXHDC)(HDC)hDCMem) )
return 0;
return (WXHBRUSH)::CreatePatternBrush(hBmp);
}
@ -1011,7 +1030,7 @@ void wxNotebook::UpdateBgBrush()
{
m_hbrBackground = QueryBgBitmap();
}
else // no themes
else // no themes or we've got user-defined solid colour
{
m_hbrBackground = NULL;
}
@ -1039,63 +1058,13 @@ WXHBRUSH wxNotebook::MSWGetBgBrushForChild(WXHDC hDC, wxWindow *win)
return wxNotebookBase::MSWGetBgBrushForChild(hDC, win);
}
wxColour wxNotebook::MSWGetBgColourForChild(wxWindow *WXUNUSED(win))
bool wxNotebook::MSWPrintChild(WXHDC hDC, wxWindow *child)
{
if ( m_hasBgCol )
return GetBackgroundColour();
// solid background colour overrides themed background drawing
if ( !UseBgCol() && DoDrawBackground(hDC, child) )
return true;
// Experimental: don't do this since we're doing it in wxPanel
#if 0 // defined(__POCKETPC__) || defined(__SMARTPHONE__)
// For some reason, the pages will be grey by default.
// Normally they should be white on these platforms.
// (However the static control backgrounds are painted
// in the correct colour, just not the rest of it.)
// So let's give WinCE a hint.
else if (!win->m_hasBgCol)
return *wxWHITE;
#endif
if ( !wxUxThemeEngine::GetIfActive() )
return wxNullColour;
return GetThemeBackgroundColour();
}
bool
wxNotebook::MSWPrintChild(wxWindow *win,
WXWPARAM wParam,
WXLPARAM WXUNUSED(lParam))
{
// Don't paint the theme for the child if we have a solid background
if ( m_hasBgCol )
return false;
RECT rc;
::GetClientRect(GetHwnd(), &rc);
// adjust position
TabCtrl_AdjustRect(GetHwnd(), false, &rc);
wxUxThemeHandle theme(win, L"TAB");
if ( theme )
{
// map from this client to win client coords
::MapWindowPoints(GetHwnd(), GetHwndOf(win), (POINT *)&rc, 2);
AdjustRectForThemeBg(rc);
wxUxThemeEngine::Get()->DrawThemeBackground
(
theme,
(WXHDC)wParam,
9 /* TABP_PANE */,
0,
&rc,
NULL
);
}
return true;
return wxNotebookBase::MSWPrintChild(hDC, child);
}
#endif // wxUSE_UXTHEME

View File

@ -644,6 +644,31 @@ void wxRadioBox::DoSetSize(int x, int y, int width, int height, int sizeFlags)
}
}
// ----------------------------------------------------------------------------
// radio box drawing
// ----------------------------------------------------------------------------
#ifndef __WXWINCE__
WXHRGN wxRadioBox::MSWGetRegionWithoutChildren()
{
RECT rc;
::GetWindowRect(GetHwnd(), &rc);
HRGN hrgn = ::CreateRectRgn(rc.left, rc.top, rc.right + 1, rc.bottom + 1);
const size_t count = GetCount();
for ( size_t i = 0; i < count; ++i )
{
::GetWindowRect((*m_radioButtons)[i], &rc);
AutoHRGN hrgnchild(::CreateRectRgnIndirect(&rc));
::CombineRgn(hrgn, hrgn, hrgnchild, RGN_DIFF);
}
return (WXHRGN)hrgn;
}
#endif // __WXWINCE__
// ---------------------------------------------------------------------------
// window proc for radio buttons
// ---------------------------------------------------------------------------
@ -810,57 +835,12 @@ LRESULT APIENTRY _EXPORT wxRadioBtnWndProc(HWND hwnd,
break;
}
break;
#endif // !__WXWINCE__
}
return ::CallWindowProc(CASTWNDPROC s_wndprocRadioBtn, hwnd, message, wParam, lParam);
}
WXHRGN wxRadioBox::MSWGetRegionWithoutChildren()
{
RECT rc;
::GetWindowRect(GetHwnd(), &rc);
HRGN hrgn = ::CreateRectRgn(rc.left, rc.top, rc.right + 1, rc.bottom + 1);
const size_t count = GetCount();
for ( size_t i = 0; i < count; ++i )
{
::GetWindowRect((*m_radioButtons)[i], &rc);
AutoHRGN hrgnchild(::CreateRectRgnIndirect(&rc));
::CombineRgn(hrgn, hrgn, hrgnchild, RGN_DIFF);
}
return (WXHRGN)hrgn;
}
WXLRESULT wxRadioBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
{
#ifndef __WXWINCE__
if ( nMsg == WM_PRINTCLIENT )
{
// first check to see if a parent window knows how to paint us better
for ( wxWindow *win = GetParent(); win; win = win->GetParent() )
if ( win->MSWPrintChild(this, wParam, lParam) )
return true;
// nope, so lets do it ourselves
RECT rc;
WXHBRUSH hbr = DoMSWControlColor((HDC)wParam, wxNullColour);
if ( !hbr )
{
wxBrush *brush = wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID);
hbr = (WXHBRUSH)brush->GetResourceHandle();
}
::GetClientRect(GetHwnd(), &rc);
::FillRect((HDC)wParam, &rc, (HBRUSH)hbr);
return true;
}
#endif
// __WXWINCE__
return wxStaticBox::MSWWindowProc(nMsg, wParam, lParam);
}
#endif // wxUSE_RADIOBOX

View File

@ -123,7 +123,7 @@ bool wxStaticBox::Create(wxWindow *parent,
#ifndef __WXWINCE__
Connect(wxEVT_PAINT, wxPaintEventHandler(wxStaticBox::OnPaint));
#endif
#endif // !__WXWINCE__
return true;
}
@ -161,9 +161,19 @@ wxSize wxStaticBox::DoGetBestSize() const
return wxSize(wBox, hBox);
}
void wxStaticBox::GetBordersForSizer(int *borderTop, int *borderOther) const
{
wxStaticBoxBase::GetBordersForSizer(borderTop, borderOther);
// need extra space, don't know how much but this seems to be enough
*borderTop += GetCharHeight()/3;
}
// all the hacks below are not necessary for WinCE
#ifndef __WXWINCE__
WXLRESULT wxStaticBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
{
#ifndef __WXWINCE__
if ( nMsg == WM_NCHITTEST )
{
// This code breaks some other processing such as enter/leave tracking
@ -174,8 +184,8 @@ WXLRESULT wxStaticBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lPar
s_useHTClient = wxSystemOptions::GetOptionInt(wxT("msw.staticbox.htclient"));
if (s_useHTClient == 1)
{
int xPos = LOWORD(lParam); // horizontal position of cursor
int yPos = HIWORD(lParam); // vertical position of cursor
int xPos = GET_X_LPARAM(lParam);
int yPos = GET_Y_LPARAM(lParam);
ScreenToClient(&xPos, &yPos);
@ -185,18 +195,21 @@ WXLRESULT wxStaticBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lPar
return (long)HTCLIENT;
}
}
#endif // !__WXWINCE__
return wxControl::MSWWindowProc(nMsg, wParam, lParam);
}
void wxStaticBox::GetBordersForSizer(int *borderTop, int *borderOther) const
{
wxStaticBoxBase::GetBordersForSizer(borderTop, borderOther);
// ----------------------------------------------------------------------------
// static box drawing
// ----------------------------------------------------------------------------
// need extra space, don't know how much but this seems to be enough
*borderTop += GetCharHeight()/3;
}
/*
We draw the static box ourselves because it's the only way to prevent it
from flickering horribly on resize (because everything inside the box is
erased twice: once when the box itself is repainted and second time when
the control inside it is repainted) without using WS_EX_TRANSPARENT style as
we used to do and which resulted in other problems.
*/
// MSWGetRegionWithoutSelf helper: removes the given rectangle from region
static inline void
@ -279,42 +292,60 @@ WXHRGN wxStaticBox::MSWGetRegionWithoutChildren()
return (WXHRGN)hrgn;
}
// helper for OnPaint()
// helper for OnPaint(): really erase the background, i.e. do it even if we
// don't have any non default brush for doing it (DoEraseBackground() doesn't
// do anything in such case)
void wxStaticBox::PaintBackground(wxDC& dc, const RECT& rc)
{
// note that static box should be transparent, so it should show its
// parents colour, not its own
wxWindow * const parent = GetParent();
// note that we do not use the box background colour here, it shouldn't
// apply to its interior for several reasons:
// 1. wxGTK doesn't do it
// 2. controls inside the box don't get correct bg colour because they
// are not our children so we'd have some really ugly colour mix if
// we did it
// 3. this is backwards compatible behaviour and some people rely on it,
// see http://groups.google.com/groups?selm=4252E932.3080801%40able.es
wxWindow *parent = GetParent();
HBRUSH hbr = (HBRUSH)parent->MSWGetBgBrush(dc.GetHDC(), this);
HBRUSH hbr = (HBRUSH)parent->MSWGetBgBrush(dc.GetHDC());
// if there is no special brush for painting this control, just use the
// solid background colour
wxBrush brush;
if ( !hbr )
{
wxBrush *brush =
wxTheBrushList->FindOrCreateBrush(parent->GetBackgroundColour());
if ( brush )
hbr = GetHbrushOf(*brush);
brush = wxBrush(parent->GetBackgroundColour());
hbr = GetHbrushOf(brush);
}
if ( hbr )
::FillRect(GetHdcOf(dc), &rc, hbr);
::FillRect(GetHdcOf(dc), &rc, hbr);
}
void wxStaticBox::OnPaint(wxPaintEvent& WXUNUSED(event))
{
wxPaintDC dc(this);
RECT rc;
::GetClientRect(GetHwnd(), &rc);
// draw the entire box in a memory DC, but only blit the bits not redrawn
// either by our children windows nor by FillRect() painting the background
// below
// draw the entire box in a memory DC
wxMemoryDC memdc;
wxBitmap bitmap(rc.right, rc.bottom);
memdc.SelectObject(bitmap);
PaintBackground(memdc, rc);
// NB: neither setting the text colour nor transparent background mode
// doesn't change anything: the static box def window proc still
// draws the label in its own colours, so if we want to have control
// over this we really have to draw everything ourselves
MSWDefWindowProc(WM_PAINT, (WPARAM)GetHdcOf(memdc), 0);
// now only blit the static box border itself, not the interior, to avoid
// flicker when background is drawn below
//
// note that it seems to be faster to do 4 small blits here and then paint
// directly into wxPaintDC than painting background in wxMemoryDC and then
// blitting everything at once to wxPaintDC, this is why we do it like this
wxPaintDC dc(this);
int borderTop, border;
GetBordersForSizer(&borderTop, &border);
@ -331,20 +362,22 @@ void wxStaticBox::OnPaint(wxPaintEvent& WXUNUSED(event))
dc.Blit(rc.right - border, 0, rc.right, rc.bottom,
&memdc, rc.right - border, 0);
// create the region excluding box children
AutoHRGN hrgn((HRGN)MSWGetRegionWithoutChildren());
RECT rcWin;
::GetWindowRect(GetHwnd(), &rcWin);
::OffsetRgn(hrgn, -rcWin.left, -rcWin.top);
// now remove the box itself
// and also the box itself
MSWGetRegionWithoutSelf((WXHRGN) hrgn, rc.right, rc.bottom);
HDCClipper clipToBg(GetHdcOf(dc), hrgn);
// and paint the inside of the box (excluding child controls)
::SelectClipRgn(GetHdcOf(dc), hrgn);
// paint the inside of the box (excluding box itself and child controls)
PaintBackground(dc, rc);
::SelectClipRgn(GetHdcOf(dc), NULL);
}
#endif // !__WXWINCE__
#endif // wxUSE_STATBOX

View File

@ -126,27 +126,6 @@ WXDWORD wxStaticText::MSWGetStyle(long style, WXDWORD *exstyle) const
return msStyle;
}
WXHBRUSH wxStaticText::DoMSWControlColor(WXHDC pDC, wxColour colBg)
{
// If this control has a non-standard fg colour but still has the standard
// bg then we need to also give it a non-standard bg otherwise the fg
// setting has no effect.
WXHBRUSH hbr = wxControl::DoMSWControlColor(pDC, colBg);
if (!hbr && m_hasFgCol)
{
hbr = MSWGetBgBrushForChild(pDC, this);
if (!hbr)
{
HDC hdc = (HDC)pDC;
wxColour bg = GetBackgroundColour();
::SetBkColor(hdc, wxColourToRGB(bg));
wxBrush *brush = wxTheBrushList->FindOrCreateBrush(bg, wxSOLID);
hbr = (WXHBRUSH)brush->GetResourceHandle();
}
}
return hbr;
}
wxSize wxStaticText::DoGetBestSize() const
{
wxClientDC dc(wx_const_cast(wxStaticText *, this));

View File

@ -1891,7 +1891,7 @@ WXHBRUSH wxTextCtrl::MSWControlColor(WXHDC hDC)
if ( !IsEnabled() && !HasFlag(wxTE_MULTILINE) )
return MSWControlColorDisabled(hDC);
return wxTextCtrlBase::MSWControlColorSolid(hDC);
return wxTextCtrlBase::MSWControlColor(hDC);
}
bool wxTextCtrl::AdjustSpaceLimit()

View File

@ -2318,55 +2318,57 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
processed = HandleKillFocus((WXHWND)(HWND)wParam);
break;
case WM_PAINT:
{
if ( wParam )
{
// cast to wxWindow is needed for wxUniv
wxPaintDCEx dc((wxWindow *)this, (WXHDC)wParam);
processed = HandlePaint();
}
else
{
processed = HandlePaint();
}
break;
}
#ifdef WM_PRINT
case WM_PRINTCLIENT:
if ( GetParent() &&
GetParent()->MSWPrintChild((wxWindow *)this, wParam, lParam) )
// we receive this message when DrawThemeParentBackground() is
// called from def window proc of several controls under XP and we
// must draw properly themed background here
//
// note that naively I'd expect filling the client rect with the
// brush returned by MSWGetBgBrush() work -- but for some reason it
// doesn't and we have to call parents MSWPrintChild() which is
// supposed to call DrawThemeBackground() with appropriate params
//
// also note that in this case lParam == PRF_CLIENT but we're
// clearly expected to paint the background and nothing else!
{
processed = true;
for ( wxWindow *win = GetParent(); win; win = win->GetParent() )
{
if ( win->MSWPrintChild((WXHDC)wParam, (wxWindow *)this) )
{
processed = true;
break;
}
if ( win->IsTopLevel() || win->InheritsBackgroundColour() )
break;
}
}
break;
case WM_PRINT:
case WM_PAINT:
if ( wParam )
{
if ( lParam & PRF_ERASEBKGND )
HandleEraseBkgnd((WXHDC)(HDC)wParam);
wxPaintDCEx dc((wxWindow *)this, (WXHDC)wParam);
processed = HandlePaint();
}
else // no DC given
{
processed = HandlePaint();
}
break;
#endif // WM_PRINT
case WM_CLOSE:
#ifdef __WXUNIVERSAL__
// Universal uses its own wxFrame/wxDialog, so we don't receive
// close events unless we have this.
Close();
processed = true;
rc.result = TRUE;
#else
#endif // __WXUNIVERSAL__
// don't let the DefWindowProc() destroy our window - we'll do it
// ourselves in ~wxWindow
processed = true;
rc.result = TRUE;
#endif
break;
case WM_SHOWWINDOW:
@ -3708,7 +3710,8 @@ bool wxWindowMSW::HandleDisplayChange()
bool wxWindowMSW::HandleCtlColor(WXHBRUSH *brush, WXHDC pDC, WXHWND pWnd)
{
#if wxUSE_CONTROLS
wxWindow *item = FindItemByHWND(pWnd, true);
wxControl *item = wxDynamicCast(FindItemByHWND(pWnd, true), wxControl);
if ( item )
*brush = item->MSWControlColor(pDC);
else
@ -3720,11 +3723,6 @@ bool wxWindowMSW::HandleCtlColor(WXHBRUSH *brush, WXHDC pDC, WXHWND pWnd)
#endif // __WXMICROWIN__
WXHBRUSH wxWindowMSW::MSWControlColor(WXHDC WXUNUSED(hDC))
{
return (WXHBRUSH)0;
}
bool wxWindowMSW::HandlePaletteChanged(WXHWND hWndPalChange)
{
#if wxUSE_PALETTE
@ -3986,93 +3984,70 @@ void wxWindowMSW::OnEraseBackground(wxEraseEvent& event)
// do default background painting
if ( !DoEraseBackground(*event.GetDC()) )
if ( !DoEraseBackground(GetHdcOf(*event.GetDC())) )
{
// let the system paint the background
event.Skip();
}
}
bool wxWindowMSW::DoEraseBackground(wxDC& dc)
bool wxWindowMSW::DoEraseBackground(WXHDC hDC)
{
HBRUSH hBrush = (HBRUSH)MSWGetBgBrush(dc.GetHDC());
if ( !hBrush )
HBRUSH hbr = (HBRUSH)MSWGetBgBrush(hDC);
if ( !hbr )
return false;
RECT rc;
::GetClientRect(GetHwnd(), &rc);
::FillRect(GetHdcOf(dc), &rc, hBrush);
wxFillRect(GetHwnd(), (HDC)hDC, hbr);
return true;
}
WXHBRUSH wxWindowMSW::MSWGetSolidBgBrushForChild(wxWindow *child)
{
wxColour col = MSWGetBgColourForChild(child);
if ( col.Ok() )
{
// draw children with the same colour as the parent
wxBrush *brush = wxTheBrushList->FindOrCreateBrush(col, wxSOLID);
return (WXHBRUSH)brush->GetResourceHandle();
}
return 0;
}
wxColour wxWindowMSW::MSWGetBgColourForChild(wxWindow *child)
WXHBRUSH
wxWindowMSW::MSWGetBgBrushForChild(WXHDC WXUNUSED(hDC), wxWindow *child)
{
if ( m_hasBgCol )
{
// our background colour applies to:
// 1. this window itself, always
// 2. all children unless the colour is "not inheritable"
// 3. immediate transparent children which should show the same
// background as we do, but not for transparent grandchildren
// which use the background of their immediate parent instead
if ( m_inheritBgCol ||
child == this ||
// 3. even if it is not inheritable, our immediate transparent
// children should still inherit it -- but not any transparent
// children because it would look wrong if a child of non
// transparent child would show our bg colour when the child itself
// does not
if ( child == this ||
m_inheritBgCol ||
(child->HasTransparentBackground() &&
child->GetParent() == this) )
{
return GetBackgroundColour();
// draw children with the same colour as the parent
wxBrush *
brush = wxTheBrushList->FindOrCreateBrush(GetBackgroundColour());
return (WXHBRUSH)GetHbrushOf(*brush);
}
}
return wxNullColour;
}
WXHBRUSH wxWindowMSW::MSWGetBgBrushForSelf(wxWindow *parent, WXHDC hDC)
{
return parent->MSWGetBgBrushForChild(hDC, (wxWindow *)this);
}
WXHBRUSH wxWindowMSW::MSWGetBgBrush(WXHDC hDC)
{
for ( wxWindow *win = (wxWindow *)this; win; win = win->GetParent() )
{
WXHBRUSH hBrush = MSWGetBgBrushForSelf(win, hDC);
if ( hBrush )
return hBrush;
// background is not inherited beyond the windows which have their own
// fixed background such as top level windows and notebooks and for
// windows for which a custom colour had been explicitly set with
// SetOwnBackgroundColour() and so shouldn't affect its children
if ( win->ProvidesBackground() ||
(win->UseBgCol() && !win->InheritsBackgroundColour()) )
break;
}
return 0;
}
bool
wxWindowMSW::MSWPrintChild(wxWindow * WXUNUSED(win),
WXWPARAM WXUNUSED(wParam),
WXLPARAM WXUNUSED(lParam))
WXHBRUSH wxWindowMSW::MSWGetBgBrush(WXHDC hDC, wxWindow *winToPaint)
{
return false;
if ( !winToPaint )
winToPaint = this;
for ( wxWindowMSW *win = this; win; win = win->GetParent() )
{
WXHBRUSH hBrush = win->MSWGetBgBrushForChild(hDC, winToPaint);
if ( hBrush )
return hBrush;
// background is not inherited beyond top level windows
if ( win->IsTopLevel() )
break;
}
return 0;
}
// ---------------------------------------------------------------------------