FloatWindow.cs
上传用户:szlfmled
上传日期:2020-11-22
资源大小:978k
文件大小:15k
- using System;
- using System.Collections;
- using System.Drawing;
- using System.Windows.Forms;
- using System.Runtime.InteropServices;
- using System.Security.Permissions;
- using System.Diagnostics.CodeAnalysis;
- namespace WeifenLuo.WinFormsUI.Docking
- {
- public class FloatWindow : Form, INestedPanesContainer, IDockDragSource
- {
- private NestedPaneCollection m_nestedPanes;
- internal const int WM_CHECKDISPOSE = (int)(Win32.Msgs.WM_USER + 1);
- internal protected FloatWindow(DockPanel dockPanel, DockPane pane)
- {
- InternalConstruct(dockPanel, pane, false, Rectangle.Empty);
- }
- internal protected FloatWindow(DockPanel dockPanel, DockPane pane, Rectangle bounds)
- {
- InternalConstruct(dockPanel, pane, true, bounds);
- }
- private void InternalConstruct(DockPanel dockPanel, DockPane pane, bool boundsSpecified, Rectangle bounds)
- {
- if (dockPanel == null)
- throw(new ArgumentNullException(Strings.FloatWindow_Constructor_NullDockPanel));
- m_nestedPanes = new NestedPaneCollection(this);
- FormBorderStyle = FormBorderStyle.SizableToolWindow;
- ShowInTaskbar = false;
- if (dockPanel.RightToLeft != RightToLeft)
- RightToLeft = dockPanel.RightToLeft;
- if (RightToLeftLayout != dockPanel.RightToLeftLayout)
- RightToLeftLayout = dockPanel.RightToLeftLayout;
-
- SuspendLayout();
- if (boundsSpecified)
- {
- Bounds = bounds;
- StartPosition = FormStartPosition.Manual;
- }
- else
- {
- StartPosition = FormStartPosition.WindowsDefaultLocation;
- Size = dockPanel.DefaultFloatWindowSize;
- }
- m_dockPanel = dockPanel;
- Owner = DockPanel.FindForm();
- DockPanel.AddFloatWindow(this);
- if (pane != null)
- pane.FloatWindow = this;
- ResumeLayout();
- }
- protected override void Dispose(bool disposing)
- {
- if (disposing)
- {
- if (DockPanel != null)
- DockPanel.RemoveFloatWindow(this);
- m_dockPanel = null;
- }
- base.Dispose(disposing);
- }
- private bool m_allowEndUserDocking = true;
- public bool AllowEndUserDocking
- {
- get { return m_allowEndUserDocking; }
- set { m_allowEndUserDocking = value; }
- }
- public NestedPaneCollection NestedPanes
- {
- get { return m_nestedPanes; }
- }
- public VisibleNestedPaneCollection VisibleNestedPanes
- {
- get { return NestedPanes.VisibleNestedPanes; }
- }
- private DockPanel m_dockPanel;
- public DockPanel DockPanel
- {
- get { return m_dockPanel; }
- }
- public DockState DockState
- {
- get { return DockState.Float; }
- }
-
- public bool IsFloat
- {
- get { return DockState == DockState.Float; }
- }
- internal bool IsDockStateValid(DockState dockState)
- {
- foreach (DockPane pane in NestedPanes)
- foreach (IDockContent content in pane.Contents)
- if (!DockHelper.IsDockStateValid(dockState, content.DockHandler.DockAreas))
- return false;
- return true;
- }
- protected override void OnActivated(EventArgs e)
- {
- DockPanel.FloatWindows.BringWindowToFront(this);
- base.OnActivated (e);
- // Propagate the Activated event to the visible panes content objects
- foreach (DockPane pane in VisibleNestedPanes)
- foreach (IDockContent content in pane.Contents)
- content.OnActivated(e);
- }
- protected override void OnDeactivate(EventArgs e)
- {
- base.OnDeactivate(e);
- // Propagate the Deactivate event to the visible panes content objects
- foreach (DockPane pane in VisibleNestedPanes)
- foreach (IDockContent content in pane.Contents)
- content.OnDeactivate(e);
- }
- protected override void OnLayout(LayoutEventArgs levent)
- {
- VisibleNestedPanes.Refresh();
- RefreshChanges();
- Visible = (VisibleNestedPanes.Count > 0);
- SetText();
- base.OnLayout(levent);
- }
- [SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters", MessageId = "System.Windows.Forms.Control.set_Text(System.String)")]
- internal void SetText()
- {
- DockPane theOnlyPane = (VisibleNestedPanes.Count == 1) ? VisibleNestedPanes[0] : null;
- if (theOnlyPane == null)
- Text = " "; // use " " instead of string.Empty because the whole title bar will disappear when ControlBox is set to false.
- else if (theOnlyPane.ActiveContent == null)
- Text = " ";
- else
- Text = theOnlyPane.ActiveContent.DockHandler.TabText;
- }
- protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified)
- {
- Rectangle rectWorkArea = SystemInformation.VirtualScreen;
- if (y + height > rectWorkArea.Bottom)
- y -= (y + height) - rectWorkArea.Bottom;
- if (y < rectWorkArea.Top)
- y += rectWorkArea.Top - y;
- base.SetBoundsCore (x, y, width, height, specified);
- }
- [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
- protected override void WndProc(ref Message m)
- {
- if (m.Msg == (int)Win32.Msgs.WM_NCLBUTTONDOWN)
- {
- if (IsDisposed)
- return;
- uint result = NativeMethods.SendMessage(this.Handle, (int)Win32.Msgs.WM_NCHITTEST, 0, (uint)m.LParam);
- if (result == 2 && DockPanel.AllowEndUserDocking && this.AllowEndUserDocking) // HITTEST_CAPTION
- {
- Activate();
- m_dockPanel.BeginDrag(this);
- }
- else
- base.WndProc(ref m);
- return;
- }
- else if (m.Msg == (int)Win32.Msgs.WM_NCRBUTTONDOWN)
- {
- uint result = NativeMethods.SendMessage(this.Handle, (int)Win32.Msgs.WM_NCHITTEST, 0, (uint)m.LParam);
- if (result == 2) // HITTEST_CAPTION
- {
- DockPane theOnlyPane = (VisibleNestedPanes.Count == 1) ? VisibleNestedPanes[0] : null;
- if (theOnlyPane != null && theOnlyPane.ActiveContent != null)
- {
- theOnlyPane.ShowTabPageContextMenu(this, PointToClient(Control.MousePosition));
- return;
- }
- }
- base.WndProc(ref m);
- return;
- }
- else if (m.Msg == (int)Win32.Msgs.WM_CLOSE)
- {
- if (NestedPanes.Count == 0)
- {
- base.WndProc(ref m);
- return;
- }
- for (int i = NestedPanes.Count - 1; i >= 0; i--)
- {
- DockContentCollection contents = NestedPanes[i].Contents;
- for (int j = contents.Count - 1; j >= 0; j--)
- {
- IDockContent content = contents[j];
- if (content.DockHandler.DockState != DockState.Float)
- continue;
- if (!content.DockHandler.CloseButton)
- continue;
- if (content.DockHandler.HideOnClose)
- content.DockHandler.Hide();
- else
- content.DockHandler.Close();
- }
- }
- return;
- }
- else if (m.Msg == (int)Win32.Msgs.WM_NCLBUTTONDBLCLK)
- {
- uint result = NativeMethods.SendMessage(this.Handle, (int)Win32.Msgs.WM_NCHITTEST, 0, (uint)m.LParam);
- if (result != 2) // HITTEST_CAPTION
- {
- base.WndProc(ref m);
- return;
- }
- DockPanel.SuspendLayout(true);
- // Restore to panel
- foreach (DockPane pane in NestedPanes)
- {
- if (pane.DockState != DockState.Float)
- continue;
- pane.RestoreToPanel();
- }
- DockPanel.ResumeLayout(true, true);
- return;
- }
- else if (m.Msg == WM_CHECKDISPOSE)
- {
- if (NestedPanes.Count == 0)
- Dispose();
- return;
- }
- base.WndProc(ref m);
- }
- internal void RefreshChanges()
- {
- if (IsDisposed)
- return;
- if (VisibleNestedPanes.Count == 0)
- {
- ControlBox = true;
- return;
- }
- for (int i=VisibleNestedPanes.Count - 1; i>=0; i--)
- {
- DockContentCollection contents = VisibleNestedPanes[i].Contents;
- for (int j=contents.Count - 1; j>=0; j--)
- {
- IDockContent content = contents[j];
- if (content.DockHandler.DockState != DockState.Float)
- continue;
- if (content.DockHandler.CloseButton && content.DockHandler.CloseButtonVisible)
- {
- ControlBox = true;
- return;
- }
- }
- }
- //Only if there is a ControlBox do we turn it off
- //old code caused a flash of the window.
- if (ControlBox)
- ControlBox = false;
- }
- public virtual Rectangle DisplayingRectangle
- {
- get { return ClientRectangle; }
- }
- internal void TestDrop(IDockDragSource dragSource, DockOutlineBase dockOutline)
- {
- if (VisibleNestedPanes.Count == 1)
- {
- DockPane pane = VisibleNestedPanes[0];
- if (!dragSource.CanDockTo(pane))
- return;
- Point ptMouse = Control.MousePosition;
- uint lParam = Win32Helper.MakeLong(ptMouse.X, ptMouse.Y);
- if (NativeMethods.SendMessage(Handle, (int)Win32.Msgs.WM_NCHITTEST, 0, lParam) == (uint)Win32.HitTest.HTCAPTION)
- dockOutline.Show(VisibleNestedPanes[0], -1);
- }
- }
- #region IDockDragSource Members
- #region IDragSource Members
- Control IDragSource.DragControl
- {
- get { return this; }
- }
- #endregion
- bool IDockDragSource.IsDockStateValid(DockState dockState)
- {
- return IsDockStateValid(dockState);
- }
- bool IDockDragSource.CanDockTo(DockPane pane)
- {
- if (!IsDockStateValid(pane.DockState))
- return false;
- if (pane.FloatWindow == this)
- return false;
- return true;
- }
- Rectangle IDockDragSource.BeginDrag(Point ptMouse)
- {
- return Bounds;
- }
- public void FloatAt(Rectangle floatWindowBounds)
- {
- Bounds = floatWindowBounds;
- }
- public void DockTo(DockPane pane, DockStyle dockStyle, int contentIndex)
- {
- if (dockStyle == DockStyle.Fill)
- {
- for (int i = NestedPanes.Count - 1; i >= 0; i--)
- {
- DockPane paneFrom = NestedPanes[i];
- for (int j = paneFrom.Contents.Count - 1; j >= 0; j--)
- {
- IDockContent c = paneFrom.Contents[j];
- c.DockHandler.Pane = pane;
- if (contentIndex != -1)
- pane.SetContentIndex(c, contentIndex);
- c.DockHandler.Activate();
- }
- }
- }
- else
- {
- DockAlignment alignment = DockAlignment.Left;
- if (dockStyle == DockStyle.Left)
- alignment = DockAlignment.Left;
- else if (dockStyle == DockStyle.Right)
- alignment = DockAlignment.Right;
- else if (dockStyle == DockStyle.Top)
- alignment = DockAlignment.Top;
- else if (dockStyle == DockStyle.Bottom)
- alignment = DockAlignment.Bottom;
- MergeNestedPanes(VisibleNestedPanes, pane.NestedPanesContainer.NestedPanes, pane, alignment, 0.5);
- }
- }
- public void DockTo(DockPanel panel, DockStyle dockStyle)
- {
- if (panel != DockPanel)
- throw new ArgumentException(Strings.IDockDragSource_DockTo_InvalidPanel, "panel");
- NestedPaneCollection nestedPanesTo = null;
- if (dockStyle == DockStyle.Top)
- nestedPanesTo = DockPanel.DockWindows[DockState.DockTop].NestedPanes;
- else if (dockStyle == DockStyle.Bottom)
- nestedPanesTo = DockPanel.DockWindows[DockState.DockBottom].NestedPanes;
- else if (dockStyle == DockStyle.Left)
- nestedPanesTo = DockPanel.DockWindows[DockState.DockLeft].NestedPanes;
- else if (dockStyle == DockStyle.Right)
- nestedPanesTo = DockPanel.DockWindows[DockState.DockRight].NestedPanes;
- else if (dockStyle == DockStyle.Fill)
- nestedPanesTo = DockPanel.DockWindows[DockState.Document].NestedPanes;
- DockPane prevPane = null;
- for (int i = nestedPanesTo.Count - 1; i >= 0; i--)
- if (nestedPanesTo[i] != VisibleNestedPanes[0])
- prevPane = nestedPanesTo[i];
- MergeNestedPanes(VisibleNestedPanes, nestedPanesTo, prevPane, DockAlignment.Left, 0.5);
- }
- private static void MergeNestedPanes(VisibleNestedPaneCollection nestedPanesFrom, NestedPaneCollection nestedPanesTo, DockPane prevPane, DockAlignment alignment, double proportion)
- {
- if (nestedPanesFrom.Count == 0)
- return;
- int count = nestedPanesFrom.Count;
- DockPane[] panes = new DockPane[count];
- DockPane[] prevPanes = new DockPane[count];
- DockAlignment[] alignments = new DockAlignment[count];
- double[] proportions = new double[count];
- for (int i = 0; i < count; i++)
- {
- panes[i] = nestedPanesFrom[i];
- prevPanes[i] = nestedPanesFrom[i].NestedDockingStatus.PreviousPane;
- alignments[i] = nestedPanesFrom[i].NestedDockingStatus.Alignment;
- proportions[i] = nestedPanesFrom[i].NestedDockingStatus.Proportion;
- }
- DockPane pane = panes[0].DockTo(nestedPanesTo.Container, prevPane, alignment, proportion);
- panes[0].DockState = nestedPanesTo.DockState;
- for (int i = 1; i < count; i++)
- {
- for (int j = i; j < count; j++)
- {
- if (prevPanes[j] == panes[i - 1])
- prevPanes[j] = pane;
- }
- pane = panes[i].DockTo(nestedPanesTo.Container, prevPanes[i], alignments[i], proportions[i]);
- panes[i].DockState = nestedPanesTo.DockState;
- }
- }
- #endregion
- }
- }