在Windows中将控件的图像从句柄渲染到图像

时间:2018-12-06 15:40:45

标签: c# .net controls rendering handle

我正在使用以下代码来渲染特定控件的图像,并为其指定一个指针;该控件托管在一个应用程序中,该控制台应用程序选择指向该控件的指针,并将该控件呈现为位图(您可以将该代码转储到新的控制台应用程序中并进行尝试,您只需要替换路径和指向您要使用的其他控件的句柄的指针):

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace BitmapGenerator
{
    class Program
    {

        [DllImport("gdi32.dll")]
        public static extern bool BitBlt(IntPtr hdc, int x, int y, int cx, int cy, IntPtr hdcSrc, int x1, int y1, uint rop);

        static void Main(string[] args)
        {
            ControlToPNG(1920, 1080, IntPtr.Zero, @"C:\Users\User\Desktop\Output.png");
        }

        static void ControlToPNG(int controlWidth, int controlHeight, IntPtr controlHandle, string path)
        {
            using (var fileStream = File.Create(path))
                ControlToPNG(controlWidth, controlHeight, controlHandle, fileStream);
        }

        static void ControlToPNG(int controlWidth, int controlHeight, IntPtr controlHandle, Stream stream)
        {
            using (var bitmap = new Bitmap(controlWidth, controlHeight))
            using (var destinationGraphics = Graphics.FromImage(bitmap))
            using (var sourceGraphics = Graphics.FromHwnd(controlHandle))
            {
                IntPtr destinationHandle = IntPtr.Zero;
                IntPtr sourceHandle = IntPtr.Zero;
                try
                {
                    destinationHandle = destinationGraphics.GetHdc();
                    sourceHandle = sourceGraphics.GetHdc();
                    BitBlt(destinationHandle, 0, 0, controlWidth, controlHeight, sourceHandle, 0, 0, 0xCC0020);
                }
                finally
                {
                    if (destinationHandle != IntPtr.Zero)
                        destinationGraphics.ReleaseHdc(destinationHandle);
                    if (sourceHandle != IntPtr.Zero)
                        sourceGraphics.ReleaseHdc(sourceHandle);
                }
                bitmap.Save(stream, ImageFormat.Png);
            }
        }
    }
}

这似乎还可以,但是,它始终可以准确显示我在显示器上看到的内容。更具体地说,它不仅会绘制控件,而且与控件边界重叠的所有窗口也会在位图中呈现。所以,这是我的要求:

1)是否可以单独获得控件的呈现?换句话说,是否可以过滤掉控件顶部重叠的窗口或控件?

2)是否有可能获得整个控件的渲染,甚至是我的应用程序中当前不可见的部分(例如,如果我的控件的高度为800像素,但我将窗口最小化为400像素)这样我只能看到800像素中的400像素-我可以将整个800像素渲染为位图吗?

0 个答案:

没有答案