// ***********************************************************************
// 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();
}
}
}
}
}