#include <commctrl.h>
#endif
+#define USE_DEFERRED_SIZING 1
+
// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------
const wxValidator& validator,
const wxString& name)
{
+ // our styles are redundant: wxSL_LEFT/RIGHT imply wxSL_VERTICAL and
+ // wxSL_TOP/BOTTOM imply wxSL_HORIZONTAL, but for backwards compatibility
+ // reasons we can't really change it, instead try to infer the orientation
+ // from the flags given to us here
+ switch ( style & (wxSL_LEFT | wxSL_RIGHT | wxSL_TOP | wxSL_BOTTOM) )
+ {
+ case wxSL_LEFT:
+ case wxSL_RIGHT:
+ style |= wxSL_VERTICAL;
+ break;
+
+ case wxSL_TOP:
+ case wxSL_BOTTOM:
+ style |= wxSL_HORIZONTAL;
+ break;
+
+ case 0:
+ // no specific direction, do we have at least the orientation?
+ if ( !(style & (wxSL_HORIZONTAL | wxSL_VERTICAL)) )
+ {
+ // no, choose default
+ style |= wxSL_BOTTOM | wxSL_HORIZONTAL;
+ }
+ };
+
+ wxASSERT_MSG( !(style & wxSL_VERTICAL) | !(style & wxSL_HORIZONTAL),
+ _T("incompatible slider direction and orientation") );
+
+
// initialize everything
if ( !CreateControl(parent, id, pos, size, style, validator, name) )
return false;
{
WXDWORD msStyle = wxControl::MSWGetStyle(style, exstyle);
- // TBS_HORZ is 0 anyhow, but do mention it explicitly for clarity
+ // TBS_HORZ, TBS_RIGHT and TBS_BOTTOM are 0 but do include them for clarity
msStyle |= style & wxSL_VERTICAL ? TBS_VERT : TBS_HORZ;
- if ( style & wxSL_AUTOTICKS )
- msStyle |= TBS_AUTOTICKS ;
-
- // again, TBS_RIGHT is 0 but do include it for clarity
- if ( style & wxSL_LEFT )
- msStyle |= TBS_LEFT;
- else if ( style & wxSL_RIGHT )
- msStyle |= TBS_RIGHT;
- else if ( style & wxSL_TOP )
- msStyle |= TBS_TOP;
- else if ( style & wxSL_BOTTOM )
- msStyle |= TBS_BOTTOM;
- else if ( style & wxSL_BOTH )
+ if ( style & wxSL_BOTH )
+ {
+ // this fully specifies the style combined with TBS_VERT/HORZ above
msStyle |= TBS_BOTH;
- else if ( !(style & wxSL_AUTOTICKS) )
+ }
+ else // choose one direction
+ {
+ if ( style & wxSL_LEFT )
+ msStyle |= TBS_LEFT;
+ else if ( style & wxSL_RIGHT )
+ msStyle |= TBS_RIGHT;
+ else if ( style & wxSL_TOP )
+ msStyle |= TBS_TOP;
+ else if ( style & wxSL_BOTTOM )
+ msStyle |= TBS_BOTTOM;
+ }
+
+ if ( style & wxSL_AUTOTICKS )
+ msStyle |= TBS_AUTOTICKS;
+ else
msStyle |= TBS_NOTICKS;
if ( style & wxSL_SELRANGE )
return;
}
+ // if our parent had prepared a defer window handle for us, use it (unless
+ // we are a top level window)
+ wxWindowMSW *parent = GetParent();
+
+#if USE_DEFERRED_SIZING
+ HDWP hdwp = parent && !IsTopLevel() ? (HDWP)parent->m_hDWP : NULL;
+#else
+ HDWP hdwp = 0;
+#endif
+
// be careful to position the slider itself after moving the labels as
// otherwise our GetBoundingBox(), which is called from WM_SIZE handler,
// would return a wrong result and wrong size would be cached internally
// position all labels: min at the top, value in the middle and max at
// the bottom
- ::MoveWindow((*m_labels)[SliderLabel_Min],
- xLabel, y, wLabel, hLabel, TRUE);
+ wxMoveWindowDeferred(hdwp, this, (*m_labels)[SliderLabel_Min],
+ xLabel, y, wLabel, hLabel);
- ::MoveWindow((*m_labels)[SliderLabel_Value],
- xLabel, y + (height - hLabel)/2, wLabel, hLabel, TRUE);
+ wxMoveWindowDeferred(hdwp, this, (*m_labels)[SliderLabel_Value],
+ xLabel, y + (height - hLabel)/2, wLabel, hLabel);
- ::MoveWindow((*m_labels)[SliderLabel_Max],
- xLabel, y + height - hLabel, wLabel, hLabel, TRUE);
+ wxMoveWindowDeferred(hdwp, this, (*m_labels)[SliderLabel_Max],
+ xLabel, y + height - hLabel, wLabel, hLabel);
// position the slider itself along the left/right edge
- ::MoveWindow(GetHwnd(),
+ wxMoveWindowDeferred(hdwp, this, GetHwnd(),
HasFlag(wxSL_LEFT) ? x : x + wLabel + HGAP,
y + hLabel/2,
width - wLabel - HGAP,
- height - hLabel,
- TRUE);
+ height - hLabel);
}
else // horizontal
{
// position all labels: min on the left, value in the middle and max to
// the right
- ::MoveWindow((*m_labels)[SliderLabel_Min],
- x, yLabel, wLabel, hLabel, TRUE);
+ wxMoveWindowDeferred(hdwp, this, (*m_labels)[SliderLabel_Min],
+ x, yLabel, wLabel, hLabel);
- ::MoveWindow((*m_labels)[SliderLabel_Value],
- x + (width - wLabel)/2, yLabel, wLabel, hLabel, TRUE);
+ wxMoveWindowDeferred(hdwp, this, (*m_labels)[SliderLabel_Value],
+ x + (width - wLabel)/2, yLabel, wLabel, hLabel);
- ::MoveWindow((*m_labels)[SliderLabel_Max],
- x + width - wLabel, yLabel, wLabel, hLabel, TRUE);
+ wxMoveWindowDeferred(hdwp, this, (*m_labels)[SliderLabel_Max],
+ x + width - wLabel, yLabel, wLabel, hLabel);
// position the slider itself along the top/bottom edge
- ::MoveWindow(GetHwnd(),
+ wxMoveWindowDeferred(hdwp, this, GetHwnd(),
x,
HasFlag(wxSL_TOP) ? y : y + hLabel,
width,
- height - hLabel,
- TRUE);
+ height - hLabel);
+ }
+
+#if USE_DEFERRED_SIZING
+ if ( parent )
+ {
+ // hdwp must be updated as it may have been changed
+ parent->m_hDWP = (WXHANDLE)hdwp;
}
+#endif
}
wxSize wxSlider::DoGetBestSize() const
{
// these values are arbitrary
static const int length = 100;
- static const int thickness = 26;
+ static const int thumb = 24;
+ static const int ticks = 8;
+ int *width;
wxSize size;
if ( HasFlag(wxSL_VERTICAL) )
{
- size.x = thickness;
+ size.x = thumb;
size.y = length;
+ width = &size.x;
if ( m_labels )
{
else // horizontal
{
size.x = length;
- size.y = thickness;
+ size.y = thumb;
+ width = &size.y;
if ( m_labels )
{
}
}
+ // need extra space to show ticks
+ if ( HasFlag(wxSL_TICKS) )
+ {
+ *width += ticks;
+
+ // and maybe twice as much if we show them on both sides
+ if ( HasFlag(wxSL_BOTH) )
+ *width += ticks;
+ }
+
return size;
}
m_rangeMin = minValue;
m_rangeMax = maxValue;
- ::SendMessage(GetHwnd(), TBM_SETRANGE, TRUE, MAKELONG(minValue, maxValue));
+ ::SendMessage(GetHwnd(), TBM_SETRANGEMIN, TRUE, m_rangeMin);
+ ::SendMessage(GetHwnd(), TBM_SETRANGEMAX, TRUE, m_rangeMax);
if ( m_labels )
{