mdiclientcontroller.cs
来自「Fireball.CodeEditor is an source code ed」· CS 代码 · 共 578 行 · 第 1/2 页
CS
578 行
[Category("Appearance"), DefaultValue(false)]
[LocalizedDescription("MdiClientController.StretchImage.Description")]
public bool StretchImage
{
get { return m_stretchImage; }
set
{
m_stretchImage = value;
if(MdiClient != null)
MdiClient.Invalidate();
}
}
public void RenewMdiClient()
{
// Reinitialize the MdiClient and its properties.
InitializeMdiClient();
RefreshProperties();
}
[Browsable(false)]
public event EventHandler Disposed;
[Browsable(false)]
public event EventHandler HandleAssigned;
[Browsable(false)]
public event EventHandler MdiChildActivate;
[Browsable(false)]
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);
}
[Category("Appearance")]
[LocalizedDescription("MdiClientController.Paint.Description")]
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)
{
//Do all painting in WM_PAINT to reduce flicker.
case (int)Win32.Msgs.WM_ERASEBKGND:
return;
case (int)Win32.Msgs.WM_PAINT:
// This code is influenced by Steve McMahon's article:
// "Painting in the MDI Client Area".
// http://vbaccelerator.com/article.asp?id=4306
// Use Win32 to get a Graphics object.
Win32.PAINTSTRUCT paintStruct = new Win32.PAINTSTRUCT();
IntPtr screenHdc = User32.BeginPaint(m.HWnd, ref paintStruct);
using(Graphics screenGraphics = Graphics.FromHdc(screenHdc))
{
// Get the area to be updated.
Rectangle clipRect = paintStruct.rcPaint;
// Double-buffer by painting everything to an image and
// then drawing the image.
int width = (MdiClient.ClientRectangle.Width > 0 ? MdiClient.ClientRectangle.Width : 0);
int height = (MdiClient.ClientRectangle.Height > 0 ? MdiClient.ClientRectangle.Height : 0);
if (width > 0 && height > 0)
{
using(Image i = new Bitmap(width, height))
{
using(Graphics g = Graphics.FromImage(i))
{
// This code comes from J Young's article:
// "Generating missing Paint event for TreeView and ListView".
// http://www.codeproject.com/cs/miscctrl/genmissingpaintevent.asp
// Draw base graphics and raise the base Paint event.
IntPtr hdc = g.GetHdc();
Message printClientMessage = Message.Create(m.HWnd, (int)Win32.Msgs.WM_PRINTCLIENT, hdc, IntPtr.Zero);
DefWndProc(ref printClientMessage);
g.ReleaseHdc(hdc);
// Draw the image here.
if(Image != null)
DrawImage(g, clipRect);
// Call our OnPaint here to draw graphics over the
// original and raise our Paint event.
OnPaint(new PaintEventArgs(g, clipRect));
}
// Now draw all the graphics at once.
screenGraphics.DrawImage(i, MdiClient.ClientRectangle);
}
}
}
User32.EndPaint(m.HWnd, ref paintStruct);
return;
case (int)Win32.Msgs.WM_SIZE:
// Repaint on every resize.
MdiClient.Invalidate();
break;
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)
User32.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
BackColor = m_backColor;
BorderStyle = m_borderStyle;
AutoScroll = m_autoScroll;
Image = m_image;
ImageAlign = m_imageAlign;
StretchImage = m_stretchImage;
}
private void DrawImage(Graphics g, Rectangle clipRect)
{
// Paint the background image.
if(StretchImage)
g.DrawImage(this.Image, MdiClient.ClientRectangle);
else
{
// Calculate the location of the image. (Note: this logic could be calculated during sizing
// instead of during painting to improve performance.)
Point pt = Point.Empty;
switch(ImageAlign)
{
case ContentAlignment.TopLeft:
pt = new Point(0, 0);
break;
case ContentAlignment.TopCenter:
pt = new Point((MdiClient.ClientRectangle.Width / 2) - (Image.Width / 2), 0);
break;
case ContentAlignment.TopRight:
pt = new Point(MdiClient.ClientRectangle.Width - Image.Width, 0);
break;
case ContentAlignment.MiddleLeft:
pt = new Point(0, (MdiClient.ClientRectangle.Height / 2) - (Image.Height / 2));
break;
case ContentAlignment.MiddleCenter:
pt = new Point((MdiClient.ClientRectangle.Width / 2) - (Image.Width / 2),
(MdiClient.ClientRectangle.Height / 2) - (Image.Height / 2));
break;
case ContentAlignment.MiddleRight:
pt = new Point(MdiClient.ClientRectangle.Width - Image.Width,
(MdiClient.ClientRectangle.Height / 2) - (Image.Height / 2));
break;
case ContentAlignment.BottomLeft:
pt = new Point(0, MdiClient.ClientRectangle.Height - Image.Height);
break;
case ContentAlignment.BottomCenter:
pt = new Point((MdiClient.ClientRectangle.Width / 2) - (Image.Width / 2),
MdiClient.ClientRectangle.Height - Image.Height);
break;
case ContentAlignment.BottomRight:
pt = new Point(MdiClient.ClientRectangle.Width - Image.Width,
MdiClient.ClientRectangle.Height - Image.Height);
break;
}
// Paint the image with the calculated coordinates and image size.
g.DrawImage(Image, new Rectangle(pt, Image.Size));
}
}
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.
User32.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);
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?