微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用sharpdx和hwnd捕获窗口?

如何解决如何使用sharpdx和hwnd捕获窗口?

我是编程新手,对于不准确的地方,我深表歉意。我试图捕获由它的 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;
            }

获取窗口hwnd的方法

            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 举报,一经查实,本站将立刻删除。