屏幕截图

    技术2022-05-11  71

    /****************************************************************************** * FILE NAME: CopyScreenToBitmap.h                                             * *                                                                             * * DESCRIPTION:                                                                * *   截屏位图文件                                                              * *                                                                             * * COPYRIGHT:                                                                  * *   (C) Copyright LiuYong                                                     * *   All Rights Reserved                                                       * *                                                                             * * AUTHOR:                                                                     * *  liu yong                                                                  * * DATE  :  2006-11-29                                                         * *                                                                             * *******************************************************************************/ class CCopyScreenToBitmap { public:  CCopyScreenToBitmap();  ~CCopyScreenToBitmap();  //截取指定区域的屏幕到位图文件,文件目录默认让用户自己选择  BOOL SaveRectToBitmap( LPRECT lpRect, LPSTR lpFileName = NULL );  //截取全屏幕到位图文件,文件目录默认让用户自己选择  BOOL SaveScreenToBitmap( LPSTR lpFileName = NULL );   private:  HBITMAP SaveBitmapCopyScreenToBitmap( LPRECT lpRect );  BOOL SaveBitmapToFile( HBITMAP hBitmap , LPSTR lpFileName ) ;  void SaveBitmapToClipboard( HBITMAP hBitmap, HWND hWnd ); };    /// // CopyScreenToBitmap.cpp: implementation of the CCopyScreenToBitmap class. // // #include "stdafx.h" #include "CopyScreenToBitmap.h" #include <afxdlgs.h> #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif // // Construction/Destruction // CCopyScreenToBitmap::CCopyScreenToBitmap() { } CCopyScreenToBitmap::~CCopyScreenToBitmap() { } BOOL CCopyScreenToBitmap::SaveRectToBitmap(LPRECT lpRect, LPSTR lpFileName) {  if(!lpRect)  {   ::MessageBox( NULL,"请指定要截图的区域!","提示",MB_ICONINFORMATION );   return FALSE;  }  HBITMAP hBitmap = SaveBitmapCopyScreenToBitmap(lpRect);  if( !lpFileName )  {   CString Path;   CFileDialog dlg(FALSE,"*.*","新图形",NULL,   "位图文件(*.bmp)|*.bmp|所有文件(*.*)|*.*||",NULL);   //not change the default dir   dlg.m_ofn.Flags |= OFN_EXPLORER|OFN_OVERWRITEPROMPT|OFN_HIDEREADONLY|OFN_NOCHANGEDIR;    dlg.m_ofn.lpstrTitle = "保存图形";   if (dlg.DoModal() == IDCANCEL)   {    ::DeleteObject(hBitmap);    return FALSE;   }   Path = dlg.GetPathName();  //save the bitmap   return SaveBitmapToFile(hBitmap,Path.GetBuffer( Path.GetLength() ) );  }  else  {   return SaveBitmapToFile( hBitmap, lpFileName );  } } BOOL CCopyScreenToBitmap::SaveScreenToBitmap( LPSTR lpFileName ) {  int cxSrc = GetSystemMetrics (SM_CXSCREEN) ; //源设备宽--屏幕宽     int cySrc = GetSystemMetrics (SM_CYSCREEN) ; //源设备高--屏幕高  CRect rect(0,0,cxSrc,cySrc);  HBITMAP hBitmap = SaveBitmapCopyScreenToBitmap( &rect );  if( !lpFileName )  {   CString Path;   CFileDialog dlg(FALSE,"*.*","新图形",NULL,   "位图文件(*.bmp)|*.bmp|所有文件(*.*)|*.*||",NULL);   //not change the default dir   dlg.m_ofn.Flags |= OFN_EXPLORER|OFN_OVERWRITEPROMPT|OFN_HIDEREADONLY|OFN_NOCHANGEDIR;    dlg.m_ofn.lpstrTitle = "保存图形";   if (dlg.DoModal() == IDCANCEL)   {    ::DeleteObject(hBitmap);    return FALSE;   }   Path = dlg.GetPathName();  //save the bitmap   return SaveBitmapToFile(hBitmap,Path.GetBuffer( Path.GetLength() ) );  }  else  {   return SaveBitmapToFile( hBitmap, lpFileName );  } } //lpRect 代表选定区域 HBITMAP CCopyScreenToBitmap::SaveBitmapCopyScreenToBitmap(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 = (HBITMAP)SelectObject(hMemDC, hBitmap);      // 把屏幕设备描述表拷贝到内存设备描述表中  BitBlt(hMemDC, 0, 0, nWidth, nHeight,hScrDC, nX, nY, SRCCOPY);  //得到屏幕位图的句柄  hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);      //清除  DeleteDC(hScrDC);  DeleteDC(hMemDC);  // 返回位图句柄  return hBitmap; }    /得到屏幕位图句柄以后,我们 /可以把屏幕内容粘贴到剪贴板上. void CCopyScreenToBitmap::SaveBitmapToClipboard(HBITMAP hBitmap,HWND hWnd) {  //hWnd为程序窗口句柄  if (OpenClipboard(hWnd))  {   //清空剪贴板   EmptyClipboard();   SetClipboardData(CF_BITMAP, hBitmap);   //关闭剪贴板   CloseClipboard();  } } //我们也可以把屏幕内容以位图格式存到磁盘文件上. //lpFileName 为位图文件名      BOOL CCopyScreenToBitmap::SaveBitmapToFile(HBITMAP hBitmap , LPSTR lpFileName) {     //设备描述表  HDC            hDC;                //当前显示分辨率下每个像素所占字节数  int            iBits;           //位图中每个像素所占字节数  WORD            wBitCount=32;          //定义调色板大小, 位图中像素字节大小 ,   //位图文件大小 , 写入文件字节数  DWORD           dwPaletteSize=0,   dwBmBitsSize,   dwDIBSize, dwWritten;  //位图属性结构  BITMAP          Bitmap;         //位图文件头结构  BITMAPFILEHEADER   bmfHdr;         //位图信息头结构  BITMAPINFOHEADER   bi;             //指向位图信息头结构  LPBITMAPINFOHEADER lpbi;  //定义文件,分配内存句柄,调色板句柄   HANDLE fh, hDib;  HPALETTE 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 = (HPALETTE)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,(LPBITMAPINFO)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);  return TRUE; }  

    最新回复(0)