制作自己的截图工具

本示例截图区域为有焦点窗口区域


第一步注册热键

RegisterHotKey(m_hWnd,0x01,NULL,VK_SNAPSHOT);

 

第2步处理热键

 LRESULT CTESTDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
 // TODO: Add your specialized code here and/or call the base class
 if(message==WM_HOTKEY)
 {
  if(wParam==0x01)
  {
   CWnd* wnd1=GetDesktopWindow();
   if(wnd1)
   {
    CWnd* wnd2= wnd1->GetForegroundWindow();

    if(wnd2)     {      CString name;      wnd2->GetWindowText(name);

     RECT rect;      wnd2->GetWindowRect(&rect);

     HBITMAP hBitmap;      hBitmap=CopyScreenToBitmap(&rect);

     SetForegroundWindow();      CFileDialog dlg(TRUE,".bmp",name,OFN_OVERWRITEPROMPT|OFN_HIDEREADONLY,"BMP 文件(*.bmp)|*.bmp||",this);      if(dlg.DoModal()== IDOK)      {       CString path=dlg.GetPathName();

      if(dlg.GetFileExt()==_T(""))        path+=_T(".bmp");              SaveNewImage(hBitmap,path,32);

      CString str;       str.Format(_T("已将窗口“%s”位图保存到:%s"),name,path);       MessageBox(str,_T("提示"),MB_OK);      }          }    }

     }  }    return CDialog::WindowProc(message, wParam, lParam); }

 

 第3步 添加CopyScreenToBitmap函数,本函数的目的在于将指定区域的图片拷贝到位图中.

//lpRect 代表选定区域
HBITMAP CTESTDlg::CopyScreenToBitmap(LPRECT lpRect)
{
	 HDC       hScrDC, hMemDC;      
	 // 屏幕和内存设备描述表
	 HBITMAP    hBitmap, hOldBitmap;   
	 // 位图句柄
	 int       nX, nY, nX2, nY2;      
	 // 选定区域坐标
	 int       nWidth, nHeight;
 
	 // 确保选定区域不为空矩形
	 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;

	 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;
}


 第4步 将位图保存为bmp格式

BOOL CTESTDlg::SaveNewImage(HBITMAP hbitmap, CString filename, int nColor)
{
 BITMAP Bitmap;
 HDC         hDC;                         
 DWORD     dwPaletteSize=0,dwBmBitsSize,dwDIBSize,   dwWritten;     
 BITMAPFILEHEADER       bmfHdr;                   
 BITMAPINFOHEADER       bi;                           
 LPBITMAPINFOHEADER   lpbi;           
 HANDLE   fh,   hDib,   hPal,hOldPal=NULL;   

 if   (nColor<=   8)   
  dwPaletteSize   =   (1<<nColor)   *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 = nColor;
 bi.biCompression = BI_RGB;
 bi.biSizeImage = 0;
 bi.biXPelsPerMeter = 0;
 bi.biYPelsPerMeter = 0;
 bi.biClrUsed = 0;
 bi.biClrImportant = 0; 
 dwBmBitsSize   =   ((Bitmap.bmWidth  *   nColor+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,   (HPALETTE)hPal,   FALSE);   
  RealizePalette(hDC);   
 }  
 // 获取该调色板下新的像素值
 GetDIBits(hDC,   hbitmap,   0,   Bitmap.bmHeight, 
  (LPSTR)lpbi   +   sizeof(BITMAPINFOHEADER)+dwPaletteSize,   
  (BITMAPINFO   *)lpbi,   DIB_RGB_COLORS);   
 if   (hOldPal)   
 {   
  SelectPalette(hDC,   (HPALETTE)hOldPal,   TRUE);   
  RealizePalette(hDC);   
  ::ReleaseDC(NULL,hDC);   
 }   

 fh   =   CreateFile(filename,   GENERIC_WRITE,     
  0,//not   be   shared   
  NULL,   //cannot   be   inherited   
  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;   

 //write   file   header   
 WriteFile(fh,   (LPSTR)&bmfHdr,   sizeof(BITMAPFILEHEADER),   &dwWritten,   NULL);   

 //write   bmp   data   
 WriteFile(fh,   (LPSTR)lpbi,   dwDIBSize,   &dwWritten,   NULL);   

 GlobalUnlock(hDib);   
 GlobalFree(hDib);   
 CloseHandle(fh);   
 DeleteObject(hbitmap);    
 return   TRUE;  
} 



 

 

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sckoo/article/details/6880250
个人分类: VC++
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