问题描述
我是编程新手,对于不准确的地方,我深表歉意。我试图捕获由它的 hwnd 指定的窗口并将其保存到位图。我找到了捕获整个桌面屏幕的方法,当我尝试更改代码以达到我想要的效果时,它会返回空字节数组。
如果有人知道捕获窗口的答案或其他方法(即使它被覆盖),我会非常感激。
截屏方法:
public static Bitmap ScreanCapture(Window window)
{
//SharpDX.Configuration.EnableObjectTracking = true;
//System.Diagnostics.Debug.Write(SharpDX.Diagnostics.ObjectTracker.ReportActiveObjects());
var d3device = new SharpDX.Direct3D11.Device(DriverType.Hardware,SharpDX.Direct3D11.DeviceCreationFlags.BgraSupport);
var d3dcontext = new SharpDX.Direct3D11.DeviceContext(d3device);
var dxgiDevice = d3device.QueryInterface<SharpDX.dxgi.Device1>();
var dxgiFactory = dxgiDevice.Adapter.GetParent<SharpDX.dxgi.Factory2>();
SwapChainDescription1 swapDesc = new SwapChainDescription1
{
BufferCount = 2,Format = Format.R8G8B8A8_Unorm,Usage = Usage.rendertargetOutput,Width = window.GetwindowWidth(),Height = window.GetwindowHeight(),Stereo = false,SampleDescription = new SampleDescription(1,0),AlphaMode = SharpDX.dxgi.AlphaMode.Ignore,Scaling = Scaling.None,Flags = SwapChainFlags.None,SwapEffect = SwapEffect.FlipSequential
};
var swapChain = new SwapChain1(dxgiFactory,dxgiDevice,window.GetID(),ref swapDesc);
Surface surface;
using (Texture2D backBuffer = swapChain.GetBackBuffer<Texture2D>(0))
{
Texture2DDescription desc = backBuffer.Description;
desc.cpuAccessFlags = cpuAccessFlags.Read;
desc.Usage = ResourceUsage.Staging;
desc.OptionFlags = ResourceOptionFlags.None;
desc.BindFlags = BindFlags.None;
using (Texture2D tempbuffer = new Texture2D(swapChain.GetDevice<SharpDX.Direct3D11.Device>(),desc))
{
backBuffer.Device.ImmediateContext.copyResource(backBuffer,tempbuffer);
surface = tempbuffer.QueryInterface<Surface>();
}
}
DataStream dataStream;
var map = surface.Map(SharpDX.dxgi.MapFlags.Read,out dataStream);
byte[] data = new byte[surface.Description.Width * surface.Description.Height * 4];
int dataCounter = 0;
int actualWidth = surface.Description.Width * 4;
while (dataCounter < data.Length)
{
uint currentPixel = dataStream.Read<uint>();
uint r = (currentPixel & 0x3FF);
uint g = (currentPixel & 0xFFC00) >> 10;
uint b = (currentPixel & 0x3FF00000) >> 20;
uint a = (currentPixel & 0xC0000000) >> 30;
data[dataCounter++] = (byte)(b >> 2);
data[dataCounter++] = (byte)(g >> 2);
data[dataCounter++] = (byte)(r >> 2);
data[dataCounter++] = (byte)(a << 6);
while ((dataCounter % map.Pitch) >= actualWidth)
{
dataStream.Read<byte>();
dataCounter++;
}
}
//data array has only 0
GCHandle handle = GCHandle.Alloc(data,GCHandleType.Pinned);
Bitmap bitmap = null;
try
{
bitmap = new Bitmap(surface.Description.Width,surface.Description.Height,map.Pitch,PixelFormat.Format32bppArgb,handle.AddrOfPinnedobject());
}
finally
{
if (handle.IsAllocated)
{
handle.Free();
}
}
//disposing COM
dataStream.dispose();
surface.Unmap();
swapChain.dispose();
dxgiDevice.dispose();
dxgiFactory.dispose();
d3dcontext.dispose();
d3device.dispose();
return bitmap;
}
public static IReadOnlyList<Window> allWindows()
{
List<Window> list = new List<Window>();
WndEnumProc wndEnumProc = new WndEnumProc(OnWindowsEnum);
EnumWindows(wndEnumProc,0);
return list;
bool OnWindowsEnum(IntPtr hwnd,IntPtr lparam)
{
IntPtr hwndTry,hwndWalk = IntPtr.Zero;
if (!IsWindowVisible(hwnd) || GetwindowText(hwnd) == String.Empty)
return true;
hwndTry = GetAncestor(hwnd,GA_ROOTOWNER);
while (hwndTry != hwndWalk)
{
hwndWalk = hwndTry;
hwndTry = GetLastActivePopup(hwndWalk);
if (IsWindowVisible(hwndTry))
break;
}
if (hwndWalk != hwnd)
return true;
if (IsWindowCloaked(hwnd))
return true;
if ((getwindowlongPtr(hwnd,GWL_EXSTYLE) & WS_EX_TOOLWINDOW) != 0)
return true;
var newWindow = new Window(hwnd,GetwindowText(hwnd),GetAbsoluteClientRect(hwnd));
if(!list.Contains(newWindow))
list.Add(newWindow);
return true;
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)