#include <commctrl.h>
#endif
+#define USE_DEFERRED_SIZING 1
+
// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS_XTI(wxSlider, wxControl,"wx/scrolbar.h")
wxBEGIN_PROPERTIES_TABLE(wxSlider)
- wxEVENT_RANGE_PROPERTY( Scroll , wxEVT_SCROLL_TOP , wxEVT_SCROLL_ENDSCROLL , wxScrollEvent )
+ wxEVENT_RANGE_PROPERTY( Scroll , wxEVT_SCROLL_TOP , wxEVT_SCROLL_CHANGED , wxScrollEvent )
wxEVENT_PROPERTY( Updated , wxEVT_COMMAND_SLIDER_UPDATED , wxCommandEvent )
wxPROPERTY( Value , int , SetValue, GetValue , 0, 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
m_rangeMax = 0;
m_rangeMin = 0;
m_tickFreq = 0;
+
+ m_isDragging = false;
}
bool
case SB_THUMBTRACK:
scrollEvent = wxEVT_SCROLL_THUMBTRACK;
+ m_isDragging = true;
break;
case SB_THUMBPOSITION:
- scrollEvent = wxEVT_SCROLL_THUMBRELEASE;
+ if ( m_isDragging )
+ {
+ scrollEvent = wxEVT_SCROLL_THUMBRELEASE;
+ m_isDragging = false;
+ }
+ else
+ {
+ // this seems to only happen when the mouse wheel is used: in
+ // this case, as it might be unexpected to get THUMBRELEASE
+ // without preceding THUMBTRACKs, we don't generate it at all
+ // but generate CHANGED event because the control itself does
+ // not send us SB_ENDSCROLL for whatever reason when mouse
+ // wheel is used
+ scrollEvent = wxEVT_SCROLL_CHANGED;
+ }
break;
case SB_ENDSCROLL:
- scrollEvent = wxEVT_SCROLL_ENDSCROLL;
+ scrollEvent = wxEVT_SCROLL_CHANGED;
break;
default:
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