private bool ProcessClientMouseDown(ref Message m)
{
bool processed = false;
// Convert the client position to screen point
Point screenPt = CommonHelper.ClientMouseMessageToScreenPt(m);
// Is this message for the current popup?
if (m.HWnd == _current.Handle)
{
// Message is intended for the current popup which means we ask the popup if it
// would like to kill the entire stack because it knows the mouse down should
// cancel the showing of popups.
if (_current.DoesCurrentMouseDownEndAllTracking(m, ScreenPtToClientPt(screenPt)))
{
EndAllTracking();
}
}
else
{
// If the current popup is not the intended recipient but the current popup knows
// that the mouse down is safe because it is within the client area of itself, then
// just let the message carry on as normal.
if (_current.DoesCurrentMouseDownContinueTracking(m, ScreenPtToClientPt(screenPt)))
{
return(processed);
}
else
{
// Mouse is not inside the client area of the current popup, so we are going to end all tracking
// unless we can find a popup that wants to become the current popup because the mouse happens to
// be other it, and it wants it.
VisualPopup[] popups = _stack.ToArray();
// Search from end towards the front, the last entry is the most recent 'Push'
for (int i = 0; i < popups.Length; i++)
{
// Ignore disposed popups
VisualPopup popup = popups[i];
if (!popup.IsDisposed)
{
// If the mouse down is inside the popup instance
if (popup.RectangleToScreen(popup.ClientRectangle).Contains(screenPt))
{
// Does this stacked popup want to become the current one?
if (popup.DoesStackedClientMouseDownBecomeCurrent(m, ScreenPtToClientPt(screenPt, popup.Handle)))
{
// Kill the popups until back at the requested popup
while ((_current != null) && (_current != popup))
{
_current.Dispose();
if (_stack.Count > 0)
{
_current = _stack.Pop();
}
}
}
return(processed);
}
}
}
// Do any of the current popups want the mouse down to be eaten?
if (_current != null)
{
processed = _current.DoesMouseDownGetEaten(m, screenPt);
if (!processed)
{
// Search from end towards the front, the last entry is the most recent 'Push'
for (int i = 0; i < popups.Length; i++)
{
// Ignore disposed popups
VisualPopup popup = popups[i];
if (!popup.IsDisposed)
{
processed = popup.DoesMouseDownGetEaten(m, screenPt);
if (processed)
{
break;
}
}
}
}
}
// Mouse down not intercepted by any popup, so end tracking
EndAllTracking();
}
}
return(processed);
}