#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 argGraceForm) { _parent = argGraceForm; 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 argWidth, int argHeight, bool argFocus = true) { return ShadowImage_1(argWidth, argHeight, argFocus); } private Bitmap ShadowImage_2(int argWidth, int argHeight, bool argFocus = true) { var vbitmap = new Bitmap(argWidth, argHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb); var vg = Graphics.FromImage(vbitmap); vg.Clear(Color.FromArgb(0, 0, 0, 0)); vg.SmoothingMode = SmoothingMode.HighQuality; vg.CompositingMode = CompositingMode.SourceCopy; int vwidth = _parent.Width + 200; int vheight = _parent.Height + 200; if ((vwidth > Screen.PrimaryScreen.Bounds.Width) || (vheight > Screen.PrimaryScreen.Bounds.Height)) { //using (var vp = new Pen(bordercolor)) vg.DrawRectangle(vp, 100, 100, Width - 200, Height - 200); vg.Dispose(); return vbitmap; } for (int i = 0; i < 100; i++) { var vrect = new Rectangle(i, i, vwidth - (i * 2), vheight - (i * 2)); var vpath = FormsUtility.CreatePath(vrect, 99 - i); var valpha = GetAlpha(99 - i); var vpen = new Pen(Color.FromArgb(valpha, 0, 0, 0)); // var vbrush = new SolidBrush(Color.FromArgb(valpha, 0, 0, 0)); vg.DrawRectangle(vpen, vrect); //vg.DrawPath(vpen, vpath); //vg.FillPath(vbrush, vpath); //vbrush.Dispose(); vpen.Dispose(); vpath.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)); //} vg.Dispose(); return vbitmap; } private Bitmap ShadowImage_1(int argWidth, int argHeight, bool argFocus = true) { var vbitmap = new Bitmap(argWidth, argHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb); var vg = Graphics.FromImage(vbitmap); vg.Clear(Color.FromArgb(0, 0, 0, 0)); int vwidth = _parent.Width + 200; int vheight = _parent.Height + 200; if ((vwidth > Screen.PrimaryScreen.Bounds.Width) || (vheight > Screen.PrimaryScreen.Bounds.Height)) { //using (var vp = new Pen(bordercolor)) vg.DrawRectangle(vp, 100, 100, Width - 200, Height - 200); vg.Dispose(); return vbitmap; } // 边角距离补偿 int vcorneroffset = 2; // 上 for (int y = 0; y <= 99; y++) { double vl = 100 - y; using (var vp = new Pen(Color.FromArgb(GetAlpha(vl), 0, 0, 0))) vg.DrawLine(vp, 100, y, argWidth - 101, y); } // 下 for (int y = argHeight - 100; y <= argHeight - 2; y++) { double vl = y - (argHeight - 101); using (var vp = new Pen(Color.FromArgb(GetAlpha(vl), 0, 0, 0))) vg.DrawLine(vp, 100, y, argWidth - 101, y); } // 左 for (int x = 0; x <= 99; x++) { double vl = 100 - x; using (var vp = new Pen(Color.FromArgb(GetAlpha(vl), 0, 0, 0))) vg.DrawLine(vp, x, 100, x, argHeight - 101); } // 右 for (int x = argWidth - 100; x <= argWidth - 2; x++) { double vl = x - (argWidth - 101); using (var vp = new Pen(Color.FromArgb(GetAlpha(vl), 0, 0, 0))) vg.DrawLine(vp, x, 100, x, argHeight - 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)) + vcorneroffset; vbitmap.SetPixel(x, y, Color.FromArgb(GetAlpha(vl), 0, 0, 0)); } } // 右上 for (int x = argWidth - 100; x <= argWidth - 1; x++) { for (int y = 0; y <= 99; y++) { double vx = 100 - (argWidth - x); double vy = 100 - y; double vl = Math.Sqrt((vx * vx) + (vy * vy)) + vcorneroffset; vbitmap.SetPixel(x, y, Color.FromArgb(GetAlpha(vl), 0, 0, 0)); } } // 左下 for (int x = 0; x <= 99; x++) { for (int y = argHeight - 100; y <= argHeight - 1; y++) { double vx = 100 - x; double vy = 100 - (argHeight - y); double vl = Math.Sqrt((vx * vx) + (vy * vy)) + vcorneroffset; vbitmap.SetPixel(x, y, Color.FromArgb(GetAlpha(vl), 0, 0, 0)); } } // 右下 for (int x = argWidth - 100; x <= argWidth - 1; x++) { for (int y = argHeight - 100; y <= argHeight - 1; y++) { double vx = 100 - (argWidth - x); double vy = 100 - (argHeight - y); double vl = Math.Sqrt((vx * vx) + (vy * vy)) + vcorneroffset; vbitmap.SetPixel(x, y, Color.FromArgb(GetAlpha(vl), 0, 0, 0)); } } vg.Dispose(); return vbitmap; } private static int GetAlpha(double argLength, bool argFocus = true) { // 返回值。 double valpha = 0; // 参数。 double vl = argLength; if (vl < 0) vl = 0; if (vl > 100) vl = 100; // 常数。 double alphamax = 0; // 0 <= x <=255 // 过程变量。 double x = 0, y = 0, xmax = 0, ymax = 0, lmax = 0, tanmax = 0, ratio = 0; ; // 选择方法。 int vmethod = 1; // flat from 4 switch (vmethod) { case 0: // 穷举 ratio = 0.5; int vlint = (int)argLength; switch (vlint) { #region switch block 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; #endregion } break; case 1: // 正比例 ratio = 0.2; valpha = (100 - vl) * ratio; break; case 2: // 正切函数 alphamax = 55; tanmax = 0.45; // 0 < x < 0.5 valpha = (Math.Tan(Math.PI * tanmax * ((100 - vl) / 100)) / Math.Tan(Math.PI * tanmax)) * alphamax; break; case 3: // 正弦函数 lmax = 40; if (vl <= lmax) { y = (lmax - vl) * (lmax - vl); alphamax = 30; xmax = Math.PI / 2; x = ((lmax - vl) / lmax) * xmax; if (x < 0) x = 0; if (x > Math.PI / 2) x = Math.PI / 2; valpha = (Math.Sin(Math.PI * 1.5 + x) + 1) * alphamax; } else valpha = 0; break; case 4: // 平方函数 lmax = 100; if (vl <= lmax) { alphamax = 40; y = (lmax - vl) * (lmax - vl); valpha = (y / (lmax * lmax)) * alphamax; } else valpha = 0; break; case 5: // 幂函数 lmax = 40; if (vl <= lmax) { alphamax = 1; ratio = 1.1; x = lmax - vl; y = Math.Pow(ratio, x); ymax = Math.Pow(ratio, lmax); valpha = (y / ymax) * alphamax; } else valpha = 0; break; case 6: if (vl <= 40) valpha = 40 - vl; else valpha = 0; break; } if (valpha < 0) valpha = 0; if (valpha > 255) valpha = 255; return (int)valpha; } #endregion } } #endif