C# winform窗体自动停靠控件

网上的那个很早以前就发布出来了...觉得很不好用

是用系统api做的

我改了下.思路大体上还是差不多

窗口改变位置时改变一下停靠类型

然后时钟事件判断鼠标是否在窗口内.如果窗口隐藏且鼠标在窗体中,则显示,反之则隐藏

具体看代码吧.不是很完美(没有更好的去做时钟的停止启动优化)....反正功能是实现了

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;


namespace AutoDockWindow
{
    public partial class AutoDockManager : UserControl
    {
        private Form _form;
        private int _timerInterval = 250;

        public AutoDockManager()
        {
            InitializeComponent();
        }

        public AutoDockManager(IContainer container)
        {
            container.Add(this);
            this.Hide();
            InitializeComponent();
        }


        [Description("Timer控件的事件间隔 小于100不启动")]
        public int TimerInterval
        {
            get
            {
                return _timerInterval;
            }
            set
            {
                _timerInterval = value;
                //dockWindow.TimerInterval = value;
                if (_form != null && Convert.ToInt32(_timerInterval) > 100)
                {
                    if (_form.TopMost == false)
                        _form.TopMost = true;

                    if (DesignMode)
                        return;
                    nativeDockWindow dockWindow = new nativeDockWindow(_timerInterval);
                    dockWindow.AssignHandle(_form.Handle);
                }
            }
        }


        [Description("用于控制要自动Dock的窗体")]
        public Form dockForm
        {
            get
            {
                return _form;
            }
            set
            {
                _form = value;

            }
        }


    }

    public class nativeDockWindow : NativeWindow
    {
        IntPtr handle = IntPtr.Zero;
        Form baseForm = null;

        Timer checkTimer = new Timer();    //定时器

        private int _timerInterval;
        public nativeDockWindow(int timerInterval)
        {
            _timerInterval = timerInterval;
        }


        /// <summary>
        /// 贴边设置
        /// </summary>
        internal AnchorStyles StopAanhor = AnchorStyles.None;


        protected override void OnHandleChange()
        {
            handle = this.Handle;
            if (handle != IntPtr.Zero)
            {
                baseForm = (Form)Form.FromHandle(handle);
                checkTimer.Interval = _timerInterval;
                checkTimer.Tick += new EventHandler(checkTimer_Tick);
                checkTimer.Start();

                baseForm.LocationChanged += new System.EventHandler(BaseForm_LocationChanged);//给baseForm中的事件注册方法
                baseForm.SizeChanged += new System.EventHandler(BaseForm_SizeChanged);//给baseForm中的事件注册方法
                //baseForm.Deactivate += new System.EventHandler(BaseForm_Deactivate);//给baseForm中的事件注册方法
            }
            base.OnHandleChange();
        }

        private void BaseForm_LocationChanged(object sender, EventArgs e)
        {
            this.mStopAnthor();
        }
        //private void BaseForm_Deactivate(object sender, EventArgs e)
        //{
        //    checkTimer.Start();
            
        //}

        private FormWindowState lastWindowState = FormWindowState.Normal;
        private void BaseForm_SizeChanged(object sender, EventArgs e)
        {
            if (baseForm.WindowState == FormWindowState.Minimized)
            {
                NormalToMinimized();
                checkTimer.Stop();
                lastWindowState = FormWindowState.Minimized;
            }
            else if (baseForm.WindowState == FormWindowState.Maximized)
            {
                checkTimer.Stop();
                lastWindowState = FormWindowState.Maximized;

            }
            else if (baseForm.WindowState == FormWindowState.Normal)
            {
                if (lastWindowState == FormWindowState.Minimized)
                {
                    checkTimer.Stop();
                }
                else
                {
                    checkTimer.Start();
                
                }
                lastWindowState = FormWindowState.Normal;

            }
        }

