直接贴代码,别让我再看到上次评论里的"怎么用啊?","能不能给我发份代码?"之类的屁话!
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
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 autoDockWindow11
{12
[Description("窗体自动靠边隐藏完美组件 @Author: Red_angelX")]13
public partial class autoDockManager : Component14
{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 dockForm30
{31
get32
{33
return _form;34
}35
set36
{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 : NativeWindow54
{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
else124
{ //不粘附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); // left133
Marshal.WriteInt32(m.LParam, sizeof(int) * 1, top); // top134
Marshal.WriteInt32(m.LParam, sizeof(int) * 2, right); // right135
Marshal.WriteInt32(m.LParam, sizeof(int) * 3, top + m_oldWndHeight); // bottom136
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 RECT232
{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
{ //鼠标进入时,如果是从收缩状态到显示状态则开启Timer287
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



浙公网安备 33010602011771号