直接贴代码,别让我再看到上次评论里的"怎么用啊?","能不能给我发份代码?"之类的屁话!
  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
posted on 2008-07-04 11:12  Red_angelX  阅读(4356)  评论(14编辑  收藏  举报