DockPanel.MdiClientController.cs
上传用户:szlfmled
上传日期:2020-11-22
资源大小:978k
文件大小:16k
- using System;
- using System.Drawing;
- using System.Windows.Forms;
- using System.ComponentModel;
- using System.ComponentModel.Design;
- using System.Runtime.InteropServices;
- namespace WeifenLuo.WinFormsUI.Docking
- {
- partial class DockPanel
- {
- // This class comes from Jacob Slusser's MdiClientController class:
- // http://www.codeproject.com/cs/miscctrl/mdiclientcontroller.asp
- private class MdiClientController : NativeWindow, IComponent, IDisposable
- {
- private bool m_autoScroll = true;
- private BorderStyle m_borderStyle = BorderStyle.Fixed3D;
- private MdiClient m_mdiClient = null;
- private Form m_parentForm = null;
- private ISite m_site = null;
- public MdiClientController()
- {
- }
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
- protected virtual void Dispose(bool disposing)
- {
- if (disposing)
- {
- lock (this)
- {
- if (Site != null && Site.Container != null)
- Site.Container.Remove(this);
- if (Disposed != null)
- Disposed(this, EventArgs.Empty);
- }
- }
- }
- public bool AutoScroll
- {
- get { return m_autoScroll; }
- set
- {
- // By default the MdiClient control scrolls. It can appear though that
- // there are no scrollbars by turning them off when the non-client
- // area is calculated. I decided to expose this method following
- // the .NET vernacular of an AutoScroll property.
- m_autoScroll = value;
- if (MdiClient != null)
- UpdateStyles();
- }
- }
- public BorderStyle BorderStyle
- {
- set
- {
- // Error-check the enum.
- if (!Enum.IsDefined(typeof(BorderStyle), value))
- throw new InvalidEnumArgumentException();
- m_borderStyle = value;
- if (MdiClient == null)
- return;
- // This property can actually be visible in design-mode,
- // but to keep it consistent with the others,
- // prevent this from being show at design-time.
- if (Site != null && Site.DesignMode)
- return;
- // There is no BorderStyle property exposed by the MdiClient class,
- // but this can be controlled by Win32 functions. A Win32 ExStyle
- // of WS_EX_CLIENTEDGE is equivalent to a Fixed3D border and a
- // Style of WS_BORDER is equivalent to a FixedSingle border.
- // This code is inspired Jason Dori's article:
- // "Adding designable borders to user controls".
- // http://www.codeproject.com/cs/miscctrl/CsAddingBorders.asp
- // Get styles using Win32 calls
- int style = NativeMethods.GetWindowLong(MdiClient.Handle, (int)Win32.GetWindowLongIndex.GWL_STYLE);
- int exStyle = NativeMethods.GetWindowLong(MdiClient.Handle, (int)Win32.GetWindowLongIndex.GWL_EXSTYLE);
- // Add or remove style flags as necessary.
- switch (m_borderStyle)
- {
- case BorderStyle.Fixed3D:
- exStyle |= (int)Win32.WindowExStyles.WS_EX_CLIENTEDGE;
- style &= ~((int)Win32.WindowStyles.WS_BORDER);
- break;
- case BorderStyle.FixedSingle:
- exStyle &= ~((int)Win32.WindowExStyles.WS_EX_CLIENTEDGE);
- style |= (int)Win32.WindowStyles.WS_BORDER;
- break;
- case BorderStyle.None:
- style &= ~((int)Win32.WindowStyles.WS_BORDER);
- exStyle &= ~((int)Win32.WindowExStyles.WS_EX_CLIENTEDGE);
- break;
- }
- // Set the styles using Win32 calls
- NativeMethods.SetWindowLong(MdiClient.Handle, (int)Win32.GetWindowLongIndex.GWL_STYLE, style);
- NativeMethods.SetWindowLong(MdiClient.Handle, (int)Win32.GetWindowLongIndex.GWL_EXSTYLE, exStyle);
- // Cause an update of the non-client area.
- UpdateStyles();
- }
- }
- public MdiClient MdiClient
- {
- get { return m_mdiClient; }
- }
- [Browsable(false)]
- public Form ParentForm
- {
- get { return m_parentForm; }
- set
- {
- // If the ParentForm has previously been set,
- // unwire events connected to the old parent.
- if (m_parentForm != null)
- {
- m_parentForm.HandleCreated -= new EventHandler(ParentFormHandleCreated);
- m_parentForm.MdiChildActivate -= new EventHandler(ParentFormMdiChildActivate);
- }
- m_parentForm = value;
- if (m_parentForm == null)
- return;
- // If the parent form has not been created yet,
- // wait to initialize the MDI client until it is.
- if (m_parentForm.IsHandleCreated)
- {
- InitializeMdiClient();
- RefreshProperties();
- }
- else
- m_parentForm.HandleCreated += new EventHandler(ParentFormHandleCreated);
- m_parentForm.MdiChildActivate += new EventHandler(ParentFormMdiChildActivate);
- }
- }
- public ISite Site
- {
- get { return m_site; }
- set
- {
- m_site = value;
- if (m_site == null)
- return;
- // If the component is dropped onto a form during design-time,
- // set the ParentForm property.
- IDesignerHost host = (value.GetService(typeof(IDesignerHost)) as IDesignerHost);
- if (host != null)
- {
- Form parent = host.RootComponent as Form;
- if (parent != null)
- ParentForm = parent;
- }
- }
- }
- public void RenewMdiClient()
- {
- // Reinitialize the MdiClient and its properties.
- InitializeMdiClient();
- RefreshProperties();
- }
- public event EventHandler Disposed;
- public event EventHandler HandleAssigned;
- public event EventHandler MdiChildActivate;
- public event LayoutEventHandler Layout;
- protected virtual void OnHandleAssigned(EventArgs e)
- {
- // Raise the HandleAssigned event.
- if (HandleAssigned != null)
- HandleAssigned(this, e);
- }
- protected virtual void OnMdiChildActivate(EventArgs e)
- {
- // Raise the MdiChildActivate event
- if (MdiChildActivate != null)
- MdiChildActivate(this, e);
- }
- protected virtual void OnLayout(LayoutEventArgs e)
- {
- // Raise the Layout event
- if (Layout != null)
- Layout(this, e);
- }
- public event PaintEventHandler Paint;
- protected virtual void OnPaint(PaintEventArgs e)
- {
- // Raise the Paint event.
- if (Paint != null)
- Paint(this, e);
- }
- protected override void WndProc(ref Message m)
- {
- switch (m.Msg)
- {
- case (int)Win32.Msgs.WM_NCCALCSIZE:
- // If AutoScroll is set to false, hide the scrollbars when the control
- // calculates its non-client area.
- if (!AutoScroll)
- NativeMethods.ShowScrollBar(m.HWnd, (int)Win32.ScrollBars.SB_BOTH, 0 /*false*/);
- break;
- }
- base.WndProc(ref m);
- }
- private void ParentFormHandleCreated(object sender, EventArgs e)
- {
- // The form has been created, unwire the event, and initialize the MdiClient.
- this.m_parentForm.HandleCreated -= new EventHandler(ParentFormHandleCreated);
- InitializeMdiClient();
- RefreshProperties();
- }
- private void ParentFormMdiChildActivate(object sender, EventArgs e)
- {
- OnMdiChildActivate(e);
- }
- private void MdiClientLayout(object sender, LayoutEventArgs e)
- {
- OnLayout(e);
- }
- private void MdiClientHandleDestroyed(object sender, EventArgs e)
- {
- // If the MdiClient handle has been released, drop the reference and
- // release the handle.
- if (m_mdiClient != null)
- {
- m_mdiClient.HandleDestroyed -= new EventHandler(MdiClientHandleDestroyed);
- m_mdiClient = null;
- }
- ReleaseHandle();
- }
- private void InitializeMdiClient()
- {
- // If the mdiClient has previously been set, unwire events connected
- // to the old MDI.
- if (MdiClient != null)
- {
- MdiClient.HandleDestroyed -= new EventHandler(MdiClientHandleDestroyed);
- MdiClient.Layout -= new LayoutEventHandler(MdiClientLayout);
- }
- if (ParentForm == null)
- return;
- // Get the MdiClient from the parent form.
- foreach (Control control in ParentForm.Controls)
- {
- // If the form is an MDI container, it will contain an MdiClient control
- // just as it would any other control.
- m_mdiClient = control as MdiClient;
- if (m_mdiClient == null)
- continue;
- // Assign the MdiClient Handle to the NativeWindow.
- ReleaseHandle();
- AssignHandle(MdiClient.Handle);
- // Raise the HandleAssigned event.
- OnHandleAssigned(EventArgs.Empty);
- // Monitor the MdiClient for when its handle is destroyed.
- MdiClient.HandleDestroyed += new EventHandler(MdiClientHandleDestroyed);
- MdiClient.Layout += new LayoutEventHandler(MdiClientLayout);
- break;
- }
- }
- private void RefreshProperties()
- {
- // Refresh all the properties
- BorderStyle = m_borderStyle;
- AutoScroll = m_autoScroll;
- }
- private void UpdateStyles()
- {
- // To show style changes, the non-client area must be repainted. Using the
- // control's Invalidate method does not affect the non-client area.
- // Instead use a Win32 call to signal the style has changed.
- NativeMethods.SetWindowPos(MdiClient.Handle, IntPtr.Zero, 0, 0, 0, 0,
- Win32.FlagsSetWindowPos.SWP_NOACTIVATE |
- Win32.FlagsSetWindowPos.SWP_NOMOVE |
- Win32.FlagsSetWindowPos.SWP_NOSIZE |
- Win32.FlagsSetWindowPos.SWP_NOZORDER |
- Win32.FlagsSetWindowPos.SWP_NOOWNERZORDER |
- Win32.FlagsSetWindowPos.SWP_FRAMECHANGED);
- }
- }
- private MdiClientController m_mdiClientController = null;
- private MdiClientController GetMdiClientController()
- {
- 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 ParentFormMdiChildActivate(object sender, EventArgs e)
- {
- if (GetMdiClientController().ParentForm == null)
- return;
- IDockContent content = GetMdiClientController().ParentForm.ActiveMdiChild as IDockContent;
- if (content == null)
- return;
- if (content.DockHandler.DockPanel == this && content.DockHandler.Pane != null)
- content.DockHandler.Pane.ActiveContent = content;
- }
- private bool MdiClientExists
- {
- get { return GetMdiClientController().MdiClient != null; }
- }
- private void SetMdiClientBounds(Rectangle bounds)
- {
- GetMdiClientController().MdiClient.Bounds = bounds;
- }
- private void SuspendMdiClientLayout()
- {
- if (GetMdiClientController().MdiClient != null)
- GetMdiClientController().MdiClient.SuspendLayout();
- }
- private void ResumeMdiClientLayout(bool perform)
- {
- if (GetMdiClientController().MdiClient != null)
- GetMdiClientController().MdiClient.ResumeLayout(perform);
- }
- private void PerformMdiClientLayout()
- {
- if (GetMdiClientController().MdiClient != null)
- GetMdiClientController().MdiClient.PerformLayout();
- }
- // Called when:
- // 1. DockPanel.DocumentStyle changed
- // 2. DockPanel.Visible changed
- // 3. MdiClientController.Handle assigned
- private void SetMdiClient()
- {
- MdiClientController controller = GetMdiClientController();
- if (this.DocumentStyle == DocumentStyle.DockingMdi)
- {
- controller.AutoScroll = false;
- controller.BorderStyle = BorderStyle.None;
- if (MdiClientExists)
- controller.MdiClient.Dock = DockStyle.Fill;
- }
- else if (DocumentStyle == DocumentStyle.DockingSdi || DocumentStyle == DocumentStyle.DockingWindow)
- {
- controller.AutoScroll = true;
- controller.BorderStyle = BorderStyle.Fixed3D;
- if (MdiClientExists)
- controller.MdiClient.Dock = DockStyle.Fill;
- }
- else if (this.DocumentStyle == DocumentStyle.SystemMdi)
- {
- controller.AutoScroll = true;
- controller.BorderStyle = BorderStyle.Fixed3D;
- if (controller.MdiClient != null)
- {
- controller.MdiClient.Dock = DockStyle.None;
- controller.MdiClient.Bounds = SystemMdiClientBounds;
- }
- }
- }
- internal Rectangle RectangleToMdiClient(Rectangle rect)
- {
- if (MdiClientExists)
- return GetMdiClientController().MdiClient.RectangleToClient(rect);
- else
- return Rectangle.Empty;
- }
- }
- }