📄 dockcontainer.cs
字号:
#region Fireball License
// Copyright (C) 2005 Sebastian Faltoni sebastian{at}dotnetfireball{dot}net
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#endregion
#region Original License
// *****************************************************************************
//
// Copyright 2004, Weifen Luo
// All rights reserved. The software and associated documentation
// supplied hereunder are the proprietary information of Weifen Luo
// and are supplied subject to licence terms.
//
// WinFormsUI Library Version 1.0
// *****************************************************************************
#endregion
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.IO;
using System.Text;
namespace Fireball.Docking
{
/// <include file='CodeDoc\DockPanel.xml' path='//CodeDoc/Delegate[@name="DeserializeDockContent"]/*'/>
public delegate IDockableWindow DeserializeDockContent(string persistString);
/// <include file='CodeDoc\DockPanel.xml' path='//CodeDoc/Class[@name="DockPanel"]/ClassDef/*'/>
[Designer(typeof(System.Windows.Forms.Design.ControlDesigner))]
[ToolboxBitmap(typeof(DockContainer), "Resources.DockPanel.bmp")]
public class DockContainer : Panel
{
private const int WM_REFRESHACTIVEWINDOW = (int)Win32.Msgs.WM_USER + 1;
private LocalWindowsHook m_localWindowsHook;
/// <include file='CodeDoc\DockPanel.xml' path='//CodeDoc/Class[@name="DockPanel"]/Constructor[@name="()"]/*'/>
public DockContainer()
{
m_extender = new DockPanelExtender(this);
m_dragHandler = new DragHandler(this);
m_panes = new DockPaneCollection();
m_floatWindows = new FloatWindowCollection();
SetStyle(ControlStyles.ResizeRedraw |
ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint, true);
SuspendLayout();
Font = SystemInformation.MenuFont;
m_autoHideWindow = new AutoHideWindow(this);
m_autoHideWindow.Visible = false;
if (Environment.Version.Major == 1)
{
m_dummyControl = new DummyControl();
m_dummyControl.Bounds = Rectangle.Empty;
Controls.Add(m_dummyControl);
}
m_dockWindows = new DockWindowCollection(this);
Controls.AddRange(new Control[] {
DockWindows[DockState.Document],
DockWindows[DockState.DockLeft],
DockWindows[DockState.DockRight],
DockWindows[DockState.DockTop],
DockWindows[DockState.DockBottom]
});
m_localWindowsHook = new LocalWindowsHook(HookType.WH_CALLWNDPROCRET);
m_localWindowsHook.HookInvoked += new LocalWindowsHook.HookEventHandler(this.HookEventHandler);
m_localWindowsHook.Install();
m_dummyContent = new DockableWindow();
ResumeLayout();
}
private AutoHideStripBase m_autoHideStripControl = null;
private AutoHideStripBase AutoHideStripControl
{
get
{
if (m_autoHideStripControl == null)
{
m_autoHideStripControl = AutoHideStripFactory.CreateAutoHideStrip(this);
Controls.Add(m_autoHideStripControl);
}
return m_autoHideStripControl;
}
}
private MdiClientController m_mdiClientController = null;
private MdiClientController MdiClientController
{
get
{
if (m_mdiClientController == null)
{
m_mdiClientController = new MdiClientController();
m_mdiClientController.HandleAssigned += new EventHandler(MdiClientHandleAssigned);
m_mdiClientController.MdiChildActivate += new EventHandler(ParentFormMdiChildActivate);
m_mdiClientController.Layout += new LayoutEventHandler(MdiClient_Layout);
}
return m_mdiClientController;
}
}
private void MdiClientHandleAssigned(object sender, EventArgs e)
{
SetMdiClient();
PerformLayout();
}
private void MdiClient_Layout(object sender, LayoutEventArgs e)
{
if (DocumentStyle != DocumentStyles.DockingMdi)
return;
foreach (DockPane pane in Panes)
if (pane.DockState == DockState.Document)
pane.SetContentBounds();
UpdateWindowRegion();
}
private void ParentFormMdiChildActivate(object sender, EventArgs e)
{
if (MdiClientController.ParentForm == null)
return;
IDockableWindow content = MdiClientController.ParentForm.ActiveMdiChild as IDockableWindow;
if (content == null)
return;
if (content.DockHandler.DockPanel == this && content.DockHandler.Pane != null)
content.DockHandler.Pane.ActiveContent = content;
}
private bool m_inRefreshingActiveWindow = false;
internal bool InRefreshingActiveWindow
{
get { return m_inRefreshingActiveWindow; }
set { m_inRefreshingActiveWindow = value; }
}
// Windows hook event handler
private void HookEventHandler(object sender, HookEventArgs e)
{
if (InRefreshingActiveWindow)
return;
Win32.Msgs msg = (Win32.Msgs)Marshal.ReadInt32(e.lParam, IntPtr.Size * 3);
if (msg == Win32.Msgs.WM_KILLFOCUS)
{
IntPtr wParam = Marshal.ReadIntPtr(e.lParam, IntPtr.Size * 2);
DockPane pane = GetPaneFromHandle(wParam);
if (pane == null)
User32.PostMessage(this.Handle, WM_REFRESHACTIVEWINDOW, 0, 0);
}
else if (msg == Win32.Msgs.WM_SETFOCUS)
User32.PostMessage(this.Handle, WM_REFRESHACTIVEWINDOW, 0, 0);
}
private bool m_disposed = false;
/// <exclude/>
protected override void Dispose(bool disposing)
{
lock (this)
{
if (!m_disposed && disposing)
{
m_localWindowsHook.Uninstall();
if (m_mdiClientController != null)
{
m_mdiClientController.HandleAssigned -= new EventHandler(MdiClientHandleAssigned);
m_mdiClientController.MdiChildActivate -= new EventHandler(ParentFormMdiChildActivate);
m_mdiClientController.Layout -= new LayoutEventHandler(MdiClient_Layout);
m_mdiClientController.Dispose();
}
FloatWindows.Dispose();
Panes.Dispose();
DummyContent.Dispose();
m_disposed = true;
}
base.Dispose(disposing);
}
}
/// <include file='CodeDoc\DockPanel.xml' path='//CodeDoc/Class[@name="DockPanel"]/Property[@name="ActiveAutoHideContent"]/*' />
[Browsable(false)]
public IDockableWindow ActiveAutoHideContent
{
get { return AutoHideWindow.ActiveContent; }
set { AutoHideWindow.ActiveContent = value; }
}
private IDockableWindow m_activeContent = null;
/// <include file='CodeDoc\DockPanel.xml' path='//CodeDoc/Class[@name="DockPanel"]/Property[@name="ActiveContent"]/*' />
[Browsable(false)]
public IDockableWindow ActiveContent
{
get { return m_activeContent; }
}
internal void SetActiveContent()
{
IDockableWindow value = ActivePane == null ? null : ActivePane.ActiveContent;
if (m_activeContent == value)
return;
if (m_activeContent != null)
m_activeContent.DockHandler.SetIsActivated(false);
m_activeContent = value;
if (m_activeContent != null)
m_activeContent.DockHandler.SetIsActivated(true);
OnActiveContentChanged(EventArgs.Empty);
}
private DockPane m_activePane = null;
/// <include file='CodeDoc\DockPanel.xml' path='//CodeDoc/Class[@name="DockPanel"]/Property[@name="ActivePane"]/*' />
[Browsable(false)]
public DockPane ActivePane
{
get { return m_activePane; }
}
private void SetActivePane()
{
DockPane value = GetPaneFromHandle(User32.GetFocus());
if (m_activePane == value)
return;
if (m_activePane != null)
m_activePane.SetIsActivated(false);
m_activePane = value;
if (m_activePane != null)
m_activePane.SetIsActivated(true);
}
private DockPane GetPaneFromHandle(IntPtr hWnd)
{
Control control = Control.FromChildHandle(hWnd);
IDockableWindow content = null;
DockPane pane = null;
for (; control != null; control = control.Parent)
{
content = control as IDockableWindow;
if (content != null)
content.DockHandler.ActiveWindowHandle = hWnd;
if (content != null && content.DockHandler.DockPanel == this)
return content.DockHandler.Pane;
pane = control as DockPane;
if (pane != null && pane.DockPanel == this)
break;
}
return pane;
}
private IDockableWindow m_activeDocument = null;
/// <include file='CodeDoc\DockPanel.xml' path='//CodeDoc/Class[@name="DockPanel"]/Property[@name="ActiveDocument"]/*' />
[Browsable(false)]
public IDockableWindow ActiveDocument
{
get { return m_activeDocument; }
}
private void SetActiveDocument()
{
IDockableWindow value = ActiveDocumentPane == null ? null : ActiveDocumentPane.ActiveContent;
if (m_activeDocument == value)
return;
m_activeDocument = value;
OnActiveDocumentChanged(EventArgs.Empty);
}
private DockPane m_activeDocumentPane = null;
/// <include file='CodeDoc\DockPanel.xml' path='//CodeDoc/Class[@name="DockPanel"]/Property[@name="ActiveDocumentPane"]/*' />
[Browsable(false)]
public DockPane ActiveDocumentPane
{
get { return m_activeDocumentPane; }
}
private void SetActiveDocumentPane()
{
DockPane value = null;
if (ActivePane != null && ActivePane.DockState == DockState.Document)
value = ActivePane;
if (value == null)
{
if (ActiveDocumentPane == null)
value = DockWindows[DockState.Document].DefaultPane;
else if (ActiveDocumentPane.DockPanel != this || ActiveDocumentPane.DockState != DockState.Document)
value = DockWindows[DockState.Document].DefaultPane;
else
value = m_activeDocumentPane;
}
if (m_activeDocumentPane == value)
return;
if (m_activeDocumentPane != null)
m_activeDocumentPane.SetIsActiveDocumentPane(false);
m_activeDocumentPane = value;
if (m_activeDocumentPane != null)
m_activeDocumentPane.SetIsActiveDocumentPane(true);
}
private bool m_allowRedocking = true;
/// <include file='CodeDoc\DockPanel.xml' path='//CodeDoc/Class[@name="DockPanel"]/Property[@name="AllowRedocking"]/*' />
[LocalizedCategory("Category.Docking")]
[LocalizedDescription("DockPanel.AllowRedocking.Description")]
[DefaultValue(true)]
public bool AllowRedocking
{
get { return m_allowRedocking; }
set { m_allowRedocking = value; }
}
private AutoHideWindow m_autoHideWindow;
internal AutoHideWindow AutoHideWindow
{
get { return m_autoHideWindow; }
}
private DockContentCollection m_contents = new DockContentCollection();
/// <include file='CodeDoc\DockPanel.xml' path='//CodeDoc/Class[@name="DockPanel"]/Property[@name="Contents"]/*' />
[Browsable(false)]
public DockContentCollection Contents
{
get { return m_contents; }
}
private DockableWindow m_dummyContent;
internal DockableWindow DummyContent
{
get { return m_dummyContent; }
}
private bool m_showDocumentIcon = false;
/// <include file='CodeDoc\DockPanel.xml' path='//CodeDoc/Class[@name="DockPanel"]/Property[@name="ShowDocumentIcon"]/*' />
[DefaultValue(false)]
[LocalizedCategory("Category.Docking")]
[LocalizedDescription("DockPanel.ShowDocumentIcon.Description")]
public bool ShowDocumentIcon
{
get { return m_showDocumentIcon; }
set
{
if (m_showDocumentIcon == value)
return;
m_showDocumentIcon = value;
Refresh();
}
}
private DockPanelExtender m_extender;
/// <include file='CodeDoc\DockPanel.xml' path='//CodeDoc/Class[@name="DockPanel"]/Property[@name="Extender"]/*' />
[Browsable(false)]
public DockPanelExtender Extender
{
get { return m_extender; }
}
internal DockPanelExtender.IDockPaneFactory DockPaneFactory
{
get { return Extender.DockPaneFactory; }
}
internal DockPanelExtender.IFloatWindowFactory FloatWindowFactory
{
get { return Extender.FloatWindowFactory; }
}
internal DockPanelExtender.IDockPaneCaptionFactory DockPaneCaptionFactory
{
get { return Extender.DockPaneCaptionFactory; }
}
internal DockPanelExtender.IDockPaneTabFactory DockPaneTabFactory
{
get { return Extender.DockPaneTabFactory; }
}
internal DockPanelExtender.IDockPaneStripFactory DockPaneStripFactory
{
get { return Extender.DockPaneStripFactory; }
}
internal DockPanelExtender.IAutoHideTabFactory AutoHideTabFactory
{
get { return Extender.AutoHideTabFactory; }
}
internal DockPanelExtender.IAutoHidePaneFactory AutoHidePaneFactory
{
get { return Extender.AutoHidePaneFactory; }
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -