直接贴代码,别让我再看到上次评论里的"怎么用啊?","能不能给我发份代码?"之类的屁话!
1
using System;
2
using System.ComponentModel;
3
using System.Collections.Generic;
4
using System.Diagnostics;
5
using System.Text;
6
using System.Drawing;
7
using System.Runtime.InteropServices;
8
using System.Windows.Forms;
9
10
namespace 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(0, 1);
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 阅读(1419)
评论(11) 编辑 收藏 所属分类:
.Net技术