CopyScreenToBitmap(RECT*):建立螢幕 DC → 相容記憶體 DC → 建立相容位圖 → BitBlt 複製螢幕像素 → 回傳 HBITMAP。SaveBitmapToFile(HBITMAP, filename):取得位圖屬性 → 建構 BITMAPINFOHEADER → 計算對齊掃描行大小 → 分配全域記憶體 → GetDIBits 取像素資料 (含調色盤處理) → 寫入 BMP 檔案頭 + 資訊頭 + 像素資料。HBITMAP CopyScreenToBitmap(LPRECT lpRect) {
if (IsRectEmpty(lpRect)) return NULL;
HDC hScrDC = CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
HDC hMemDC = CreateCompatibleDC(hScrDC);
int nX = lpRect->left, nY = lpRect->top;
int nX2 = lpRect->right, nY2 = lpRect->bottom;
int nWidth = nX2 - nX, nHeight = nY2 - nY;
HBITMAP hBitmap = CreateCompatibleBitmap(hScrDC, nWidth, nHeight);
HBITMAP hOld = (HBITMAP)SelectObject(hMemDC, hBitmap);
BitBlt(hMemDC, 0, 0, nWidth, nHeight, hScrDC, nX, nY, SRCCOPY);
hBitmap = (HBITMAP)SelectObject(hMemDC, hOld); // 取回新位圖句柄
DeleteDC(hScrDC); DeleteDC(hMemDC);
return hBitmap; // 呼叫端負責 DeleteObject
}
BOOL SaveBitmapToFile(HBITMAP hBitmap, LPCTSTR szFile) {
BITMAP bm; GetObject(hBitmap, sizeof(bm), &bm);
// 1. 計算位元深度與調色盤
HDC hDC = CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
int bits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
DeleteDC(hDC);
WORD wBitCount = (bits<=1)?1:(bits<=4)?4:(bits<=8)?8:(bits<=24)?24:32;
DWORD dwPaletteSize = (wBitCount<=8) ? (1<
// 1. 截取當前視窗
CRect rect; GetWindowRect(&rect);
HBITMAP hBmp = CopyScreenToBitmap(&rect);
SaveBitmapToFile(hBmp, _T("C:\\WindowCapture.bmp"));
DeleteObject(hBmp);
// 2. 全螢幕截圖
CRect scr;
scr.SetRect(0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
HBITMAP hBmp2 = CopyScreenToBitmap(&scr);
SaveBitmapToFile(hBmp2, _T("C:\\FullScreen.bmp"));
DeleteObject(hBmp2);
| 點 | 說明 |
|---|---|
| DC 類型 | CreateDC("DISPLAY") 取得螢幕 DC;CreateCompatibleDC 建立記憶體 DC 繪圖不閃爍。 |
| BitBlt | 光柵操作 SRCCOPY 直接像素複製,最快。 |
| 掃描行對齊 | BMP 規定每行 4 位元組對齊:((Width*Bits+31)/32)*4。 |
| GetDIBits | 將裝置相關位圖 (DDB) 轉為裝置獨立位圖 (DIB),含調色盤實現。 |
| 調色盤處理 | 256 色以下需 DEFAULT_PALETTE 實現顏色映射,高色深可略過。 |
| 記憶體管理 | GlobalAlloc(GHND) 可移動記憶體,GlobalLock/Unlock/Free 配對。 |
| 資源釋放 | DeleteDC, ReleaseDC, DeleteObject(hBitmap), CloseHandle 嚴格配對。 |
Bitmap::FromHBITMAP + Save,代碼更簡潔,支援 PNG/JPG。雙函式組合實現了純 GDI、無外部依賴、支援任意矩形區域、標準 BMP 輸出的螢幕截圖功能。理解 DC → BitBlt → DIB → BMP File 數據流向與對齊/調色盤細節,是 Windows 圖形程式設計的核心基本功。