Vb.net PRTSC (Screen capture) - Error - vb.net

Hi again my question this time its related with this piece of code, im using the visual studio beta 2012, i cant seem to find the issue, if you guys could help me out ill appreciate it
Public Class Form1
Private Sub fullScreen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles fullScreen.Click
SendKeys.SendWait("^{PRTSC}")
Dim clip As IDataObject = Clipboard.GetDataObject()
If clip.GetDataPresent(GetType(System.Drawing.Bitmap)) Then
Dim screenCapture As Bitmap = CType(clip.GetData(GetType(System.Drawing.Bitmap)), Bitmap)
screenCapture.Save("C:\fullScreenCapture.bmp")
End If
Clipboard.Clear()
End Sub
End Class
Error :
A first chance exception of type 'System.Runtime.InteropServices.ExternalException' occurred in System.Drawing.dll
Additional information: Error genérico en GDI+.
If there is a handler for this exception, the program may be safely continued.

You can take a screen shot more easily by using the following (send keys is always hit and miss in my experience)
Private Function TakeScreenShot() As Bitmap
Dim scrn As Screen = Screen.FromControl(Me)
Dim screenSize As Size = New Size(scrn.Bounds.Width, scrn.Bounds.Height)
Dim screenGrab As New Bitmap(screenSize.Width, screenSize.Height)
Dim g As Graphics = Graphics.FromImage(screenGrab)
g.CopyFromScreen(New Point(scrn.Bounds.X, scrn.Bounds.Y), New Point(0, 0), screenSize)
Return screenGrab
End Function

Are you trying to capture the screen? Why not use VS' classes to capture the screen?
http://forum.codecall.net/topic/51761-creating-a-screen-shot-tool-vbnet

Related

VB.Net Metafile generates error ("A generic error occurred in GDI+")

I would like get a little help from you. I am working on a diagram creator which can be called more than once. The diagram every time is different than the earlier version but I would like to use the same filename. The problem is that when I click on the button the program is showing the diagram form with the diagram in the picturebox but if the form is closed and I am clicking on the button again I have an error ("A generic error occurred in GDI+"). I think the mf.dispose() does not close the file and it opened. What do you think what is the problem, how can I solve it?
Main Form:
Imports System.Runtime.InteropServices
Imports System.Drawing.Imaging
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Diagram.create_diagram()
Diagram_FORM.PictureBox1.Image = New Metafile("c:\temp\test.wmf")
Diagram_FORM.Show()
End Sub
Diagram Class:
Imports System.Runtime.InteropServices
Imports System.Drawing.Imaging
Class Diagram
Public Sub create_diagram()
Dim diagram_width As Integer = 600
Dim diagram_Height As Integer = 600
Dim filename As String = "c:\temp\test.wmf"
Dim gr As Graphics
gr = Graphics.FromImage(New Bitmap(diagram_width, diagram_Height))
' Make a Graphics object so we can use its hDC as a reference.
Dim hdc As IntPtr = gr.GetHdc
' Make the Metafile, using the reference hDC.
Dim bounds As New RectangleF(0, 0, Diagram_WidthSize, Diagram_HeightSize)
Dim mf As New Metafile(filename, hdc, bounds, MetafileFrameUnit.Pixel)
gr.ReleaseHdc(hdc)
' Make a Graphics object and draw.
gr = Graphics.FromImage(mf)
gr.PageUnit = GraphicsUnit.Pixel
gr.Clear(Color.White)
draw_diagram_background(gr)
draw_diagram_curve(gr)
gr.Dispose()
mf.Dispose()
End Sub
Private Sub draw_diagram_background(Byval gr as Graphics)
'some code
End Sub
Private Sub draw_diagram_curve(Byval gr as Graphics)
'some code
End Sub
End Class
You need to dispose Diagram_FORM.PictureBox1.Image when you close Form Diagram_FORM, otherwise exception will occur when you init Metafile with same filename c:\temp\test.wmf next time in method create_diagram() of class Diagram:
Dim mf As New Metafile(filename, hdc, bounds, MetafileFrameUnit.Pixel)
You can add the following code in your Diagram_FORM Form to dispose it's PictureBox1.Image when you close it.
Protected Overrides Sub OnFormClosed(e As FormClosedEventArgs)
If PictureBox1.Image IsNot Nothing Then
PictureBox1.Image.Dispose()
End If
MyBase.OnFormClosed(e)
End Sub

