使用 StretchBlt 將全螢幕內容縮放複製至視窗客戶區,支援 SRCCOPY 正常複製與 NOTSRCCOPY 反色效果。本文完整解析裝置內容獲取、座標計算與光柵操作模式。
GetDC(NULL)GetDC(hWnd)GetSystemMetrics(SM_CXSCREEN/CYSCREEN)GetClientRectStretchBlt 縮放複製ReleaseDC
void CaptureScreenToWindow(HWND hWnd) {
HDC hdcScreen = GetDC(NULL); // 螢幕 DC
HDC hdcWindow = GetDC(hWnd); // 視窗 DC
int scrWidth = GetSystemMetrics(SM_CXSCREEN);
int scrHeight = GetSystemMetrics(SM_CYSCREEN);
RECT rcClient;
GetClientRect(hWnd, &rcClient); // 客戶區矩形
// 縮放複製:螢幕全螢幕 → 視窗客戶區
StretchBlt(
hdcWindow, // 目標 DC
0, 0, // 目標左上角
rcClient.right, rcClient.bottom,// 目標寬高
hdcScreen, // 來源 DC
0, 0, // 來源左上角
scrWidth, scrHeight, // 來源寬高
SRCCOPY // 光柵操作:直接複製
);
ReleaseDC(NULL, hdcScreen);
ReleaseDC(hWnd, hdcWindow);
}
BOOL StretchBlt(
HDC hdcDest, int xDest, int yDest, int wDest, int hDest, // 目標
HDC hdcSrc, int xSrc, int ySrc, int wSrc, int hSrc, // 來源
DWORD rop // 光柵操作
);
| ROP 代碼 | 效果 | 公式 |
|---|---|---|
SRCCOPY | 直接複製來源 | dest = src |
NOTSRCCOPY | 反色複製 | dest = ~src |
SRCAND | 來源 AND 目標 | dest = src & dest |
SRCINVERT | 來源 XOR 目標 | dest = src ^ dest |
WHITENESS | 填滿白色 | dest = 1 |
BLACKNESS | 填滿黑色 | dest = 0 |
// 將 SRCCOPY 改為 NOTSRCCOPY
StretchBlt(hdcWindow, 0,0, rcClient.right,rcClient.bottom,
hdcScreen, 0,0, scrWidth,scrHeight, NOTSRCCOPY);

若連續兩次 NOTSRCCOPY:

原理:NOTSRCCOPY 讀取**目標 DC 當前內容**作為運算來源之一(視 ROP 定義),而非單純反轉來源像素。
EnumDisplayMonitors 遍歷各監視器矩形,分別擷取。SetProcessDPIAware + GetScaleFactorForMonitor 計算實際像素。WS_EX_LAYERED + UpdateLayeredWindow 實現半透明疊加。CreateCompatibleDC) + 位圖 (CreateCompatibleBitmap) 雙重緩衝,減少閃爍。Desktop Duplication API (DXGI) 高效能、無撕裂、支援 HDR。
// 獲取 DC 成對釋放
HDC hdc = GetDC(hwnd);
// ... 使用 ...
ReleaseDC(hwnd, hdc); // 必須配對
// 建立 DC/位圖成對刪除
HDC memDC = CreateCompatibleDC(hdc);
HBITMAP bmp = CreateCompatibleBitmap(hdc, w, h);
// ... 使用 ...
DeleteObject(bmp);
DeleteDC(memDC);