extern WXDLLEXPORT_DATA(const char) wxPanelNameStr[] = "panel";
+namespace wxMouseCapture
+{
+
+// Check if the given window is in the capture stack.
+bool IsInCaptureStack(wxWindowBase* win);
+
+} // wxMouseCapture
+
// ----------------------------------------------------------------------------
// static data
// ----------------------------------------------------------------------------
// common clean up
wxWindowBase::~wxWindowBase()
{
- wxASSERT_MSG( GetCapture() != this, wxT("attempt to destroy window with mouse capture") );
+ wxASSERT_MSG( !wxMouseCapture::IsInCaptureStack(this),
+ "Destroying window before releasing mouse capture: this "
+ "will result in a crash later." );
// FIXME if these 2 cases result from programming errors in the user code
// we should probably assert here instead of silently fixing them
parent->SendSizeEvent(flags);
}
+bool wxWindowBase::CanScroll(int orient) const
+{
+ return (m_windowStyle &
+ (orient == wxHORIZONTAL ? wxHSCROLL : wxVSCROLL)) != 0;
+}
+
bool wxWindowBase::HasScrollbar(int orient) const
{
// if scrolling in the given direction is disabled, we can't have the
for ( node = m_children.GetFirst(); node && !res; node = node->GetNext() )
{
wxWindowBase *child = node->GetData();
+
+ // As usual, don't recurse into child dialogs, finding a button in a
+ // child dialog when looking in this window would be unexpected.
+ if ( child->IsTopLevel() )
+ continue;
+
res = child->FindWindow( id );
}
for ( node = m_children.GetFirst(); node && !res; node = node->GetNext() )
{
wxWindow *child = node->GetData();
+
+ // As in FindWindow() overload above, never recurse into child dialogs.
+ if ( child->IsTopLevel() )
+ continue;
+
res = child->FindWindow(name);
}
// Flag preventing reentrancy in {Capture,Release}Mouse().
wxRecursionGuardFlag changing;
+bool IsInCaptureStack(wxWindowBase* win)
+{
+ for ( wxVector<wxWindow*>::const_iterator it = stack.begin();
+ it != stack.end();
+ ++it )
+ {
+ if ( *it == win )
+ return true;
+ }
+
+ return false;
+}
+
} // wxMouseCapture
void wxWindowBase::CaptureMouse()
wxRecursionGuard guard(wxMouseCapture::changing);
wxASSERT_MSG( !guard.IsInside(), wxT("recursive CaptureMouse call?") );
+ wxASSERT_MSG( !wxMouseCapture::IsInCaptureStack(this),
+ "Recapturing the mouse in the same window?" );
+
wxWindow *winOld = GetCapture();
if ( winOld )
((wxWindowBase*) winOld)->DoReleaseMouse();
wxRecursionGuard guard(wxMouseCapture::changing);
wxASSERT_MSG( !guard.IsInside(), wxT("recursive ReleaseMouse call?") );
- wxASSERT_MSG( GetCapture() == this,
- "attempt to release mouse, but this window hasn't captured it" );
+#if wxDEBUG_LEVEL
+ wxWindow* const winCapture = GetCapture();
+ if ( !winCapture )
+ {
+ wxFAIL_MSG
+ (
+ wxString::Format
+ (
+ "Releasing mouse in %p(%s) but it is not captured",
+ this, GetClassInfo()->GetClassName()
+ )
+ );
+ }
+ else if ( winCapture != this )
+ {
+ wxFAIL_MSG
+ (
+ wxString::Format
+ (
+ "Releasing mouse in %p(%s) but it is captured by %p(%s)",
+ this, GetClassInfo()->GetClassName(),
+ winCapture, winCapture->GetClassInfo()->GetClassName()
+ )
+ );
+ }
+#endif // wxDEBUG_LEVEL
DoReleaseMouse();
}
wxLogTrace(wxT("mousecapture"),
- (const wxChar *) wxT("After ReleaseMouse() mouse is captured by %p"),
+ wxT("After ReleaseMouse() mouse is captured by %p"),
static_cast<void*>(GetCapture()));
}