My code only works when I insert a random MsgBox

I've encountered a very bizarre problem when trying to get a screenshot of a TableLayoutPanel in my form.
I have this code (taken from another question (How to get a screenshot, only for a picturebox); code courtesy of user "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
Now, here comes my problem. This code gives me a blank picture. It takes the screenshot apparently, but all I can see is white. Now, I was trying to see if the size was correct, so I was messing with MsgBox. I add this line to the code:
MsgBox("Random Message")
Getting
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
By some reason I don't know, the screenshot now works. I don't see white anymore, but the actual screenshot of the TableLayoutPanel. For me is very weird that the code only works with a MsgBox. Maybe I'm missing something. Does anyone know why this happens? Thank you!
How about if you try to make the TableLayoutPanel draw itself to a bitmap instead? This can be done using the Control.DrawToBitmap() method.
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
If the TableLayoutPanel fill happens in the same event handler where you grab the image then Windows has not draw the UI for the elements added to the TableLayoutPanel. Only when you exit from the event handler, the winforms engine has the opportunity to draw everything.
Adding a MessageBox changes everything because calling Show (a modal call that interrupts your code and pass control back to window) allows the Winform engine to draw the pending updates and your code works.
You can add a Timer control and put the code that execute the ScreenShoot in the Timer event.
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

An unhandled exception of type 'System.ArgumentNullException' occurred in System.dll

So i have this piece of code written in VB.NET
and when it gets to about "Dim ping As New Ping" it throws the error "An unhandled exception of type 'System.ArgumentNullException' occurred in System.dll
Additional information: Value cannot be null."
http://pastebin.com/C1nfdzUN
Imports System.Net.NetworkInformation
Public Class Form1
Dim i As Boolean
Dim pingMs As String
'I'm using this in the createTextIcon sub to releases all of the resources that the icon/icons would have used.
Public Declare Function DestroyIcon Lib "user32.dll" (ByVal hIcon As Int32) As Int32
'You should fine tune the font you want to use so the user can see the text you want them to see.
'Certain Fonts will obviously display your text better than other fonts might.
Dim fontToUse As Font = New Font("Microsoft Sans Serif", 8, FontStyle.Regular, GraphicsUnit.Pixel)
'A basic brush with a Dark Blue Color. This should show up pretty well in the icon tray if the user uses the default tray color.
Dim brushToUse As Brush = New SolidBrush(Color.DarkBlue)
'A bitmap used to setup how the icon will display.
Dim bitmapText As Bitmap = New Bitmap(16, 16)
'A simply Grahics object to draw the text to a bitmap.
Dim g As Graphics = Drawing.Graphics.FromImage(bitmapText)
'Will be used to get the Handle to the bitmap Icon.
Dim hIcon As IntPtr
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Application.DoEvents()
Threading.Thread.Sleep(10)
Dim pingTarget As String = ""
Dim numberOfPings As Integer = 0
Dim ping As New Ping
Dim pingRe As PingReply = ping.Send(pingTarget, 1)
Dim o As Boolean = True
Dim delay As Integer = 1
pingTarget = "www.google.com"
i = True
While i
pingMs = pingRe.RoundtripTime.ToString
Label1.Text = pingMs
createTextIcon()
Application.DoEvents()
Do Until o = False
Application.DoEvents()
Threading.Thread.Sleep(10)
delay = delay + 1
If delay = 100 Then
o = False
delay = 1
End If
Loop
o = True
End While
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
i = False
Application.DoEvents()
Close()
End Sub
Sub createTextIcon()
'Clear any previous ‘stuff’ instead of creating a new bitmap.
g.Clear(Color.Transparent)
'Setup the text, font, brush, and position for the system tray icon. For the font type and
'size I used, a good position for the X coordinate is a -1 or -2. And the Y coordinate seems
'to work well at a 5.
'You specify the actual text you want to be displayed in the draw string parameter that you
'want to display in the notify area of the system tray. You will only be able to display a
'few characters, depending on the font, size of the font, and the coordinates you used.
g.DrawString(pingMs, fontToUse, brushToUse, -2, 5)
'Get a handle to the bitmap as a Icon.
hIcon = (bitmapText.GetHicon)
'Display that new usage value image in the system tray.
NotifyText.Icon = Drawing.Icon.FromHandle(hIcon)
'Added this to try and get away from a rare Generic Error from the code above. Using this API Function seems to have stopped that error from happening.
DestroyIcon(hIcon.ToInt32)
End Sub
End Class
You are getting an ArgumentNullException from ping.Send() since pingTarget is an empty string when you call the method.
Move the line
pingTarget = "www.google.com"
above ping.Send().

Capture Image of Entire Panel Control In Vb.net

I have added some richtextboxes and some picture boxes in a panel control with scrolling option enabled. I want to capture image of Panel control along with all its child controls. I tried various solutions available on net but still not able to find perfect solution to do my job. The best one available (which dose not capture what is off the scroll bars) is given below. Please help me to do this.
Dim bmp As New Bitmap(Panel1.Width, Panel1.Height)
Using gr As Graphics = Graphics.FromImage(bmp)
gr.CopyFromScreen(Panel1.PointToScreen(Point.Empty), Point.Empty, Panel1.Size)
End Using
Private Function TakeScreenShot(ByVal Control As Control) As Bitmap
Dim tmpImg As New Bitmap(Control.Width, Control.Height)
Using g As Graphics = Graphics.FromImage(tmpImg)
G.CopyFromScreen(Panel1.PointToScreen(New Point(0, 0)), New Point(0, 0), New Size(Panel1.Width, Panel1.Height))
End Using
Return tmpImg
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
TakeScreenShot(Panel1).Save("D:\Screenshot.png", System.Drawing.Imaging.ImageFormat.Png)
End Sub

Printing a Graphic Object VB.NET

I have a module that generates fill out a System.Drawing.Graphics object.
I then try to print it with a event on my main form but the print preview comes out blank.
This is my print page
Private Sub MyPrintDocument_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles MyPrintDocument.PrintPage
Dim MyGraphic As Graphics
MyPrintDocument.PrinterSettings.DefaultPageSettings.Margins.Top = 200
MyPrintDocument.PrinterSettings.DefaultPageSettings.Margins.Left = 100
MyPrintDocument.PrinterSettings.DefaultPageSettings.Margins.Right = 100
MyPrintDocument.PrinterSettings.DefaultPageSettings.Margins.Bottom = 75
MyGraphic = MyGrpahicPage
End Sub
MyGrpahicPage is the public graphics object my module fill out.
I think the problem is that you have to print to the Graphics object provided by the event argument, not another one that you may have hanging around. In other words, you need to draw on e.Graphics. The help page for PrintPageEventArgs.Graphics shows how this is supposed to work.
I found the way.
1. step: you must create thy MyGraphics in your form:
... Form declaration ...
Private GrBitmap As Bitmap
Private GrGraphics As Graphics
Dimm Withevents pd as new PrintDocument 'The withevents is important!
...
2. step: Anywhere (ig, in the formload sub, or in a buttonclick sub) :
GrBitmap = New Bitmap(Width, Height)
GrGraphics = Graphics.FromImage(GrBitmap)
...
(the Width and the Height values you must calculate by the content of the graphics)
3. step:
Complete the GrGraphics with any .DrawString, .DrawLine, etc. methods
4. step:
Create a sub of Printdocument:
Private Sub pd_PrintPage(sender As Object, ev As PrintPageEventArgs) Handles pd.PrintPage
ev.Graphics.DrawImage(Me.GrBitmap, New Point(0, 0))
End Sub