DockPanel.MdiClientController.cs
上传用户:szlfmled
上传日期:2020-11-22
资源大小:978k
文件大小:16k
源码类别:

C#编程

开发平台:

C#

  1. using System;
  2. using System.Drawing;
  3. using System.Windows.Forms;
  4. using System.ComponentModel;
  5. using System.ComponentModel.Design;
  6. using System.Runtime.InteropServices;
  7. namespace WeifenLuo.WinFormsUI.Docking
  8. {
  9.     partial class DockPanel
  10.     {
  11.         //  This class comes from Jacob Slusser's MdiClientController class:
  12.         //  http://www.codeproject.com/cs/miscctrl/mdiclientcontroller.asp
  13.         private class MdiClientController : NativeWindow, IComponent, IDisposable
  14.         {
  15.             private bool m_autoScroll = true;
  16.             private BorderStyle m_borderStyle = BorderStyle.Fixed3D;
  17.             private MdiClient m_mdiClient = null;
  18.             private Form m_parentForm = null;
  19.             private ISite m_site = null;
  20.             public MdiClientController()
  21.             {
  22.             }
  23.             public void Dispose()
  24.             {
  25.                 Dispose(true);
  26.                 GC.SuppressFinalize(this);
  27.             }
  28.             protected virtual void Dispose(bool disposing)
  29.             {
  30.                 if (disposing)
  31.                 {
  32.                     lock (this)
  33.                     {
  34.                         if (Site != null && Site.Container != null)
  35.                             Site.Container.Remove(this);
  36.                         if (Disposed != null)
  37.                             Disposed(this, EventArgs.Empty);
  38.                     }
  39.                 }
  40.             }
  41.             public bool AutoScroll
  42.             {
  43.                 get { return m_autoScroll; }
  44.                 set
  45.                 {
  46.                     // By default the MdiClient control scrolls. It can appear though that
  47.                     // there are no scrollbars by turning them off when the non-client
  48.                     // area is calculated. I decided to expose this method following
  49.                     // the .NET vernacular of an AutoScroll property.
  50.                     m_autoScroll = value;
  51.                     if (MdiClient != null)
  52.                         UpdateStyles();
  53.                 }
  54.             }
  55.             public BorderStyle BorderStyle
  56.             {
  57.                 set
  58.                 {
  59.                     // Error-check the enum.
  60.                     if (!Enum.IsDefined(typeof(BorderStyle), value))
  61.                         throw new InvalidEnumArgumentException();
  62.                     m_borderStyle = value;
  63.                     if (MdiClient == null)
  64.                         return;
  65.                     // This property can actually be visible in design-mode,
  66.                     // but to keep it consistent with the others,
  67.                     // prevent this from being show at design-time.
  68.                     if (Site != null && Site.DesignMode)
  69.                         return;
  70.                     // There is no BorderStyle property exposed by the MdiClient class,
  71.                     // but this can be controlled by Win32 functions. A Win32 ExStyle
  72.                     // of WS_EX_CLIENTEDGE is equivalent to a Fixed3D border and a
  73.                     // Style of WS_BORDER is equivalent to a FixedSingle border.
  74.                     // This code is inspired Jason Dori's article:
  75.                     // "Adding designable borders to user controls".
  76.                     // http://www.codeproject.com/cs/miscctrl/CsAddingBorders.asp
  77.                     // Get styles using Win32 calls
  78.                     int style = NativeMethods.GetWindowLong(MdiClient.Handle, (int)Win32.GetWindowLongIndex.GWL_STYLE);
  79.                     int exStyle = NativeMethods.GetWindowLong(MdiClient.Handle, (int)Win32.GetWindowLongIndex.GWL_EXSTYLE);
  80.                     // Add or remove style flags as necessary.
  81.                     switch (m_borderStyle)
  82.                     {
  83.                         case BorderStyle.Fixed3D:
  84.                             exStyle |= (int)Win32.WindowExStyles.WS_EX_CLIENTEDGE;
  85.                             style &= ~((int)Win32.WindowStyles.WS_BORDER);
  86.                             break;
  87.                         case BorderStyle.FixedSingle:
  88.                             exStyle &= ~((int)Win32.WindowExStyles.WS_EX_CLIENTEDGE);
  89.                             style |= (int)Win32.WindowStyles.WS_BORDER;
  90.                             break;
  91.                         case BorderStyle.None:
  92.                             style &= ~((int)Win32.WindowStyles.WS_BORDER);
  93.                             exStyle &= ~((int)Win32.WindowExStyles.WS_EX_CLIENTEDGE);
  94.                             break;
  95.                     }
  96.                     // Set the styles using Win32 calls
  97.                     NativeMethods.SetWindowLong(MdiClient.Handle, (int)Win32.GetWindowLongIndex.GWL_STYLE, style);
  98.                     NativeMethods.SetWindowLong(MdiClient.Handle, (int)Win32.GetWindowLongIndex.GWL_EXSTYLE, exStyle);
  99.                     // Cause an update of the non-client area.
  100.                     UpdateStyles();
  101.                 }
  102.             }
  103.             public MdiClient MdiClient
  104.             {
  105.                 get { return m_mdiClient; }
  106.             }
  107.             [Browsable(false)]
  108.             public Form ParentForm
  109.             {
  110.                 get { return m_parentForm; }
  111.                 set
  112.                 {
  113.                     // If the ParentForm has previously been set,
  114.                     // unwire events connected to the old parent.
  115.                     if (m_parentForm != null)
  116.                     {
  117.                         m_parentForm.HandleCreated -= new EventHandler(ParentFormHandleCreated);
  118.                         m_parentForm.MdiChildActivate -= new EventHandler(ParentFormMdiChildActivate);
  119.                     }
  120.                     m_parentForm = value;
  121.                     if (m_parentForm == null)
  122.                         return;
  123.                     // If the parent form has not been created yet,
  124.                     // wait to initialize the MDI client until it is.
  125.                     if (m_parentForm.IsHandleCreated)
  126.                     {
  127.                         InitializeMdiClient();
  128.                         RefreshProperties();
  129.                     }
  130.                     else
  131.                         m_parentForm.HandleCreated += new EventHandler(ParentFormHandleCreated);
  132.                     m_parentForm.MdiChildActivate += new EventHandler(ParentFormMdiChildActivate);
  133.                 }
  134.             }
  135.             public ISite Site
  136.             {
  137.                 get { return m_site; }
  138.                 set
  139.                 {
  140.                     m_site = value;
  141.                     if (m_site == null)
  142.                         return;
  143.                     // If the component is dropped onto a form during design-time,
  144.                     // set the ParentForm property.
  145.                     IDesignerHost host = (value.GetService(typeof(IDesignerHost)) as IDesignerHost);
  146.                     if (host != null)
  147.                     {
  148.                         Form parent = host.RootComponent as Form;
  149.                         if (parent != null)
  150.                             ParentForm = parent;
  151.                     }
  152.                 }
  153.             }
  154.             public void RenewMdiClient()
  155.             {
  156.                 // Reinitialize the MdiClient and its properties.
  157.                 InitializeMdiClient();
  158.                 RefreshProperties();
  159.             }
  160.             public event EventHandler Disposed;
  161.             public event EventHandler HandleAssigned;
  162.             public event EventHandler MdiChildActivate;
  163.             public event LayoutEventHandler Layout;
  164.             protected virtual void OnHandleAssigned(EventArgs e)
  165.             {
  166.                 // Raise the HandleAssigned event.
  167.                 if (HandleAssigned != null)
  168.                     HandleAssigned(this, e);
  169.             }
  170.             protected virtual void OnMdiChildActivate(EventArgs e)
  171.             {
  172.                 // Raise the MdiChildActivate event
  173.                 if (MdiChildActivate != null)
  174.                     MdiChildActivate(this, e);
  175.             }
  176.             protected virtual void OnLayout(LayoutEventArgs e)
  177.             {
  178.                 // Raise the Layout event
  179.                 if (Layout != null)
  180.                     Layout(this, e);
  181.             }
  182.             public event PaintEventHandler Paint;
  183.             protected virtual void OnPaint(PaintEventArgs e)
  184.             {
  185.                 // Raise the Paint event.
  186.                 if (Paint != null)
  187.                     Paint(this, e);
  188.             }
  189.             protected override void WndProc(ref Message m)
  190.             {
  191.                 switch (m.Msg)
  192.                 {
  193.                     case (int)Win32.Msgs.WM_NCCALCSIZE:
  194.                         // If AutoScroll is set to false, hide the scrollbars when the control
  195.                         // calculates its non-client area.
  196.                         if (!AutoScroll)
  197.                             NativeMethods.ShowScrollBar(m.HWnd, (int)Win32.ScrollBars.SB_BOTH, 0 /*false*/);
  198.                         break;
  199.                 }
  200.                 base.WndProc(ref m);
  201.             }
  202.             private void ParentFormHandleCreated(object sender, EventArgs e)
  203.             {
  204.                 // The form has been created, unwire the event, and initialize the MdiClient.
  205.                 this.m_parentForm.HandleCreated -= new EventHandler(ParentFormHandleCreated);
  206.                 InitializeMdiClient();
  207.                 RefreshProperties();
  208.             }
  209.             private void ParentFormMdiChildActivate(object sender, EventArgs e)
  210.             {
  211.                 OnMdiChildActivate(e);
  212.             }
  213.             private void MdiClientLayout(object sender, LayoutEventArgs e)
  214.             {
  215.                 OnLayout(e);
  216.             }
  217.             private void MdiClientHandleDestroyed(object sender, EventArgs e)
  218.             {
  219.                 // If the MdiClient handle has been released, drop the reference and
  220.                 // release the handle.
  221.                 if (m_mdiClient != null)
  222.                 {
  223.                     m_mdiClient.HandleDestroyed -= new EventHandler(MdiClientHandleDestroyed);
  224.                     m_mdiClient = null;
  225.                 }
  226.                 ReleaseHandle();
  227.             }
  228.             private void InitializeMdiClient()
  229.             {
  230.                 // If the mdiClient has previously been set, unwire events connected
  231.                 // to the old MDI.
  232.                 if (MdiClient != null)
  233.                 {
  234.                     MdiClient.HandleDestroyed -= new EventHandler(MdiClientHandleDestroyed);
  235.                     MdiClient.Layout -= new LayoutEventHandler(MdiClientLayout);
  236.                 }
  237.                 if (ParentForm == null)
  238.                     return;
  239.                 // Get the MdiClient from the parent form.
  240.                 foreach (Control control in ParentForm.Controls)
  241.                 {
  242.                     // If the form is an MDI container, it will contain an MdiClient control
  243.                     // just as it would any other control.
  244.                     m_mdiClient = control as MdiClient;
  245.                     if (m_mdiClient == null)
  246.                         continue;
  247.                     // Assign the MdiClient Handle to the NativeWindow.
  248.                     ReleaseHandle();
  249.                     AssignHandle(MdiClient.Handle);
  250.                     // Raise the HandleAssigned event.
  251.                     OnHandleAssigned(EventArgs.Empty);
  252.                     // Monitor the MdiClient for when its handle is destroyed.
  253.                     MdiClient.HandleDestroyed += new EventHandler(MdiClientHandleDestroyed);
  254.                     MdiClient.Layout += new LayoutEventHandler(MdiClientLayout);
  255.                     break;
  256.                 }
  257.             }
  258.             private void RefreshProperties()
  259.             {
  260.                 // Refresh all the properties
  261.                 BorderStyle = m_borderStyle;
  262.                 AutoScroll = m_autoScroll;
  263.             }
  264.             private void UpdateStyles()
  265.             {
  266.                 // To show style changes, the non-client area must be repainted. Using the
  267.                 // control's Invalidate method does not affect the non-client area.
  268.                 // Instead use a Win32 call to signal the style has changed.
  269.                 NativeMethods.SetWindowPos(MdiClient.Handle, IntPtr.Zero, 0, 0, 0, 0,
  270.                     Win32.FlagsSetWindowPos.SWP_NOACTIVATE |
  271.                     Win32.FlagsSetWindowPos.SWP_NOMOVE |
  272.                     Win32.FlagsSetWindowPos.SWP_NOSIZE |
  273.                     Win32.FlagsSetWindowPos.SWP_NOZORDER |
  274.                     Win32.FlagsSetWindowPos.SWP_NOOWNERZORDER |
  275.                     Win32.FlagsSetWindowPos.SWP_FRAMECHANGED);
  276.             }
  277.         }
  278.         private MdiClientController m_mdiClientController = null;
  279.         private MdiClientController GetMdiClientController()
  280.         {
  281.             if (m_mdiClientController == null)
  282.             {
  283.                 m_mdiClientController = new MdiClientController();
  284.                 m_mdiClientController.HandleAssigned += new EventHandler(MdiClientHandleAssigned);
  285.                 m_mdiClientController.MdiChildActivate += new EventHandler(ParentFormMdiChildActivate);
  286.                 m_mdiClientController.Layout += new LayoutEventHandler(MdiClient_Layout);
  287.             }
  288.             return m_mdiClientController;
  289.         }
  290.         private void ParentFormMdiChildActivate(object sender, EventArgs e)
  291.         {
  292.             if (GetMdiClientController().ParentForm == null)
  293.                 return;
  294.             IDockContent content = GetMdiClientController().ParentForm.ActiveMdiChild as IDockContent;
  295.             if (content == null)
  296.                 return;
  297.             if (content.DockHandler.DockPanel == this && content.DockHandler.Pane != null)
  298.                 content.DockHandler.Pane.ActiveContent = content;
  299.         }
  300.         private bool MdiClientExists
  301.         {
  302.             get { return GetMdiClientController().MdiClient != null; }
  303.         }
  304.         private void SetMdiClientBounds(Rectangle bounds)
  305.         {
  306.             GetMdiClientController().MdiClient.Bounds = bounds;
  307.         }
  308.         private void SuspendMdiClientLayout()
  309.         {
  310.             if (GetMdiClientController().MdiClient != null)
  311.                 GetMdiClientController().MdiClient.SuspendLayout();
  312.         }
  313.         private void ResumeMdiClientLayout(bool perform)
  314.         {
  315.             if (GetMdiClientController().MdiClient != null)
  316.                 GetMdiClientController().MdiClient.ResumeLayout(perform);
  317.         }
  318.         private void PerformMdiClientLayout()
  319.         {
  320.             if (GetMdiClientController().MdiClient != null)
  321.                 GetMdiClientController().MdiClient.PerformLayout();
  322.         }
  323.         // Called when:
  324.         // 1. DockPanel.DocumentStyle changed
  325.         // 2. DockPanel.Visible changed
  326.         // 3. MdiClientController.Handle assigned
  327.         private void SetMdiClient()
  328.         {
  329.             MdiClientController controller = GetMdiClientController();
  330.             if (this.DocumentStyle == DocumentStyle.DockingMdi)
  331.             {
  332.                 controller.AutoScroll = false;
  333.                 controller.BorderStyle = BorderStyle.None;
  334.                 if (MdiClientExists)
  335.                     controller.MdiClient.Dock = DockStyle.Fill;
  336.             }
  337.             else if (DocumentStyle == DocumentStyle.DockingSdi || DocumentStyle == DocumentStyle.DockingWindow)
  338.             {
  339.                 controller.AutoScroll = true;
  340.                 controller.BorderStyle = BorderStyle.Fixed3D;
  341.                 if (MdiClientExists)
  342.                     controller.MdiClient.Dock = DockStyle.Fill;
  343.             }
  344.             else if (this.DocumentStyle == DocumentStyle.SystemMdi)
  345.             {
  346.                 controller.AutoScroll = true;
  347.                 controller.BorderStyle = BorderStyle.Fixed3D;
  348.                 if (controller.MdiClient != null)
  349.                 {
  350.                     controller.MdiClient.Dock = DockStyle.None;
  351.                     controller.MdiClient.Bounds = SystemMdiClientBounds;
  352.                 }
  353.             }
  354.         }
  355.         internal Rectangle RectangleToMdiClient(Rectangle rect)
  356.         {
  357.             if (MdiClientExists)
  358.                 return GetMdiClientController().MdiClient.RectangleToClient(rect);
  359.             else
  360.                 return Rectangle.Empty;
  361.         }
  362.     }
  363. }