【问题标题】:Make .NET snipping tool compatible with multiple monitors使 .NET 截图工具与多台显示器兼容
【发布时间】:2010-10-23 20:26:26
【问题描述】:

此帖子中提供了另一种截图工具解决方案:.NET Equivalent of Snipping Tool

现在有必要让它适用于选定的屏幕(在多显示器系统上)。

代码做了相应的修改:

Public Class SnippingTool


    Private Shared _Screen As Screen

    Private Shared BitmapSize As Size

    Private Shared Graph As Graphics


    Public Shared Function Snip(ByVal screen As Screen) As Image

        _Screen = screen

        Dim bmp As New Bitmap(screen.Bounds.Width, screen.Bounds.Height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb)

        Dim gr As Graphics = Graphics.FromImage(bmp)

        Graph = gr


        gr.SmoothingMode = Drawing2D.SmoothingMode.None '###

        BitmapSize = bmp.Size


        Using snipper = New SnippingTool(bmp)

            snipper.Location = New Point(screen.Bounds.Left, screen.Bounds.Top)

            If snipper.ShowDialog() = DialogResult.OK Then
                Return snipper.Image
            End If

        End Using

        Return Nothing


    End Function



    Public Sub New(ByVal screenShot As Image)
        InitializeComponent()
        Me.BackgroundImage = screenShot
        Me.ShowInTaskbar = False
        Me.FormBorderStyle = FormBorderStyle.None


        'Me.WindowState = FormWindowState.Maximized

        Me.DoubleBuffered = True
    End Sub
    Public Property Image() As Image
        Get
            Return m_Image
        End Get
        Set(ByVal value As Image)
            m_Image = Value
        End Set
    End Property
    Private m_Image As Image


    Private rcSelect As New Rectangle()
    Private pntStart As Point

    Protected Overrides Sub OnMouseDown(ByVal e As MouseEventArgs)
        ' Start the snip on mouse down
        If e.Button <> MouseButtons.Left Then
            Return
        End If
        pntStart = e.Location
        rcSelect = New Rectangle(e.Location, New Size(0, 0))
        Me.Invalidate()
    End Sub
    Protected Overrides Sub OnMouseMove(ByVal e As MouseEventArgs)
        ' Modify the selection on mouse move
        If e.Button <> MouseButtons.Left Then
            Return
        End If
        Dim x1 As Integer = Math.Min(e.X, pntStart.X)
        Dim y1 As Integer = Math.Min(e.Y, pntStart.Y)
        Dim x2 As Integer = Math.Max(e.X, pntStart.X)
        Dim y2 As Integer = Math.Max(e.Y, pntStart.Y)
        rcSelect = New Rectangle(x1, y1, x2 - x1, y2 - y1)
        Me.Invalidate()
    End Sub


    Protected Overrides Sub OnMouseUp(ByVal e As MouseEventArgs)
        ' Complete the snip on mouse-up
        If rcSelect.Width <= 0 OrElse rcSelect.Height <= 0 Then
            Return
        End If
        Image = New Bitmap(rcSelect.Width, rcSelect.Height)
        Using gr As Graphics = Graphics.FromImage(Image)
            gr.DrawImage(Me.BackgroundImage, New Rectangle(0, 0, Image.Width, Image.Height), rcSelect, GraphicsUnit.Pixel)
        End Using
        DialogResult = DialogResult.OK
    End Sub
    Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
        ' Draw the current selection
        Using br As Brush = New SolidBrush(Color.FromArgb(120, Color.White))
            Dim x1 As Integer = rcSelect.X
            Dim x2 As Integer = rcSelect.X + rcSelect.Width
            Dim y1 As Integer = rcSelect.Y
            Dim y2 As Integer = rcSelect.Y + rcSelect.Height
            e.Graphics.FillRectangle(br, New Rectangle(0, 0, x1, Me.Height))
            e.Graphics.FillRectangle(br, New Rectangle(x2, 0, Me.Width - x2, Me.Height))
            e.Graphics.FillRectangle(br, New Rectangle(x1, 0, x2 - x1, y1))
            e.Graphics.FillRectangle(br, New Rectangle(x1, y2, x2 - x1, Me.Height - y2))
        End Using
        Using pen As New Pen(Color.Red, 3)
            e.Graphics.DrawRectangle(pen, rcSelect)
        End Using
    End Sub
    Protected Overrides Function ProcessCmdKey(ByRef msg As Message, ByVal keyData As Keys) As Boolean
        ' Allow canceling the snip with the Escape key
        If keyData = Keys.Escape Then
            Me.DialogResult = DialogResult.Cancel
        End If
        Return MyBase.ProcessCmdKey(msg, keyData)
    End Function

    Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
        MyBase.OnLoad(e)
        Me.Size = New Size(_Screen.Bounds.Width, _Screen.Bounds.Height)
        Dim area = _Screen.WorkingArea
        Graph.CopyFromScreen(area.X, area.Y, area.Y, area.Y, BitmapSize)
    End Sub

End Class

但它拒绝按预期工作。剪辑器不会出现在所选屏幕上,而是出现在第一个屏幕上,无论“剪辑”功能中的“屏幕”参数如何。 如何使其正常工作?

更新:最新的 snipper 版本出现在正确的屏幕上,但为空白。

UPDATE X2 :上面的代码已经更新以反映最新版本,现在可以正常工作。

【问题讨论】:

    标签: .net screen screenshot capture


    【解决方案1】:

    LoveDotNet,我相信你的源代码有一个小问题,如下一行:

    Graph.CopyFromScreen(area.X, area.Y, area.Y, area.Y, BitmapSize)

    应该是:

    Graph.CopyFromScreen(area.X, area.Y, 0, 0, BitmapSize)

    另外,给想要使用此代码的任何人的快速提示,您可以像下面这样调用它:

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim img As Image = SnippingTool.Snip(Screen.AllScreens(0)) 'Set to (1) for secondary monitor'
    End Sub
    

    另外,当您创建 SnippingTool 表单时,请务必将 StartPosition 属性更改为 Manual

    大编辑:

    我做了一些工作来一次支持多个监视器,这不需要开发人员选择要使用的监视器(这克隆了“截图工具”更接近一点)。

    基本上我会遍历所有屏幕以找到最小的XY 坐标,以及最大的RightBottom,这让我们可以评估“虚拟监视器”的全尺寸:

    我已经用我的配置对其进行了测试:

    Primary 1280x800

    Secondary 1280x1024 w/ -224 X offset

    代码:

    'SnippingTool Code: Place this in a new form (set the StartUp Property to Manual)'
    Public Class SnippingTool
    
    
    Private Shared _Screen As Screen
    
    Private Shared BitmapSize As Size
    
    Private Shared Graph As Graphics
    
    Private Structure MultiScreenSize
        Dim minX As Integer
        Dim minY As Integer
        Dim maxRight As Integer
        Dim maxBottom As Integer
    End Structure
    
    
    Private Shared Function FindMultiScreenSize() As MultiScreenSize
    
        Dim minX As Integer = Screen.AllScreens(0).Bounds.X
        Dim minY As Integer = Screen.AllScreens(0).Bounds.Y
    
        Dim maxRight As Integer = Screen.AllScreens(0).Bounds.Right
        Dim maxBottom As Integer = Screen.AllScreens(0).Bounds.Bottom
    
        For Each aScreen As Screen In Screen.AllScreens
            If aScreen.Bounds.X < minX Then
                minX = aScreen.Bounds.X
            End If
    
            If aScreen.Bounds.Y < minY Then
                minY = aScreen.Bounds.Y
            End If
    
            If aScreen.Bounds.Right > maxRight Then
                maxRight = aScreen.Bounds.Right
            End If
    
            If aScreen.Bounds.Bottom > maxBottom Then
                maxBottom = aScreen.Bounds.Bottom
            End If
        Next
        Dim m_MultiScreenSize As MultiScreenSize
        With m_MultiScreenSize
            .minX = minX
            .minY = minY
            .maxBottom = maxBottom
            .maxRight = maxRight
        End With
        Return m_MultiScreenSize
    End Function
    Public Shared Function Snip() As Image
        Dim m_MultiScreenSize As MultiScreenSize = FindMultiScreenSize()
    
        Dim bmp As New Bitmap(m_MultiScreenSize.maxRight - m_MultiScreenSize.minX, _
                              m_MultiScreenSize.maxBottom - m_MultiScreenSize.minY, _
                              System.Drawing.Imaging.PixelFormat.Format32bppPArgb)
        Dim gr As Graphics = Graphics.FromImage(bmp)
    
        Graph = gr
    
    
        gr.SmoothingMode = Drawing2D.SmoothingMode.None 
        BitmapSize = bmp.Size
    
    
        Using snipper = New SnippingTool(bmp)
    
            snipper.Location = New Point(m_MultiScreenSize.minX, m_MultiScreenSize.minY)
    
            If snipper.ShowDialog() = DialogResult.OK Then
                Return snipper.Image
            End If
    
        End Using
    
        Return Nothing
    
    
    End Function
    
    
    
    Public Sub New(ByVal screenShot As Image)
        InitializeComponent()
        Me.BackgroundImage = screenShot
        Me.ShowInTaskbar = False
        Me.FormBorderStyle = FormBorderStyle.None
    
        Me.DoubleBuffered = True
    End Sub
    Public Property Image() As Image
        Get
            Return m_Image
        End Get
        Set(ByVal value As Image)
            m_Image = Value
        End Set
    End Property
    Private m_Image As Image
    
    
    Private rcSelect As New Rectangle()
    Private pntStart As Point
    
    Protected Overrides Sub OnMouseDown(ByVal e As MouseEventArgs)
        ' Start the snip on mouse down'
        If e.Button <> MouseButtons.Left Then
            Return
        End If
        pntStart = e.Location
        rcSelect = New Rectangle(e.Location, New Size(0, 0))
        Me.Invalidate()
    End Sub
    Protected Overrides Sub OnMouseMove(ByVal e As MouseEventArgs)
        ' Modify the selection on mouse move'
        If e.Button <> MouseButtons.Left Then
            Return
        End If
        Dim x1 As Integer = Math.Min(e.X, pntStart.X)
        Dim y1 As Integer = Math.Min(e.Y, pntStart.Y)
        Dim x2 As Integer = Math.Max(e.X, pntStart.X)
        Dim y2 As Integer = Math.Max(e.Y, pntStart.Y)
        rcSelect = New Rectangle(x1, y1, x2 - x1, y2 - y1)
        Me.Invalidate()
    End Sub
    
    
    Protected Overrides Sub OnMouseUp(ByVal e As MouseEventArgs)
        ' Complete the snip on mouse-up'
        If rcSelect.Width <= 0 OrElse rcSelect.Height <= 0 Then
            Return
        End If
        Image = New Bitmap(rcSelect.Width, rcSelect.Height)
        Using gr As Graphics = Graphics.FromImage(Image)
            gr.DrawImage(Me.BackgroundImage, New Rectangle(0, 0, Image.Width, Image.Height), _
                         rcSelect, GraphicsUnit.Pixel)
        End Using
        DialogResult = DialogResult.OK
    End Sub
    Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
        ' Draw the current selection'
        Using br As Brush = New SolidBrush(Color.FromArgb(120, Color.White))
            Dim x1 As Integer = rcSelect.X
            Dim x2 As Integer = rcSelect.X + rcSelect.Width
            Dim y1 As Integer = rcSelect.Y
            Dim y2 As Integer = rcSelect.Y + rcSelect.Height
            e.Graphics.FillRectangle(br, New Rectangle(0, 0, x1, Me.Height))
            e.Graphics.FillRectangle(br, New Rectangle(x2, 0, Me.Width - x2, Me.Height))
            e.Graphics.FillRectangle(br, New Rectangle(x1, 0, x2 - x1, y1))
            e.Graphics.FillRectangle(br, New Rectangle(x1, y2, x2 - x1, Me.Height - y2))
        End Using
        Using pen As New Pen(Color.Red, 3)
            e.Graphics.DrawRectangle(pen, rcSelect)
        End Using
    End Sub
    Protected Overrides Function ProcessCmdKey(ByRef msg As Message, ByVal keyData As Keys) As Boolean
        ' Allow canceling the snip with the Escape key'
        If keyData = Keys.Escape Then
            Me.DialogResult = DialogResult.Cancel
        End If
        Return MyBase.ProcessCmdKey(msg, keyData)
    End Function
    
    Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
        MyBase.OnLoad(e)
        Dim m_MultiScreenSize As MultiScreenSize = FindMultiScreenSize()
        Me.Size = New Size(m_MultiScreenSize.maxRight - m_MultiScreenSize.minX, _
                           m_MultiScreenSize.maxBottom - m_MultiScreenSize.minY)
    
        Graph.CopyFromScreen(m_MultiScreenSize.minX, m_MultiScreenSize.minY, 0, 0, BitmapSize)
    End Sub
     End Class
    

    你可以这样称呼它:

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim img As Image = SnippingTool.Snip()
        img.Save("C:\ScreenShot.png")
    End Sub
    

    【讨论】:

    • 谢谢你,但是当Bitmap bmp = bmp = new Bitmap(m_MultiScreenSize.maxRight - m_MultiScreenSize.minX, m_MultiScreenSize.maxBottom - m_MultiScreenSize.minY, System.Drawing.Imaging.PixelFormat.Format32bppPArgb); 被调用时,所有的参数都是0(除了PixelFormat),这会导致一个参数异常被抛出。知道是什么原因造成的吗?
    • 关于我上面的评论:我无脑(而且愚蠢地)通过 VB > C# 转换器运行它,这就是导致我的问题的原因。具体来说,结构的成员没有被设置!这段代码很好用!谢谢。
    【解决方案2】:

    在设置SnippingTool的位置之前,需要将表单的StartPosition设置为Manual,否则无论如何都会放在主屏幕上。在构造函数或 using 语句中执行此操作,它应该可以解决您的问题。

    StartPosition = FormStartPosition.Manual;
    

    【讨论】:

    • 谢谢,但这只是解决方案的一部分,我已经在 .Designer 文件中设置了这个。我将在下面回答问题并描述使其工作的方法。
    • @Sphynx:我明白了。我没有看到那句话,所以这就是为什么我认为这是原因。我让它在我的电脑上运行并使用了WorkingArea(正如你在回答中描述的那样),但不知道他们都需要让它工作。很高兴你能解决它。
    【解决方案3】:

    我没有看到你做错了什么。我无法测试这个,现在没有设置。 Bounds 有点棘手,它背后有一堆代码可以确保表单不能显示在屏幕外。作为替代方案,您可以改为设置 Location 属性并覆盖 SnippingTool 中的 OnLoad() 以设置 WindowState 属性。

    【讨论】:

    • 尝试了许多不同的方法。上面的帖子已经过编辑以反映最新版本。现在它在正确的屏幕上显示表单,但无法在其上绘制任何内容。表单显示为空白,就像我们删除 CopyFromScreen 一样。有什么想法吗?
    • 我不知道,仍然没有硬件。如果你把它寄给我,我会修理它。 Graphics.CopyFromScreen() 中有一个错误,它看不到分层窗口。将 notepad.exe 放在该屏幕上进行检查。
    • 当然可以发送。您只需要 SnippingTool 类还是整个测试应用程序?我认为它与分层窗口无关......
    • 我也没有第二台显示器或其他任何人来帮助我解决这个问题。我唯一能提供的就是赏金,你可能不会对此感兴趣。但无论如何我都赞成你的评论,因为它很有趣:)
    • 不,你是对的,但我将应用程序提供给其他有额外监视器的人进行测试。他不是程序员。
    【解决方案4】:

    我创建了帮助程序类来捕获控件所在的特定屏幕上的选定区域。它适用于多个屏幕。

    这个想法取自多个在线资源,基本上冻结屏幕并放入 PictureBox .NET 控件。

    代码如下:

    public class CaptureScreen : IDisposable
    {
        readonly Control control;
        readonly Pen penSelectedAreaScreenShot;
    
        Form frmPictureBox = null;
        PictureBox pictureBoxScreenShot = null;
        Point selectedScreenShotStartPoint;
        Size selectedScreenShotSize;
        bool isMouseDownSelectedScreenShot = false;
    
        public event Action<object, Bitmap> SelectedScreenAreaCaptured;
    
        public event Action<object, Exception> ScreenCaptureFailed;
    
        public CaptureScreen(Control control)
        {
            if (control == null)
            {
                throw new ArgumentNullException("control");
            }
    
            this.control = control;
    
            this.penSelectedAreaScreenShot = new Pen(Color.Red, 1);
            this.penSelectedAreaScreenShot.DashStyle = DashStyle.Dot;
        }
    
        public void BeginStart()
        {
            #region Setup the Picture Box for ScreenShot
    
            if (this.frmPictureBox != null)
            {
                this.frmPictureBox.Close();
                this.frmPictureBox.Dispose();
                this.frmPictureBox = null;
            }
    
            if (this.pictureBoxScreenShot != null)
            {
                this.pictureBoxScreenShot.Dispose();
                this.pictureBoxScreenShot = null;
            }
    
            this.frmPictureBox = new Form
            {
                BackColor = Color.Black,
                Cursor = Cursors.Cross,
                FormBorderStyle = FormBorderStyle.None,
                StartPosition = FormStartPosition.CenterParent,
                TopLevel = true,
                TopMost = true,
                Top = 0,
                Left = 0,
                WindowState = FormWindowState.Maximized,
                KeyPreview = true
            };
    
            this.pictureBoxScreenShot = new PictureBox
            {
                Location = new Point(0, 0),
                SizeMode = PictureBoxSizeMode.Zoom
            };
            this.frmPictureBox.Controls.Add(this.pictureBoxScreenShot);
    
            #endregion
    
            #region Capture the Screen
    
            Bitmap screenShotBitmap = null;
            Graphics graphics = null;
            MemoryStream stream = null;
            try
            {
                Screen currentScreen = Screen.FromControl(this.control);
    
                screenShotBitmap = new Bitmap(currentScreen.Bounds.Width, currentScreen.Bounds.Height);
    
                graphics = Graphics.FromImage(screenShotBitmap as Image);
                graphics.CopyFromScreen(currentScreen.Bounds.X, currentScreen.Bounds.Y, 0, 0, screenShotBitmap.Size);
    
                stream = new MemoryStream();
                screenShotBitmap.Save(stream, ImageFormat.Png);
    
                this.pictureBoxScreenShot.Size = screenShotBitmap.Size;
                this.pictureBoxScreenShot.Image = Image.FromStream(stream);
            }
            catch (Exception ex)
            {
                if (this.ScreenCaptureFailed != null)
                {
                    this.ScreenCaptureFailed(this, ex);
                }
            }
            finally
            {
                if (stream != null)
                {
                    stream.Close();
                    stream.Dispose();
                    stream = null;
                }
    
                if (graphics != null)
                {
                    graphics.Dispose();
                    graphics = null;
                }
    
                if (screenShotBitmap != null)
                {
                    screenShotBitmap.Dispose();
                    screenShotBitmap = null;
                }
            }
    
            #endregion
    
            this.frmPictureBox.KeyDown += this.frmPictureBox_KeyDown;
    
            this.pictureBoxScreenShot.MouseMove += this.pictureBoxScreenShot_MouseMove;
            this.pictureBoxScreenShot.MouseDown += this.pictureBoxScreenShot_MouseDown;
            this.pictureBoxScreenShot.MouseUp += this.pictureBoxScreenShot_MouseUp;
    
            this.frmPictureBox.Show(this.control);
        }
    
        public void Exit()
        {
            if (this.frmPictureBox != null)
            {
                this.frmPictureBox.Close();
                this.frmPictureBox.Dispose();
                this.frmPictureBox = null;
            }
    
            if (this.pictureBoxScreenShot != null)
            {
                this.pictureBoxScreenShot.Dispose();
                this.pictureBoxScreenShot = null;
            }
    
            this.isMouseDownSelectedScreenShot = false;
        }
    
        [DebuggerStepThrough]
        void frmPictureBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Escape)
            {
                this.Exit();
            }
        }
    
        void pictureBoxScreenShot_MouseMove(object sender, MouseEventArgs e)
        {
            if (this.pictureBoxScreenShot.Image == null)
            {
                this.Exit();
                return;
            }
    
            if (this.isMouseDownSelectedScreenShot)
            {
                this.pictureBoxScreenShot.Refresh();
    
                this.selectedScreenShotSize = new Size(
                    e.X - this.selectedScreenShotStartPoint.X,
                    e.Y - this.selectedScreenShotStartPoint.Y);
    
                // Draw the selected area rectangle.
                this.pictureBoxScreenShot.CreateGraphics().DrawRectangle(this.penSelectedAreaScreenShot,
                    this.selectedScreenShotStartPoint.X, this.selectedScreenShotStartPoint.Y,
                    this.selectedScreenShotSize.Width, this.selectedScreenShotSize.Height);
            }
        }
    
        void pictureBoxScreenShot_MouseDown(object sender, MouseEventArgs e)
        {
            if (!this.isMouseDownSelectedScreenShot)
            {
                if (e.Button == MouseButtons.Left)
                {
                    this.selectedScreenShotStartPoint = new Point(e.X, e.Y);
                }
    
                this.pictureBoxScreenShot.Refresh();
    
                this.isMouseDownSelectedScreenShot = true;
            }
        }
    
        void pictureBoxScreenShot_MouseUp(object sender, MouseEventArgs e)
        {
            if (this.pictureBoxScreenShot.Image == null)
            {
                this.Exit();
                return;
            }
    
            isMouseDownSelectedScreenShot = false;
    
            this.frmPictureBox.Hide();
    
            // Check whether there is something get selected.
            if (this.selectedScreenShotSize.Width > 0 && this.selectedScreenShotSize.Height > 0)
            {
                Bitmap selectedAreaBitmap = null;
                Graphics graphics = null;
                Bitmap screenShotBitmap = null;
    
                try
                {
                    selectedAreaBitmap = new Bitmap(this.selectedScreenShotSize.Width, this.selectedScreenShotSize.Height);
    
                    graphics = Graphics.FromImage(selectedAreaBitmap);
    
                    graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
                    graphics.CompositingQuality = CompositingQuality.HighQuality;
    
                    screenShotBitmap = new Bitmap(this.pictureBoxScreenShot.Image, this.pictureBoxScreenShot.Size);
                    graphics.DrawImage(screenShotBitmap, 0, 0, new Rectangle(this.selectedScreenShotStartPoint, this.selectedScreenShotSize), GraphicsUnit.Pixel);
    
                    if (this.SelectedScreenAreaCaptured != null)
                    {
                        this.SelectedScreenAreaCaptured(this, selectedAreaBitmap);
                    }
                    else
                    {
                        Clipboard.SetImage(selectedAreaBitmap);
                        MessageBox.Show(this.control, "Selected Screen is copied to Clipboard.");
                    }
                }
                catch (Exception ex)
                {
                    if (this.ScreenCaptureFailed != null)
                    {
                        this.ScreenCaptureFailed(this, ex);
                    }
                }
                finally
                {
                    if (screenShotBitmap != null)
                    {
                        screenShotBitmap.Dispose();
                        screenShotBitmap = null;
                    }
    
                    if (graphics != null)
                    {
                        graphics.Dispose();
                        graphics = null;
                    }
    
                    if (selectedAreaBitmap != null)
                    {
                        selectedAreaBitmap.Dispose();
                        selectedAreaBitmap = null;
                    }
                }
            }
    
            this.Exit();
        }
    
        #region IDisposable Member
    
        public void Dispose()
        {
            try
            {
                this.Exit();
            }
            catch { }
        }
    
        #endregion
    
    }
    

    你可以这样使用它:

       CaptureScreen captureScreen = new CaptureScreen(this);
    
       // If event not implement, then by default it will copied to clipboard.
       //captureScreen.SelectedScreenAreaCaptured += delegate(object am_sender, Bitmap am_selectedAreaBitmap)
       //{
            //string destFilename = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), String.Format("Capture_{0}.png", DateTime.Now.ToString("yyyyMMddHHmmss")));
            //am_selectedAreaBitmap.Save(destFilename, System.Drawing.Imaging.ImageFormat.Png);                
       //};
    
       // Implements this to handle the exception that occurs during screen capture.
       //captureScreen.ScreenCaptureFailed += delegate(object am_sender, Exception am_ex)
       //{
            //MessageBox.Show(this, am_ex.Message, "Unable to Capture the Screen", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
       //};
    
       captureScreen.BeginStart();
    

    【讨论】:

      【解决方案5】:

      解决方案是使用Screen.WorkingArea 属性而不是Screen.Bounds。 第二个选项使用Graphics.CopyFromScreen 产生不正确的结果。 上面的代码 sn-p 已经更新为全功能版本。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-03-30
        • 1970-01-01
        • 1970-01-01
        • 2016-09-30
        • 1970-01-01
        • 2021-05-16
        • 2011-03-08
        • 2021-07-19
        相关资源
        最近更新 更多