调用Win32API来捕获屏幕或当前活动窗口的源代码

来源:互联网 发布:js 椭圆运动轨迹 编辑:程序博客网 时间:2024/06/08 17:34

本文使用GDI32.dll来实现捕获屏幕或者当前活动窗口。所有API都在"Kernel""User ""GDI"三个库中得以运行:其中"Kernel",他的库名为 "KERNEL32.DLL" 他主要用于产生与操作系统之间的关联,譬如:程序加载,上下文选择,文件输入输出,内存管理等等。"User "这个类库在Win32中名叫 "USER32.DLL" 它允许管理全部的用户接口。譬如:窗口 、菜单 、对话框 、图标等等。"GDI"(图象设备接口),它在Win32中的库名为:"GDI32.dll",它是图形输出库。使用GDI Windows""出窗口、菜单以及对话框等;它能创建图形输出;它也能保存图形文件。

本文中我们使用的API函数是"BitBlt",介绍如下: 

 函数功能:该函数对指定的源设备环境区域中的像素进行位块(bit_block)转换,以传送到目标设备环境。
    
函数原型:BOOL BitBlt(HDC hdcDest,int nXDest,int nYDest,int nWidth,int nHeight,HDC hdcSrc,int nXSrc,int nYSrc,DWORD dwRop)
    
参数:
    hdcDest
:指向目标设备环境的句柄。
    nXDest
:指定目标矩形区域左上角的X轴逻辑坐标。
    nYDest
:指定目标矩形区域左上角的Y轴逻辑坐标。
    nWidth
:指定源和目标矩形区域的逻辑宽度。
    nHeight
:指定源和目标矩形区域的逻辑高度。
    hdcSrc
:指向源设备环境的句柄。
    nXSrc
:指定源矩形区域左上角的X轴逻辑坐标。
    nYSrc
:指定源矩形区域左上角的Y轴逻辑坐标。
    dwRop
:指定光栅操作代码。这些代码将定义源矩形区域的颜色数据,如何与目标矩形区域的颜色数据组合以完成最后的颜色。

 C#中调用方法在下面的源代码中。这里定义了一个ScreenCapture类,其中有一个静态方法GetScreenMap(Graphics g1 ,Rectangle rect)。

//ScreenCapture.cs

//Author:hetonghai 2004/06/23

namespace ScreenCapture {

     using System;

     using System.Runtime.InteropServices;

     using System.Windows.Forms;

     using System.Drawing;

 

     /// <summary>

     /// 抓取当前屏幕的类

     /// </summary>

     public class ScreenCapture {

          protected ScreenCapture() {

              ;

         }

             

         /// <summary>

         /// 声明一个API函数

         /// 函数功能:该函数对指定的源设备环境区域中的像素进行位块(bit_block)转换,以传送到目标设备环境。

         /// 函数原型:BOOL BitBlt(HDC hdcDest,int nXDest,int nYDest,int nWidth,int nHeight,HDC hdcSrc,int nXSrc,int nYSrc,DWORD dwRop);

         /// </summary>

         /// <param name="hdcDest">hdcDest:指向目标设备环境的句柄。</param>

         /// <param name="nXDest">nXDest:指定目标矩形区域左上角的X轴逻辑坐标。</param>

         /// <param name="nYDest">nYDest:指定目标矩形区域左上角的Y轴逻辑坐标。</param>

         /// <param name="nWidth">nWidth:指定源和目标矩形区域的逻辑宽度。</param>

         /// <param name="nHeight">nHeight:指定源和目标矩形区域的逻辑高度。</param>

         /// <param name="hdcSrc">hdcSrc:指向源设备环境的句柄。</param>

         /// <param name="nXSrc">nXSrc:指定源矩形区域左上角的X轴逻辑坐标。</param>

         /// <param name="nYSrc">nYSrc:指定源矩形区域左上角的Y轴逻辑坐标。</param>

