// COPYRIGHT (C) Tom. ALL RIGHTS RESERVED. // THE AntdUI PROJECT IS AN WINFORM LIBRARY LICENSED UNDER THE Apache-2.0 License. // LICENSED UNDER THE Apache License, VERSION 2.0 (THE "License") // YOU MAY NOT USE THIS FILE EXCEPT IN COMPLIANCE WITH THE License. // YOU MAY OBTAIN A COPY OF THE LICENSE AT // // http://www.apache.org/licenses/LICENSE-2.0 // // UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING, SOFTWARE // DISTRIBUTED UNDER THE LICENSE IS DISTRIBUTED ON AN "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. // SEE THE LICENSE FOR THE SPECIFIC LANGUAGE GOVERNING PERMISSIONS AND // LIMITATIONS UNDER THE License. // GITEE: https://gitee.com/antdui/AntdUI // GITHUB: https://github.com/AntdUI/AntdUI // CSDN: https://blog.csdn.net/v_132 // QQ: 17379620 using System; using System.Drawing; using System.Windows.Forms; namespace AntdUI { public abstract class ILayeredForm : Form, IMessageFilter { public ILayeredForm() { SetStyle( ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.DoubleBuffer, true); UpdateStyles(); FormBorderStyle = FormBorderStyle.None; ShowInTaskbar = false; Size = new Size(0, 0); } public Control? PARENT = null; public Func? KeyCall = null; public virtual bool CanLoadMessage { get; set; } = true; public virtual void LoadMessage() { if (InvokeRequired) { Invoke(new Action(LoadMessage)); return; } if (MessageEnable) Application.AddMessageFilter(this); } protected override void OnLoad(EventArgs e) { base.OnLoad(e); if (CanLoadMessage) LoadMessage(); } bool can_render = true; protected override void Dispose(bool disposing) { can_render = false; base.Dispose(disposing); Application.RemoveMessageFilter(this); } public virtual bool UFocus => true; public abstract Bitmap PrintBit(); public byte alpha = 10; #region 渲染坐标 Rectangle target_rect = new Rectangle(-1000, -1000, 0, 0); /// /// 目标区域 /// public Rectangle TargetRect { get => target_rect; } public Rectangle TargetRectXY { get => new Rectangle(0, 0, target_rect.Width, target_rect.Height); } public void SetRect(Rectangle rect) { target_rect.X = rect.X; target_rect.Y = rect.Y; target_rect.Width = rect.Width; target_rect.Height = rect.Height; } public void SetSize(Size size) { target_rect.Width = size.Width; target_rect.Height = size.Height; } public void SetSize(int w, int h) { target_rect.Width = w; target_rect.Height = h; } public void SetSize(int size) { target_rect.Width = target_rect.Height = size; } public void SetSizeW(int w) { target_rect.Width = w; } public void SetSizeH(int h) { target_rect.Height = h; } public void SetLocation(Point point) { target_rect.X = point.X; target_rect.Y = point.Y; } public void SetLocationX(int x) { target_rect.X = x; } public void SetLocationY(int y) { target_rect.Y = y; } public void SetLocation(int x, int y) { target_rect.X = x; target_rect.Y = y; } #endregion public void Print() { if (IsHandleCreated && can_render && target_rect.Width > 0 && target_rect.Height > 0) { try { using (var bmp = PrintBit()) { if (bmp == null) return; Render(bmp); } GC.Collect(); } catch { } } } public void Render(Bitmap bmp) { try { if (InvokeRequired) Invoke(new Action(() => { Render(bmp); })); else Win32.SetBits(bmp, target_rect, Handle, alpha); } catch { } } public void SetCursor(bool val) { if (InvokeRequired) { Invoke(new Action(() => { SetCursor(val); })); return; } Cursor = val ? Cursors.Hand : DefaultCursor; } #region 无焦点窗体 protected override CreateParams CreateParams { get { var cp = base.CreateParams; cp.ExStyle |= 0x08000000 | 0x00080000; cp.Parent = IntPtr.Zero; return cp; } } protected override bool ShowWithoutActivation { get => UFocus; } protected override void WndProc(ref System.Windows.Forms.Message m) { if (UFocus && m.Msg == 0x21) { m.Result = new IntPtr(3); return; } base.WndProc(ref m); } #endregion public void IClose(bool isdispose = false) { if (IsHandleCreated) { try { if (InvokeRequired) { Invoke(new Action(() => { IClose(isdispose); })); return; } Close(); if (isdispose) Dispose(); } catch { } } } /// /// 点击外面关闭使能 /// public virtual bool MessageEnable => false; public virtual bool MessageCloseSub => false; /// /// 鼠标离开关闭 /// public bool MessageCloseMouseLeave { get; set; } public bool PreFilterMessage(ref System.Windows.Forms.Message m) { //if (m.Msg == 0x31f || m.Msg == 0xc31a || m.Msg == 0x60 || m.Msg == 0xf || m.Msg == 0xc0a2 || m.Msg == 0x118 || m.Msg == 0x113) return false; //0x2a1 (WM_MOUSEHOVER) //0x2a3 (WM_MOUSELEAVE) if ((m.Msg == 0x201 || m.Msg == 0x204 || m.Msg == 0x207 || m.Msg == 0xa0)) { var mousePosition = MousePosition; if (!target_rect.Contains(mousePosition)) { try { if (PARENT != null && PARENT.IsHandleCreated) { if (ContainsPosition(PARENT, mousePosition)) return false; if (new Rectangle(PARENT.PointToScreen(Point.Empty), PARENT.Size).Contains(mousePosition)) return false; #region 判断内容 if (MessageCloseSub && FunSub(PARENT, mousePosition)) return false; #endregion } IClose(); } catch { } return false; } } else if (m.Msg == 0x2a3 && MessageCloseMouseLeave) { var mousePosition = MousePosition; if (!target_rect.Contains(mousePosition)) { try { if (PARENT != null && PARENT.IsHandleCreated) { if (ContainsPosition(PARENT, mousePosition)) return false; if (new Rectangle(PARENT.PointToScreen(Point.Empty), PARENT.Size).Contains(mousePosition)) return false; #region 判断内容 if (MessageCloseSub && FunSub(PARENT, mousePosition)) return false; #endregion } IClose(); } catch { } return false; } } else if (m.Msg == 0x100 && KeyCall != null) { //0x100 (WM_KEYDOWN) //0x101 (WM_KEYUP) var keys = (Keys)(int)m.WParam; return KeyCall.Invoke(keys); } return false; } bool FunSub(Control control, Point mousePosition) { if (control is SubLayeredForm subForm) { var subform = subForm.SubForm(); if (subform != null && ContainsPosition(subform, mousePosition) > 0) return true; } if (control.Controls == null || control.Controls.Count == 0) return false; foreach (Control it in control.Controls) { if (FunSub(it, mousePosition)) return true; } return false; } bool ContainsPosition(Control control, Point mousePosition) { if (new Rectangle(control.PointToScreen(Point.Empty), control.Size).Contains(mousePosition)) return true; try { if (control is SubLayeredForm subForm) { var subform = subForm.SubForm(); if (subform != null && ContainsPosition(subform, mousePosition) > 0) return true; } } catch { } return false; } int ContainsPosition(ILayeredForm control, Point mousePosition) { int count = 0; try { if (control.TargetRect.Contains(mousePosition)) count++; if (control is LayeredFormSelectDown layered && layered.SubForm != null) count += ContainsPosition(layered.SubForm, mousePosition); } catch { } return count; } #region 触屏 bool mdown = false; int mdownd = 0, oldX, oldY; protected virtual void OnTouchDown(int x, int y) { oldMY = 0; oldX = x; oldY = y; if (Config.TouchEnabled) { taskTouch?.Dispose(); taskTouch = null; mdownd = 0; mdown = true; } } int oldMY = 0; protected virtual bool OnTouchMove(int x, int y) { if (mdown) { int moveX = oldX - x, moveY = oldY - y, moveXa = Math.Abs(moveX), moveYa = Math.Abs(moveY); oldMY = moveY; if (mdownd > 0) { if (mdownd == 1) OnTouchScrollY(-moveY); else OnTouchScrollX(-moveX); oldX = x; oldY = y; return false; } else if (moveXa > 2 || moveYa > 2) { if (moveYa > moveXa) { mdownd = 1; OnTouchScrollY(-moveY); } else { mdownd = 2; OnTouchScrollX(-moveX); } oldX = x; oldY = y; return false; } } return true; } ITask? taskTouch = null; protected virtual bool OnTouchUp() { taskTouch?.Dispose(); taskTouch = null; mdown = false; if (mdownd > 0) { if (mdownd == 1) { int moveY = oldMY, moveYa = Math.Abs(moveY); if (moveYa > 10) { // 缓冲动画 int duration = (int)Math.Ceiling(moveYa * .1F), incremental = moveYa / 2, sleep = 20; if (moveY > 0) { taskTouch = new ITask(this, () => { if (moveYa > 0 && OnTouchScrollY(-incremental)) { moveYa -= duration; return true; } return false; }, sleep); } else { taskTouch = new ITask(this, () => { if (moveYa > 0 && OnTouchScrollY(incremental)) { moveYa -= duration; return true; } return false; }, sleep); } } } return false; } return true; } protected virtual bool OnTouchScrollX(int value) => false; protected virtual bool OnTouchScrollY(int value) => false; protected override void OnMouseWheel(MouseEventArgs e) { taskTouch?.Dispose(); taskTouch = null; base.OnMouseWheel(e); } #endregion } public interface SubLayeredForm { ILayeredForm? SubForm(); } }