我的代码仅在插入随机 MsgBox 时有效
My code only works when I insert a random MsgBox
我在尝试获取表单中 TableLayoutPanel 的屏幕截图时遇到了一个非常奇怪的问题。
我有这段代码(取自另一个问题 (How to get a screenshot, only for a picturebox);代码由用户 "Chase Rocker" 提供):
Dim s As Size = TableLayoutPanel1.Size
Dim memoryImage = New Bitmap(s.Width, s.Height)
Dim memoryGraphics As Graphics = Graphics.FromImage(memoryImage)
Dim ScreenPos As Point = Me.TableLayoutPanel1.PointToScreen(New Point(0, 0))
memoryGraphics.CopyFromScreen(ScreenPos.X, ScreenPos.Y, 0, 0, s)
Form3.PictureBox1.SizeMode = PictureBoxSizeMode.AutoSize
Form3.PictureBox1.BringToFront()
Form3.PictureBox1.Image = memoryImage
现在,我的问题来了。这段代码给了我一张空白图片。它显然截取了屏幕截图,但我只能看到白色。现在,我试图查看大小是否正确,所以我在搞乱 MsgBox。我将这一行添加到代码中:
MsgBox("Random Message")
得到
Dim s As Size = TableLayoutPanel1.Size
MsgBox("Random Message")
Dim memoryImage = New Bitmap(s.Width, s.Height)
Dim memoryGraphics As Graphics = Graphics.FromImage(memoryImage)
Dim ScreenPos As Point = Me.TableLayoutPanel1.PointToScreen(New Point(0, 0))
memoryGraphics.CopyFromScreen(ScreenPos.X, ScreenPos.Y, 0, 0, s)
Form3.PictureBox1.SizeMode = PictureBoxSizeMode.AutoSize
Form3.PictureBox1.BringToFront()
Form3.PictureBox1.Image = memoryImage
由于某种我不知道的原因,屏幕截图现在可以使用了。我不再看到白色,而是 TableLayoutPanel 的实际屏幕截图。对我来说,代码只适用于 MsgBox 是很奇怪的。也许我错过了什么。有谁知道为什么会这样?谢谢!
如果您尝试让 TableLayoutPanel
将其自身绘制到位图上呢?这可以使用 Control.DrawToBitmap()
方法来完成。
Dim s As Size = TableLayoutPanel1.Size
Dim memoryImage As New Bitmap(s.Width, s.Height)
TableLayoutPanel1.DrawToBitmap(memoryImage, New Rectangle(New Point(0, 0), s))
Form3.PictureBox1.Image = memoryImage
如果 TableLayoutPanel 填充发生在您抓取图像的同一事件处理程序中,则 Windows 没有为添加到 TableLayoutPanel 的元素绘制 UI。只有当你从事件处理程序中退出时,winforms 引擎才有机会绘制所有内容。
添加 MessageBox 会改变一切,因为调用 Show(一种模式调用会中断您的代码并将控制权交还给 window)允许 Winform 引擎绘制挂起的更新并且您的代码可以正常工作。
您可以添加一个Timer控件,将执行ScreenShoot的代码放在Timer事件中。
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
......
' code that fills the TableLayoutPanel
......
Dim tim1 = new System.Windows.Forms.Timer()
tim1.Interval = 1
AddHandler tim1.Tick, AddressOf tim1Ticked
tim1.Start()
End Sub
Private Sub tim1Ticked(sender As Object, e As EventArgs)
......
' Code that execute the screenshoot.
......
Dim t = DirectCast(sender, System.Windows.Forms.Timer)
t.Stop()
End Sub
我在尝试获取表单中 TableLayoutPanel 的屏幕截图时遇到了一个非常奇怪的问题。
我有这段代码(取自另一个问题 (How to get a screenshot, only for a picturebox);代码由用户 "Chase Rocker" 提供):
Dim s As Size = TableLayoutPanel1.Size
Dim memoryImage = New Bitmap(s.Width, s.Height)
Dim memoryGraphics As Graphics = Graphics.FromImage(memoryImage)
Dim ScreenPos As Point = Me.TableLayoutPanel1.PointToScreen(New Point(0, 0))
memoryGraphics.CopyFromScreen(ScreenPos.X, ScreenPos.Y, 0, 0, s)
Form3.PictureBox1.SizeMode = PictureBoxSizeMode.AutoSize
Form3.PictureBox1.BringToFront()
Form3.PictureBox1.Image = memoryImage
现在,我的问题来了。这段代码给了我一张空白图片。它显然截取了屏幕截图,但我只能看到白色。现在,我试图查看大小是否正确,所以我在搞乱 MsgBox。我将这一行添加到代码中:
MsgBox("Random Message")
得到
Dim s As Size = TableLayoutPanel1.Size
MsgBox("Random Message")
Dim memoryImage = New Bitmap(s.Width, s.Height)
Dim memoryGraphics As Graphics = Graphics.FromImage(memoryImage)
Dim ScreenPos As Point = Me.TableLayoutPanel1.PointToScreen(New Point(0, 0))
memoryGraphics.CopyFromScreen(ScreenPos.X, ScreenPos.Y, 0, 0, s)
Form3.PictureBox1.SizeMode = PictureBoxSizeMode.AutoSize
Form3.PictureBox1.BringToFront()
Form3.PictureBox1.Image = memoryImage
由于某种我不知道的原因,屏幕截图现在可以使用了。我不再看到白色,而是 TableLayoutPanel 的实际屏幕截图。对我来说,代码只适用于 MsgBox 是很奇怪的。也许我错过了什么。有谁知道为什么会这样?谢谢!
如果您尝试让 TableLayoutPanel
将其自身绘制到位图上呢?这可以使用 Control.DrawToBitmap()
方法来完成。
Dim s As Size = TableLayoutPanel1.Size
Dim memoryImage As New Bitmap(s.Width, s.Height)
TableLayoutPanel1.DrawToBitmap(memoryImage, New Rectangle(New Point(0, 0), s))
Form3.PictureBox1.Image = memoryImage
如果 TableLayoutPanel 填充发生在您抓取图像的同一事件处理程序中,则 Windows 没有为添加到 TableLayoutPanel 的元素绘制 UI。只有当你从事件处理程序中退出时,winforms 引擎才有机会绘制所有内容。
添加 MessageBox 会改变一切,因为调用 Show(一种模式调用会中断您的代码并将控制权交还给 window)允许 Winform 引擎绘制挂起的更新并且您的代码可以正常工作。
您可以添加一个Timer控件,将执行ScreenShoot的代码放在Timer事件中。
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
......
' code that fills the TableLayoutPanel
......
Dim tim1 = new System.Windows.Forms.Timer()
tim1.Interval = 1
AddHandler tim1.Tick, AddressOf tim1Ticked
tim1.Start()
End Sub
Private Sub tim1Ticked(sender As Object, e As EventArgs)
......
' Code that execute the screenshoot.
......
Dim t = DirectCast(sender, System.Windows.Forms.Timer)
t.Stop()
End Sub