15

我想在我的应用程序中为用户提供他们桌面的缩小屏幕截图。

有没有办法截取当前用户的 Windows 桌面?

我正在用 C# 编写,但如果有其他语言的更好解决方案,我愿意接受。

澄清一下,我需要一张 Windows 桌面的截图——那只是壁纸和图标;没有应用程序或任何有焦点的东西。

4

5 回答 5

16

您正在寻找Graphics.CopyFromScreen。创建一个大小合适的新 Bitmap,并将 Bitmap 的 Graphics 对象屏幕坐标传递给要复制的区域。

还有一篇文章描述了如何以编程方式拍摄快照。

对编辑的回应:我误解了您所说的“桌面”是什么意思。如果您想为桌面拍照,您必须:

  1. 首先使用 Win32API (发送MIN_ALL消息)最小化所有窗口
  2. 拍摄快照
  3. 然后撤消所有最小化(发送MIN_ALL_UNDO消息)。

更好的方法是不要干扰其他窗口,而是直接从桌面窗口复制图像。User32 中的 GetDesktopWindow将返回桌面句柄。获得窗口句柄后,获取它的设备上下文并将图像复制到新的位图。

CodeProject上有一个很好的例子,说明如何从中复制图像。在“捕获窗口内容”部分中查找有关获取和创建设备上下文的示例代码。

于 2009-05-19T03:52:30.860 回答
10

我的印象是,您正在拍摄实际桌面的照片(带有壁纸和图标),仅此而已。

1) 使用 COM 在 Shell32 中调用 ToggleDesktop()
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;

    }

调整以适应多个显示器场景(尽管听起来这对您的应用程序来说应该很好)。

于 2009-05-19T04:12:06.597 回答
2

您可能会考虑通过 p/invoke使用GetDesktopWindow ,然后获取设备上下文并拍摄快照。这里有一个非常详细的教程。这可能比扰乱现有的窗户更好。

于 2009-05-19T04:28:15.263 回答
0

在应用程序运行或使用其他桌面之前,您始终可以通过桌面切换在 Windows 启动时捕获屏幕截图。看看这里: http: //www.codeproject.com/Articles/7666/Desktop-Switching 切换到其他桌面,拍照并记住你不需要显示它只需创建它“桌面”

于 2012-09-26T07:45:24.260 回答
-2

所有以前的答案都是完全错误的(最小化应用程序是荒谬的
只需使用 SHW api:一行代码(桌面位图被缓存,api 只是将它传送到你的 HDC ......)

于 2009-05-20T14:31:55.330 回答