幕截取是使人比較感興趣的事情.雖然如今有很多應用程序如HYPERSNAP等能夠用來截取你所喜歡的屏幕畫面,可是若是能把這個功能加到本身的程序中,就更能利用它強大的做用.
下面用VC來逐步介紹在Windows95下的實現過程.首先咱們要肯定屏幕截取的區域,用LPRECT結構來定義.能夠截取一個窗口,或整個屏幕.如下代碼把選定的屏幕區域拷貝到位圖中.
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 = SelectObject(hMemDC, hBitmap); // 把屏幕設備描述表拷貝到內存設備描述表中BitBlt(hMemDC, 0, 0, nWidth, nHeight, hScrDC, nX, nY, SRCCOPY); //獲得屏幕位圖的句柄 hBitmap = SelectObject(hMemDC, hOldBitmap); //清除 DeleteDC(hScrDC); DeleteDC(hMemDC); // 返回位圖句柄 return hBitmap;} 獲得屏幕位圖句柄之後,咱們能夠把屏幕內容粘貼到剪貼板上. if (OpenClipboard(hWnd)) //hWnd爲程序窗口句柄 { //清空剪貼板 EmptyClipboard(); //把屏幕內容粘貼到剪貼板上, hBitmap 爲剛纔的屏幕位圖句柄 SetClipboardData(CF_BITMAP, hBitmap); //關閉剪貼板 CloseClipboard(); } 咱們也能夠把屏幕內容以位圖格式存到磁盤文件上. int SaveBitmapToFile(HBITMAP hBitmap , LPSTR lpFileName) //hBitmap 爲剛纔的屏幕位圖句柄{ //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,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 = SelectPalette(hDC, hPal, FALSE); RealizePalette(hDC); } // 獲取該調色板下新的像素值 GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight, (LPSTR)lpbi + sizeof(BITMAPINFOHEADER) +dwPaletteSize, (BITMAPINFOHEADER *) 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);}