首页 > 开发 > 综合 > 正文

C#实现类似qq的屏幕截图程序

2024-07-21 02:26:24
字体:
来源:转载
供稿:网友

因为近来想写个类似于远程桌面监控的程序,该程序中要用到屏幕捕捉.为实现该程序的一部分功能,做了个小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();
}

到这里,代码就算是写完了,运行





截取结果,这里截取的边界没有控制好,所以还有边界可以见到,稍微设置一下就可以了



好了,这个东东就这样搞完了,接下来要做利用钩子的了....希望能够快点完成,累呀~~~~


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表