因为近来想写个类似于远程桌面监控的程序,该程序中要用到屏幕捕捉.为实现该程序的一部分功能,做了个小DEMO.程序很简单,用到的技术也不多,只能实现类似qq的截图功能(方法虽然很笨)程序流程如下:1.截取整个屏幕并保存2.新开一个全屏窗口,将保存的屏幕作为背景3.鼠标拖动改变截取范围,右键取消4.双击截取,保存在粘贴板,全屏窗口关闭好了,下面的是代码部分首先新建一个项目ScreenCutter(VS2005),将窗体名改为MainForm,再新建一个窗体ScreenBody.添加一个按钮btnCutter到ScreenCutter并添加按钮事件:
private
void
btnCutter_Click(
object
sender, EventArgs e) { 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);
ScreenBody body
=
new
ScreenBody(); body.BackgroundImage
=
img;
body.Show(); }
Screen.AllScreens[0]是获取当前所有设备窗口的第一个,我这里只有一个显示器,当然我就是第一个.利用Graphics的CopyFromScreen函数获取当前屏幕.好了,现在按下按钮全屏窗口就会出来了.下面讲全屏窗口ScreenBody,首先设置窗体的FormBorderStyle为None,然后声明以下变量
private
Graphics MainPainter; //主画笔
private
Pen pen; //就是笔咯
private
bool
isDowned; //判断鼠标是否按下
private
bool
RectReady; //矩形是否绘制完成
private
Image baseImage; //基本图形(原来的画面)
private
Rectangle Rect; //就是要保存的矩形
private
Point downPoint; //鼠标按下的点
int
tmpx;
int
tmpy;
之后就是窗体的鼠标函数了,里面很多代码都没有作出整理,看了一下,整理后的代码应该会更少更精简的
private
void
ScreenBody_DoubleClick(
object
sender, EventArgs e){
if
(((MouseEventArgs)e).Button
==
MouseButtons.Left
&&
Rect.Contains(((MouseEventArgs)e).X, ((MouseEventArgs)e).Y)) { //保存的时候有很多种方法的......我这里只用了这种 Image memory
=
new
Bitmap(Rect.Width, Rect.Height); Graphics g
=
Graphics.FromImage(memory); g.CopyFromScreen(Rect.X
+
1
, Rect.Y
+
1
,
0
,
0
, Rect.Size);
Clipboard.SetImage(memory);
this
.Close(); }}
private
void
ScreenBody_MouseDown(
object
sender, MouseEventArgs e){
if
(e.Button
==
MouseButtons.Left) { isDowned
=
true
;
if
(RectReady
==
false
) { Rect.X
=
e.X; Rect.Y
=
e.Y; downPoint
=
new
Point(e.X, e.Y); }
if
(RectReady
==
true
) { tmpx
=
e.X; tmpy
=
e.Y; }
}
if
(e.Button
==
MouseButtons.Right) {
if
(RectReady
!=
true
) {
this
.Close();
return
; } MainPainter.
DrawImage(baseImage,
0
,
0
); 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){
if
(RectReady
==
false
) {
if
(isDowned
==
true
) { Image New
=
DrawScreen((Image)baseImage.Clone(), e.X, e.Y); MainPainter.DrawImage(New,
0
,
0
); New.Dispose(); } }
if
(RectReady
==
true
) {
if
(Rect.Contains(e.X, e.Y)) {
//
this.Cursor = Cursors.Hand;
if
(isDowned
==
true
) {
//
和上一次的位置比较获取偏移量
Rect.X
=
Rect.X
+
e.X
-
tmpx; Rect.Y
=
Rect.Y
+
e.Y
-
tmpy;
//
记录现在的位置
tmpx
=
e.X; tmpy
=
e.Y; MoveRect((Image)baseImage.Clone(), Rect); } }
} }
private
void
ScreenBody_Load(
object
sender, EventArgs e){
this
.WindowState
=
FormWindowState.Maximized; MainPainter
=
this
.CreateGraphics(); pen
=
new
Pen(Brushes.Blue); isDowned
=
false
; baseImage
=
this
.BackgroundImage; Rect
=
new
Rectangle(); RectReady
=
false
;
}
辅助函数本来应该写更多的辅助函数的,将窗体响应函数里面的代码放到里面来,不过本人很懒,就这样将就了.呵呵
private
void
DrawRect(Graphics Painter,
int
Mouse_x,
int
Mouse_y){
int
width
=
0
;
int
heigth
=
0
;
if
(Mouse_y
<
Rect.Y) { Rect.Y
=
Mouse_y; heigth
=
downPoint.Y
-
Mouse_y; }
else
{ heigth
=
Mouse_y
-
downPoint.Y; }
if
(Mouse_x
<
Rect.X) { Rect.X
=
Mouse_x; width
=
downPoint.X
-
Mouse_x; }
else
{ width
=
Mouse_x
-
downPoint.X; } Rect.Size
=
new
Size(width, heigth); Painter.DrawRectangle(pen, Rect);}
private
Image DrawScreen(Image back,
int
Mouse_x,
int
Mouse_y){ Graphics Painter
=
Graphics.FromImage(back); DrawRect(Painter, Mouse_x, Mouse_y);
return
back;}
private
void
MoveRect(Image image, Rectangle Rect){ Graphics Painter
=
Graphics.FromImage(image); Painter.DrawRectangle(pen, Rect.X, Rect.Y, Rect.Width, Rect.Height); DrawRects(Painter); MainPainter.DrawImage(image,
0
,
0
); image.Dispose();}
到这里,代码就算是写完了,运行截取结果,这里截取的边界没有控制好,所以还有边界可以见到,稍微设置一下就可以了好了,这个东东就这样搞完了,接下来要做利用钩子的了....希望能够快点完成,累呀~~~~
转载请注明原文地址: https://ibbs.8miu.com/read-25359.html