网页功能: 加入收藏 设为首页 网站搜索  
用VC进行屏幕截取编程
发表日期:2002-12-08作者:[] 出处:  

---- 屏幕截取是令人比较感兴趣的事情.虽然现在有不少应用程序如HYPERSNAP等可以用来截取你所喜欢的屏幕画面,但是如果能把这个功能加到自己的程序中,就更能利用它强大的作用.

---- 下面用VC来逐步介绍在Windows95下的实现过程.首先我们要确定屏幕截取的区域,用LPRECT结构来定义.可以截取一个窗口,或整个屏幕.以下代码把选定的屏幕区域拷贝到位图中.

HBITMAP CopyScreenToBitmap(LPRECT lpRect)

//lpRect 代表选定区域

{

HDC    hScrDC, hMemDC;   

// 屏幕和内存设备描述表

HBITMAP  hBitmap, hOldBitmap; 

// 位图句柄

int    nX, nY, nX2, nY2;   

// 选定区域坐标

int    nWidth, nHeight;   

// 位图宽度和高度

int    xScrn, yScrn;    

// 屏幕分辨率

  // 确保选定区域不为空矩形

  if (IsRectEmpty(lpRect))

   return NULL;

  //为屏幕创建设备描述表

  hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);

  //为屏幕设备描述表创建兼容的内存设备描述表

  hMemDC = CreateCompatibleDC(hScrDC);

  // 获得选定区域坐标

  nX = lpRect- >left;

  nY = lpRect- >top;

  nX2 = lpRect- >right;

  nY2 = lpRect- >bottom;

  // 获得屏幕分辨率

  xScrn = GetDeviceCaps(hScrDC, HORZRES);

  yScrn = GetDeviceCaps(hScrDC, VERTRES);

  //确保选定区域是可见的

  if (nX 〈0)

   nX = 0;

  if (nY 〈 0)

   nY = 0;

  if (nX2 > xScrn)

   nX2 = xScrn;

  if (nY2 > yScrn)

   nY2 = yScrn;

  nWidth = nX2 - nX;

  nHeight = nY2 - nY;

  // 创建一个与屏幕设备描述表兼容的位图

hBitmap = CreateCompatibleBitmap

(hScrDC, nWidth, nHeight);

  // 把新位图选到内存设备描述表中

  hOldBitmap = SelectObject(hMemDC, hBitmap);

  // 把屏幕设备描述表拷贝到内存设备描述表中

BitBlt(hMemDC, 0, 0, nWidth, nHeight,

hScrDC, nX, nY, SRCCOPY);

  //得到屏幕位图的句柄

  hBitmap = SelectObject(hMemDC, hOldBitmap);

  //清除

  DeleteDC(hScrDC);

  DeleteDC(hMemDC);

  // 返回位图句柄

  return hBitmap;

}

 

得到屏幕位图句柄以后,我们

可以把屏幕内容粘贴到剪贴板上.

  if (OpenClipboard(hWnd))

   //hWnd为程序窗口句柄

   {

    //清空剪贴板

    EmptyClipboard();

    //把屏幕内容粘贴到剪贴板上,

    hBitmap 为刚才的屏幕位图句柄

    SetClipboardData(CF_BITMAP, hBitmap);

    //关闭剪贴板

    CloseClipboard();

   }

  我们也可以把屏幕内容以位图格式存到磁盘文件上.

   

int SaveBitmapToFile(HBITMAP hBitmap ,

LPSTR lpFileName) //hBitmap 为刚才的屏幕位图句柄

