因为近来想写个类似于远程桌面监控的程序,该程序中要用到屏幕捕捉.为实现该程序的一部分功能,做了个小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();
}
到这里,代码就算是写完了,运行
截取结果,这里截取的边界没有控制好,所以还有边界可以见到,稍微设置一下就可以了
好了,这个东东就这样搞完了,接下来要做利用钩子的了....希望能够快点完成,累呀~~~~
新闻热点
疑难解答