vc++指定区域截屏

来源:互联网 发布:蓝桥物流软件 编辑:程序博客网 时间:2024/05/22 06:19
int   CCaptureDeskDlg::SaveBitmapToFile(HBITMAP   hBitmap,   LPCWSTR   lpFileName)   //hBitmap   为刚才的屏幕位图句柄   {           //lpFileName   为位图文件名   WORD   wBitCount;   //位图中每个像素所占字节数     //定义调色板大小,位图中像素字节大小,位图文件大小,写入文件字节数     DWORD   dwPaletteSize=0,dwBmBitsSize,dwDIBSize,   dwWritten;     BITMAP   Bitmap; //位图属性结构     BITMAPFILEHEADER   bmfHdr;   //位图文件头结构     BITMAPINFOHEADER   bi;   //位图信息头结构     HANDLE   fh;   //定义文件,分配内存句柄,调色板句柄   LPSTR   lpbk,lpmem;   wBitCount   =   32;     //设置位图信息头结构     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;     //创建位图文件     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)+dwBmBitsSize;     bmfHdr.bfSize   =   dwDIBSize;     bmfHdr.bfReserved1   =   0;     bmfHdr.bfReserved2   =   0;     bmfHdr.bfOffBits   =   (DWORD)sizeof(BITMAPFILEHEADER)+(DWORD)sizeof(BITMAPINFOHEADER);   //写入位图文件头     WriteFile(fh,   (LPSTR)&bmfHdr,   sizeof(BITMAPFILEHEADER),&dwWritten,   NULL);     //写入位图信息头   WriteFile(fh,   (LPSTR)&bi,sizeof(BITMAPINFOHEADER),&dwWritten,   NULL);   //获取位图阵列   lpmem=new   char[dwBmBitsSize];   lpbk=(LPSTR)   new   char[dwBmBitsSize];   GetBitmapBits(hBitmap,dwBmBitsSize,lpmem);//正向的内存图象数据   //转化为倒向数据(仅在bmHeight为正时需要)   for(int   i=0;i<Bitmap.bmHeight;i++)   {   memcpy(lpbk+Bitmap.bmWidth*i*4,lpmem+Bitmap.bmWidth*(Bitmap.bmHeight-i-1)*4,Bitmap.bmWidth*4);   }   //写位图数据   WriteFile(fh,   lpbk,dwBmBitsSize,&dwWritten,   NULL);   //清除     delete   []lpbk;   delete   []lpmem;   CloseHandle(fh);   return   TRUE;   }HBITMAP   CCaptureDeskDlg::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(L"DISPLAY",   NULL,   NULL,   NULL);   //为屏幕设备描述表创建兼容的内存设备描述表   hMemDC=CreateCompatibleDC(hScrDC);   //或者::CreateCompatibleDC(NULL)   //获得选定区域坐标     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 CCaptureDeskDlg::OnBnClickedButton1(){RECT  rect;rect.top=0;rect.left=0;rect.right=500;rect.bottom=500;HBITMAP h_Bitmp=CopyScreenToBitmap(&rect);SaveBitmapToFile(h_Bitmp,L"Test.bmp");}

0 0