DockPanel.DragHandler.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /*******************************************************************************
  2. * Copyright(c) 2014 DongkeSoft All rights reserved. / Confidential
  3. * 类的信息:
  4. * 1.程序名称:DockPanel.cs
  5. * 2.功能描述:类文件
  6. * 编辑履历:
  7. * 作者 日期 版本 修改内容
  8. * 陈晓野 2014/09/01 1.00 新建
  9. *******************************************************************************/
  10. using System.Drawing;
  11. using System.Windows.Forms;
  12. namespace Dongke.IBOSS.PRD.Basics.DockPanel
  13. {
  14. /// <summary>
  15. /// 类文件
  16. /// </summary>
  17. partial class DockPanel
  18. {
  19. /// <summary>
  20. /// DragHandlerBase is the base class for drag handlers. The derived class should:
  21. /// 1. Define its public method BeginDrag. From within this public BeginDrag method,
  22. /// DragHandlerBase.BeginDrag should be called to initialize the mouse capture
  23. /// and message filtering.
  24. /// 2. Override the OnDragging and OnEndDrag methods.
  25. /// </summary>
  26. private abstract class DragHandlerBase : NativeWindow, IMessageFilter
  27. {
  28. protected DragHandlerBase()
  29. {
  30. }
  31. protected abstract Control DragControl
  32. {
  33. get;
  34. }
  35. private Point m_startMousePosition = Point.Empty;
  36. protected Point StartMousePosition
  37. {
  38. get
  39. {
  40. return m_startMousePosition;
  41. }
  42. private set
  43. {
  44. m_startMousePosition = value;
  45. }
  46. }
  47. protected bool BeginDrag()
  48. {
  49. // Avoid re-entrance;
  50. lock (this)
  51. {
  52. if (DragControl == null)
  53. return false;
  54. StartMousePosition = Control.MousePosition;
  55. if (!Win32Helper.IsRunningOnMono)
  56. if (!NativeMethods.DragDetect(DragControl.Handle, StartMousePosition))
  57. return false;
  58. DragControl.FindForm().Capture = true;
  59. AssignHandle(DragControl.FindForm().Handle);
  60. Application.AddMessageFilter(this);
  61. return true;
  62. }
  63. }
  64. protected abstract void OnDragging();
  65. protected abstract void OnEndDrag(bool abort);
  66. private void EndDrag(bool abort)
  67. {
  68. ReleaseHandle();
  69. Application.RemoveMessageFilter(this);
  70. DragControl.FindForm().Capture = false;
  71. OnEndDrag(abort);
  72. }
  73. bool IMessageFilter.PreFilterMessage(ref Message m)
  74. {
  75. if (m.Msg == (int)Win32.Msgs.WM_MOUSEMOVE)
  76. OnDragging();
  77. else if (m.Msg == (int)Win32.Msgs.WM_LBUTTONUP)
  78. EndDrag(false);
  79. else if (m.Msg == (int)Win32.Msgs.WM_CAPTURECHANGED)
  80. EndDrag(true);
  81. else if (m.Msg == (int)Win32.Msgs.WM_KEYDOWN && (int)m.WParam == (int)Keys.Escape)
  82. EndDrag(true);
  83. return OnPreFilterMessage(ref m);
  84. }
  85. protected virtual bool OnPreFilterMessage(ref Message m)
  86. {
  87. return false;
  88. }
  89. protected sealed override void WndProc(ref Message m)
  90. {
  91. if (m.Msg == (int)Win32.Msgs.WM_CANCELMODE || m.Msg == (int)Win32.Msgs.WM_CAPTURECHANGED)
  92. EndDrag(true);
  93. base.WndProc(ref m);
  94. }
  95. }
  96. private abstract class DragHandler : DragHandlerBase
  97. {
  98. private DockPanel m_dockPanel;
  99. protected DragHandler(DockPanel dockPanel)
  100. {
  101. m_dockPanel = dockPanel;
  102. }
  103. public DockPanel DockPanel
  104. {
  105. get
  106. {
  107. return m_dockPanel;
  108. }
  109. }
  110. private IDragSource m_dragSource;
  111. protected IDragSource DragSource
  112. {
  113. get
  114. {
  115. return m_dragSource;
  116. }
  117. set
  118. {
  119. m_dragSource = value;
  120. }
  121. }
  122. protected sealed override Control DragControl
  123. {
  124. get
  125. {
  126. return DragSource == null ? null : DragSource.DragControl;
  127. }
  128. }
  129. protected sealed override bool OnPreFilterMessage(ref Message m)
  130. {
  131. if ((m.Msg == (int)Win32.Msgs.WM_KEYDOWN || m.Msg == (int)Win32.Msgs.WM_KEYUP) &&
  132. ((int)m.WParam == (int)Keys.ControlKey || (int)m.WParam == (int)Keys.ShiftKey))
  133. OnDragging();
  134. return base.OnPreFilterMessage(ref m);
  135. }
  136. }
  137. }
  138. }