Абстрактные фабрики отлично подходят для поддержки нескольких платформ, сохраняя при этом унифицированную кодовую базу. Предположим, у вас есть большая программа на 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);
Вы ищете Graphics.CopyFromScreen . Создайте новый Bitmap подходящего размера и передайте экранные координаты области объекта Bitmap Graphics области для копирования.
Также есть статья , описывающая, как программно делать снимки.
Response to edit ]: Я неправильно понял, что вы имели в виду под «рабочим столом». Если вы хотите сделать снимок рабочего стола, вам необходимо:
MIN_ALL
) сначала MIN_ALL_UNDO
). Лучшим способом сделать это было бы не мешать другим окнам, а скопировать изображение прямо из окна рабочего стола . GetDesktopWindow в User32 вернет дескриптор рабочего стола. Получив дескриптор окна, получите контекст устройства и скопируйте изображение в новое растровое изображение.
В CodeProject есть отличный пример того, как скопировать изображение из него. Найдите пример кода о получении и создании контекста устройства в разделе «Захват содержимого окна».
У меня сложилось впечатление, что вы снимаете фактический рабочий стол (с обоями и значками) и ничего больше.
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;
}
Настройте по вкусу для сценариев с несколькими мониторами (хотя это звучит так, как будто это должно работать в вашем приложении).
Все предыдущие ответы полностью неверны ( минимизировать приложения абсурдно )
Просто используйте SHW api: одна строка кода (растровое изображение рабочего стола кэшируется, api просто копирует его на HDC ...)
Вы можете посмотреть использование GetDesktopWindow через p / invoke, затем получить контекст устройства и сделать снимок. Здесь есть очень подробное руководство . Это может быть лучше, чем беспокоить существующие окна.