WinForm下屏幕截图程序的实现

        截图程序的代码参考了一个印度人的博客还有周银辉的博客, 这两位都是用WPF做的, 在截图的时候半透明遮罩都是用的WPF里的Canvas, 但WinForm里没有这个控件, 我想出了另一个办法.

        大致思路是按截图按钮后, 打开另一个Form, 这个Form没有边框, 初始就是最大化占满整个屏幕, 背景色为白色, 透明度为50%. 这样就差不多是个半透明遮罩的效果了, 在任务栏显示图标这个属性也要设为false, 大概这样大家就明白我的意思了. 而在截取屏幕部分图像时, 这部分的半透明色彩要恢复成屏幕这部分的真面目, 所以我想了一个办法, 把这个窗口的TransParencyKey设为CornflowerBlue, 然后在屏幕上画CornflowerBlue这个颜色的矩形框, 这样就可以把这个框框部位的颜色变成屏幕的颜色了. 效果如下图:

 

        那个矩形框是这样绘制出来的:

private void Form2_MouseDown(object sender, MouseEventArgs e)
{
    x = MousePosition.X;
    y = MousePosition.Y;
    isMouthDown = true;
}

private void Form2_MouseMove(object sender, MouseEventArgs e)
{
    if (isMouthDown)
    {
        width = Math.Abs(MousePosition.X - x);
        height = Math.Abs(MousePosition.Y - y);
        g = CreateGraphics();
        g.Clear(BackColor);
        g.FillRectangle(Brushes.CornflowerBlue, x<MousePosition.X?x:MousePosition.X, y<MousePosition.Y?y:MousePosition.Y, width + 1, height + 1);
    }
}

private void Form2_MouseUp(object sender, MouseEventArgs e)
{
    nowX = MousePosition.X + 1;
    nowY = MousePosition.Y + 1;
    this.Close();
    formMain.pcurrentWin.Snap(x < nowX ? x : nowX, y < nowY ? y : nowY, Math.Abs(nowX - x), Math.Abs(nowY - y));//开始截图
    formMain.pcurrentWin.Show();
}

        周博客里提到的用这样的绘图方式在单显示器里效果还行, 双显示器里有明显的滞后感...我没有双显示器的环境, 希望有心人帮我测试一下在双显示器里画这个框框有没有滞后感. 但实际上在我电脑上运行的时候, 当鼠标移动重绘这个矩形时, 尽管没有所谓的滞后感, 但还是比较耗CPU的. 不知道Windows7桌面上的半透明蓝色矩形框是用什么技巧画出来的?

        另外我发现了这两个人写的CopyFromScreen貌似写的都有一点问题, 比如周是这样写的:

g.CopyFromScreen(rc.X, rc.Y, 0, 0, rc.Size, CopyPixelOperation.SourceCopy);

        我后来也是传进这几个参数的, 但发现截全屏的时候, 比如我的显示器是1280*800, 截到的却总是1279*799这么大, 并且如果在屏幕的左上角(0, 0)单击一下, 却是截取的整个屏幕! 所以我后来把这个矩形的长宽都加上了1, 于是正常了...但尚不清楚这是为何(特别是单击左上角接触整个屏幕这个情况).

        程序界面(部分功能还未写):

程序下载: ScreenSnap.zip

代码下载: ScreenSnapCode.zip

posted @ 2010-08-31 20:27  Create Chen  阅读(...)  评论(...编辑  收藏