2015-08-22 61 views
8

我想捕獲基於窗口句柄的C#中的桌面窗口。我使用.NET並使用PInvoke來GetWindowRect()來捕獲窗口矩形。我有窗口選擇和矩形捕獲工作正常。沒有窗口陰影檢索窗口大小

但是,捕獲的窗口矩形不僅包括實際的窗口大小,還包括窗口的裝飾物,比如它周圍的陰影。當我嘗試將窗口剪輯爲位圖時,位圖包含區域和陰影。在Windows 10,我得到透明的陰影區,包括可能是活動窗口下方可見的任何內容:

enter image description here

我用的是很簡單的捕獲通過PInvoke的呼叫使用Win32 GetWindowRect()的窗口中的代碼:

var rect = new Rect(); 
GetWindowRect(handle, ref rect); 
var bounds = new Rectangle(rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top); 
var result = new Bitmap(bounds.Width, bounds.Height); 

using (var graphics = Graphics.FromImage(result)) 
{ 
    graphics.CopyFromScreen(new Point(bounds.Left, bounds.Top), Point.Empty, bounds.Size); 
} 

return result; 

然後我捕捉圖像並將其分配到圖片框中。

另外,它看起來像是在窗戶之間有一些變化 - 有些窗戶有其他人沒有的陰影。大部分都是這樣,但有些像Visual Studio和Chrome一樣,所以它甚至不是一個簡單的剝離無關像素的問題。

我試過使用GetClientRect(),但這只是客戶區,這是不是我以後。我想得到的是具有邊框但沒有陰影的實際窗口矩形。

有沒有辦法做到這一點?

+0

您可能需要查看[SystemInformation](https://msdn.microsoft.com/en-us/library/system.windows.forms.systeminformation.aspx)以獲得一致的邊框尺寸,添加到客戶區域。 – t0mm13b

+0

而不是從屏幕上覆制,你應該從窗口的DC('GetWindowDC')複製 - 即使它被另一個覆蓋,這個窗口也會得到。此外,請參閱[本頁]的第3條評論(https://msdn.microsoft.com/en-us/library/windows/desktop/ms633519.aspx)。 –

+0

看到這個[問題](http://stackoverflow.com/questions/16493698/drop-shadow-on-a-borderless-winform)臨時修改窗口創建params通過反轉CS_DROPSHADOW標誌去除陰影,捕獲窗口,並恢復掩碼。 – t0mm13b

回答

1

我正在運行Windows 10,並在編寫應用程序將窗口對齊到屏幕的頂部或底部時出現相同的問題。我發現DwmGetWindowAttribute()可以工作。它返回比GetWindowRect()稍微不同的值的RECT ...

結果從採樣窗口:

GetWindowRect():{X = 88,Y = 26,寬度= 871,高度= 363}

DwmGetWindowAttribute():{X = 95,Y = 26,寬度= 857,高度= 356}

我的測試表明,GetWindowRect()包括的裝飾,而DwmGetWindowAttribute()沒有。

如果你在裝飾物的窗口上得到兩種方法的相同結果,那可能是那個特定的窗口正在繪製它自己的裝飾物,或者有一些其他的屬性或屬性需要設置到窗口中考慮到。

+0

這是從DwmGetWindowAttribute檢索到的擴展框架邊界嗎? – NetMage

+0

DwmGetWindowAttribute()給了我實際的邊框,而GetWindowRect()在邊框周圍包含了半透明的「模糊」陰影。 – dynamichael