big transformation , using DockPanels now
it feels good to me! -Thoys git-svn-id: https://lsleditor.svn.sourceforge.net/svnroot/lsleditor@26 3f4676ac-adda-40fd-8265-58d1435b1672
This commit is contained in:
parent
75c722f354
commit
573823c181
92 changed files with 16899 additions and 760 deletions
430
trunk/Docking/DockPanel.MdiClientController.cs
Normal file
430
trunk/Docking/DockPanel.MdiClientController.cs
Normal file
|
@ -0,0 +1,430 @@
|
|||
using System;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.Design;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace LSLEditor.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;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue