【问题标题】:Is there a way to take a screenshot of the user's Windows desktop?有没有办法截取用户的 Windows 桌面?
【发布时间】:2009-05-19 03:47:40
【问题描述】:

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

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

我用 C# 编写,但如果有更好的解决方案用另一种语言,我愿意接受。

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

【问题讨论】:

    标签: c# windows desktop screenshot


    【解决方案1】:

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

    还有an article 描述了如何以编程方式拍摄快照。

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

    1. Minimize all windows using the Win32API(发MIN_ALL消息)
    2. 拍摄快照
    3. 然后撤消所有最小化(发送MIN_ALL_UNDO 消息)。

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

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

    【讨论】:

    • 如果我的应用程序是焦点,我可以这样做吗?如果它们在桌面前面,它不会捕获我的应用程序窗口(和其他)吗?
    • 我试过GetDesktopWindow,但它捕获了桌面前面的窗口
    • 任何带有完整源代码示例的最终解决方案?
    【解决方案2】:

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

    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;
    
        }
    

    调整以适应多个监视器场景(尽管听起来这对您的应用程序来说应该可以正常工作)。

    【讨论】:

    • 很好的答案!在不被剪切 -n- 粘贴的情况下说明需要的内容。我希望更多这样的答案是这样的。
    • 谢谢,这正是我所追求的。我假设在 Shell32 中有一个类似的方法,我可以调用它来恢复我的应用程序以在之后获得焦点。
    • @Damovisa - 需要恢复的不仅仅是您的应用程序。随机最小化用户的所有应用程序并不是一个好习惯......
    • @Damovisa:我完全同意。 @Mr_Mom:谢谢。
    【解决方案3】:

    您可以通过 p/invoke 查看使用GetDesktopWindow,然后获取设备上下文并拍摄快照。有很详细的教程here。这可能比扰乱现有的窗口更好。

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-12-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-11-18
          • 1970-01-01
          相关资源
          最近更新 更多