首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

Win32 開發入門(22):螢幕擷取 - StretchBlt 縮放複製與 NOTSRCCOPY 反色效果

     編輯:關於C++

使用 StretchBlt 將全螢幕內容縮放複製至視窗客戶區,支援 SRCCOPY 正常複製與 NOTSRCCOPY 反色效果。本文完整解析裝置內容獲取、座標計算與光柵操作模式。

核心流程

  1. 獲取螢幕 DC:GetDC(NULL)
  2. 獲取視窗 DC:GetDC(hWnd)
  3. 取得螢幕解析度:GetSystemMetrics(SM_CXSCREEN/CYSCREEN)
  4. 取得視窗客戶區矩形:GetClientRect
  5. 呼叫 StretchBlt 縮放複製
  6. 釋放 DC: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);
}

StretchBlt 參數詳解


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) 常用值

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:

  1. 第一次:螢幕正常 → 視窗反色
  2. 第二次:視窗反色內容作為來源 → 再次反色 → 回復正常
  3. 結果:視窗顯示「正常螢幕」疊加「先前反色殘留」的混合畫面

原理:NOTSRCCOPY 讀取**目標 DC 當前內容**作為運算來源之一(視 ROP 定義),而非單純反轉來源像素。

進階:高品質螢幕擷取

  • 多顯示器:EnumDisplayMonitors 遍歷各監視器矩形,分別擷取。
  • DPI 感知:SetProcessDPIAware + GetScaleFactorForMonitor 計算實際像素。
  • 無框/透明視窗:WS_EX_LAYERED + UpdateLayeredWindow 實現半透明疊加。
  • 效能優化:建立相容記憶體 DC (CreateCompatibleDC) + 位圖 (CreateCompatibleBitmap) 雙重緩衝,減少閃爍。
  • 現代 API: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);
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved