如题

解决方案 »

  1.   

    (1).首先要创建一个和当前屏幕大小相同的Bitmap对象:  要实现此操作,首先就要现获得当前显示器的DC,然后根据此DC来创建Graphic对象,再由此Graphic对象产生此位图对象。这样产生的位图对象才是和当前屏幕大小相一致的。由于要获得显示器的DC,利用.Net的类库是无法实现的,这需要调用一个Windows的API函数。我们知道视窗所有API都封装在"Kernel"、"User "和"GDI"三个库中文件中:其中"Kernel",他的库名为 "KERNEL32.DLL"。"User "这个类库在Win32中名叫 "USER32.DLL"。 它主要管理全部的用户接口。譬如:窗口 、菜单 、对话框 、图标等等。"GDI"(图象设备接口),它在Win32中的库名为:"GDI32.dll",要获得显示器的DC,所调用的API函数--CreateDC ( ),就被封装在此类库中。而要在C#中声明视窗的API函数需要使用.Net FrameWork SDK中的名字空间"System.Runtime.InteropServices",此名字空间提供了一系列的类来访问COM对象,和调用本地的API函数。下面是在C#中声明此函数:[ System.Runtime.InteropServices.DllImportAttribute ( "gdi32.dll" ) ]
    private static extern IntPtr CreateDC (
    string lpszDriver , // 驱动名称
    string lpszDevice , // 设备名称
    string lpszOutput , // 无用,可以设定位"NULL"
    IntPtr lpInitData // 任意的打印机数据
    ) ;
    在C#中声明过此API函数,就可以创建和显示器大小一致的位图对象,具体实现语句如下:
    IntPtr dc1 = CreateDC ( "DISPLAY" , null , null , ( IntPtr ) null ) ;
    //创建显示器的DC
    Graphics g1 = Graphics.FromHdc ( dc1 ) ;
    //由一个指定设备的句柄创建一个新的Graphics对象
    MyImage = new Bitmap ( Screen.PrimaryScreen.Bounds.Width , Screen.PrimaryScreen.Bounds.Height , g1 ) ;
    //根据屏幕大小创建一个与之相同大小的Bitmap对象   (2).根据此位图创建一个和其一样的Graphic对象:  通过下面代码就可以实现此功能:Graphics g2 = Graphics.FromImage ( MyImage ) ;   (3).获得当前屏幕和位图的句柄:  获得此二个对象的句柄是为了下一步实现对当前屏幕图象的捕获,程序中实现的具体捕获的方法是把当前屏幕捕获到已经创建的位图对象中。具体实现代码如下://获得屏幕的句柄
    IntPtr dc3 = g1.GetHdc ( ) ;
    //获得位图的句柄
    IntPtr dc2 = g2.GetHdc ( ) ;
    //把当前屏幕捕获到位图对象中   (4).捕获当前屏幕:  我们是通过当前屏幕保存到创建的位图对象中来实现的,具体的实现过程中是通过Windows的一个API函数--Bitblt。我想大多数程序员对此API函数一定不陌生,因为在Windows的图象编程中,会在很多地方使用到此函数。这个API函数和上面介绍的那个API函数一样,也是被封装在"GDI32.dll"中的,下面是此函数在C#中的声明:[ System.Runtime.InteropServices.DllImportAttribute ( "gdi32.dll" ) ]
    private static extern bool BitBlt (
    IntPtr hdcDest , // 目标设备的句柄
    int nXDest , // 目标对象的左上角的X坐标
    int nYDest , // 目标对象的左上角的X坐标
    int nWidth , // 目标对象的矩形的宽度
    int nHeight , // 目标对象的矩形的长度
    IntPtr hdcSrc , // 源设备的句柄
    int nXSrc , // 源对象的左上角的X坐标
    int nYSrc , // 源对象的左上角的X坐标
    System.Int32 dwRop // 光栅的操作值
    ) ;
    知道了此声明就可以实现对当前屏幕的保存了,具体如下:
    BitBlt ( dc2 , 0 , 0 , Screen.PrimaryScreen.Bounds.Width , Screen.PrimaryScreen.Bounds.Height , dc3 , 0 , 0 , 13369376 ) ;   (5).把当前屏幕保存到硬盘,并释放句柄:g1.ReleaseHdc ( dc3 ) ;
    //释放屏幕句柄
    g2.ReleaseHdc ( dc2 ) ;
    //释放位图句柄
    MyImage.Save ( "c:\\MyJpeg.jpg" , ImageFormat.Jpeg ) ;   我们可以根据自己的要求把当前屏幕以不同的文件格式来保存,在本文中介绍的程序是以"jpg"文件来保存的,你可以通过修改"Save"方法的第二个参数来改变保存到硬盘的文件类型,譬如,如果第二个参数为"ImageFormat.Gif",那么你保存到硬盘的文件就为"GIF"文件了。对于其他文件格式可以参考.Net FrameWork SDK,里面有详细的介绍。三. 用C#做Screen Capture程序的代码和运行节目:  在掌握了上面这些重要步骤后,可以得到用C#做Screen Capture程序的源代码(Capture.cs),具体如下:using System ;
    using System.Drawing ;
    using System.Collections ;
    using System.ComponentModel ;
    using System.Windows.Forms ;
    using System.Data ;
    using System.Drawing.Imaging ;
    using System.IO ;
    //导入在程序中使用到的名称空间
    public class Capture : Form
    {
    private System.ComponentModel.Container components = null ;
    private Icon mNetTrayIcon = new Icon ( "Tray.ico" ) ;
    private Bitmap MyImage = null ;
    private NotifyIcon TrayIcon ;
    private ContextMenu notifyiconMnu ;
    public Capture ( )
    {
    //初始化窗体中使用到的组件
    InitializeComponent ( ) ;

    protected override void OnActivated ( EventArgs e )
    {
    this.Hide ( ) ;
    }
    [ System.Runtime.InteropServices.DllImportAttribute ( "gdi32.dll" ) ]
    private static extern bool BitBlt (
    IntPtr hdcDest , //目标设备的句柄
    int nXDest , // 目标对象的左上角的X坐标
    int nYDest , // 目标对象的左上角的X坐标
    int nWidth , // 目标对象的矩形的宽度
    int nHeight , // 目标对象的矩形的长度
    IntPtr hdcSrc , // 源设备的句柄
    int nXSrc , // 源对象的左上角的X坐标
    int nYSrc , // 源对象的左上角的X坐标
    System.Int32 dwRop // 光栅的操作值
    ) ;[ System.Runtime.InteropServices.DllImportAttribute ( "gdi32.dll" ) ]
    private static extern IntPtr CreateDC (
    string lpszDriver , // 驱动名称
    string lpszDevice , // 设备名称
    string lpszOutput , // 无用,可以设定位"NULL"
    IntPtr lpInitData // 任意的打印机数据
    ) ;
    public void capture ( object sender , System.EventArgs e )
    {
    this.Visible = false ;
    IntPtr dc1 = CreateDC ( "DISPLAY" , null , null , ( IntPtr ) null ) ;
    //创建显示器的DC
    Graphics g1 = Graphics.FromHdc ( dc1 ) ;
    //由一个指定设备的句柄创建一个新的Graphics对象
    MyImage = new Bitmap ( Screen.PrimaryScreen.Bounds.Width , Screen.PrimaryScreen.Bounds.Height , g1 ) ;
    //根据屏幕大小创建一个与之相同大小的Bitmap对象
    Graphics g2 = Graphics.FromImage ( MyImage ) ;
    //获得屏幕的句柄
    IntPtr dc3 = g1.GetHdc ( ) ;
    //获得位图的句柄
    IntPtr dc2 = g2.GetHdc ( ) ;
    //把当前屏幕捕获到位图对象中
    BitBlt ( dc2 , 0 , 0 , Screen.PrimaryScreen.Bounds.Width , Screen.PrimaryScreen.Bounds.Height , dc3 , 0 , 0 , 13369376 ) ;
    //把当前屏幕拷贝到位图中
    g1.ReleaseHdc ( dc3 ) ;
    //释放屏幕句柄
    g2.ReleaseHdc ( dc2 ) ;
    //释放位图句柄
    MyImage.Save ( "c:\\MyJpeg.jpg" , ImageFormat.Jpeg ) ;
    MessageBox.Show ( "已经把当前屏幕保存到C:\\MyJpeg.jpg文件中!" ) ;
    this.Visible = true ;
    }
    public void ExitSelect ( object sender , System.EventArgs e )
    {
    //隐藏托盘程序中的图标
    TrayIcon.Visible = false ;
    //关闭系统
    this.Close ( ) ;
    }
    //清除程序中使用过的资源
    public override void Dispose ( )
    {
    base.Dispose ( ) ;
    if ( components != null )
    components.Dispose ( ) ;
    }
    private void InitializeComponent ( )
    {
    //设定托盘程序的各个属性
    TrayIcon = new NotifyIcon ( ) ;
    TrayIcon.Icon = mNetTrayIcon ;
    TrayIcon.Text = "用C#做Screen Capture程序" ;
    TrayIcon.Visible = true ; 
    //定义一个MenuItem数组,并把此数组同时赋值给ContextMenu对象
    MenuItem [ ] mnuItms = new MenuItem [ 3 ] ;
    mnuItms [ 0 ] = new MenuItem ( ) ;
    mnuItms [ 0 ] .Text = "捕获当前屏幕!" ;
    mnuItms [ 0 ] .Click += new System.EventHandler ( this.capture ) ;
    mnuItms [ 1 ] = new MenuItem ( "-" ) ;
    mnuItms [ 2 ] = new MenuItem ( ) ;
    mnuItms [ 2 ] .Text = "退出系统" ;
    mnuItms [ 2 ] .Click += new System.EventHandler ( this.ExitSelect ) ;
    mnuItms [ 2 ] .DefaultItem = true ;
    notifyiconMnu = new ContextMenu ( mnuItms ) ;
    TrayIcon.ContextMenu = notifyiconMnu ;
    //为托盘程序加入设定好的ContextMenu对象
    this.SuspendLayout ( ) ;
    this.AutoScaleBaseSize = new System.Drawing.Size ( 5 , 13 ) ;
    this.ClientSize = new System.Drawing.Size ( 320 , 56 ) ;
    this.ControlBox = false ;
    this.MaximizeBox = false ;
    this.MinimizeBox = false ;
    this.WindowState = System.Windows.Forms.FormWindowState.Minimized ;
    this.Name = "capture" ;
    this.ShowInTaskbar = false ;
    this.Text = "用C#做Screen Capture程序!" ;
    this.ResumeLayout ( false ) ;
    }
    static void Main ( ) 
    {
    Application.Run ( new Capture ( ) ) ;
    }
    }
      

  2.   

    获取桌面窗口的HDC句柄, 计算出鼠标拖动的矩形的位置,大小,调用BitBlt函数截屏.private Bitmap GetDesktopBitmap()
    {
    int Start = Environment.TickCount; Size DesktopBitmapSize = GetDesktopBitmapSize(); Graphics Graphic = Graphics.FromHwnd(GetDesktopWindow()); int GraphicsFromHwndTime = Environment.TickCount - Start;
    Start = Environment.TickCount; Bitmap MemImage = new Bitmap(DesktopBitmapSize.Width, DesktopBitmapSize.Height, Graphic); int MemImageTime = Environment.TickCount - Start;
    Start = Environment.TickCount; Graphics MemGraphic = Graphics.FromImage(MemImage); int FromImageTime = Environment.TickCount - Start; IntPtr dc1 = Graphic.GetHdc();
    IntPtr dc2 = MemGraphic.GetHdc();
    BitBlt(dc2, 0, 0, DesktopBitmapSize.Width, DesktopBitmapSize.Height, dc1, 0, 0, SRCCOPY); int BitBltTime = Environment.TickCount - Start; Graphic.ReleaseHdc(dc1);
    MemGraphic.ReleaseHdc(dc2);

    Console.WriteLine("GraphicsFromHwndTime: " + GraphicsFromHwndTime.ToString());
    Console.WriteLine("MemImageTime:         " + MemImageTime.ToString());
    Console.WriteLine("FromImageTime:        " + FromImageTime.ToString());
    Console.WriteLine("BitBltTime:           " + BitBltTime.ToString()); Graphic.Dispose();
    MemGraphic.Dispose(); return MemImage;
    }
      

  3.   

    using System;
    using System.Drawing;
    using System.Collections;
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.Data;
    using System.Drawing.Imaging;namespace Example023_屏幕捕获程序
    {
    /// <summary>
    /// Form1 的摘要说明。
    /// </summary>
    public class Form1 : System.Windows.Forms.Form
    {
    private System.Windows.Forms.Button button1;
    /// <summary>
    /// 必需的设计器变量。
    /// </summary>
    private System.ComponentModel.Container components = null; public Form1()
    {
    //
    // Windows 窗体设计器支持所必需的
    //
    InitializeComponent(); //
    // TODO: 在 InitializeComponent 调用后添加任何构造函数代码
    //
    } /// <summary>
    /// 清理所有正在使用的资源。
    /// </summary>
    protected override void Dispose( bool disposing )
    {
    if( disposing )
    {
    if (components != null) 
    {
    components.Dispose();
    }
    }
    base.Dispose( disposing );
    } #region Windows Form Designer generated code
    /// <summary>
    /// 设计器支持所需的方法 - 不要使用代码编辑器修改
    /// 此方法的内容。
    /// </summary>
    private void InitializeComponent()
    {
    this.button1 = new System.Windows.Forms.Button();
    this.SuspendLayout();
    // 
    // button1
    // 
    this.button1.Location = new System.Drawing.Point(48, 48);
    this.button1.Name = "button1";
    this.button1.Size = new System.Drawing.Size(112, 40);
    this.button1.TabIndex = 0;
    this.button1.Text = "开始";
    this.button1.Click += new System.EventHandler(this.button1_Click);
    // 
    // Form1
    // 
    this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
    this.ClientSize = new System.Drawing.Size(232, 149);
    this.Controls.AddRange(new System.Windows.Forms.Control[] {
      this.button1});
    this.Name = "Form1";
    this.Text = "Form1";
    this.ResumeLayout(false); }
    #endregion /// <summary>
    /// 应用程序的主入口点。
    /// </summary>
    [STAThread]
    static void Main() 
    {
    Application.Run(new Form1());
    } [ System.Runtime.InteropServices.DllImportAttribute ( "gdi32.dll" ) ]
    private static extern bool BitBlt (
    IntPtr hdcDest , //目标设备的句柄
    int nXDest , // 目标对象的左上角的X坐标
    int nYDest , // 目标对象的左上角的X坐标
    int nWidth , // 目标对象的矩形的宽度
    int nHeight , // 目标对象的矩形的长度
    IntPtr hdcSrc , // 源设备的句柄
    int nXSrc , // 源对象的左上角的X坐标
    int nYSrc , // 源对象的左上角的X坐标
    System.Int32 dwRop // 光栅的操作值
    ) ; [ System.Runtime.InteropServices.DllImportAttribute ( "gdi32.dll" ) ]
    private static extern IntPtr CreateDC (
    string lpszDriver , // 驱动名称
    string lpszDevice , // 设备名称
    string lpszOutput , // 无用,可以设定位"NULL"
    IntPtr lpInitData // 任意的打印机数据
    ) ; private void button1_Click(object sender, System.EventArgs e)
    {
    this.Hide();
    IntPtr dc1 = CreateDC ( "DISPLAY" , null , null , ( IntPtr ) null ) ;
    //创建显示器的DC
    Graphics g1 = Graphics.FromHdc ( dc1 ) ;
    //由一个指定设备的句柄创建一个新的Graphics对象
    Bitmap MyImage = new Bitmap ( Screen.PrimaryScreen.Bounds.Width , Screen.PrimaryScreen.Bounds.Height , g1 ) ;
    //根据屏幕大小创建一个与之相同大小的Bitmap对象
    Graphics g2 = Graphics.FromImage ( MyImage ) ;
    //获得屏幕的句柄
    IntPtr dc3 = g1.GetHdc ( ) ;
    //获得位图的句柄
    IntPtr dc2 = g2.GetHdc ( ) ;
    //把当前屏幕捕获到位图对象中
    BitBlt ( dc2 , 0 , 0 , Screen.PrimaryScreen.Bounds.Width , Screen.PrimaryScreen.Bounds.Height , dc3 , 0 , 0 , 13369376 ) ;
    //把当前屏幕拷贝到位图中
    g1.ReleaseHdc ( dc3 ) ;
    //释放屏幕句柄
    g2.ReleaseHdc ( dc2 ) ;
    //释放位图句柄
    MyImage.Save ( "c:\\MyJpeg.jpg" , ImageFormat.Jpeg ) ;
    MessageBox.Show ( "已经把当前屏幕保存到C:\\MyJpeg.jpg文件中!" ) ;
    this.Show();
    }
    }
    }
    可以直接運行的