1. 程式人生 > >VC螢幕截圖(將螢幕指定區域存成圖片)

VC螢幕截圖(將螢幕指定區域存成圖片)

HBITMAP CLoadpicDlg::CopyScreenToBitmap(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; 

}

int CLoadpicDlg::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; 
else 
wBitCount = 32; 
//計算調色盤大小 
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; 
//為點陣圖內容分配記憶體 
/*xxxxxxxx計算點陣圖大小分解一下(解釋一下上面的語句)xxxxxxxxxxxxxxxxxxxx
//每個掃描行所佔的位元組數應該為4的整數倍,具體演算法為:
1int biWidth = (Bitmap.bmWidth*wBitCount) / 32;
if((Bitmap.bmWidth*wBitCount) % 32)
 biWidth++; //不是整數倍的加1
biWidth *= 4;//到這裡,計算得到的為每個掃描行的位元組數。
dwBmBitsSize = biWidth * Bitmap.bmHeight;//得到大小
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/ 
 
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,(UINT)Bitmap.bmHeight,(LPSTR)lpbi+sizeof(BITMAPINFOHEADER)+dwPaletteSize, (BITMAPINFO *)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, sizeof(BITMAPINFOHEADER)+dwPaletteSize+dwBmBitsSize , &dwWritten, NULL); 
//清除 
GlobalUnlock(hDib); 
GlobalFree(hDib); 
CloseHandle(fh); 
return TRUE;
}

void CLoadpicDlg::OnButton1()
{
 CRect rect; 
// GetWindowRect(&rect); 
    GetDlgItem(IDC_TEMPLATE)->GetWindowRect(&rect);
 HBITMAP hMap = CopyScreenToBitmap(rect); 
 SaveBitmapToFile(hMap,"C://seu07201213(汪洋中的一片葉子).bmp"); 

 
}