{   //lpFileName 为位图文件名

HDC      hDC;    

  //设备描述表

   int      iBits;   

//当前显示分辨率下每个像素所占字节数

WORD      wBitCount; 

  //位图中每个像素所占字节数

   //定义调色板大小, 位图中像素字节大小 ,

   位图文件大小 , 写入文件字节数

DWORD      dwPaletteSize=0,

dwBmBitsSize,

dwDIBSize, dwWritten;

BITMAP     Bitmap;    

//位图属性结构

BITMAPFILEHEADER  bmfHdr;    

//位图文件头结构

   BITMAPINFOHEADER  bi;      

//位图信息头结构

LPBITMAPINFOHEADER lpbi;     

//指向位图信息头结构

   HANDLE     fh, hDib, hPal,hOldPal=NULL;

//定义文件,分配内存句柄,调色板句柄

 

  //计算位图文件每个像素所占字节数

  hDC = CreateDC("DISPLAY",NULL,NULL,NULL);

iBits = GetDeviceCaps(hDC, BITSPIXEL) *

GetDeviceCaps(hDC, PLANES);

  DeleteDC(hDC);

  if (iBits 〈 = 1)

   wBitCount = 1;

  else if (iBits 〈 = 4)

   wBitCount = 4;

  else if (iBits 〈 = 8)

   wBitCount = 8;

  else if (iBits 〈 = 24)

   wBitCount = 24;

  //计算调色板大小

  if (wBitCount 〈 = 8)

   dwPaletteSize = (1 〈 〈  wBitCount) *

   sizeof(RGBQUAD);

 

  //设置位图信息头结构

  GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);

  bi.biSize      = sizeof(BITMAPINFOHEADER);

  bi.biWidth      = Bitmap.bmWidth;

  bi.biHeight     = Bitmap.bmHeight;

  bi.biPlanes     = 1;

  bi.biBitCount     = wBitCount;

  bi.biCompression   = BI_RGB;

  bi.biSizeImage    = 0;

  bi.biXPelsPerMeter   = 0;

  bi.biYPelsPerMeter   = 0;

  bi.biClrUsed     = 0;

  bi.biClrImportant   = 0;

  dwBmBitsSize = ((Bitmap.bmWidth *

  wBitCount+31)/32)* 4

*Bitmap.bmHeight ;

  //为位图内容分配内存

  hDib = GlobalAlloc(GHND,dwBmBitsSize+

dwPaletteSize+sizeof(BITMAPINFOHEADER));

  lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);

  *lpbi = bi;

  // 处理调色板 

  hPal = GetStockObject(DEFAULT_PALETTE);

  if (hPal)

  {

   hDC = GetDC(NULL);

   hOldPal = SelectPalette(hDC, hPal, FALSE);

   RealizePalette(hDC);

  }

  // 获取该调色板下新的像素值

  GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight,

(LPSTR)lpbi + sizeof(BITMAPINFOHEADER)

  +dwPaletteSize,

(BITMAPINFOHEADER *)

  lpbi, DIB_RGB_COLORS);

  //恢复调色板 

  if (hOldPal)

  {

   SelectPalette(hDC, hOldPal, TRUE);

   RealizePalette(hDC);

   ReleaseDC(NULL, hDC);

  }

  //创建位图文件  

fh = CreateFile(lpFileName, GENERIC_WRITE,

0, NULL, CREATE_ALWAYS,

     FILE_ATTRIBUTE_NORMAL | FILE_

     FLAG_SEQUENTIAL_SCAN, NULL);

  if (fh == INVALID_HANDLE_VALUE)

   return FALSE;

  // 设置位图文件头

  bmfHdr.bfType = 0x4D42; // "BM"

dwDIBSize  = sizeof(BITMAPFILEHEADER)

      + sizeof(BITMAPINFOHEADER)

    + dwPaletteSize + dwBmBitsSize; 

  bmfHdr.bfSize = dwDIBSize;

  bmfHdr.bfReserved1 = 0;

  bmfHdr.bfReserved2 = 0;

  bmfHdr.bfOffBits = (DWORD)sizeof

  (BITMAPFILEHEADER)

   + (DWORD)sizeof(BITMAPINFOHEADER)

   + dwPaletteSize;

  // 写入位图文件头

WriteFile(fh, (LPSTR)&bmfHdr, sizeof

(BITMAPFILEHEADER), &dwWritten, NULL);

  // 写入位图文件其余内容

  WriteFile(fh, (LPSTR)lpbi, dwDIBSize,

  &dwWritten, NULL);

  //清除 

  GlobalUnlock(hDib);

  GlobalFree(hDib);

  CloseHandle(fh);

}

我来说两句】 【加入收藏】 【返加顶部】 【打印本页】 【关闭窗口
中搜索 用VC进行屏幕截取编程
本类热点文章
  WIN32音频数据采集 WaveIn-Out实现
  Windows环境下Unicode编程总结
  Windows SDK入门浅谈 — 写给初学者
  SendMessage进程间简单通信问题
  以程序的方式操纵NTFS的文件权限
  SDK编程笔记 - DLL篇
  API 层实现语音录制
  利用HOOK拦截封包原理
  SDK编程笔记 — 计时器篇
  消息钩子函数入门篇
  在Win2000中动态禁用/启用Ctrl-Alt-Del
  盗QQ的密码软件模拟实现
最新分类信息我要发布 
最新招聘信息

关于我们 / 合作推广 / 给我留言 / 版权举报 / 意见建议 / 广告投放  
Copyright ©2003-2018 Lihuasoft.net webmaster(at)lihuasoft.net
网站编程QQ群   京ICP备05001064号 页面生成时间:0.00367