RaUI/Source/ryControls/Gdu.WinFormUI/Forms/GMShadow.cs

396 lines
11 KiB
C#
Raw Normal View History

/*
*
* 使
* 使ping3108@163.com,
*/
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using MGdu.WinFormUI.Win32;
using MGdu.WinFormUI.MyGraphics;
namespace MGdu.WinFormUI
{
internal partial class GMShadow : Form
{
private GMForm _owner;
private bool _timeToResizeOwner;
public GMShadow(GMForm owner)
{
_owner = owner;
_timeToResizeOwner = false;
InitializeComponent();
FormIni();
}
public void BeginToResizeOwner()
{
_timeToResizeOwner = true;
}
private void FormIni()
{
base.FormBorderStyle = FormBorderStyle.None;
base.WindowState = FormWindowState.Normal;
base.ShowInTaskbar = false;
SetStyle(
ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.OptimizedDoubleBuffer |
ControlStyles.ResizeRedraw |
ControlStyles.DoubleBuffer, true);
UpdateStyles();
base.AutoScaleMode = AutoScaleMode.None;
}
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= (int)Win32.WinAPI.WindowStyleEx.WS_EX_LAYERED;
return cp;
}
}
private void SetFormReion()
{
if (base.Region != null)
base.Region.Dispose();
using (GraphicsPath path = GraphicsPathHelper.CreateRoundedRect(
new Rectangle(Point.Empty, base.Size), 16, RoundStyle.All, false))
{
this.Region = new Region(path);
}
}
private void SetOwnerSize()
{
var size = base.Size;
size.Width -= ShadowWidth * 2;
size.Height -= ShadowWidth * 2;
if (_owner.Size != size)
{
_owner.Size = size;
_owner.Update();
}
}
private void SetOwnerLocation()
{
Point location = base.Location;
location.Offset(ShadowWidth, ShadowWidth);
if (_owner.Location != location)
{
_owner.Location = location;
_owner.Update();
}
}
#region properties from owner
private int ShadowWidth
{
get { return _owner.XTheme.ShadowWidth==0?1: _owner.XTheme.ShadowWidth; }
}
private bool UseShadowToResize
{
get { return _owner.XTheme.UseShadowToResize; }
}
private Color ShadowColor
{
get { return _owner.XTheme.ShadowColor; }
}
private int ShadowAValueDark
{
get { return _owner.XTheme.ShadowAValueDark; }
}
private int ShadowAValueLight
{
get { return _owner.XTheme.ShadowAValueLight; }
}
#endregion
#region resize rect region
private Rectangle TopLeftRect
{
get
{
return new Rectangle(0, 0, ShadowWidth, ShadowWidth);
}
}
private Rectangle TopRect
{
get
{
return new Rectangle(
ShadowWidth,
0,
this.Size.Width - ShadowWidth * 2,
ShadowWidth);
}
}
private Rectangle TopRightRect
{
get
{
return new Rectangle(
this.Size.Width - ShadowWidth,
0,
ShadowWidth,
ShadowWidth);
}
}
private Rectangle LeftRect
{
get
{
return new Rectangle(
0,
ShadowWidth,
ShadowWidth,
this.Size.Height - ShadowWidth * 2);
}
}
private Rectangle RightRect
{
get
{
return new Rectangle(
this.Size.Width - ShadowWidth,
ShadowWidth,
ShadowWidth,
this.Size.Height - ShadowWidth * 2);
}
}
private Rectangle BottomLeftRect
{
get
{
return new Rectangle(
0,
this.Size.Height - ShadowWidth,
ShadowWidth,
ShadowWidth);
}
}
private Rectangle BottomRect
{
get
{
return new Rectangle(
ShadowWidth,
this.Size.Height - ShadowWidth,
this.Size.Width - ShadowWidth * 2,
ShadowWidth);
}
}
private Rectangle BottomRightRect
{
get
{
return new Rectangle(
this.Size.Width - ShadowWidth,
this.Size.Height - ShadowWidth,
ShadowWidth,
ShadowWidth);
}
}
#endregion
private void DrawShadow(Graphics g)
{
int aDark = ShadowAValueDark;
int aLight = ShadowAValueLight;
if (aDark < 0)
aDark = 0;
if (aDark > 180)
aDark = 180;
if (aLight < 0)
aLight = 0;
if (aLight > 180)
aLight = 180;
if (aLight > aDark)
{
int t = aLight;
aLight = aDark;
aDark = t;
}
int diff = (aDark - aLight) / ShadowWidth;
Rectangle rect = base.ClientRectangle;
rect.Width--;
rect.Height--;
g.SmoothingMode = SmoothingMode.AntiAlias;
for (int i = 0; i < ShadowWidth; i++)
{
using (Pen p = new Pen(Color.FromArgb(aLight + diff * i, ShadowColor)))
{
g.DrawRectangle(p, rect);
}
rect.Inflate(-1, -1);
}
}
internal void RefleshLayeredForm()
{
Bitmap formBitMap = new Bitmap(base.Width, base.Height);
Graphics g = Graphics.FromImage(formBitMap);
DrawShadow(g);
Win32.WinAPI.POINT ptSrc = new Win32.WinAPI.POINT(0, 0);
Win32.WinAPI.POINT ptWinPos = new Win32.WinAPI.POINT(base.Left, base.Top);
Win32.WinAPI.SIZE szWinSize = new Win32.WinAPI.SIZE(Width, Height);
byte biAlpha = 0xFF;
Win32.WinAPI.BLENDFUNCTION stBlend = new Win32.WinAPI.BLENDFUNCTION(
(byte)Win32.WinAPI.BlendOp.AC_SRC_OVER, 0, biAlpha, (byte)Win32.WinAPI.BlendOp.AC_SRC_ALPHA);
IntPtr gdiBitMap = IntPtr.Zero;
IntPtr memoryDC = IntPtr.Zero;
IntPtr preBits = IntPtr.Zero;
IntPtr screenDC = IntPtr.Zero;
try
{
screenDC = Win32.WinAPI.GetDC(IntPtr.Zero);
memoryDC = Win32.WinAPI.CreateCompatibleDC(screenDC);
gdiBitMap = formBitMap.GetHbitmap(Color.FromArgb(0));
preBits = Win32.WinAPI.SelectObject(memoryDC, gdiBitMap);
Win32.WinAPI.UpdateLayeredWindow(base.Handle
, screenDC
, ref ptWinPos
, ref szWinSize
, memoryDC
, ref ptSrc
, 0
, ref stBlend
, (uint)Win32.WinAPI.ULWPara.ULW_ALPHA);
}
finally
{
if (gdiBitMap != IntPtr.Zero)
{
Win32.WinAPI.SelectObject(memoryDC, preBits);
Win32.WinAPI.DeleteObject(gdiBitMap);
}
Win32.WinAPI.DeleteDC(memoryDC);
Win32.WinAPI.ReleaseDC(IntPtr.Zero, screenDC);
g.Dispose();
formBitMap.Dispose();
}
}
private void WmNcHitTest(ref Message m)
{
int para = m.LParam.ToInt32();
int x0 = Win32.WinAPI.LOWORD(para);
int y0 = Win32.WinAPI.HIWORD(para);
Point p = PointToClient(new Point(x0, y0));
if (UseShadowToResize)
{
if (TopLeftRect.Contains(p))
{
m.Result = new IntPtr((int)Win32.WinAPI.NCHITTEST.HTTOPLEFT);
return ;
}
if (TopRect.Contains(p))
{
m.Result = new IntPtr((int)Win32.WinAPI.NCHITTEST.HTTOP);
return ;
}
if (TopRightRect.Contains(p))
{
m.Result = new IntPtr((int)Win32.WinAPI.NCHITTEST.HTTOPRIGHT);
return ;
}
if (LeftRect.Contains(p))
{
m.Result = new IntPtr((int)Win32.WinAPI.NCHITTEST.HTLEFT);
return ;
}
if (RightRect.Contains(p))
{
m.Result = new IntPtr((int)Win32.WinAPI.NCHITTEST.HTRIGHT);
return ;
}
if (BottomLeftRect.Contains(p))
{
m.Result = new IntPtr((int)Win32.WinAPI.NCHITTEST.HTBOTTOMLEFT);
return ;
}
if (BottomRect.Contains(p))
{
m.Result = new IntPtr((int)Win32.WinAPI.NCHITTEST.HTBOTTOM);
return ;
}
if (BottomRightRect.Contains(p))
{
m.Result = new IntPtr((int)Win32.WinAPI.NCHITTEST.HTBOTTOMRIGHT);
return ;
}
}
m.Result = new IntPtr((int)Win32.WinAPI.NCHITTEST.HTCLIENT);
return ;
}
protected override void WndProc(ref Message m)
{
if (m.Msg == (int)Win32.WinAPI.WindowMessages.WM_NCHITTEST)
{
WmNcHitTest(ref m);
return;
}
base.WndProc(ref m);
}
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
RefleshLayeredForm();
SetFormReion();
if (UseShadowToResize && _timeToResizeOwner && _owner.WindowState == FormWindowState.Normal)
SetOwnerSize();
}
protected override void OnLocationChanged(EventArgs e)
{
base.OnLocationChanged(e);
if (UseShadowToResize && _timeToResizeOwner && _owner.WindowState == FormWindowState.Normal)
SetOwnerLocation();
}
}
}