        private void checkTimer_Tick(object sender, EventArgs e)
        {
            //checkTimer.Stop();
            //MessageBox.Show(_timerInterval.ToString());
            //baseForm.Text = _timerInterval.ToString();
            //_timerInterval += 1;

            if (baseForm.Bounds.Contains(Cursor.Position))
            {
                //checkTimer.Start(); //鼠标进入时,如果是从收缩状态到显示状态则开启Timer
                this.FormShow();

            }
            else
            {
                //checkTimer.Stop();
                this.FormHide();
            }
        }

        #region 窗口停靠位置计算
        /// <summary>
        /// 窗口停靠位置计算
        /// </summary>
        private void mStopAnthor()
        {
            if (baseForm.Top <= 0)
            {
                checkTimer.Stop(); 
                StopAanhor = AnchorStyles.Top;
                checkTimer.Start();  //靠边则开始
            }
            else if (baseForm.Left <= 0)
            {
                checkTimer.Stop(); 
                StopAanhor = AnchorStyles.Left;
                checkTimer.Start();  //靠边则开始
            }
            else if (baseForm.Left >= Screen.PrimaryScreen.Bounds.Width - baseForm.Width)
            {
                checkTimer.Stop(); 
                StopAanhor = AnchorStyles.Right;
                checkTimer.Start();  //靠边则开始
            }
            //else if (baseForm.Top + baseForm.Height >= Screen.PrimaryScreen.Bounds.Height)
            //{
            //    checkTimer.Stop();
            //    StopAanhor = AnchorStyles.Bottom;
            //    checkTimer.Start();  //靠边则开始
            //}
            else
            {
                checkTimer.Stop();  //不靠边则停止
                StopAanhor = AnchorStyles.None;
            }
        }
        #endregion

        #region 窗口最小化到默认
        /// <summary>
        /// 窗口最小化到默认
        /// </summary>
        private void MinimizedToNormal()
        {
            //baseForm.Visible = true;
            baseForm.WindowState = FormWindowState.Normal;
            checkTimer.Start();
            //notifyIcon1.Visible = false;
        }
        #endregion

        #region 窗口默认到最小化
        /// <summary>
        /// 窗口默认到最小化
        /// </summary>
        private void NormalToMinimized()
        {
            baseForm.WindowState = FormWindowState.Minimized;
            //baseForm.Visible = false;
            checkTimer.Stop();
        }
        #endregion

        #region 窗体不贴边显示
        /// <summary>
        /// 窗体不贴边显示
        /// </summary>
        private void FormShow()
        {
            switch (this.StopAanhor)
            {
                case AnchorStyles.Top:
                    baseForm.Location = new Point(baseForm.Location.X, 0);
                    break;
                case AnchorStyles.Left:
                    baseForm.Location = new Point(0, baseForm.Location.Y);
                    break;
                case AnchorStyles.Right:
                    baseForm.Location = new Point(Screen.PrimaryScreen.Bounds.Width - baseForm.Width, baseForm.Location.Y);
                    break;
                //case AnchorStyles.Bottom:
                //    baseForm.Location = new Point(baseForm.Location.X, baseForm.Location.Y - baseForm.Height);
                //    break;
            }
        }
        #endregion

        #region 窗体贴边隐藏
        /// <summary>
        /// 窗体贴边隐藏
        /// </summary>
        private void FormHide()
        {
            switch (this.StopAanhor)
            {
                case AnchorStyles.Top:
                    baseForm.Location = new Point(baseForm.Location.X, (baseForm.Height - 2) * (-1));
                    break;
                case AnchorStyles.Left:
                    baseForm.Location = new Point((-1) * (baseForm.Width - 2), baseForm.Location.Y);
                    break;
                case AnchorStyles.Right:
                    baseForm.Location = new Point(Screen.PrimaryScreen.Bounds.Width - 2, baseForm.Location.Y);
                    break;
                //case AnchorStyles.Bottom:
                //    baseForm.Location = new Point(baseForm.Location.X, Screen.PrimaryScreen.Bounds.Height + baseForm.Height - 2);
                //    break;
            }
        }
        #endregion




    }
}
原文地址:https://www.cnblogs.com/DoNetCShap/p/2445864.html