         /// <param name="dwRop">dwRop:指定光栅操作代码。这些代码将定义源矩形区域的颜色数据,如何与目标矩形区域的颜色数据组合以完成最后的颜色。</param>

         /// <returns>返回值:如果函数成功,那么返回值非零;如果函数失败,则返回值为零。</returns>

          [ System.Runtime.InteropServices.DllImportAttribute ( "gdi32.dll" ) ]

          private static extern bool BitBlt (

              IntPtr hdcDest , // 目标 DC的句柄

              int nXDest ,

              int nYDest ,

              int nWidth ,

              int nHeight ,

              IntPtr hdcSrc ,  // 源DC的句柄

              int nXSrc ,

              int nYSrc ,

              System.Int32 dwRop  // 光栅的处理数值

              ) ;

         /// <summary>

         /// 创建一个以当前屏幕为模板的rect范围的图象

         /// </summary>

         /// <param name="rect">定义屏幕的范围</param>

         /// <returns></returns>

         public static Image GetScreenMap(Graphics g1 ,Rectangle rect) {

              //创建一个以当前屏幕为模板的图象

              //Graphics g1 = this.CreateGraphics ( ) ;

              //创建以屏幕大小为标准的位图

              Image myimage = new Bitmap ( rect.Width , rect.Height , g1 ) ;

              Graphics g2 = Graphics.FromImage ( myimage ) ;

              //得到屏幕的DC

              IntPtr dc1 = g1.GetHdc ( ) ;

              //得到Bitmap的DC

              IntPtr dc2 = g2.GetHdc ( ) ;

              //调用此API函数,实现屏幕捕获

              BitBlt ( dc2 ,0, 0 ,rect.Width , rect.Height , dc1 , rect.X , rect.Y , 13369376 ) ;

              //释放掉屏幕的DC

              g1.ReleaseHdc ( dc1 ) ;

              //释放掉Bitmap的DC

              g2.ReleaseHdc ( dc2 ) ;          

              return myimage;

         }

     }

}

下面给出调用的源代码。

private string saveFile(Rectangle rect) {

              Graphics g1 = this.CreateGraphics ( ) ;         

              Image myimg=ScreenCapture.GetScreenMap(g1,rect);

              string path=this.txtDirectory.Text.Trim();

              string filter=path.Substring(path.Length-3,3);

              string ret="ok";

              switch(filter.ToLower()) {

                   case "jpg": {

                        myimg.Save(path,ImageFormat.Jpeg );

                       break;

                   }

                   case "bmp": {

                        myimg.Save(path,ImageFormat.Bmp );

                       break;

                   }

                   case "gif": {

                        myimg.Save(path,ImageFormat.Gif );

                       break;

                   }

                   default: {

                        ret="error";

                       break;

                   }

              }

              return ret;

         }

 

调用方式:

private void btnsaveCurrent_Click(object sender, System.EventArgs e) {

              string path=this.txtDirectory.Text.Trim();

              Rectangle rect=this.RectangleToClient(new Rectangle(this.Left,this.Top,this.Width,this.Height));            

              if(saveFile(rect)=="ok") {

                   MessageBox.Show ( "保存为"+path+"文件成功!" ) ;

              }

              else {

                   MessageBox.Show ( "保存为"+path+"文件失败!" ) ;

              }

         }

//保存整个屏幕
  private void btnsaveScreen_Click(object sender, System.EventArgs e) {
   string path=this.txtDirectory.Text.Trim();
   Rectangle r = new Rectangle ( ) ;
   r = Screen.GetWorkingArea ( this ) ;
   Rectangle rect=this.RectangleToClient(r);   
   if(saveFile(rect)=="ok") {
    MessageBox.Show ( "保存为"+path+"文件成功!" ) ;
   }
   else {
    MessageBox.Show ( "保存为"+path+"文件失败!" ) ;
   }
  }

原创粉丝点击