/*******************************************************************************
* Copyright(c) 2014 DongkeSoft All rights reserved. / Confidential
* 类的信息:
* 1.程序名称:DockPanel.cs
* 2.功能描述:类文件
* 编辑履历:
* 作者 日期 版本 修改内容
* 陈晓野 2014/09/01 1.00 新建
*******************************************************************************/
using System.Drawing;
using System.Windows.Forms;
namespace Dongke.IBOSS.PRD.Basics.DockPanel
{
///
/// 类文件
///
partial class DockPanel
{
///
/// DragHandlerBase is the base class for drag handlers. The derived class should:
/// 1. Define its public method BeginDrag. From within this public BeginDrag method,
/// DragHandlerBase.BeginDrag should be called to initialize the mouse capture
/// and message filtering.
/// 2. Override the OnDragging and OnEndDrag methods.
///
private abstract class DragHandlerBase : NativeWindow, IMessageFilter
{
protected DragHandlerBase()
{
}
protected abstract Control DragControl
{
get;
}
private Point m_startMousePosition = Point.Empty;
protected Point StartMousePosition
{
get
{
return m_startMousePosition;
}
private set
{
m_startMousePosition = value;
}
}
protected bool BeginDrag()
{
// Avoid re-entrance;
lock (this)
{
if (DragControl == null)
return false;
StartMousePosition = Control.MousePosition;
if (!Win32Helper.IsRunningOnMono)
if (!NativeMethods.DragDetect(DragControl.Handle, StartMousePosition))
return false;
DragControl.FindForm().Capture = true;
AssignHandle(DragControl.FindForm().Handle);
Application.AddMessageFilter(this);
return true;
}
}
protected abstract void OnDragging();
protected abstract void OnEndDrag(bool abort);
private void EndDrag(bool abort)
{
ReleaseHandle();
Application.RemoveMessageFilter(this);
DragControl.FindForm().Capture = false;
OnEndDrag(abort);
}
bool IMessageFilter.PreFilterMessage(ref Message m)
{
if (m.Msg == (int)Win32.Msgs.WM_MOUSEMOVE)
OnDragging();
else if (m.Msg == (int)Win32.Msgs.WM_LBUTTONUP)
EndDrag(false);
else if (m.Msg == (int)Win32.Msgs.WM_CAPTURECHANGED)
EndDrag(true);
else if (m.Msg == (int)Win32.Msgs.WM_KEYDOWN && (int)m.WParam == (int)Keys.Escape)
EndDrag(true);
return OnPreFilterMessage(ref m);
}
protected virtual bool OnPreFilterMessage(ref Message m)
{
return false;
}
protected sealed override void WndProc(ref Message m)
{
if (m.Msg == (int)Win32.Msgs.WM_CANCELMODE || m.Msg == (int)Win32.Msgs.WM_CAPTURECHANGED)
EndDrag(true);
base.WndProc(ref m);
}
}
private abstract class DragHandler : DragHandlerBase
{
private DockPanel m_dockPanel;
protected DragHandler(DockPanel dockPanel)
{
m_dockPanel = dockPanel;
}
public DockPanel DockPanel
{
get
{
return m_dockPanel;
}
}
private IDragSource m_dragSource;
protected IDragSource DragSource
{
get
{
return m_dragSource;
}
set
{
m_dragSource = value;
}
}
protected sealed override Control DragControl
{
get
{
return DragSource == null ? null : DragSource.DragControl;
}
}
protected sealed override bool OnPreFilterMessage(ref Message m)
{
if ((m.Msg == (int)Win32.Msgs.WM_KEYDOWN || m.Msg == (int)Win32.Msgs.WM_KEYUP) &&
((int)m.WParam == (int)Keys.ControlKey || (int)m.WParam == (int)Keys.ShiftKey))
OnDragging();
return base.OnPreFilterMessage(ref m);
}
}
}
}