Существует ли способ сделать снимок экрана рабочего стола Windows пользователя?

Абстрактные фабрики отлично подходят для поддержки нескольких платформ, сохраняя при этом унифицированную кодовую базу. Предположим, у вас есть большая программа на Qt или GTK + или .NET / Mono, которую вы хотите запустить в Windows, Linux и OSX. Но у вас есть функция, которая реализуется по-разному на каждой платформе (возможно, через API-интерфейс kernel32 или POSIX).

public abstract class Feature
{
    public abstract int PlatformSpecificValue { get; }

    public static Feature PlatformFeature
    {
        get
        {
            string platform;
            // do platform detection here
            if (platform == "Win32")
                return new Win32Feature();
            if (platform == "POSIX")
                return new POSIXFeature();
        }
    }

    // platform overrides omitted
}

С помощью этой абстрактной фабрики вашему интерфейсу не нужно ничего знать о текущей платформе.

Feature feature = Feature.PlatformFeature;
Console.WriteLine(feature.PlatformSpecificValue);
15
задан Damovisa 19 May 2009 в 04:27
поделиться

4 ответа

Вы ищете Graphics.CopyFromScreen . Создайте новый Bitmap подходящего размера и передайте экранные координаты области объекта Bitmap Graphics области для копирования.

Также есть статья , описывающая, как программно делать снимки.

Response to edit ]: Я неправильно понял, что вы имели в виду под «рабочим столом». Если вы хотите сделать снимок рабочего стола, вам необходимо:

  1. Свернуть все окна с помощью Win32API (отправить сообщение MIN_ALL ) сначала
  2. Сделать снимок
  3. Затем отмените свертывание всех (отправьте сообщение MIN_ALL_UNDO ).

Лучшим способом сделать это было бы не мешать другим окнам, а скопировать изображение прямо из окна рабочего стола . GetDesktopWindow в User32 вернет дескриптор рабочего стола. Получив дескриптор окна, получите контекст устройства и скопируйте изображение в новое растровое изображение.

В CodeProject есть отличный пример того, как скопировать изображение из него. Найдите пример кода о получении и создании контекста устройства в разделе «Захват содержимого окна».

16
ответ дан 1 December 2019 в 02:46
поделиться

У меня сложилось впечатление, что вы снимаете фактический рабочий стол (с обоями и значками) и ничего больше.

1) Вызов ToggleDesktop () в Shell32 с помощью COM
2) Используйте Graphics.CopyFromScreen, чтобы скопировать текущую область рабочего стола
3) Вызов ToggleDesktop (), чтобы восстановить предыдущее состояние рабочего стола

Изменить: Да, вызов MinimizeAll () является агрессивным.

Вот обновленная версия, которую я собрал вместе:

    /// <summary>
    /// Minimizes all running applications and captures desktop as image
    /// Note: Requires reference to "Microsoft Shell Controls and Automation"
    /// </summary>
    /// <returns>Image of desktop</returns>
    private Image CaptureDesktopImage() {

        //May want to play around with the delay.
        TimeSpan ToggleDesktopDelay = new TimeSpan(0, 0, 0, 0, 150);

        Shell32.ShellClass ShellReference = null;

        Bitmap WorkingImage = null;
        Graphics WorkingGraphics = null;
        Rectangle TargetArea = Screen.PrimaryScreen.WorkingArea;
        Image ReturnImage = null;

        try
        {

            ShellReference = new Shell32.ShellClass();
            ShellReference.ToggleDesktop();

            System.Threading.Thread.Sleep(ToggleDesktopDelay);

            WorkingImage = new Bitmap(TargetArea.Width,
                TargetArea.Height);

            WorkingGraphics = Graphics.FromImage(WorkingImage);
            WorkingGraphics.CopyFromScreen(TargetArea.X, TargetArea.X, 0, 0, TargetArea.Size);

            System.Threading.Thread.Sleep(ToggleDesktopDelay);
            ShellReference.ToggleDesktop();

            ReturnImage = (Image)WorkingImage.Clone();

        }
        catch
        {
            System.Diagnostics.Debugger.Break();
            //...
        }
        finally
        {
            WorkingGraphics.Dispose();
            WorkingImage.Dispose();
        }

        return ReturnImage;

    }

Настройте по вкусу для сценариев с несколькими мониторами (хотя это звучит так, как будто это должно работать в вашем приложении).

10
ответ дан 1 December 2019 в 02:46
поделиться

Все предыдущие ответы полностью неверны ( минимизировать приложения абсурдно )
Просто используйте SHW api: одна строка кода (растровое изображение рабочего стола кэшируется, api просто копирует его на HDC ...)

-2
ответ дан 1 December 2019 в 02:46
поделиться

Вы можете посмотреть использование GetDesktopWindow через p / invoke, затем получить контекст устройства и сделать снимок. Здесь есть очень подробное руководство . Это может быть лучше, чем беспокоить существующие окна.

2
ответ дан 1 December 2019 в 02:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: