Capture Image of Entire Panel Control In Vb.net - 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

Related

How do I make controls inside of a FlowLayoutPanel do things?

I'm adding controls to a FlowLayoutPanel like this:
Dim box As New PictureBox
(I'm making the controls using code, then I'm using FlowPanelLayout1.Controls.Add(box)).
How do I make these controls do things? In my code I'm using For Each, so multiple are made using this, my goal is to make each one be able to do what I want and the code for each would be different. How can I achieve this goal?
I believe what you're after is AddHandler. AddHandler allows you to programmatically assign code to an event at runtime. So you can create a Sub specifically to handle events from the picture boxes you create.
You can also retrieve the control that raised the event. This allows you to modify it, or access it's tag, allowing you to attach data to the PictureBox when you add it to the FlowLayoutPanel.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'Create a new picturebox
Dim PB As New PictureBox With {.Size = New Drawing.Size(50, 50), .SizeMode = PictureBoxSizeMode.Normal}
PB.Image = Image.FromFile("res.png")
'Add it to the FlowLayoutPanel
FlowLayoutPanel1.Controls.Add(PB)
'Assign HandlePictureboxClick() to handle the PictureBox's DoubleClick event.
AddHandler PB.DoubleClick, AddressOf HandlePictureboxClick
End Sub
Public Sub HandlePictureboxClick(sender As Object, e As EventArgs)
'Retrive the control that raised the event (In this case, the one you double-clicked)
Dim Picturebox As PictureBox = CType(sender, PictureBox)
'Do whatever you want to do with it
Picturebox.SizeMode = PictureBoxSizeMode.Zoom
End Sub
The example above will change the PictureBox's size mode to zoom when the user double clicks on it, without modifying the other PictureBoxes in the FlowLayoutPanel

How to place a transparent picture box above a web browser control

I want a webbrowser control on the background and a picturebox above it where I can draw and then it will appear above the webbrowser control. It's like I am writing on some paper which already has something written on it. I have placed a webbrowser control and a picture box above it both with same dimensions.
I know similar question has been asked a lot of time on this website in different forms but none of the solutions mentioned are working for me.
The solutions mentioned are usually for picturebox over picturebox not picturebox over webbrowser control. simply putting webbrowser control instead of picture does not work. Here is the code I used. The square that should have been formed was not formed.
Public Class Form1
Dim BMP As New Drawing.Bitmap(640, 480)
Dim GFX As Graphics = Graphics.FromImage(BMP)
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
PictureBox1.Controls.Add(WebBrowser1)
PictureBox1.Location = New Point(0, 0)
PictureBox1.BackColor = Color.Transparent
Dim blackPen As New Pen(Color.Black, 3)
Dim point1 As New Point(100, 100)
Dim point2 As New Point(100, 200)
Dim point3 As New Point(200, 200)
Dim point4 As New Point(200, 100)
Dim curvePoints As Point() = {point1, point2, point3, point4}
GFX.FillRectangle(Brushes.White, 0, 0, PictureBox1.Width, PictureBox1.Height)
GFX.DrawPolygon(blackPen, curvePoints)
PictureBox1.Image = BMP
End Sub
End Class
It did not work the other way around either, I mean drawing first and than making the picturebox transparent.

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

Vb.net PRTSC (Screen capture) - Error

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

add on click event to picturebox vb.net

I have a flowLayoutPanel which I am programatically adding new panelLayouts to. Each panelLayout has a pictureBox within it. It's all working nicely, but I need to detect when that picture box is clicked on. How do I add an event to the picture? I seem to only be able to find c# examples....
my code to add the image is as follows...
' add pic to the little panel container
Dim pic As New PictureBox()
pic.Size = New Size(cover_width, cover_height)
pic.Location = New Point(10, 0)
pic.Image = Image.FromFile("c:/test.jpg")
panel.Controls.Add(pic)
'add pic and other labels (hidden in this example) to the big panel flow
albumFlow.Controls.Add(panel)
So I assume somewhere when I'm creating the image I add an onclick event. I need to get the index for it also if that is possible! Thanks for any help!
Use the AddHandler statement to subscribe to the Click event:
AddHandler pic.Click, AddressOf pic_Click
The sender argument of the pic_Click() method gives you a reference to the picture box back:
Private Sub pic_Click(ByVal sender As Object, ByVal e As EventArgs)
Dim pic As PictureBox = DirectCast(sender, PictureBox)
' etc...
End Sub
If you need additional info about the specific control, like an index, then you can use the Tag property.
Substitute PictureBox1 with the name of your control.
Private Sub PictureBox1_Click(sender As Object, e As EventArgs) Handles PictureBox1.Click
'executes when PictureBox1 is clicked
End Sub