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

使用GDI32.dll捕获屏幕或活动窗口的Win32API实现
本文详细介绍了如何利用GDI32.dll中的BitBlt函数来捕获Windows系统屏幕或当前活动窗口的图像。通过解释Kernel32.DLL、USER32.DLL和GDI32.DLL的作用,以及BitBlt函数的参数和功能,展示了捕获图形的具体步骤。
部署运行你感兴趣的模型镜像

本文使用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+"文件失败!" ) ;
   }
  }

您可能感兴趣的与本文相关的镜像

ComfyUI

ComfyUI

AI应用
ComfyUI

ComfyUI是一款易于上手的工作流设计工具,具有以下特点:基于工作流节点设计,可视化工作流搭建,快速切换工作流,对显存占用小,速度快,支持多种插件,如ADetailer、Controlnet和AnimateDIFF等

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值