在公司,不能自己安装软件,也不能下载,但有时候需要截图。用PrintScreen键只能截取全屏,感觉很麻烦。于是决定自己编写一个截图工具 。
众所周知,QQ截图首先将截取全屏为一个图片,然后用在这个图片基础上截取需要的部分。本程序实现方法类似。
程序运行截图如下:
概述:
在公司,不能自己安装软件,也不能下载,但有时候需要截图。用PrintScreen键只能截取全屏,感觉很麻烦。于是决定自己编写一个截图工具 。
众所周知,QQ截图首先将截取全屏为一个图片,然后用在这个图片基础上截取需要的部分。本程序实现方法类似。
程序运行截图如下:
图中心矩形为即将截取区域
程序很粗糙,希望大家提出宝贵意见。
1,自定义矩形类MyRectangle
在QQ截图程序中,用户用鼠标绘制出的截图区域是可调整大小和位置的,在4个边的中点和4个顶点各有一个小矩形标记。(如图所示)
.NET Framework中本身没有这样的矩形,因此要自定义实现。
考虑到类的专用性,不必实现.Net Framework2.0中Rectangle的全部功能。
该MyRectangle类图如下:
MyRectangle需包含如下
属性
int X 记录矩形左上角x坐标
int Y 记录矩形左上角y坐标
int DownPointX 绘制矩形时鼠标落点x坐标
int DownPointY 绘制矩形时鼠标落点y坐标
int Width 矩形宽
int Height 矩形高
int MinWidth 矩形最小宽度
int MinHeight 矩形最小高度
bool ChangeSizeMode 标识矩形当前绘制模式是否为“改变大小”
bool MoveMode 标识矩形当前绘制模式是否为“移动”
bool MouseOnLeftTop 标识鼠标当前位置是否在矩形左上角
bool MouseOnLeftMiddle 标识鼠标当前位置是否在矩形左边中点
bool MouseOnLeftBottom 标识鼠标当前位置是否在矩形左下角
bool MouseOnRightTop 标识鼠标当前位置是否在矩形右上角
bool MouseOnRightMiddle 标识鼠标当前位置是否在矩形右边中点
bool MouseOnRightBottom 标识鼠标当前位置是否在矩形右下角
bool MouseOnTopMiddle 标识鼠标当前位置是否在矩形顶边中点
bool MouseOnBottomMiddle 标识鼠标当前位置是否在矩形底边中点
bool MouseOnMiddle 标识鼠标当前位置是否在矩形中心
int LittleRectangleWidth 矩形周边8个小矩形的宽度
int LittleRectangleHeight 矩形周边8个小矩形的高度
Rectangle LeftTopRectangle 矩形左上角小矩形
Rectangle LeftMiddleRectangle 矩形左边中点小矩形
Rectangle LeftBottomRectangle 矩形左下角小矩形
Rectangle RightTopRectangle 矩形右上角小矩形
Rectangle RightMiddleRectangle 矩形右边中点小矩形
Rectangle RightBottomRectangle 矩形右下角小矩形
Rectangle TopMiddleRectangle 矩形顶边中点小矩形
Rectangle BottomMiddleRectangle 矩形底边中点小矩形
Rectangle Rect 主体矩形
Size Size 矩形大小
Image BackImage 背景图片
Cursor MyCursor 光标样式
矩形本身包含监测当前绘制模式和绘制方法,主要方法成员如下:
SetLittleRectangle() 设置8个小矩形
Draw(Color backColor) 绘制方法,+1重载
ChangeSize(MouseEventArgs e) 改变矩形大小
Move(int newX, int newY) 改变矩形位置
CheckMouseLocation(MouseEventArgs e) 判断鼠标当前落点
setAllModeFalse() 将所有模式设定为false
public bool onChangingMode() 判断当前绘制模式是否为“改变大小”或“移动”
Initialize(int x, int y, int width, int height) 根据给定参数初始化矩形
MyRectagle类代码实现如下:
MyRectangle.class
1class MyRectangle
2 {
3 /**//// <summary>
4 /// The x-coordinate of the upper-left corner of the main rectangle
5 /// </summary>
6 private int x;
7
8 /**//// <summary>
9 /// The star x-coordinate when you draw the main rectangle
10 /// </summary>
11 private int downPointX;
12
13 /**//// <summary>
14 /// The y-coordinate of the upper-left corner of the main rectangle
15 /// </summary>
16 private int y;
17
18 /**//// <summary>
19 /// The star y-coordinate when you draw the main rectangle
20 /// </summary>
21 private int downPointY;
22
23 /**//// <summary>
24 /// The width of the main rectangle
25 /// </summary>
26 private int width;
27
28 /**//// <summary>
29 /// The height of the main rectangle
30 /// </summary>
31 private int height;
32
33 /**//// <summary>
34 /// The least width of the main rectangle
35 /// </summary>
36 private int minWidth;
37
38 /**//// <summary>
39 /// The least height of the main rectangle
40 /// </summary>
41 private int minHeight;
42
43 /**//// <summary>
44 /// Sign the main rectangle is on change size mode or not
45 /// </summary>
46 private bool changeSizeMode;
47
48 /**//// <summary>
49 /// Sign the main rectangle is on move mode or not
50 /// </summary>
51 private bool moveMode;
52
53 /**//// <summary>
54 /// Sign the current mouse position is on the upper-left corner of the main rectangle or not
55 /// </summary>
56 private bool mouseOnLeftTop;
57 /**//// <summary>
58 /// Sign the current mouse position is on the middle point of the left line of the main rectangle or not
59 /// </summary>
60 private bool mouseOnLeftMiddle;
61 /**//// <summary>
62 /// Sign the current mouse position is on the bottom-left corner of the main rectangle or not
63 /// </summary>
64 private bool mouseOnLeftBottom;
65
66 /**//// <summary>
67 /// Sign the current mouse position is on the upper-right corner of the mian rectangle or not
68 /// </summary>
69 private bool mouseOnRightTop;
70 /**//// <summary>
71 /// 鼠标落点在右中点标志
72 /// </summary>
73 private bool mouseOnRightMiddle;
74 /**//// <summary>
75 /// Sign the current mouse position is on the middle point of the right line of the main rectangle or not
76 /// </summary>
77 private bool mouseOnRightBottom;
78
79 /**//// <summary>
80 /// Sign the current mouse position is on the middle point of the top line of the main rectangle or not
81 /// </summary>
82 private bool mouseOnTopMiddle;
83 /**//// <summary>
84 /// Sign the current mouse position is on the middle point of the bottom line of the main rectangle or not
85 /// </summary>
86 private bool mouseOnBottomMiddle;
87
88 /**//// <summary>
89 /// Sign the current mouse position is in the main rectangle or not
90 /// </summary>
91 private bool mouseOnMiddle;
92 /**//// <summary>
93 /// The width of the 8 little rectangles that on the 4 corners and the 4 middle points that of the 4 lines of the main rectangle
94 /// </summary>
95 private int littleRectangleWidth;
96 /**//// <summary>
97 /// The height of the 8 little rectangles that on the 4 corners and the 4 middle points that of the 4 lines of the main rectangle
98 /// </summary>
99 private int littleRectangleHeight;
100
101 /**//// <summary>
102 /// The little rectangle on the upper-left corner of the main rectangle
103 /// </summary>
104 private Rectangle leftTopRectangle;
105 /**//// <summary>
106 /// The little rectangle on the middle point of the left line of the main rectangle
107 /// </summary>
108 private Rectangle leftMiddleRectangle;
109 /**//// <summary>
110 /// The little rectangle on the bottom-left corner of the main rectangle
111 /// </summary>
112 private Rectangle leftBottomRectangle;
113
114 /**//// <summary>
115 /// The little rectangle on the upper-right corner of the main rectangle
116 /// </summary>
117 private Rectangle rightTopRectangle;
118 /**//// <summary>
119 /// The little rectangle on the middle point of the right line of the main rectangle
120 /// </summary>
121 private Rectangle rightMiddleRectangle;
122 /**//// <summary>
123 /// The little rectangle on the bottom-right corner of the main rectangle
124 /// </summary>
125 private Rectangle rightBottomRectangle;
126
127 /**//// <summary>
128 /// The little rectangle on the middle point of the top line of the main rectangle
129 /// </summary>
130 private Rectangle topMiddleRectangle;
131 /**//// <summary>
132 /// The little rectangle on the middle point of the bottom line of the main rectangle
133 /// </summary>
134 private Rectangle bottomMiddleRectangle;
135
136 /**//// <summary>
137 /// The main rectangle
138 /// </summary>
139 private Rectangle rect;
140
141 /**//// <summary>
142 /// The size of the main rectangle
143 /// </summary>
144 private Size size;
145
146 /**//// <summary>
147 /// The background image of the screen
148 /// </summary>
149 private Image backImage;
150
151 /**//// <summary>
152 /// The cursor manner
153 /// </summary>
154 private Cursor myCursor;
155
156 /**//// <summary>
157 /// Gets of sets the x-coordinate of the upper-left corner of the main rectangle
158 /// </summary>
159 public int X
160 {
161 get { return x; }
162 set
163 {
164 x = value;
165 rect.X = value;
166 }
167 }
168 /**//// <summary>
169 /// Gets of sets the y-coordinate of the upper-left corner of the main rectangle
170 /// </summary>
171 public int Y
172 {
173 get { return y; }
174 set
175 {
176 y = value;
177 rect.Y = value;
178 }
179 }
180
181 /**//// <summary>
182 /// Gets of sets the star x-coordinate when you draw the main rectangle
183 /// </summary>
184 public int DownPointX
185 {
186 get { return downPointX; }
187 set { downPointX = value; }
188 }
189 /**//// <summary>
190 /// Gets of sets the star y-coordinate when you draw the main rectangle
191 /// </summary>
192 public int DownPointY
193 {
194 get { return downPointY; }
195 set { downPointY = value; }
196 }
197 /**//// <summary>
198 /// Gets of sets the width of the main rectangle
199 /// </summary>
200 public int Width
201 {
202 get { return width; }
203 set
204 {
205 width = value;
206 rect.Width = value;
207 }
208 }
209 /**//// <summary>
210 /// Gets or sets the height of the main rectangle
211 /// </summary>
212 public int Height
213 {
214 get { return height; }
215 set
216 {
217 height = value;
218 rect.Height = value;
219 }
220 }
221
222 /**//// <summary>
223 /// Gets or sets the least width of the main rectangle
224 /// </summary>
225 public int MinWidth
226 {
227 get { return minWidth; }
228 set { minWidth = value; }
229 }
230
231 /**//// <summary>
232 /// Gets or sets the least height of the main rectangle
233 /// </summary>
234 public int MinHeight
235 {
236 get { return minHeight; }
237 set { minHeight = value; }
238 }
239
240 /**//// <summary>
241 /// Gets or sets the sign of the change size mode of the main rectangle
242 /// </summary>
243 public bool ChangeSizeMode
244 {
245 get { return changeSizeMode; }
246 set
247 {
248 changeSizeMode = value;
249 moveMode = !value;
250 }
251 }
252
253 /**//// <summary>
254 /// Gets or sets the sign of the move mode of the main rectangle
255 /// </summary>
256 public bool MoveMode
257 {
258 get { return moveMode; }
259 set
260 {
261 moveMode = value;
262 changeSizeMode = !value;
263 }
264 }
265
266 /**//// <summary>
267 /// Gets or sets the sign of current mouse position
268 /// (is on the upper-left corner of the main rectangle or not)
269 /// </summary>
270 public bool MouseOnLeftTop
271 {
272 get { return mouseOnLeftTop; }
273 set
274 {
275 mouseOnLeftTop = value;
276 if (value)
277 {
278 mouseOnLeftMiddle = false;
279 mouseOnLeftBottom = false;
280
281 mouseOnRightTop = false;
282 mouseOnRightMiddle = false;
283 mouseOnRightBottom = false;
284
285 mouseOnTopMiddle = false;
286 mouseOnBottomMiddle = false;
287
288 mouseOnMiddle = false;
289 }
290 }
291 }
292 /**//// <summary>
293 /// Gets or sets the sign of current mouse position
294 /// (is on the middle point of the left line of the main rectangle or not)
295 /// </summary>
296 public bool MouseOnLeftMiddle
297 {
298 get { return mouseOnLeftMiddle; }
299 set
300 {
301 mouseOnLeftMiddle = value;
302 if (value)
303 {
304 mouseOnLeftTop = false;
305 mouseOnLeftBottom = false;
306
307 mouseOnRightTop = false;
308 mouseOnRightMiddle = false;
309 mouseOnRightBottom = false;
310
311 mouseOnTopMiddle = false;
312 mouseOnBottomMiddle = false;
313
314 mouseOnMiddle = false;
315 }
316 }
317 }
318 /**//// <summary>
319 /// Gets or sets the sign of current mouse position
320 /// (is on the bottom-left corner of the main rectangle or not)
321 /// </summary>
322 public bool MouseOnLeftBottom
323 {
324 get { return mouseOnLeftBottom; }
325 set
326 {
327 mouseOnLeftBottom = value;
328 if (value)
329 {
330 mouseOnLeftTop = false;
331 mouseOnLeftMiddle = false;
332
333 mouseOnRightTop = false;
334 mouseOnRightMiddle = false;
335 mouseOnRightBottom = false;
336
337 mouseOnTopMiddle = false;
338 mouseOnBottomMiddle = false;
339
340 mouseOnMiddle = false;
341 }
342 }
343 }
344
345 /**//// <summary>
346 /// Gets or sets the sign of current mouse position
347 /// (is on the upper-right corner of the main rectangle or not)
348 /// </summary>
349 public bool MouseOnRightTop
350 {
351 get { return mouseOnRightTop; }
352 set
353 {
354 mouseOnRightTop = value;
355 if (value)
356 {
357 mouseOnLeftTop = false;
358 MouseOnLeftMiddle = false;
359 mouseOnLeftBottom = false;
360
361 mouseOnRightMiddle = false;
362 mouseOnRightBottom = false;
363
364 mouseOnTopMiddle = false;
365 mouseOnBottomMiddle = false;
366
367 mouseOnMiddle = false;
368 }
369 }
370 }
371 /**//// <summary>
372 /// Gets or sets the sign of current mouse position
373 /// (is on the middle point of the right line of the main rectangle or not)
374 /// </summary>
375 public bool MouseOnRightMiddle
376 {
377 get { return mouseOnRightMiddle; }
378 set
379 {
380 mouseOnRightMiddle = value;
381 if (value)
382 {
383 mouseOnLeftTop = false;
384 mouseOnLeftBottom = false;
385 mouseOnLeftMiddle = false;
386
387 mouseOnRightTop = false;
388 mouseOnRightBottom = false;
389
390 mouseOnTopMiddle = false;
391 mouseOnBottomMiddle = false;
392
393 mouseOnMiddle = false;
394 }
395 }
396 }
397 /**//// <summary>
398 /// Gets or sets the sign of current mouse position
399 /// (is on the bottom-right corner of the main rectangle or not)
400 /// </summary>
401 public bool MouseOnRightBottom
402 {
403 get { return mouseOnRightBottom; }
404 set
405 {
406 mouseOnRightBottom = value;
407 if (value)
408 {
409 mouseOnLeftTop = false;
410 mouseOnLeftBottom = false;
411 mouseOnLeftMiddle = false;
412
413 mouseOnRightTop = false;
414 mouseOnRightMiddle = false;
415
416 mouseOnTopMiddle = false;
417 mouseOnBottomMiddle = false;
418
419 mouseOnMiddle = false;
420 }
421 }
422 }
423
424 /**//// <summary>
425 /// Gets or sets the sign of current mouse position
426 /// (is on the middle point of the top line of the main rectangle or not)
427 /// </summary>
428 public bool MouseOnTopMiddle
429 {
430 get { return mouseOnTopMiddle; }
431 set
432 {
433 mouseOnTopMiddle = value;
434 if (value)
435 {
436 mouseOnLeftTop = false;
437 mouseOnLeftBottom = false;
438 mouseOnLeftMiddle = false;
439
440 mouseOnRightTop = false;
441 mouseOnRightBottom = false;
442 mouseOnRightMiddle = false;
443
444 mouseOnBottomMiddle = false;
445
446 mouseOnMiddle = false;
447 }
448 }
449 }
450 /**//// <summary>
451 /// Gets or sets the sign of current mouse position
452 /// (is on the middle point of the middle line of the main rectangle or not)
453 /// </summary>
454 public bool MouseOnBottomMiddle
455 {
456 get { return mouseOnBottomMiddle; }
457 set
458 {
459 mouseOnBottomMiddle = value;
460 if (value)
461 {
462 mouseOnLeftTop = false;
463 mouseOnLeftBottom = false;
464 mouseOnLeftMiddle = false;
465
466 mouseOnRightTop = false;
467 mouseOnRightBottom = false;
468 mouseOnRightMiddle = false;
469
470 mouseOnTopMiddle = false;
471
472 mouseOnMiddle = false;
473 }
474 }
475 }
476
477 /**//// <summary>
478 /// Gets or sets the sign of current mouse position
479 /// (is in the main rectangle or not)
480 /// </summary>
481 public bool MouseOnMiddle
482 {
483 get { return mouseOnMiddle; }
484 set
485 {
486 mouseOnMiddle = value;
487 if (value)
488 {
489 mouseOnLeftTop = false;
490 mouseOnLeftBottom = false;
491 mouseOnLeftMiddle = false;
492
493 mouseOnRightTop = false;
494 mouseOnRightBottom = false;
495 mouseOnRightMiddle = false;
496
497 mouseOnTopMiddle = false;
498 MouseOnBottomMiddle = false;
499 }
500 }
501 }
502 /**//// <summary>
503 /// Gets or sets the width of the 8 little rectangles
504 /// (rectangles that on the 4 corners and the 4 middle points that of the 4 lines of the main rectangle)
505 /// </summary>
506 public int LittleRectangleWidth
507 {
508 get { return littleRectangleWidth; }
509 set { littleRectangleWidth = value; }
510 }
511 /**//// <summary>
512 /// Gets or sets the height of the 8 little rectangles
513 /// (rectangles that on the 4 corners and the 4 middle points that of the 4 lines of the main rectangle)
514 /// </summary>
515 public int LittleRectangleHeight
516 {
517 get { return littleRectangleHeight; }
518 set { littleRectangleHeight = value; }
519 }
520
521 /**//// <summary>
522 /// Gets or sets he little rectangle on the upper-left corner of the main rectangle
523 /// </summary>
524 public Rectangle LeftTopRectangle
525 {
526 get { return leftTopRectangle; }
527 set { leftTopRectangle = value; }
528 }
529 /**//// <summary>
530 /// Gets or sets he little rectangle on the middle point of the left line of the main rectangle
531 /// </summary>
532 public Rectangle LeftMiddleRectangle
533 {
534 get { return leftMiddleRectangle; }
535 set { leftMiddleRectangle = value; }
536 }
537 /**//// <summary>
538 /// Gets or sets he little rectangle on the bottom-left corner of the main rectangle
539 /// </summary>
540 public Rectangle LeftBottomRectangle
541 {
542 get { return leftBottomRectangle; }
543 set { leftBottomRectangle = value; }
544 }
545
546 /**//// <summary>
547 /// Gets or sets he little rectangle on the upper-right corner of the main rectangle
548 /// </summary>
549 public Rectangle RightTopRectangle
550 {
551 get { return rightTopRectangle; }
552 set { rightTopRectangle = value; }
553 }
554 /**//// <summary>
555 /// Gets or sets he little rectangle on the middle point of the right line of the main rectangle
556 /// </summary>
557 public Rectangle RightMiddleRectangle
558 {
559 get { return rightMiddleRectangle; }
560 set { rightMiddleRectangle = value; }
561 }
562 /**//// <summary>
563 /// Gets or sets he little rectangle on the bottom-right corner of the main rectangle
564 /// </summary>
565 public Rectangle RightBottomRectangle
566 {
567 get { return rightBottomRectangle; }
568 set { rightBottomRectangle = value; }
569 }
570
571 /**//// <summary>
572 /// Gets or sets he little rectangle on the middle point of the top line of the main rectangle
573 /// </summary>
574 public Rectangle TopMiddleRectangle
575 {
576 get { return topMiddleRectangle; }
577 set { topMiddleRectangle = value; }
578 }
579 /**//// <summary>
580 /// Gets or sets he little rectangle on the middle point of the bottom line of the main rectangle
581 /// </summary>
582 public Rectangle BottomMiddleRectangle
583 {
584 get { return bottomMiddleRectangle; }
585 set { bottomMiddleRectangle = value; }
586 }
587
588 /**//// <summary>
589 /// Gets or sets the main rectangle
590 /// </summary>
591 public Rectangle Rect
592 {
593 get { return rect; }
594 set
595 {
596 rect = value;
597 x = value.X;
598 y = value.Y;
599 width = value.Width;
600 height = value.Height;
601 }
602 }
603
604 /**//// <summary>
605 /// Gets the size of the main rectangle
606 /// </summary>
607 public Size Size
608 {
609 get { return rect.Size; }
610 }
611
612 /**//// <summary>
613 /// Gets or sets the background image of the screen
614 /// </summary>
615 public Image BackImage
616 {
617 get { return backImage; }
618 set { backImage = value; }
619 }
620
621
622 /**//// <summary>
623 /// Gets or sets the manner of the cursor
624 /// </summary>
625 public Cursor MyCursor
626 {
627 get { return myCursor; }
628 set { myCursor = value; }
629 }
630
631
632 /**//// <summary>
633 /// Constructor function
634 /// </summary>
635 public MyRectangle()
636 {
637 Rect = new Rectangle();
638
639 setAllModeFalse();
640
641 LittleRectangleWidth = 4;
642 LittleRectangleHeight = 4;
643
644 MinHeight = 5;
645 MinWidth = 5;
646
647 LeftTopRectangle = new Rectangle();
648 LeftMiddleRectangle = new Rectangle();
649 LeftBottomRectangle = new Rectangle();
650
651 RightTopRectangle = new Rectangle();
652 RightMiddleRectangle = new Rectangle();
653 RightBottomRectangle = new Rectangle();
654
655 TopMiddleRectangle = new Rectangle();
656 BottomMiddleRectangle = new Rectangle();
657
658 MyCursor = new Cursor(@"..\..\Cursors\hcross.cur");
659
660 }
661
662 public void SetLittleRectangle()
663 {
664 int excursionX = LittleRectangleWidth / 2;
665 int excursionY = LittleRectangleHeight / 2;
666 LeftTopRectangle = new Rectangle(X - excursionX, Y - excursionY, LittleRectangleWidth, LittleRectangleHeight);
667 leftMiddleRectangle = new Rectangle(X - excursionX, Y - excursionY + Height / 2, LittleRectangleWidth, LittleRectangleHeight);
668 leftBottomRectangle = new Rectangle(X - excursionX, Y - excursionY + Height, LittleRectangleWidth, LittleRectangleHeight);
669
670 rightTopRectangle = new Rectangle(X - excursionX + Width, Y - excursionY, LittleRectangleWidth, LittleRectangleHeight);
671 rightMiddleRectangle = new Rectangle(X - excursionX + Width, Y - excursionY + Height / 2, LittleRectangleWidth, LittleRectangleHeight);
672 rightBottomRectangle = new Rectangle(X - excursionX + Width, Y - excursionY + Height, LittleRectangleWidth, LittleRectangleHeight);
673
674 topMiddleRectangle = new Rectangle(X - excursionX + Width / 2, Y - excursionY, LittleRectangleWidth, LittleRectangleHeight);
675 bottomMiddleRectangle = new Rectangle(X - excursionX + Width / 2, Y - excursionY + Height, LittleRectangleWidth, LittleRectangleHeight);
676 }
677
678 /**//// <summary>
679 /// draw rectangle function
680 /// </summary>
681 /// <param name="e">mouse event </param>
682 /// <param name="backColor">back color</param>
683 public void Draw(MouseEventArgs e, Color backColor)
684 {
685 Draw(backColor);
686 if (e.X < DownPointX)
687 {
688 Width = DownPointX - e.X;
689 X = e.X;
690 }
691 else
692 {
693 Width = e.X - DownPointX;
694 }
695 if (e.Y < DownPointY)
696 {
697 Height = DownPointY - e.Y;
698 Y = e.Y;
699 }
700 else
701 {
702 Height = e.Y - DownPointY;
703 }
704 Draw(backColor);
705 }
706 /**//// <summary>
707 /// draw rectangle function
708 /// </summary>
709 /// <param name="backColor">back color</param>
710 public void Draw(Color backColor)
711 {
712 //Initialize the 8 little rectangles
713 SetLittleRectangle();
714
715 //draw the main rectangle and the 8 little rectangles
716 ControlPaint.DrawReversibleFrame(rect, backColor, FrameStyle.Dashed);
717
718 ControlPaint.FillReversibleRectangle(leftTopRectangle, Color.White);
719 ControlPaint.FillReversibleRectangle(leftMiddleRectangle, Color.White);
720 ControlPaint.FillReversibleRectangle(leftBottomRectangle, Color.White);
721 ControlPaint.FillReversibleRectangle(rightTopRectangle, Color.White);
722 ControlPaint.FillReversibleRectangle(rightMiddleRectangle, Color.White);
723 ControlPaint.FillReversibleRectangle(rightBottomRectangle, Color.White);
724 ControlPaint.FillReversibleRectangle(topMiddleRectangle, Color.White);
725 ControlPaint.FillReversibleRectangle(bottomMiddleRectangle, Color.White);
726 }
727
728 /**//// <summary>
729 /// change size when the rectangle is on the change size mode
730 /// </summary>
731 /// <param name="e"></param>
732 public void ChangeSize(MouseEventArgs e)
733 {
734 //change size according the mouse location
735 if (ChangeSizeMode)
736 {
737
738 if (MouseOnLeftTop)
739 {
740 if ((Rect.Right - e.X < MinWidth) || (Rect.Bottom - e.Y < MinHeight))
741 {
742 return;
743 }
744 Width = Math.Abs(Rect.Right - e.X);
745 Height = Math.Abs(Rect.Bottom - e.Y);
746 X = e.X;
747 Y = e.Y;
748 }
749 else if (MouseOnLeftMiddle)
750 {
751 if (Rect.Right - e.X < MinWidth)
752 {
753 return;
754 }
755 else
756 {
757 Width = Math.Abs(Rect.Right - e.X);
758 X = e.X;
759 }
760 }
761 else if (MouseOnLeftBottom)
762 {
763 if (Rect.Right - e.X < MinWidth || e.Y - Rect.Top < MinHeight)
764 {
765 return;
766 }
767 Width = Math.Abs(Rect.Right - e.X);
768 Height = Math.Abs(e.Y - Rect.Top);
769 X = e.X;
770 }
771 else if (MouseOnRightTop)
772 {
773 if (e.X - Rect.Left < MinWidth || Rect.Bottom - e.Y < MinHeight)
774 {
775 return;
776 }
777 Width = Math.Abs(e.X - X);
778 Height = Math.Abs(Rect.Bottom - e.Y);
779 Y = e.Y;
780 }
781 else if (MouseOnRightMiddle)
782 {
783 if (e.X - Rect.Left < MinWidth)
784 {
785 return;
786 }
787 Width = Math.Abs(e.X - X);
788
789 }
790 else if (MouseOnRightBottom)
791 {
792 if (e.X - Rect.Left < MinWidth || e.Y - Rect.Top < MinHeight)
793 {
794 return;
795 }
796 Width = Math.Abs(e.X - X);
797 Height = Math.Abs(e.Y - Y);
798 }
799 else if (MouseOnTopMiddle)
800 {
801 if (Rect.Bottom - e.Y < MinHeight)
802 {
803 return;
804 }
805 Height = Math.Abs(Rect.Bottom - e.Y);
806 Y = e.Y;
807 }
808 else if (MouseOnBottomMiddle)
809 {
810 if (e.Y - Rect.Top < MinHeight)
811 {
812 return;
813 }
814 Height = Math.Abs(e.Y - Y);
815 }
816
817 }
818 }
819
820 /**//// <summary>
821 /// move the location of the rectangle
822 /// </summary>
823 /// <param name="newX">The x-coordinate of the new location</param>
824 /// <param name="newY">The y-coordinate of the new location</param>
825 public void Move(int newX, int newY)
826 {
827 X = newX;
828 Y = newY;
829 }
830
831 /**//// <summary>
832 /// check the current mouse location and set the cursor manner according the mouse location
833 /// </summary>
834 /// <param name="e">mouse</param>
835 public void CheckMouseLocation(MouseEventArgs e)
836 {
837 if (leftTopRectangle.Contains(e.X, e.Y))
838 {
839 if (!onChangingMode())
840 {
841 MouseOnLeftTop = true;
842 myCursor = new Cursor(@"..\..\Cursors\size2_m.cur");
843 }
844
845 if (e.Button == MouseButtons.Left)
846 {
847 if (!MoveMode)
848 {
849 ChangeSizeMode = true;
850 }
851 }
852 else
853 {
854 changeSizeMode = false;
855 moveMode = false;
856 }
857 }
858 else if (leftMiddleRectangle.Contains(e.X, e.Y))
859 {
860 if (!onChangingMode())
861 {
862 MouseOnLeftMiddle = true;
863 myCursor = new Cursor(@"..\..\Cursors\size3_m.cur");
864 }
865
866 if (e.Button == MouseButtons.Left)
867 {
868 if (!MoveMode)
869 {
870 ChangeSizeMode = true;
871 }
872 }
873 else
874 {
875 changeSizeMode = false;
876 moveMode = false;
877 }
878 }
879 else if (leftBottomRectangle.Contains(e.X, e.Y))
880 {
881 if (!onChangingMode())
882 {
883 MouseOnLeftBottom = true;
884 myCursor = new Cursor(@"..\..\Cursors\size1_m.cur");
885 }
886
887 if (e.Button == MouseButtons.Left)
888 {
889 if (!MoveMode)
890 {
891 ChangeSizeMode = true;
892 }
893 }
894 else
895 {
896 changeSizeMode = false;
897 moveMode = false;
898 }
899 }
900
901 else if (rightTopRectangle.Contains(e.X, e.Y))
902 {
903 mouseOnLeftBottom = false;
904
905 if (!onChangingMode())
906 {
907 MouseOnRightTop = true;
908 myCursor = new Cursor(@"..\..\Cursors\size1_m.cur");
909 }
910
911 mouseOnMiddle = false;
912
913 if (e.Button == MouseButtons.Left)
914 {
915 if (!MoveMode)
916 {
917 ChangeSizeMode = true;
918 }
919 }
920 else
921 {
922 changeSizeMode = false;
923 moveMode = false;
924 }
925 }
926 else if (rightMiddleRectangle.Contains(e.X, e.Y))
927 {
928 if (!onChangingMode())
929 {
930 MouseOnRightMiddle = true;
931 myCursor = new Cursor(@"..\..\Cursors\size3_m.cur");
932 }
933
934 if (e.Button == MouseButtons.Left)
935 {
936 if (!MoveMode)
937 {
938 ChangeSizeMode = true;
939 }
940 }
941 else
942 {
943 changeSizeMode = false;
944 moveMode = false;
945 }
946 }
947 else if (rightBottomRectangle.Contains(e.X, e.Y))
948 {
949 if (!onChangingMode())
950 {
951 MouseOnRightBottom = true;
952 myCursor = new Cursor(@"..\..\Cursors\size2_m.cur");
953 }
954
955 if (e.Button == MouseButtons.Left)
956 {
957 if (!MoveMode)
958 {
959 ChangeSizeMode = true;
960 }
961 }
962 else
963 {
964 changeSizeMode = false;
965 moveMode = false;
966 }
967 }
968 else if (topMiddleRectangle.Contains(e.X, e.Y))
969 {
970
971 if (!onChangingMode())
972 {
973 MouseOnTopMiddle = true;
974 myCursor = new Cursor(@"..\..\Cursors\size4_m.cur");
975 }
976
977
978 if (e.Button == MouseButtons.Left)
979 {
980 if (!MoveMode)
981 {
982 ChangeSizeMode = true;
983 }
984 }
985 else
986 {
987 changeSizeMode = false;
988 moveMode = false;
989 }
990 }
991 else if (bottomMiddleRectangle.Contains(e.X, e.Y))
992 {
993 if (!onChangingMode())
994 {
995 MouseOnBottomMiddle = true;
996 myCursor = new Cursor(@"..\..\Cursors\size4_m.cur");
997 }
998
999 if (e.Button == MouseButtons.Left)
1000 {
1001 if (!MoveMode)
1002 {
1003 ChangeSizeMode = true;
1004 }
1005 }
1006 else
1007 {
1008 changeSizeMode = false;
1009 moveMode = false;
1010 }
1011 }
1012 else if (rect.Contains(e.X, e.Y))
1013 {
1014
1015 if (!changeSizeMode)
1016 {
1017 MouseOnMiddle = true;
1018 myCursor = new Cursor(@"..\..\Cursors\move_m.cur");
1019 }
1020 if (e.Button == MouseButtons.Left)
1021 {
1022 if (!ChangeSizeMode)
1023 {
1024 MoveMode = true;
1025 }
1026 }
1027 else
1028 {
1029 moveMode = false;
1030 changeSizeMode = false;
1031 }
1032 }
1033 else
1034 {
1035 if (e.Button != MouseButtons.Left)
1036 {
1037 setAllModeFalse();
1038
1039 myCursor = new Cursor(@"..\..\Cursors\hcross.cur");
1040 }
1041 }
1042 }
1043 public bool Contains(int x, int y)
1044 {
1045 if (rect.Contains(x, y))
1046 {
1047 return true;
1048 }
1049 else return false;
1050 }
1051
1052 /**//// <summary>
1053 /// set all mode false
1054 /// (the sign of the mouse location and the change size mode ,move mode)
1055 /// </summary>
1056 public void setAllModeFalse()
1057 {
1058 mouseOnLeftTop = false;
1059 mouseOnLeftMiddle = false;
1060 mouseOnLeftBottom = false;
1061
1062 mouseOnRightTop = false;
1063 mouseOnRightMiddle = false;
1064 mouseOnRightBottom = false;
1065
1066 mouseOnTopMiddle = false;
1067 mouseOnBottomMiddle = false;
1068
1069 mouseOnMiddle = false;
1070 changeSizeMode = false;
1071 moveMode = false;
1072 myCursor = new Cursor(@"..\..\Cursors\hcross.cur");
1073 }
1074
1075 /**//// <summary>
1076 /// check whether the rectangle is on change mode now
1077 /// </summary>
1078 /// <returns></returns>
1079 public bool onChangingMode()
1080 {
1081 return ((MouseOnLeftTop || MouseOnLeftMiddle || mouseOnLeftBottom || mouseOnRightTop || mouseOnRightMiddle || MouseOnRightBottom || mouseOnTopMiddle || MouseOnBottomMiddle) && changeSizeMode);
1082 }
1083
1084 /**//// <summary>
1085 /// Initialize the rectangle
1086 /// </summary>
1087 /// <param name="x">The x-coordinate of the rectangle</param>
1088 /// <param name="y">The y-coordinate of the rectangle</param>
1089 /// <param name="width">The width of the rectangle</param>
1090 /// <param name="height">The height of the rectangle</param>
1091 public void Initialize(int x, int y, int width, int height)
1092 {
1093 X = x;
1094 Y = y;
1095 Width = width;
1096 Height = height;
1097 SetLittleRectangle();
1098 }
1099 }
2,建立截图主窗口
核心类MyRectangle已经完成,剩下的工作就是使用改类实现预想的截图功能。
用VS2005 新建Project,命名为ScreenCutter。将主窗口命名为MainForm,新建一个窗口命名为ScreenBody,将其 ShowInTaskbar属性设置为False,TopMost属性设置为True,FormBorderStyle属性设置为None,在 ScreenBody上添加一个panel控件panel1,设置BackColor属性为蓝色,在panel1上添加相应个数的label,如 labelLocation、labelWidth、labelHeight等,用于指示当前选区位置和大小,panel1最终样式为:
修改ScreenBody的引用命名空间为:
using System;
using System.Drawing;
using System.Windows.Forms;
在ScreenBody类中添加如下私有成员:
private Graphics MainPainter; //the main painter
private bool isDowned; //check whether the mouse is down
private bool RectReady; //check whether the rectangle is finished
private Image baseImage; //the back ground of the screen
private Point moveModeDownPoint; //the mouse location when you move the rectangle
private MyRectangle myRectangle; //the rectangle
private bool moveMode; //check whether the rectangle is on move mode or not
private bool changeSizeMode; //check whether the rectangle is on change size mode or not
修改ScreenBody构造函数:
public ScreenBody()
{
InitializeComponent();
panel1.Location = new Point(this.Left, this.Top);
myRectangle = new MyRectangle();
moveModeDownPoint = new Point();
this.Cursor = myRectangle.MyCursor;
}
添加ScreenBody窗口的DoubleClick、MouseDown、MouseUp、MouseMove及Load事件代码:
private void ScreenBody_DoubleClick(object sender, EventArgs e)
{
if (((MouseEventArgs)e).Button == MouseButtons.Left && myRectangle.Contains(((MouseEventArgs)e).X, ((MouseEventArgs)e).Y))
{
panel1.Visible = false;
MainPainter.DrawImage(baseImage, 0, 0);
Image memory = new Bitmap(myRectangle.Width, myRectangle.Height);
Graphics g = Graphics.FromImage(memory);
g.CopyFromScreen(myRectangle.X, myRectangle.Y, 0, 0, myRectangle.Size);
Clipboard.SetImage(memory);
this.Close();
}
}
private void ScreenBody_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
isDowned = true;
if (!RectReady)
{
myRectangle.DownPointX = e.X;
myRectangle.DownPointY = e.Y;
myRectangle.X = e.X;
myRectangle.Y = e.Y;
}
if (RectReady == true)
{
moveModeDownPoint = new Point(e.X, e.Y);
}
}
if (e.Button == MouseButtons.Right)
{
if (!RectReady)
{
this.Close();
return;
}
MainPainter.DrawImage(baseImage, 0, 0);
myRectangle.Initialize(0, 0, 0, 0);
myRectangle.setAllModeFalse();
this.Cursor = myRectangle.MyCursor;
RectReady = false;
}
}
private void ScreenBody_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
isDowned = false;
RectReady = true;
}
}
private void ScreenBody_MouseMove(object sender, MouseEventArgs e)
{
labelWidth.Text = myRectangle.Width.ToString();
labelHeight.Text = myRectangle.Height.ToString();
labelLocation.Text = "X "+myRectangle.X.ToString() + ", Y " + myRectangle.Y.ToString();
if (!RectReady)
{
if (isDowned)
{
myRectangle.Draw(e, this.BackColor);
}
}
else
{
myRectangle.CheckMouseLocation(e);
this.Cursor = myRectangle.MyCursor;
this.changeSizeMode = myRectangle.ChangeSizeMode;
this.moveMode = myRectangle.MoveMode&&myRectangle.Contains(moveModeDownPoint.X,moveModeDownPoint.Y);
if (changeSizeMode)
{
this.moveMode = false;
myRectangle.Draw(BackColor);
myRectangle.ChangeSize(e);
myRectangle.Draw(BackColor);
}
if (moveMode)
{
this.changeSizeMode = false;
myRectangle.Draw(BackColor);
myRectangle.X = myRectangle.X + e.X - moveModeDownPoint.X;
myRectangle.Y = myRectangle.Y + e.Y - moveModeDownPoint.Y;
moveModeDownPoint.X = e.X;
moveModeDownPoint.Y = e.Y;
myRectangle.Draw(this.BackColor);
}
}
}
private void ScreenBody_Load(object sender, EventArgs e)
{
this.WindowState = FormWindowState.Maximized;
MainPainter = this.CreateGraphics();
isDowned = false;
baseImage = this.BackgroundImage;
panel1.Visible = true;
RectReady = false;
changeSizeMode = false;
moveMode = false;
}
为了不至截到panel1,添加panel1的MouseEnter事件如下:
private void panel1_MouseEnter(object sender, EventArgs e)
{
if (panel1.Location==new Point(this.Left,this.Top))
{
panel1.Location = new Point(this.Right-panel1.Width, this.Top);
}
else
{
panel1.Location = new Point(this.Left,this.Top);
}
}
至此,ScreenBody窗口完成,QQ截图功能可以通过热键触发,下面为本程序添加热键
3,创建热键类
网上有许多这方面的资料,本程序中这段代码取自互联网,如有版权问题请给我留言,我会尽快删除。
添加类HotKey
HotKey.cs文件内容如下
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace ScreenCutter
{
class HotKey
{
//如果函数执行成功,返回值不为0。
//如果函数执行失败,返回值为0。要得到扩展错误信息,调用GetLastError。
[DllImport("user32.dll", SetLastError = true)]
public static extern bool RegisterHotKey(
IntPtr hWnd, //要定义热键的窗口的句柄
int id, //定义热键ID(不能与其它ID重复)
uint fsModifiers, //标识热键是否在按Alt、Ctrl、Shift、Windows等键时才会生效
Keys vk //定义热键的内容
);
[DllImport("user32.dll", SetLastError = true)]
public static extern bool UnregisterHotKey(
IntPtr hWnd, //要取消热键的窗口的句柄
int id //要取消热键的ID
);
//定义了辅助键的名称(将数字转变为字符以便于记忆,也可去除此枚举而直接使用数值)
[Flags()]
public enum KeyModifiers
{
None = 0,
Alt = 1,
Ctrl = 2,
Shift = 4,
WindowsKey = 8
}
}
}
4,使用热键及托盘区图标
为了使程序更方便使用,程序启动的时候最下化到托盘区,在按下程序热键时会启动截图功能。这些功能在程序的主窗口MainForm类中实现。
为了在托盘区显示图标,为MainForm添加一个NotifyIcon控件,为其指定一Icon图标,并设定visable属性为true
为了实现可以更改热键,首先在项目属性的Setting中添加如下图成员:
MainForm.cs文件代码如下:
using System;
using System.Drawing;
using System.Windows.Forms;
using System.ComponentModel;
using ScreenCutter.Properties;
namespace ScreenCutter
{
public enum KeyModifiers //组合键枚举
{
None = 0,
Alt = 1,
Control = 2,
Shift = 4,
Windows = 8
}
public partial class MainForm : Form
{
private ContextMenu contextMenu1;
private MenuItem menuItem1;
private MenuItem menuItem2;
private ScreenBody body;
public MainForm()
{
InitializeComponent();
this.components = new Container();
this.contextMenu1 = new ContextMenu();
this.menuItem2 = new MenuItem();
this.menuItem1 = new MenuItem();
this.contextMenu1.MenuItems.AddRange(
new MenuItem[] { this.menuItem1,this.menuItem2 });
this.menuItem1.Index = 1;
this.menuItem1.Text = "E&xit";
this.menuItem1.Click += new EventHandler(this.menuItem1_Click);
this.menuItem2.Index = 0;
this.menuItem2.Text = "S&et HotKey";
this.menuItem2.Click += new EventHandler(this.menuItem2_Click);
notifyIcon1.ContextMenu = this.contextMenu1;
notifyIcon1.Text = "Screen Cutter";
notifyIcon1.Visible = true;
body = null;
}
private void MainForm_SizeChanged(object sender, EventArgs e)
{
if (this.WindowState == FormWindowState.Minimized)
{
this.Hide();
this.notifyIcon1.Visible = true;
}
}
private void CutScreen()
{
Image img = new Bitmap(Screen.AllScreens[0].Bounds.Width, Screen.AllScreens[0].Bounds.Height);
Graphics g = Graphics.FromImage(img);
g.CopyFromScreen(new Point(0, 0), new Point(0, 0), Screen.AllScreens[0].Bounds.Size);
body = new ScreenBody();
body.BackgroundImage = img;
body.Show();
}
private void ProcessHotkey(Message m) //按下设定的键时调用该函数
{
IntPtr id = m.WParam; //IntPtr用于表示指针或句柄的平台特定类型
string sid = id.ToString();
switch (sid)
{
case "100":
CutScreen();
break;
default:
break;
}
}
private void MainForm_Load(object sender, EventArgs e)
{
uint ctrHotKey = (uint)KeyModifiers.Control;
if (Settings.Default.isAltHotKey)
{
ctrHotKey =(uint)(KeyModifiers.Alt | KeyModifiers.Control);
}
HotKey.RegisterHotKey(Handle, 100, ctrHotKey, Settings.Default.HotKey);//这时热键为Alt+CTRL+A
}
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
HotKey.UnregisterHotKey(Handle, 100);//卸载第1个快捷键
}
//重写WndProc()方法,通过监视系统消息,来调用过程
protected override void WndProc(ref Message m)//监视Windows消息
{
const int WM_HOTKEY = 0x0312;//如果m.Msg的值为0x0312那么表示用户按下了热键
switch (m.Msg)
{
case WM_HOTKEY:
ProcessHotkey(m);//按下热键时调用ProcessHotkey()函数
break;
}
base.WndProc(ref m); //将系统消息传递自父类的WndProc
}
private void menuItem1_Click(object Sender, EventArgs e)
{
HotKey.UnregisterHotKey(Handle, 100);//卸载第1个快捷键
this.notifyIcon1.Visible = false;
this.Close();
}
private void menuItem2_Click(object Sender, EventArgs e)
{
SetHotKey setHotKey = new SetHotKey();
setHotKey.ShowDialog();
}
}
}
5,添加设定热键功能:
新建窗口,命名为SetHotkey,该窗口样式及主要控件命名如下图所示
设定窗口主体FormBorderStyle属性值为FixedToolWindow,Text属性为SetHotKey,MaximizeBox和MinimizeBox属性为false。
添加checkBox1的(ApplicationSettings)-(PropertyBinding)-Checked为isCtrlHotKey,CheckState为Checked,Enable属性为false,Text属性为Ctrl
添加checkBox2的(ApplicationSettings)-(PropertyBinding)-Checked为isAltHotKey,CheckState为Checked,Enable属性为true,Text属性为Alt
comboBox1的Items值为
A
Z
X
为按钮btnDefault添加click事件
private void btnDefault_Click(object sender, EventArgs e)
{
Settings.Default.HotKey = Keys.A;
Settings.Default.Save();
this.Close();
}
为按钮btnOk添加click事件
private void btnOK_Click(object sender, EventArgs e)
{
switch (comboBox1.SelectedIndex)
{
case 0:
Settings.Default.HotKey = Keys.A;
break;
case 1:
Settings.Default.HotKey = Keys.Z;
break;
case 2:
Settings.Default.HotKey = Keys.X;
break;
default:
break;
}
Settings.Default.Save();
this.Close();
}
为按钮btnCancel添加click事件
private void btnCancel_Click(object sender, EventArgs e)
{
this.Close();
}
为SetHotkey窗口添加load事件
private void SetHotKey_Load(object sender, EventArgs e)
{
comboBox1.Text = Settings.Default.HotKey.ToString();
}
6,防止程序多次运行
同样,网上有许多这方面的资料,本部分代码基本来自互联网,如有版权问题请给我留言,我将立即删除
为防止程序多次运行,修改Program.cs文件内容如下:
using System;
using System.Reflection;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace ScreenCutter
{
static class Program
{
[DllImport("User32.dll")]
private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
[DllImport("User32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
private const int WS_SHOWNORMAL = 1;
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Process instance = RunningInstance();
if (instance == null)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
else
{
HandleRunningInstance(instance);
}
}
public static Process RunningInstance()
{
Process current = Process.GetCurrentProcess();
Process[] processes = Process.GetProcessesByName(current.ProcessName);
//Loop through the running processes in with the same name
foreach (Process process in processes)
{
//Ignore the current process
if (process.Id != current.Id)
{
//Make sure that the process is running from the exe file.
if (Assembly.GetExecutingAssembly().Location.Replace("/", """) ==
current.MainModule.FileName)
{
//Return the other process instance.
return process;
}
}
}
//No other instance was found, return null.
return null;
}
public static void HandleRunningInstance(Process instance)
{
//Make sure the window is not minimized or maximized
ShowWindowAsync(instance.MainWindowHandle, WS_SHOWNORMAL);
//Set the real intance to foreground window
SetForegroundWindow(instance.MainWindowHandle);
}
}
}
至此,该截图程序基本完成,实现了类似QQ截图的功能。(默认热键为Ctrl+Alt+A)
注意:程序中用到了一些图片,Icon文件和cur文件,请复制系统目录(C:"WINDOWS"Cursors)下的hcross.cur、 move_m.cur、size1_m.cur、size2_m.cur、size3_m.cur、size4_m.cur文件到.." ScreenCutter"ScreenCutter"Cursors目录下,在.."ScreenCutter"ScreenCutter"Icons 目录下添加相应图标,在.."ScreenCutter"ScreenCutter"Images目录下添加相应图片。如路径不同,请在代码中自行更改。
感谢您的关注,愿您留下宝贵意见。
感谢博友们的关注,现奉上源代码。另注:这个程序是我刚刚学习C#时候写的,难免有不专业的地方,希望多多包含,更希望不要被误导。