截圖 c++


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 = (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 OpClip(HBITMAP hBitmap, HWND jhWnd)
{
 if(OpenClipboard(jhWnd))
  //hWnd爲程序窗口句柄
  //清空剪貼板
  EmptyClipboard();
 //把屏幕內容粘貼到剪貼板上,
 //hBitmap 爲剛纔的屏幕位圖句柄
 SetClipboardData(CF_BITMAP, hBitmap);
 //關閉剪貼板
 CloseClipboard();
}

//我們也可以把屏幕內容以位圖格式存到磁盤文件上.

//hBitmap 爲剛纔的屏幕位圖句柄
int SaveBitmapToFile(HBITMAP hBitmap , LPSTR lpFileName)

 //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;
 HPALETTE 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 = (HPALETTE)SelectPalette(hDC, (HPALETTE)hPal, FALSE);
 RealizePalette(hDC);
 }

 // 獲取該調色板下新的像素值
 GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight,
 (LPSTR)lpbi + sizeof(BITMAPINFOHEADER)
 +dwPaletteSize,
 (tagBITMAPINFO *)
 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 0;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章