Визуализация изображения элемента управления в Windows из дескриптора к нему - PullRequest
0 голосов
/ 06 декабря 2018

Я использую следующий код для визуализации изображения определенного элемента управления с указателем на него;элемент управления размещен в одном приложении, и это консольное приложение получает указатель на него и отображает этот элемент управления в растровое изображение (вы можете выгрузить этот код в новое консольное приложение и попробовать его, вам просто нужно заменить путь иуказатель на дескриптор другого элемента управления, который вы хотите использовать):

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 пикселей, чтобы я мог видеть только 400 из 800 пикселей - могу ли я получить все 800 пикселей для рендеринга в растровое изображение)?

...