+// helper class for wxScrolled<T> below
+struct WXDLLIMPEXP_CORE wxScrolledT_Helper
+{
+ static wxSize FilterBestSize(const wxWindow *win,
+ const wxScrollHelper *helper,
+ const wxSize& origBest);
+#ifdef __WXMSW__
+ static WXLRESULT FilterMSWWindowProc(WXUINT nMsg, WXLRESULT origResult);
+#endif
+};
+
+// Scrollable window base on window type T. This used to be wxScrolledWindow,
+// but wxScrolledWindow includes wxControlContainer functionality and that's
+// not always desirable.
+template<class T>
+class wxScrolled : public T,
+ public wxScrollHelper,
+ private wxScrolledT_Helper
+{
+public:
+ wxScrolled() : wxScrollHelper(this) { }
+ wxScrolled(wxWindow *parent,
+ wxWindowID winid = wxID_ANY,
+ const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize,
+ long style = wxScrolledWindowStyle,
+ const wxString& name = wxPanelNameStr)
+ : wxScrollHelper(this)
+ {
+ Create(parent, winid, pos, size, style, name);
+ }
+
+ bool Create(wxWindow *parent,
+ wxWindowID winid,
+ const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize,
+ long style = wxScrolledWindowStyle,
+ const wxString& name = wxPanelNameStr)
+ {
+ m_targetWindow = this;
+
+#ifdef __WXMAC__
+ this->MacSetClipChildren(true);
+#endif
+
+ this->Connect(wxEVT_PAINT, wxPaintEventHandler(wxScrolled::OnPaint));
+
+ // by default, we're scrollable in both directions (but if one of the
+ // styles is specified explicitly, we shouldn't add the other one
+ // automatically)
+ if ( !(style & (wxHSCROLL | wxVSCROLL)) )
+ style |= wxHSCROLL | wxVSCROLL;
+
+ return T::Create(parent, winid, pos, size, style, name);
+ }
+
+ // we need to return a special WM_GETDLGCODE value to process just the
+ // arrows but let the other navigation characters through
+#ifdef __WXMSW__
+ virtual WXLRESULT MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
+ {
+ return FilterMSWWindowProc(nMsg, T::MSWWindowProc(nMsg, wParam, lParam));
+ }
+#endif // __WXMSW__
+
+ WX_FORWARD_TO_SCROLL_HELPER()
+
+protected:
+ virtual wxSize DoGetBestSize() const
+ {
+ return FilterBestSize(this, this, T::DoGetBestSize());
+ }