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