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

Windows 多顯示器截圖實現:從單螢幕到虛擬螢幕的關鍵差異

     編輯:關於C語言

前言:為什麼網路上的截圖代碼多不支援多螢幕?

許多開發者在實作截圖功能時,直接複製單螢幕版本的代碼,發現在多顯示器環境下失效。其實,支援多顯示器並不需要複雜的 EnumDisplayMonitors 等 API,只需修正兩個核心點:裝置內容(DC)獲取方式 與 虛擬螢幕座標系計算。

核心差異一:DC(Device Context)的獲取

場景API 呼叫說明
單主螢幕hScrDC = CreateDC(_T("DISPLAY"), NULL, NULL, NULL);建立主顯示裝置的 DC
多顯示器(虛擬螢幕)hScrDC = ::GetDC(GetDesktopWindow());獲取整個桌面視窗的 DC,涵蓋所有顯示器組成的虛擬螢幕

關鍵點: GetDesktopWindow() 返回的視窗跨越所有監視器,其 DC 即為「虛擬螢幕 DC」。

核心差異二:座標系與尺寸計算

多顯示器環境下,桌面形成一個大的「虛擬螢幕」,原點 (0,0) 固定在主顯示器的左上角。副螢幕若在主螢幕左側或上方,其座標會是負值。

必須使用 GetSystemMetrics 的虛擬螢幕參數:

int cxVirtual = GetSystemMetrics(SM_CXVIRTUALSCREEN);  // 虛擬螢幕總寬度
int cyVirtual = GetSystemMetrics(SM_CYVIRTUALSCREEN);  // 虛擬螢幕總高度
int xVirtual  = GetSystemMetrics(SM_XVIRTUALSCREEN);   // 虛擬螢幕左上角 X(可能為負)
int yVirtual  = GetSystemMetrics(SM_YVIRTUALSCREEN);   // 虛擬螢幕左上角 Y(可能為負)

座標系圖解

主螢幕 (0,0) ──────────────────► X
      │
      │   副螢幕 (負座標)
      ▼
      Y

錯誤假設: 以為邊界是 (0,0) → (cx, cy)。
正確邊界: (xVirtual, yVirtual) → (xVirtual + cxVirtual, yVirtual + cyVirtual)。

完整截圖流程調整

  1. 用 GetDC(GetDesktopWindow()) 取得虛擬螢幕 DC。
  2. 用 SM_CXVIRTUALSCREEN 等指標取得完整範圍與原點。
  3. 建立相容 DC 與位圖,寬高用虛擬螢幕尺寸。
  4. BitBlt 時,來源座標從 (xVirtual, yVirtual) 開始。
  5. 釋放資源時注意 ReleaseDC 對應 GetDC。

快速移植檢查清單

若你手邊有單螢幕截圖代碼,只需修改以下三處即可支援多顯示器:

  • ✅ DC 來源:CreateDC("DISPLAY") → GetDC(GetDesktopWindow())
  • ✅ 寬高:SM_CXSCREEN → SM_CXVIRTUALSCREEN
  • ✅ 起始座標:(0,0) → (SM_XVIRTUALSCREEN, SM_YVIRTUALSCREEN)

多螢幕截圖其實很簡單,關鍵在於理解「虛擬螢幕」座標系與主螢幕原點的關係。別再被 EnumDisplayMonitors 嚇倒了!

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved