From c3732409acc7a1e0b3cdb1f0a5dec7cc49a4b28b Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 10 Apr 2005 15:23:08 +0000 Subject: [PATCH] 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 --- include/wx/bmpbuttn.h | 4 - include/wx/bookctrl.h | 5 - include/wx/generic/panelg.h | 4 - include/wx/msw/button.h | 8 -- include/wx/msw/checkbox.h | 1 - include/wx/msw/control.h | 23 +---- include/wx/msw/listbox.h | 5 - include/wx/msw/notebook.h | 20 +++- include/wx/msw/private.h | 8 ++ include/wx/msw/radiobox.h | 5 +- include/wx/msw/radiobut.h | 4 +- include/wx/msw/statbox.h | 5 +- include/wx/msw/stattext.h | 2 +- include/wx/msw/window.h | 63 ++++------- include/wx/palmos/button.h | 6 -- include/wx/palmos/radiobox.h | 3 - include/wx/palmos/radiobut.h | 4 - include/wx/slider.h | 3 - include/wx/statline.h | 2 - include/wx/toplevel.h | 1 - include/wx/vlbox.h | 4 - include/wx/window.h | 15 --- src/generic/timer.cpp | 42 ++++---- src/msw/checkbox.cpp | 22 +--- src/msw/choice.cpp | 2 +- src/msw/control.cpp | 29 ++++-- src/msw/notebook.cpp | 195 +++++++++++++++-------------------- src/msw/radiobox.cpp | 72 +++++-------- src/msw/statbox.cpp | 97 +++++++++++------ src/msw/stattext.cpp | 21 ---- src/msw/textctrl.cpp | 2 +- src/msw/window.cpp | 141 +++++++++++-------------- 32 files changed, 331 insertions(+), 487 deletions(-) diff --git a/include/wx/bmpbuttn.h b/include/wx/bmpbuttn.h index 442369808c..61a5428e20 100644 --- a/include/wx/bmpbuttn.h +++ b/include/wx/bmpbuttn.h @@ -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(); } diff --git a/include/wx/bookctrl.h b/include/wx/bookctrl.h index 6bc12d1ec9..82f956d58e 100644 --- a/include/wx/bookctrl.h +++ b/include/wx/bookctrl.h @@ -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; diff --git a/include/wx/generic/panelg.h b/include/wx/generic/panelg.h index 75c666f08e..3175d0bb34 100644 --- a/include/wx/generic/panelg.h +++ b/include/wx/generic/panelg.h @@ -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(); diff --git a/include/wx/msw/button.h b/include/wx/msw/button.h index 2728b70739..8ae1f466fd 100644 --- a/include/wx/msw/button.h +++ b/include/wx/msw/button.h @@ -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 diff --git a/include/wx/msw/checkbox.h b/include/wx/msw/checkbox.h index c15b226eda..31f3bddfba 100644 --- a/include/wx/msw/checkbox.h +++ b/include/wx/msw/checkbox.h @@ -50,7 +50,6 @@ public: protected: virtual wxSize DoGetBestSize() const; - virtual WXHBRUSH MSWGetDefaultBgBrush(); virtual void DoSet3StateValue(wxCheckBoxState value); virtual wxCheckBoxState DoGet3StateValue() const; diff --git a/include/wx/msw/control.h b/include/wx/msw/control.h index ab32c80c76..a917a0e449 100644 --- a/include/wx/msw/control.h +++ b/include/wx/msw/control.h @@ -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 diff --git a/include/wx/msw/listbox.h b/include/wx/msw/listbox.h index a901adf31c..5104928429 100644 --- a/include/wx/msw/listbox.h +++ b/include/wx/msw/listbox.h @@ -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(); diff --git a/include/wx/msw/notebook.h b/include/wx/msw/notebook.h index ef54ae0aec..27e9160960 100644 --- a/include/wx/msw/notebook.h +++ b/include/wx/msw/notebook.h @@ -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) diff --git a/include/wx/msw/private.h b/include/wx/msw/private.h index 86cc595d89..a2a08d8316 100644 --- a/include/wx/msw/private.h +++ b/include/wx/msw/private.h @@ -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 // ---------------------------------------------------------------------------- diff --git a/include/wx/msw/radiobox.h b/include/wx/msw/radiobox.h index cb08edafee..ae7041a3c0 100644 --- a/include/wx/msw/radiobox.h +++ b/include/wx/msw/radiobox.h @@ -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 diff --git a/include/wx/msw/radiobut.h b/include/wx/msw/radiobut.h index da92a8e18f..287bce70cc 100644 --- a/include/wx/msw/radiobut.h +++ b/include/wx/msw/radiobut.h @@ -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; diff --git a/include/wx/msw/statbox.h b/include/wx/msw/statbox.h index e3714e0a36..81c70ecdd2 100644 --- a/include/wx/msw/statbox.h +++ b/include/wx/msw/statbox.h @@ -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_ diff --git a/include/wx/msw/stattext.h b/include/wx/msw/stattext.h index 6f6016f11c..6194187606 100644 --- a/include/wx/msw/stattext.h +++ b/include/wx/msw/stattext.h @@ -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) }; diff --git a/include/wx/msw/window.h b/include/wx/msw/window.h index ef21be2ecf..dc7bbad256 100644 --- a/include/wx/msw/window.h +++ b/include/wx/msw/window.h @@ -358,54 +358,31 @@ 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) - { - return MSWGetSolidBgBrushForChild(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 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 + // return the background brush to use for painting the given window by + // quering the parent windows via their MSWGetBgBrushForChild() recursively // - // 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 + // 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 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); + // return true if background was drawn, false otherwise + virtual bool MSWPrintChild(WXHDC WXUNUSED(hDC), wxWindow * WXUNUSED(child)) + { + return false; + } // Responds to colour changes: passes event on to children. @@ -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 diff --git a/include/wx/palmos/button.h b/include/wx/palmos/button.h index 4c01bac899..37f60a9551 100644 --- a/include/wx/palmos/button.h +++ b/include/wx/palmos/button.h @@ -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 diff --git a/include/wx/palmos/radiobox.h b/include/wx/palmos/radiobox.h index 39640d620c..337e52a69f 100644 --- a/include/wx/palmos/radiobox.h +++ b/include/wx/palmos/radiobox.h @@ -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)) { } diff --git a/include/wx/palmos/radiobut.h b/include/wx/palmos/radiobut.h index db4746f1d3..5e0040e738 100644 --- a/include/wx/palmos/radiobut.h +++ b/include/wx/palmos/radiobut.h @@ -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; diff --git a/include/wx/slider.h b/include/wx/slider.h index dbd0a2a958..20e2b75dcd 100644 --- a/include/wx/slider.h +++ b/include/wx/slider.h @@ -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 diff --git a/include/wx/statline.h b/include/wx/statline.h index e472503747..18d48a7f68 100644 --- a/include/wx/statline.h +++ b/include/wx/statline.h @@ -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 diff --git a/include/wx/toplevel.h b/include/wx/toplevel.h index 2ea84745b8..6820f9cfee 100644 --- a/include/wx/toplevel.h +++ b/include/wx/toplevel.h @@ -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); diff --git a/include/wx/vlbox.h b/include/wx/vlbox.h index 598fa2e058..a512d05108 100644 --- a/include/wx/vlbox.h +++ b/include/wx/vlbox.h @@ -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()); diff --git a/include/wx/window.h b/include/wx/window.h index 06b9ad44d4..19c6a01a25 100644 --- a/include/wx/window.h +++ b/include/wx/window.h @@ -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) { diff --git a/src/generic/timer.cpp b/src/generic/timer.cpp index 24d5888cdd..b8e4c1e1c7 100644 --- a/src/generic/timer.cpp +++ b/src/generic/timer.cpp @@ -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->deleteFlag = NULL; - if ( !oneShot ) - QueueTimer(desc, now + desc->timer->GetInterval()); + desc = m_timers; + oneShot = desc->timer->IsOneShot(); + RemoveTimer(desc); + + 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()); + } } } } diff --git a/src/msw/checkbox.cpp b/src/msw/checkbox.cpp index 9e0897ed4e..3955dba064 100644 --- a/src/msw/checkbox.cpp +++ b/src/msw/checkbox.cpp @@ -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 diff --git a/src/msw/choice.cpp b/src/msw/choice.cpp index a243f36fb0..bf0739540f 100644 --- a/src/msw/choice.cpp +++ b/src/msw/choice.cpp @@ -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__) diff --git a/src/msw/control.cpp b/src/msw/control.cpp index 7d8c6024f2..d17556945e 100644 --- a/src/msw/control.cpp +++ b/src/msw/control.cpp @@ -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; + + if ( HasTransparentBackground() ) + ::SetBkMode((HDC)pDC, TRANSPARENT); + else // if the control is opaque it shouldn't use the parents background + colBg = GetBackgroundColour(); - return DoMSWControlColor(pDC, wxNullColour); + return DoMSWControlColor(pDC, colBg); } WXHBRUSH wxControl::MSWControlColorDisabled(WXHDC pDC) diff --git a/src/msw/notebook.cpp b/src/msw/notebook.cpp index eb4410c99c..a9d59425a9 100644 --- a/src/msw/notebook.cpp +++ b/src/msw/notebook.cpp @@ -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 -WXHBRUSH wxNotebook::QueryBgBitmap() +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; - ::GetClientRect(GetHwnd(), &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; +} - // adjust position - TabCtrl_AdjustRect(GetHwnd(), false, &rc); +WXHBRUSH wxNotebook::QueryBgBitmap() +{ + 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)) -{ - if ( m_hasBgCol ) - return GetBackgroundColour(); - - // 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)) +bool wxNotebook::MSWPrintChild(WXHDC hDC, wxWindow *child) { - // Don't paint the theme for the child if we have a solid background - if ( m_hasBgCol ) - return false; - - - RECT rc; - ::GetClientRect(GetHwnd(), &rc); + // solid background colour overrides themed background drawing + if ( !UseBgCol() && DoDrawBackground(hDC, child) ) + return true; - // 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 diff --git a/src/msw/radiobox.cpp b/src/msw/radiobox.cpp index 253c31204d..26890f192c 100644 --- a/src/msw/radiobox.cpp +++ b/src/msw/radiobox.cpp @@ -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 diff --git a/src/msw/statbox.cpp b/src/msw/statbox.cpp index 441dd5147f..beb2797300 100644 --- a/src/msw/statbox.cpp +++ b/src/msw/statbox.cpp @@ -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); } -WXLRESULT wxStaticBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) +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) +{ 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(); - - HBRUSH hbr = (HBRUSH)parent->MSWGetBgBrush(dc.GetHDC()); + // 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); + + // 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 diff --git a/src/msw/stattext.cpp b/src/msw/stattext.cpp index 466fb5484d..124d9e471d 100644 --- a/src/msw/stattext.cpp +++ b/src/msw/stattext.cpp @@ -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)); diff --git a/src/msw/textctrl.cpp b/src/msw/textctrl.cpp index 7604356776..0d2db8f3ca 100644 --- a/src/msw/textctrl.cpp +++ b/src/msw/textctrl.cpp @@ -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() diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 68136888e9..43d21ba44d 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -2318,55 +2318,57 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l processed = HandleKillFocus((WXHWND)(HWND)wParam); break; - case WM_PAINT: + case WM_PRINTCLIENT: + // 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! { - if ( wParam ) - { - // cast to wxWindow is needed for wxUniv - wxPaintDCEx dc((wxWindow *)this, (WXHDC)wParam); - processed = HandlePaint(); - } - else + for ( wxWindow *win = GetParent(); win; win = win->GetParent() ) { - processed = HandlePaint(); - } - break; - } + if ( win->MSWPrintChild((WXHDC)wParam, (wxWindow *)this) ) + { + processed = true; + break; + } -#ifdef WM_PRINT - case WM_PRINTCLIENT: - if ( GetParent() && - GetParent()->MSWPrintChild((wxWindow *)this, wParam, lParam) ) - { - processed = true; + 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,95 +3984,72 @@ 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; + return 0; } -WXHBRUSH wxWindowMSW::MSWGetBgBrushForSelf(wxWindow *parent, WXHDC hDC) +WXHBRUSH wxWindowMSW::MSWGetBgBrush(WXHDC hDC, wxWindow *winToPaint) { - return parent->MSWGetBgBrushForChild(hDC, (wxWindow *)this); -} + if ( !winToPaint ) + winToPaint = this; -WXHBRUSH wxWindowMSW::MSWGetBgBrush(WXHDC hDC) -{ - for ( wxWindow *win = (wxWindow *)this; win; win = win->GetParent() ) + for ( wxWindowMSW *win = this; win; win = win->GetParent() ) { - WXHBRUSH hBrush = MSWGetBgBrushForSelf(win, hDC); + WXHBRUSH hBrush = win->MSWGetBgBrushForChild(hDC, winToPaint); 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()) ) + // background is not inherited beyond top level windows + if ( win->IsTopLevel() ) break; } return 0; } -bool -wxWindowMSW::MSWPrintChild(wxWindow * WXUNUSED(win), - WXWPARAM WXUNUSED(wParam), - WXLPARAM WXUNUSED(lParam)) -{ - return false; -} - // --------------------------------------------------------------------------- // moving and resizing // --------------------------------------------------------------------------- -- 2.45.2