You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
464 lines
16 KiB
464 lines
16 KiB
#if NETFX || NETCORE
|
|
|
|
using System;
|
|
using System.Drawing;
|
|
using System.Windows.Forms;
|
|
using System.Runtime.InteropServices;
|
|
using System.Drawing.Drawing2D;
|
|
|
|
namespace Apewer.Surface
|
|
{
|
|
|
|
internal class BlockShadow : BaseForm
|
|
{
|
|
|
|
#region definition
|
|
|
|
private BlockForm _parent;
|
|
|
|
#endregion
|
|
|
|
#region this
|
|
|
|
public void Constructor()
|
|
{
|
|
this.Optimize();
|
|
|
|
_parent.TopMost = TopMost = _parent.TopMost;
|
|
_parent.BringToFront();
|
|
|
|
this.Location = new Point(_parent.Location.X - 100, _parent.Location.Y - 100);
|
|
this.Width = _parent.Width + 200;
|
|
this.Height = _parent.Height + 200;
|
|
|
|
this.TopMost = _parent.TopMost;
|
|
this.ShowInTaskbar = false;
|
|
this.FormBorderStyle = FormBorderStyle.None;
|
|
this.Icon = _parent.Icon;
|
|
this.ShowIcon = _parent.ShowIcon;
|
|
this.Text = _parent.Text;
|
|
|
|
FormsUtility.UpdateShadow(this, ShadowImage(Width, Height));
|
|
FormsUtility.MousePenetration(this);
|
|
|
|
this.Paint += Event_This_Paint;
|
|
|
|
_parent.LocationChanged += new EventHandler(Main_LocationChanged);
|
|
_parent.SizeChanged += new EventHandler(Main_SizeChanged);
|
|
_parent.VisibleChanged += new EventHandler(Main_VisibleChanged);
|
|
_parent.ResizeBegin += Event_Form_ResizeBegin;
|
|
_parent.ResizeEnd += Event_Form_Resizeend;
|
|
}
|
|
|
|
public BlockShadow(BlockForm graceForm)
|
|
{
|
|
_parent = graceForm;
|
|
Constructor();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region base
|
|
|
|
protected override CreateParams CreateParams
|
|
{
|
|
get
|
|
{
|
|
CreateParams cParms = base.CreateParams;
|
|
cParms.ExStyle |= 0x00080000; // WS_EX_LAYERED
|
|
return cParms;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region event
|
|
|
|
private void Event_This_Paint(object sender, PaintEventArgs e)
|
|
{
|
|
}
|
|
|
|
private void Event_Form_Resizeend(object sender, EventArgs e)
|
|
{
|
|
//this.Visible = true;
|
|
}
|
|
|
|
private void Event_Form_ResizeBegin(object sender, EventArgs e)
|
|
{
|
|
//this.Visible = false;
|
|
}
|
|
|
|
private void Main_LocationChanged(object sender, EventArgs e)
|
|
{
|
|
Location = new Point(_parent.Left - 100, _parent.Top - 100);
|
|
}
|
|
|
|
private void Main_SizeChanged(object sender, EventArgs e)
|
|
{
|
|
this.Size = new Size(_parent.Width + 200, _parent.Height + 200);
|
|
FormsUtility.UpdateShadow(this, ShadowImage(Width, Height));
|
|
}
|
|
|
|
private void Main_VisibleChanged(object sender, EventArgs e)
|
|
{
|
|
this.Visible = _parent.Visible;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region shadow
|
|
|
|
private Bitmap ShadowImage(int width, int height, bool focus = true)
|
|
{
|
|
return ShadowImage_1(width, height, focus);
|
|
}
|
|
|
|
private Bitmap ShadowImage_2(int width, int height, bool focus = true)
|
|
{
|
|
var bitmap = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
|
|
var g = Graphics.FromImage(bitmap);
|
|
g.Clear(Color.FromArgb(0, 0, 0, 0));
|
|
g.SmoothingMode = SmoothingMode.HighQuality;
|
|
g.CompositingMode = CompositingMode.SourceCopy;
|
|
|
|
int w = _parent.Width + 200;
|
|
int h = _parent.Height + 200;
|
|
if ((w > Screen.PrimaryScreen.Bounds.Width) || (h > Screen.PrimaryScreen.Bounds.Height))
|
|
{
|
|
//using (var vp = new Pen(bordercolor)) vg.DrawRectangle(vp, 100, 100, Width - 200, Height - 200);
|
|
g.Dispose();
|
|
return bitmap;
|
|
}
|
|
|
|
for (int i = 0; i < 100; i++)
|
|
{
|
|
var rect = new Rectangle(i, i, w - (i * 2), h - (i * 2));
|
|
var path = FormsUtility.CreatePath(rect, 99 - i);
|
|
var alpha = GetAlpha(99 - i);
|
|
var pen = new Pen(Color.FromArgb(alpha, 0, 0, 0));
|
|
// var vbrush = new SolidBrush(Color.FromArgb(valpha, 0, 0, 0));
|
|
g.DrawRectangle(pen, rect);
|
|
//vg.DrawPath(vpen, vpath);
|
|
//vg.FillPath(vbrush, vpath);
|
|
//vbrush.Dispose();
|
|
pen.Dispose();
|
|
path.Dispose();
|
|
}
|
|
|
|
//for (int i = 0; i < 100; i++)
|
|
//{
|
|
// var vrect = new Rectangle(i, i, 100 - i, 100 - i);
|
|
// var valpha = getalpha(99 - i);
|
|
// using (var vbrush = new SolidBrush(Color.FromArgb(valpha, 0, 0, 0)))
|
|
// {
|
|
// vg.FillPie(vbrush, vrect, 180, 90);
|
|
// vg.FillPie(vbrush, new Rectangle(0,0,100,100));
|
|
// }
|
|
//}
|
|
|
|
//using (var vbrush = new SolidBrush(Color.Transparent))
|
|
//{
|
|
|
|
// vg.FillRectangle(vbrush, new Rectangle(100, 100, vwidth - 200, vheight - 200));
|
|
//}
|
|
|
|
//using (var vbrush = new SolidBrush(Color.Transparent))
|
|
//{
|
|
// vg.FillRectangle(vbrush, new Rectangle(100, 100, vwidth - 200, vheight - 200));
|
|
//}
|
|
|
|
g.Dispose();
|
|
return bitmap;
|
|
}
|
|
|
|
private Bitmap ShadowImage_1(int width, int height, bool focus = true)
|
|
{
|
|
var bitmap = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
|
|
var g = Graphics.FromImage(bitmap);
|
|
g.Clear(Color.FromArgb(0, 0, 0, 0));
|
|
|
|
int w = _parent.Width + 200;
|
|
int h = _parent.Height + 200;
|
|
if ((w > Screen.PrimaryScreen.Bounds.Width) || (h > Screen.PrimaryScreen.Bounds.Height))
|
|
{
|
|
//using (var vp = new Pen(bordercolor)) vg.DrawRectangle(vp, 100, 100, Width - 200, Height - 200);
|
|
g.Dispose();
|
|
return bitmap;
|
|
}
|
|
|
|
// 边角距离补偿
|
|
int cornerOffset = 2;
|
|
|
|
// 上
|
|
for (int y = 0; y <= 99; y++)
|
|
{
|
|
double length = 100 - y;
|
|
using (var pen = new Pen(Color.FromArgb(GetAlpha(length), 0, 0, 0))) g.DrawLine(pen, 100, y, width - 101, y);
|
|
}
|
|
|
|
// 下
|
|
for (int y = height - 100; y <= height - 2; y++)
|
|
{
|
|
double length = y - (height - 101);
|
|
using (var pen = new Pen(Color.FromArgb(GetAlpha(length), 0, 0, 0))) g.DrawLine(pen, 100, y, width - 101, y);
|
|
}
|
|
|
|
// 左
|
|
for (int x = 0; x <= 99; x++)
|
|
{
|
|
double length = 100 - x;
|
|
using (var pen = new Pen(Color.FromArgb(GetAlpha(length), 0, 0, 0))) g.DrawLine(pen, x, 100, x, height - 101);
|
|
}
|
|
|
|
// 右
|
|
for (int x = width - 100; x <= width - 2; x++)
|
|
{
|
|
double length = x - (width - 101);
|
|
using (var pen = new Pen(Color.FromArgb(GetAlpha(length), 0, 0, 0))) g.DrawLine(pen, x, 100, x, height - 101);
|
|
}
|
|
|
|
// 左上
|
|
for (int x = 0; x <= 99; x++)
|
|
{
|
|
for (int y = 0; y <= 99; y++)
|
|
{
|
|
double vx = 100 - x; double vy = 100 - y;
|
|
double vl = Math.Sqrt((vx * vx) + (vy * vy)) + cornerOffset;
|
|
bitmap.SetPixel(x, y, Color.FromArgb(GetAlpha(vl), 0, 0, 0));
|
|
}
|
|
}
|
|
|
|
// 右上
|
|
for (int x = width - 100; x <= width - 1; x++)
|
|
{
|
|
for (int y = 0; y <= 99; y++)
|
|
{
|
|
double vx = 100 - (width - x); double vy = 100 - y;
|
|
double vl = Math.Sqrt((vx * vx) + (vy * vy)) + cornerOffset;
|
|
bitmap.SetPixel(x, y, Color.FromArgb(GetAlpha(vl), 0, 0, 0));
|
|
}
|
|
}
|
|
|
|
// 左下
|
|
for (int x = 0; x <= 99; x++)
|
|
{
|
|
for (int y = height - 100; y <= height - 1; y++)
|
|
{
|
|
double vx = 100 - x; double vy = 100 - (height - y);
|
|
double vl = Math.Sqrt((vx * vx) + (vy * vy)) + cornerOffset;
|
|
bitmap.SetPixel(x, y, Color.FromArgb(GetAlpha(vl), 0, 0, 0));
|
|
}
|
|
}
|
|
|
|
// 右下
|
|
for (int x = width - 100; x <= width - 1; x++)
|
|
{
|
|
for (int y = height - 100; y <= height - 1; y++)
|
|
{
|
|
double vx = 100 - (width - x); double vy = 100 - (height - y);
|
|
double vl = Math.Sqrt((vx * vx) + (vy * vy)) + cornerOffset;
|
|
bitmap.SetPixel(x, y, Color.FromArgb(GetAlpha(vl), 0, 0, 0));
|
|
}
|
|
}
|
|
|
|
g.Dispose();
|
|
return bitmap;
|
|
}
|
|
|
|
private static int GetAlpha(double length, bool focus = true)
|
|
{
|
|
// 返回值。
|
|
double alpha = 0;
|
|
|
|
// 参数。
|
|
if (length < 0) length = 0;
|
|
if (length > 100) length = 100;
|
|
|
|
// 常数。
|
|
double alphaMax = 0; // 0 <= x <=255
|
|
|
|
// 过程变量。
|
|
double x = 0, y = 0, xMax = 0, yMax = 0, lMax = 0, tanMax = 0, ratio = 0; ;
|
|
|
|
// 选择方法。
|
|
int method = 1; // flat from 4
|
|
|
|
switch (method)
|
|
{
|
|
|
|
case 0: // 穷举
|
|
ratio = 0.5;
|
|
int vlint = (int)length;
|
|
switch (vlint)
|
|
{
|
|
case 0: return 40;
|
|
case 1: return 39;
|
|
case 2: return 38;
|
|
case 3: return 37;
|
|
case 4: return 36;
|
|
case 5: return 36;
|
|
case 6: return 35;
|
|
case 7: return 34;
|
|
case 8: return 33;
|
|
case 9: return 33;
|
|
case 10: return 32;
|
|
case 11: return 31;
|
|
case 12: return 30;
|
|
case 13: return 30;
|
|
case 14: return 29;
|
|
case 15: return 28;
|
|
case 16: return 28;
|
|
case 17: return 27;
|
|
case 18: return 26;
|
|
case 19: return 26;
|
|
case 20: return 25;
|
|
case 21: return 24;
|
|
case 22: return 24;
|
|
case 23: return 23;
|
|
case 24: return 23;
|
|
case 25: return 22;
|
|
case 26: return 21;
|
|
case 27: return 21;
|
|
case 28: return 20;
|
|
case 29: return 20;
|
|
case 30: return 19;
|
|
case 31: return 19;
|
|
case 32: return 18;
|
|
case 33: return 17;
|
|
case 34: return 17;
|
|
case 35: return 16;
|
|
case 36: return 16;
|
|
case 37: return 15;
|
|
case 38: return 15;
|
|
case 39: return 14;
|
|
case 40: return 14;
|
|
case 41: return 13;
|
|
case 42: return 13;
|
|
case 43: return 12;
|
|
case 44: return 12;
|
|
case 45: return 12;
|
|
case 46: return 11;
|
|
case 47: return 11;
|
|
case 48: return 10;
|
|
case 49: return 10;
|
|
case 50: return 10;
|
|
case 51: return 9;
|
|
case 52: return 9;
|
|
case 53: return 8;
|
|
case 54: return 8;
|
|
case 55: return 8;
|
|
case 56: return 7;
|
|
case 57: return 7;
|
|
case 58: return 7;
|
|
case 59: return 6;
|
|
case 60: return 6;
|
|
case 61: return 6;
|
|
case 62: return 5;
|
|
case 63: return 5;
|
|
case 64: return 5;
|
|
case 65: return 4;
|
|
case 66: return 4;
|
|
case 67: return 4;
|
|
case 68: return 4;
|
|
case 69: return 3;
|
|
case 70: return 3;
|
|
case 71: return 3;
|
|
case 72: return 3;
|
|
case 73: return 2;
|
|
case 74: return 2;
|
|
case 75: return 2;
|
|
case 76: return 2;
|
|
case 77: return 2;
|
|
case 78: return 1;
|
|
case 79: return 1;
|
|
case 80: return 1;
|
|
case 81: return 1;
|
|
case 82: return 1;
|
|
case 83: return 1;
|
|
case 84: return 1;
|
|
case 85: return 0;
|
|
case 86: return 0;
|
|
case 87: return 0;
|
|
case 88: return 0;
|
|
case 89: return 0;
|
|
case 90: return 0;
|
|
case 91: return 0;
|
|
case 92: return 0;
|
|
case 93: return 0;
|
|
case 94: return 0;
|
|
case 95: return 0;
|
|
case 96: return 0;
|
|
case 97: return 0;
|
|
case 98: return 0;
|
|
case 99: return 0;
|
|
case 100: return 0;
|
|
}
|
|
break;
|
|
|
|
case 1: // 正比例
|
|
ratio = 0.2;
|
|
alpha = (100 - length) * ratio;
|
|
break;
|
|
|
|
case 2: // 正切函数
|
|
alphaMax = 55;
|
|
tanMax = 0.45; // 0 < x < 0.5
|
|
alpha = (Math.Tan(Math.PI * tanMax * ((100 - length) / 100)) / Math.Tan(Math.PI * tanMax)) * alphaMax;
|
|
break;
|
|
|
|
case 3: // 正弦函数
|
|
lMax = 40;
|
|
if (length <= lMax)
|
|
{
|
|
y = (lMax - length) * (lMax - length);
|
|
alphaMax = 30;
|
|
xMax = Math.PI / 2;
|
|
x = ((lMax - length) / lMax) * xMax;
|
|
if (x < 0) x = 0;
|
|
if (x > Math.PI / 2) x = Math.PI / 2;
|
|
alpha = (Math.Sin(Math.PI * 1.5 + x) + 1) * alphaMax;
|
|
}
|
|
else alpha = 0;
|
|
break;
|
|
|
|
case 4: // 平方函数
|
|
lMax = 100;
|
|
if (length <= lMax)
|
|
{
|
|
alphaMax = 40;
|
|
y = (lMax - length) * (lMax - length);
|
|
alpha = (y / (lMax * lMax)) * alphaMax;
|
|
}
|
|
else alpha = 0;
|
|
break;
|
|
|
|
case 5: // 幂函数
|
|
lMax = 40;
|
|
if (length <= lMax)
|
|
{
|
|
alphaMax = 1;
|
|
ratio = 1.1;
|
|
x = lMax - length;
|
|
y = Math.Pow(ratio, x);
|
|
yMax = Math.Pow(ratio, lMax);
|
|
alpha = (y / yMax) * alphaMax;
|
|
}
|
|
else alpha = 0;
|
|
break;
|
|
|
|
case 6:
|
|
if (length <= 40) alpha = 40 - length;
|
|
else alpha = 0;
|
|
break;
|
|
}
|
|
if (alpha < 0) alpha = 0; if (alpha > 255) alpha = 255;
|
|
return (int)alpha;
|
|
}
|
|
|
|
#endregion
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|