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

原创 2004年06月24日 13:58:00

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

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

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

捕捉Win32窗口操作

// CreateProcessSuspend.cpp : 定义控制台应用程序的入口点。 // //在桌面打开记事本,然后通过spy++来查看窗口的类和标题,或者句柄(不推荐直接使用句柄,因为会程序关...
  • a1013642808
  • a1013642808
  • 2017年10月05日 23:31
  • 70

GetForegroundWindow获取系统最前端的窗口

1、GetActiveWindow返回线程的活动窗口,而不是系统的活动窗口。如果要得到用户正在激活的窗口,应该使用 GetForegroundWindow。 2、例如...
  • lz465350
  • lz465350
  • 2014年11月03日 17:12
  • 4157

c# 获取当前活动窗口句柄,获取窗口大小及位置

需调用API函数 需在开头引入命名空间 using System.Runtime.InteropServices; 获取当前窗口句柄:GetForegroundWindow() [DllI...
  • pangwenquan5
  • pangwenquan5
  • 2014年10月20日 21:09
  • 17283

在屏幕坐标和窗口坐标之见的转换

       在你刚刚创建的OnMouseMove()处理程序中,MFC使用名为CPoint 的MFC 类,将鼠标指针坐标传递到处理函数中。CPoint类型的对象一般被用语描述屏幕上的一个点。访问的C...
  • infoncust
  • infoncust
  • 2005年07月28日 18:32
  • 10011

c++ 屏幕截图源程序,这个截图程序思路清晰,大家很快能明白qq截图的原理

  • 2010年04月18日 16:45
  • 76KB
  • 下载

win32api编程源代码

  • 2013年01月29日 08:54
  • 719KB
  • 下载

Win32 API 封装类总结

以下是一些封装的Win32 API类;备用; 重温WIN32 API ------ 最简单的Windows窗口封装类 http://blog.csdn.net/smstong/arti...
  • bcbobo21cn
  • bcbobo21cn
  • 2016年08月16日 10:56
  • 3540

c#捕获当前屏幕

编程思路(API 编程): 先调用 GetForegroundWindow 获取当前活动程序窗口句柄,然后调用 GetWindowDC 获取窗口的设备句柄(或 GetDC 函数),调用 BitBl...
  • ghevinn
  • ghevinn
  • 2013年03月29日 18:45
  • 1321

重温 Win32 API ----- 截屏指定窗口并打印

朋友说在一个VC++6.0开发的项目中要加入打印窗口的功能,让帮忙写个代码供其调用。这么老的IDE当然不想碰了,而且也不喜欢MFC笨拙不清晰的封装,所以决定采用纯Win32 API,然后用C++类简单...
  • smstong
  • smstong
  • 2014年12月22日 17:12
  • 6589

【QT】在Qt中获取屏幕大小

如何在Qt中获取屏幕大小呢? 首先要调用QApplication类中的一个static方法,如下: QDesktopWidget *QApplication::desktop() QApplicati...
  • iEearth
  • iEearth
  • 2015年02月09日 13:23
  • 7563
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:调用Win32API来捕获屏幕或当前活动窗口的源代码
举报原因:
原因补充:

(最多只允许输入30个字)