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

C# 螢幕截圖三種方案深度解析 (一)

     編輯:關於C語言

自動化測試中截取 WPF Popup 視窗失敗,引發對三種截圖方案的深入探索。本文記錄從 GDI → PrintWindow → 模擬鍵盤的嘗試歷程與失敗原因分析。

方案一:GDI BitBlt (標準 HWND 截圖)

BitBlt(hdcDest, 0, 0, width, height, hdcSrc, left, top, SRCCOPY);

現象:截取 Popup 只得到背景,Popup 內容透明。
原因:WPF 使用 DirectX 渲染,不繪製到 GDI DC。BitBlt 僅能捕捉 GDI 繪製內容。

方案二:PrintWindow API

IntPtr hdc = GetWindowDC(hwnd);
IntPtr hdcMem = CreateCompatibleDC(hdc);
IntPtr hBmp = CreateCompatibleBitmap(hdc, w, h);
SelectObject(hdcMem, hBmp);
PrintWindow(hwnd, hdcMem, 0); // 關鍵調用
// ... 取得位圖並儲存

現象:視窗框架 (MFC 部分) 正常,但所有 WPF 區域 (按鈕、文字、圖表) 均為純黑。
原因:PrintWindow 發送 WM_PRINT/WM_PRINTCLIENT 訊息要求視窗繪製到指定 DC,但 WPF 視覺樹不處理此訊息進行 DirectX→GDI 回繪。

核心結論:WPF ≠ GDI

WPF (Windows Presentation Foundation) 採用保留模式繪圖,透過 DirectX (Milcore) 直接與 GPU 交互,繞過傳統 GDI/GDI+ 堆疊。因此:

  • 任何依賴 HDC/BitBlt/PrintWindow 的傳統截圖手段,**無法**捕捉 WPF 視覺內容。
  • 僅能捕捉視窗非用戶區 (標題列、邊框) 及裝載於 HWND 中的 Win32 子控制項。

方案三預告:模擬 PrintScreen

系統級 PrintScreen 由 Windows 視窗管理器 (DWM) 協助完成畫面合成,包含 DirectX 表面。下一篇將實測模擬鍵盤事件 + 剪貼簿讀取方案。

延伸知識:DWM 與畫面合成

Windows Vista 引入 Desktop Window Manager (DWM),所有視窗 (含 WPF、Win32) 以紋理形式提交給 DWM 合成最終桌面影像。PrintScreen 實際讀取的是這張合成後的桌面紋理,故能包含 WPF 內容。

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