// *********************************************************************** // Assembly : HZH_Controls // Created : 08-08-2019 // // *********************************************************************** // // Copyright by Huang Zhenghui(黄正辉) All, QQ group:568015492 QQ:623128629 Email:623128629@qq.com // // // Blog: https://www.cnblogs.com/bfyx // GitHub:https://github.com/kwwwvagaa/NetWinformControl // gitee:https://gitee.com/kwwwvagaa/net_winform_custom_control.git // // If you use this code, please keep this note. // *********************************************************************** using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace HZH_Controls.Forms { /// /// 功能描述:停靠窗体 /// 作  者:HZH /// 创建日期:2019-02-27 11:49:03 /// 任务编号:POS /// /// /// public partial class FrmAnchor : Form, IMessageFilter { /// /// The m parent control /// Control m_parentControl = null; /// /// The BLN down /// private bool blnDown = true; /// /// The m size /// Size m_size; /// /// The m deviation /// Point? m_deviation; /// /// The m is not focus /// bool m_isNotFocus = true; #region 构造函数 /// /// 功能描述:构造函数 /// 作  者:HZH /// 创建日期:2019-02-27 11:49:08 /// 任务编号:POS /// /// 父控件 /// 子控件 /// 偏移 /// 是否无焦点窗体 public FrmAnchor(Control parentControl, Control childControl, Point? deviation = null,bool isNotFocus=true) { m_isNotFocus = isNotFocus; m_parentControl = parentControl; InitializeComponent(); this.Size = childControl.Size; this.HandleCreated += FrmDownBoard_HandleCreated; this.HandleDestroyed += FrmDownBoard_HandleDestroyed; this.Controls.Add(childControl); childControl.Dock = DockStyle.Fill; m_size = childControl.Size; m_deviation = deviation; if (parentControl.FindForm() != null) { Form frmP = parentControl.FindForm(); if (!frmP.IsDisposed) { frmP.LocationChanged += frmP_LocationChanged; } } parentControl.LocationChanged += frmP_LocationChanged; } /// /// Initializes a new instance of the class. /// /// The parent control. /// The size. /// The deviation. /// if set to true [is not focus]. public FrmAnchor(Control parentControl, Size size, Point? deviation = null, bool isNotFocus = true) { m_isNotFocus = isNotFocus; m_parentControl = parentControl; InitializeComponent(); this.Size = size; this.HandleCreated += FrmDownBoard_HandleCreated; this.HandleDestroyed += FrmDownBoard_HandleDestroyed; m_size = size; m_deviation = deviation; } /// /// Handles the LocationChanged event of the frmP control. /// /// The source of the event. /// The instance containing the event data. void frmP_LocationChanged(object sender, EventArgs e) { this.Hide(); } #endregion /// /// Handles the HandleDestroyed event of the FrmDownBoard control. /// /// The source of the event. /// The instance containing the event data. private void FrmDownBoard_HandleDestroyed(object sender, EventArgs e) { Application.RemoveMessageFilter(this); } /// /// Handles the HandleCreated event of the FrmDownBoard control. /// /// The source of the event. /// The instance containing the event data. private void FrmDownBoard_HandleCreated(object sender, EventArgs e) { Application.AddMessageFilter(this); } #region 无焦点窗体 /// /// Sets the active window. /// /// The handle. /// IntPtr. [System.Runtime.InteropServices.DllImport("user32.dll")] private extern static IntPtr SetActiveWindow(IntPtr handle); /// /// The wm activate /// private const int WM_ACTIVATE = 0x006; /// /// The wm activateapp /// private const int WM_ACTIVATEAPP = 0x01C; /// /// The wm ncactivate /// private const int WM_NCACTIVATE = 0x086; /// /// The wa inactive /// private const int WA_INACTIVE = 0; /// /// The wm mouseactivate /// private const int WM_MOUSEACTIVATE = 0x21; /// /// The ma noactivate /// private const int MA_NOACTIVATE = 3; /// /// WNDs the proc. /// /// 要处理的 Windows 。 protected override void WndProc(ref Message m) { if (m_isNotFocus) { if (m.Msg == WM_MOUSEACTIVATE) { m.Result = new IntPtr(MA_NOACTIVATE); return; } else if (m.Msg == WM_NCACTIVATE) { if (((int)m.WParam & 0xFFFF) != WA_INACTIVE) { if (m.LParam != IntPtr.Zero) { SetActiveWindow(m.LParam); } else { SetActiveWindow(IntPtr.Zero); } } } } base.WndProc(ref m); } #endregion /// /// 在调度消息之前将其筛选出来。 /// /// 要调度的消息。无法修改此消息。 /// 如果筛选消息并禁止消息被调度,则为 true;如果允许消息继续到达下一个筛选器或控件,则为 false。 public bool PreFilterMessage(ref Message m) { if (m.Msg != 0x0201 || this.Visible == false) return false; var pt = this.PointToClient(MousePosition); this.Visible = this.ClientRectangle.Contains(pt); return false; } /// /// Handles the Load event of the FrmAnchor control. /// /// The source of the event. /// The instance containing the event data. private void FrmAnchor_Load(object sender, EventArgs e) { } /// /// Handles the VisibleChanged event of the FrmAnchor control. /// /// The source of the event. /// The instance containing the event data. private void FrmAnchor_VisibleChanged(object sender, EventArgs e) { timer1.Enabled = this.Visible; if (this.Visible) { Point p = m_parentControl.Parent.PointToScreen(m_parentControl.Location); int intX = 0; int intY = 0; if (p.Y + m_parentControl.Height + m_size.Height > Screen.PrimaryScreen.Bounds.Height) { intY = p.Y - m_size.Height - 1; blnDown = false; } else { intY = p.Y + m_parentControl.Height + 1; blnDown = true; } if (p.X + m_size.Width > Screen.PrimaryScreen.Bounds.Width) { intX = Screen.PrimaryScreen.Bounds.Width - m_size.Width; } else { intX = p.X; } if (m_deviation.HasValue) { intX += m_deviation.Value.X; intY += m_deviation.Value.Y; } this.Location = new Point(intX, intY); } } /// /// Handles the Tick event of the timer1 control. /// /// The source of the event. /// The instance containing the event data. private void timer1_Tick(object sender, EventArgs e) { if (this.Owner != null) { Form frm = this.Owner as Form; IntPtr _ptr = ControlHelper.GetForegroundWindow(); if (_ptr != frm.Handle && _ptr!=this.Handle) { this.Hide(); } } } } }