• C#贴边自动隐藏组件完美版


          直接贴代码,别让我再看到上次评论里的"怎么用啊?","能不能给我发份代码?"之类的屁话!
      1using System;
      2using System.ComponentModel;
      3using System.Collections.Generic;
      4using System.Diagnostics;
      5using System.Text;
      6using System.Drawing;
      7using System.Runtime.InteropServices;
      8using System.Windows.Forms;
      9
     10namespace autoDockWindow
     11{
     12    [Description("窗体自动靠边隐藏完美组件 @Author: Red_angelX")]
     13    public partial class autoDockManager : Component
     14    {
     15        private Form _form;
     16
     17        public autoDockManager()
     18        {
     19            InitializeComponent();
     20        }

     21
     22        public autoDockManager(IContainer container)
     23        {
     24            container.Add(this);
     25            InitializeComponent();
     26        }

     27
     28        [Description("用于控制要自动Dock的窗体")]
     29        public Form dockForm
     30        {
     31            get
     32            {
     33                return _form;
     34            }

     35            set
     36            {
     37                _form = value;
     38                if (_form != null)
     39                {
     40                    if (_form.TopMost == false)
     41                        _form.TopMost = true;
     42
     43                    if (DesignMode)
     44                        return;
     45
     46                    nativeDockWindow dockWindow = new nativeDockWindow();
     47                    dockWindow.AssignHandle(_form.Handle);
     48                }

     49            }

     50        }

     51    }

     52
     53    public class nativeDockWindow : NativeWindow
     54    {
     55        IntPtr handle = IntPtr.Zero;
     56        Form baseForm = null;
     57
     58        const int HM_NONE = 0;   //不收缩
     59        const int HM_TOP = 1;   //向上收缩
     60        const int HM_BOTTOM = 2;   //向下收缩
     61        const int HM_LEFT = 3;   //向左收缩
     62        const int HM_RIGHT = 4;   //向右收缩
     63
     64        const int INTERVAL = 20;  //触发粘附的最小间隔,单位为象素
     65        const int INFALTE = 4;  //触发收缩的小间隔,单位为象素
     66
     67
     68        bool m_isWndHide = false;       //窗口是否隐藏
     69        bool m_isSizeChanged = false;   //窗口大小是否改变了 
     70        bool m_isSetTimer = false;      //窗口大小是否改变了
     71        int m_oldWndHeight;    //旧的窗口宽度
     72        int m_hideMode = HM_NONE;         //隐藏模式
     73
     74        Timer checkTimer = new Timer();    //定时器
     75
     76        protected override void OnHandleChange()
     77        {
     78            handle = this.Handle;
     79            if (handle != IntPtr.Zero)
     80            {
     81                baseForm = (Form)Form.FromHandle(handle);
     82                checkTimer.Interval = 200;
     83                checkTimer.Tick +=new EventHandler(checkTimer_Tick);
     84            }

     85            base.OnHandleChange();
     86        }

     87
     88        //修正移动时窗口的大小
     89        void FixMoving(ref Message m)
     90        {
     91            //已经隐藏了的情况
     92            if (m_hideMode != HM_NONE && m_isWndHide == true)
     93            {
     94                return;
     95            }

     96
     97            if (Control.MousePosition.Y <= INTERVAL)
     98            {   //粘附在上边
     99                m_hideMode = HM_TOP;
    100            }

    101            else if (Control.MousePosition.Y >= (Screen.PrimaryScreen.Bounds.Width - INTERVAL))
    102            {   //粘附在下边
    103                m_hideMode = HM_BOTTOM;
    104            }

    105            else if (Control.MousePosition.X < INTERVAL)
    106            {    //粘附在左边    
    107                if (!m_isSizeChanged)
    108                {
    109                    m_oldWndHeight = baseForm.Height;
    110                }

    111                m_isSizeChanged = true;
    112                m_hideMode = HM_LEFT;
    113            }

    114            else if (Control.MousePosition.X >= (Screen.PrimaryScreen.Bounds.Width - INTERVAL))
    115            {   //粘附在右边
    116                if (!m_isSizeChanged)
    117                {
    118                    m_oldWndHeight = baseForm.Height;
    119                }

    120                m_isSizeChanged = true;
    121                m_hideMode = HM_RIGHT;
    122            }

    123            else
    124            {   //不粘附
    125
    126                if (m_isSizeChanged)
    127                {   //如果收缩到两边,则拖出来后会变回原来大小
    128                    //在"拖动不显示窗口内容下"只有光栅变回原来大小
    129                    int left = Marshal.ReadInt32(m.LParam, sizeof(int* 0);
    130                    int top = Marshal.ReadInt32(m.LParam, sizeof(int* 1);
    131                    int right = Marshal.ReadInt32(m.LParam, sizeof(int* 2);
    132                    Marshal.WriteInt32(m.LParam, sizeof(int* 0, left); // left
    133                    Marshal.WriteInt32(m.LParam, sizeof(int* 1, top); // top
    134                    Marshal.WriteInt32(m.LParam, sizeof(int* 2, right); // right
    135                    Marshal.WriteInt32(m.LParam, sizeof(int* 3, top + m_oldWndHeight); // bottom
    136                    m_isSizeChanged = false;
    137                }

    138                if (m_isSetTimer)
    139                {   //如果Timer开启了,则关闭之
    140                    checkTimer.Stop();
    141                    m_isSetTimer = false;
    142                }

    143                m_isWndHide = false;
    144                m_hideMode = HM_NONE;
    145            }

    146        }

    147
    148        //从收缩状态显示窗口
    149        void DoShow()
    150        {
    151            if (m_hideMode == HM_NONE || !m_isWndHide)
    152                return;
    153
    154            switch (m_hideMode)
    155            {
    156                case HM_TOP:
    157                    baseForm.Location = new Point(baseForm.Location.X, 0);
    158                    m_isWndHide = false;
    159                    break;
    160                case HM_BOTTOM:
    161                    //不处理
    162                    //m_isWndHide = false;
    163                    break;
    164                case HM_LEFT:
    165                    baseForm.Location = new Point(01);
    166                    m_isWndHide = false;
    167                    break;
    168                case HM_RIGHT:
    169                    baseForm.Location = new Point(Screen.PrimaryScreen.Bounds.Width - baseForm.Width, 1);
    170                    m_isWndHide = false;
    171                    break;
    172                default:
    173                    break;
    174            }

    175        }

    176
    177        //从显示状态收缩窗口
    178        void DoHide()
    179        {
    180            if (m_hideMode == HM_NONE || m_isWndHide)
    181                return;
    182
    183            switch (m_hideMode)
    184            {
    185                case HM_TOP:
    186                    //此句必须放在MoveWindow之上,否则大小变成m_wndRect,其他case同样        
    187                    m_isWndHide = true;
    188                    baseForm.Location = new Point(baseForm.Location.X, (baseForm.Height - INFALTE) * (-1));
    189                    break;
    190                case HM_BOTTOM:
    191                    //m_isWndHide = true;
    192                    break;
    193                case HM_LEFT:
    194                    m_isWndHide = true;
    195                    baseForm.Size = new Size(baseForm.Width, Screen.PrimaryScreen.WorkingArea.Height);
    196                    baseForm.Location = new Point((-1* (baseForm.Width - INFALTE), 1);
    197                    break;
    198                case HM_RIGHT:
    199                    m_isWndHide = true;
    200                    baseForm.Size = new Size(baseForm.Width, Screen.PrimaryScreen.WorkingArea.Height);
    201                    baseForm.Location = new Point(Screen.PrimaryScreen.Bounds.Width - INFALTE, 1);
    202                    break;
    203                default:
    204                    break;
    205            }

    206        }

    207
    208
    209        const UInt32 SWP_NOSIZE = 0x0001;
    210        const UInt32 SWP_NOMOVE = 0x0002;
    211        const UInt32 SWP_NOZORDER = 0x0004;
    212        const UInt32 SWP_NOREDRAW = 0x0008;
    213        const UInt32 SWP_NOACTIVATE = 0x0010;
    214        const UInt32 SWP_FRAMECHANGED = 0x0020;  // The frame changed: send WM_NCCALCSIZE 
    215        const UInt32 SWP_SHOWWINDOW = 0x0040;
    216        const UInt32 SWP_HIDEWINDOW = 0x0080;
    217        const UInt32 SWP_NOCOPYBITS = 0x0100;
    218        const UInt32 SWP_NOOWNERZORDER = 0x0200;  // Don't do owner Z ordering 
    219        const UInt32 SWP_NOSENDCHANGING = 0x0400// Don't send WM_WINDOWPOSCHANGING 
    220
    221        [DllImport("user32.dll")]
    222        static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X,
    223           int Y, int cx, int cy, uint uFlags);
    224
    225        [DllImport("user32.dll")]
    226        [return: MarshalAs(UnmanagedType.Bool)]
    227        static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
    228
    229        //这个结构在改lparam时要用到
    230        [StructLayout(LayoutKind.Sequential)]
    231        public struct RECT
    232        {
    233            public int Left;
    234            public int Top;
    235            public int Right;
    236            public int Bottom;
    237        }

    238
    239        [DllImport("user32.dll")]
    240        [return: MarshalAs(UnmanagedType.Bool)]
    241        static extern bool GetCursorPos(out Point lpPoint);
    242
    243        [DllImport("user32.dll")]
    244        static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth,
    245           int nHeight, bool bRepaint);
    246
    247        [DllImport("user32.dll")]
    248        static extern bool InflateRect(ref RECT lprc, int dx, int dy);
    249
    250        [DllImport("user32.dll")]
    251        static extern bool PtInRect([In] ref RECT lprc, Point pt);
    252
    253
    254        private void checkTimer_Tick(object sender, EventArgs e)
    255        {
    256            RECT tRect;
    257            //获取此时窗口大小
    258            GetWindowRect(this.Handle, out tRect);
    259            //膨胀tRect,以达到鼠标离开窗口边沿一定距离才触发事件
    260            InflateRect(ref tRect, INFALTE, INFALTE);
    261
    262            if (!PtInRect(ref tRect, Control.MousePosition))   //如果鼠标离开了这个区域
    263            {
    264                checkTimer.Stop();
    265                m_isSetTimer = false;
    266                DoHide();  //隐藏
    267            }

    268        }

    269
    270        const int WM_NCHITTEST = 0x84;
    271        const int WM_MOVING = 0x216;
    272        const int WM_MOVE = 0x3;
    273        const int WM_SIZING = 0x214;
    274        const int HTCAPTION = 0x0002;
    275        const int WM_EXITSIZEMOVE = 0x232;
    276        const int WM_ENTERSIZEMOVE = 0x231;
    277        const int WM_SYSCOMMAND = 0x112;
    278        const int SC_SIZE = 0xF000;
    279        const int WM_SETTINGCHANGE = 0x1A;
    280
    281        protected override void WndProc(ref Message m)
    282        {
    283            if (m.Msg == WM_NCHITTEST)
    284            {
    285                if (m_hideMode != HM_NONE && !m_isSetTimer)
    286                {   //鼠标进入时,如果是从收缩状态到显示状态则开启Timer
    287                    checkTimer.Start();
    288                    m_isSetTimer = true;
    289                    DoShow();
    290                }

    291            }

    292            else if (m.Msg == WM_MOVING)
    293            {                
    294                FixMoving(ref m);
    295            }

    296            else if(m.Msg == WM_ENTERSIZEMOVE)
    297            {
    298                baseForm.SuspendLayout();
    299            }

    300            else if (m.Msg == WM_EXITSIZEMOVE)
    301            {
    302                baseForm.ResumeLayout();
    303            }

    304            base.WndProc(ref m);
    305        }

    306    }

    307}

    308
  • 相关阅读:
    SpringBoot实现原理
    常见Http状态码大全
    forward(转发)和redirect(重定向)有什么区别
    1094. Car Pooling (M)
    0980. Unique Paths III (H)
    1291. Sequential Digits (M)
    0121. Best Time to Buy and Sell Stock (E)
    1041. Robot Bounded In Circle (M)
    0421. Maximum XOR of Two Numbers in an Array (M)
    0216. Combination Sum III (M)
  • 原文地址:https://www.cnblogs.com/Red_angelX/p/1235377.html
Copyright © 2020-2023  润新知