Center form on screen during runtime - vb.net

I'm using vb.net, and what I have in mind is on clicking a button, the current form will expand and it will be centered on screen.
I've figured out how to expand the form, but I can't center it on screen.
I've tried using this code but it's not what I wanted to get.
Dim Width As Integer = Screen.PrimaryScreen.Bounds.Width
Dim Height As Integer = Screen.PrimaryScreen.Bounds.Height
Me.Location = New Point(Height / 2, Width / 2)
or otherwise: Me.Location = New Point(Width / 2, Height/ 2)
even tried this: Me.StartPosition = FormStartPosition.Center

Use .CentreToScreen()
Like this:
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Me.Size = New System.Drawing.Size(400, 650)
Me.CenterToScreen()
End Sub

Related

How to show custom drawn lines in combobox

I am looking for a way to draw multiple custom lines in my checkbox. I have the following code:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
ComboBox1.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed
ComboBox1.Size = New System.Drawing.Size(100, 20)
ComboBox1.DropDownWidth = 100
ComboBox1.TabIndex = 0
ComboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
ComboBox1.Items.Add("test1")
ComboBox1.Items.Add("test2")
ComboBox1.Items.Add("test3")
AddHandler ComboBox1.DrawItem, AddressOf ComboBox1_DrawItem
End Sub
Private Sub ComboBox1_DrawItem(sender As Object, e As System.Windows.Forms.DrawItemEventArgs)
e.DrawBackground()
Dim black_pen As System.Drawing.Pen = New System.Drawing.Pen(System.Drawing.Color.Black, 2)
black_pen.DashStyle = System.Drawing.Drawing2D.DashStyle.DashDotDot
black_pen.Width = 2
Dim point1 As System.Drawing.Point = New System.Drawing.Point(10, 10)
Dim point2 As System.Drawing.Point = New System.Drawing.Point(90, 10)
e.Graphics.DrawLine(black_pen, point1, point2)
End Sub
I am looking for a way to show three different styled lines in my checkbox, which would be selected by the user. My current result is that I can only see one line so far (it's drawn on the top one combobox item) and other combobox items are empty. I see no values there.
How can I add additional lines/drawn graphics into my checkbox and make them "selectable"?

how to draw on picture box without losing the content after minimizing, vb.net?

When I minimize the form, I lose all the contents drawn on the picture box. I want it to be retain on the picture box. Please help me in this regard.
The code can be seen below..
Private Sub ButtonDraw_Click(sender As Object, e As EventArgs) Handles ButtonDraw.Click
Dim g As Graphics = PictureBox1.CreateGraphics
Dim MyPen As New Pen(Color.Red)
MyPen.Width = 2
MyPen.DashStyle = DashStyle.Solid
g.TranslateTransform(PictureBox1.Width / 2, PictureBox1.Height / 2)
g.DrawEllipse(MyPen, New Rectangle(-150, -150, 300, 300))
End Sub
Example code, using e.Graphics in the Paint() event, as suggested by Jimi:
Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
Dim g As Graphics = e.Graphics
Using MyPen As New Pen(Color.Red)
MyPen.Width = 2
MyPen.DashStyle = DashStyle.Solid
g.TranslateTransform(PictureBox1.Width / 2, PictureBox1.Height / 2)
g.DrawEllipse(MyPen, New Rectangle(-150, -150, 300, 300))
End Using
End Sub

How to avoid overlapping of opaque rectangles on graphics.drawrectangle()?

After a bunch of fail on Google searches finally I thought for asking for experts here to help me at this problem as this site always helped me.
What I want?
I want to create a Highlighter for my some kind of drawing application. I want this to be similar to the highlighter you can see on the Windows Snipping Tool.
What is my problem?
The problem is that although I can draw the semitransparent or opaque rectangles using the code, gfx.FillRectangle(New SolidBrush(Color.FromArgb(100, Colors.GreenYellow)), x, y, width, height), but if I draw another rectangle overlapping any previous rectangles the colors gets darker and reduces the transparency of the rectangles where they overlapped.
Code:
Public Class Form1
Dim drag As Boolean
Dim mouseX, mouseY As Integer
Dim prev As Point
Dim initi As Point
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
Dim grx As Graphics = Panel1.CreateGraphics
grx.DrawString("+", New Font("Arial", 144, FontStyle.Regular), New SolidBrush(Color.FromArgb(100, Color.GreenYellow)), New Point(200, 200))
End Sub
Private Sub Panel1_MouseDown(sender As Object, e As MouseEventArgs) Handles Panel1.MouseDown
drag = True
mouseX = MousePosition.X - Me.Left - 8
mouseY = MousePosition.Y - Me.Top - 34
initi = New Point(mouseX, mouseY)
End Sub
Private Sub Panel1_MouseMove(sender As Object, e As MouseEventArgs) Handles Panel1.MouseMove
If drag Then
mouseX = MousePosition.X - Me.Left - 8
mouseY = MousePosition.Y - Me.Top - 34
End If
End Sub
Private Sub Panel1_MouseUp(sender As Object, e As MouseEventArgs) Handles Panel1.MouseUp
drag = False
prev = New Point(0, 0)
Dim grx As Graphics = Panel1.CreateGraphics
grx.FillRectangle(New SolidBrush(Color.FromArgb(100, Color.GreenYellow)), initi.X, initi.Y, (mouseX - initi.X), (mouseY - initi.Y))
End Sub
End Class
Screenshot of the application (Showing the problem)
Left "+" is the one that I want to draw.
Right "+" is the one that I get when I draw.
I tried this and it works: There are no borders you can't even distinguish the different boxes:
I changed the following:
New SolidBrush(Color.FromArgb(100, Color.GreenYellow)), New Point(200, 200))
Into this:
New SolidBrush(Color.GreenYellow), New Point(200, 200))
For BOTH times: For the declarations and for the Panel1_MouseDown
That is because this sets the Alpha to 1 by defualt making unchangable as well, so over lapping will not change any colours, layers, or visibility.
You should only use FromArgb when you are going to control the alpha of the colour, but in this case you are letting the computer do that for you
Well. I've never really used graphics, but the only thing I could come up with is to create a list of the highlights to be drawn and then each time the mouse_up event fires, create a new bitmap, draw each rectangle pixel by pixel, with semi-transparent pixels to the bitmap and then draw the resulting bitmap to the panel using the panel's paint event handler that fires when you refresh the panel. This seems the built-in alpha blending that .net does automatically.
Add this to your form's variable declarations
Dim highlightsList As New List(Of Rectangle)
Dim bmp1 As Bitmap
alter your form_shown event to
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
bmp1 = New Bitmap(Panel1.Width, Panel1.Height)
End Sub
add this sub which handles the addition of the rectangles to the list and the creation of the bitmap
Private Sub addRectangle(gr As Graphics, x As Integer, y As Integer, v1 As Integer, v2 As Integer)
Dim newRectangle As New Rectangle(x, y, v1, v2)
highlightsList.Add(newRectangle)
Using G As Graphics = Graphics.FromImage(bmp1)
G.Clear(Color.White)
End Using
bmp1.MakeTransparent(Color.White)
For Each rect As Rectangle In highlightsList
For i As Integer = rect.X To rect.X + rect.Width - 1
For j As Integer = rect.Y To rect.Y + rect.Height - 1
bmp1.SetPixel(i, j, Color.FromArgb(100, Color.GreenYellow))
Next
Next
Next
Panel1.Refresh()
End Sub
add a handler for the panel's paint event so that when you refresh the panel, the bitmap is drawn onto it
Private Sub Panel1_Paint(sender As Object, e As PaintEventArgs) Handles Panel1.Paint
e.Graphics.DrawImage(bmp1, 0, 0)
End Sub
and change your mouse_up event to use the above sub to do the drawing
Private Sub Panel1_MouseUp(sender As Object, e As MouseEventArgs) Handles Panel1.MouseUp
drag = False
prev = New Point(0, 0)
Dim grx As Graphics = Panel1.CreateGraphics
'grx.Clear(Panel1.BackColor)
addRectangle(grx, initi.X, initi.Y, (mouseX - initi.X), (mouseY - initi.Y))
End Sub
This seems to work, but if you're using the panel for anything other that showing highlights, it may not work as expected.

How to prevent graphics from resetting [duplicate]

I need to put some graphics in one section of a TableLayoutPanel.
I'm doing this by creating a PictureBox in one cell of the TLP.
Can't get two things to work:
1) The initial display is blank! Drawing appears only when you resize the form
2) The resize event doesn't fire equally when expanding the size as compared contracting.
Any suggestions to improve the above two problems would be great!
Here is my code. The form has a 2x2 TableLayoutPanel in it, and one cell of the TLP has a PictureBox in it. Both the TLP and the PictureBox are set to Fill Parent:
Imports System.Drawing.Drawing2D
Public Class Form1
Private g As Graphics
Dim n As Integer = 0
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Debug.Print(String.Format("{0}{0}Form1_Load at {1}", vbCrLf, Now()))
Me.SetDesktopLocation(800, 200)
End Sub
Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
n += 1
Debug.Print(String.Format("MyBase.Paint: {0}", n))
DisplayMyStuff()
End Sub
Private Sub PictureBox1_Resize(sender As Object, e As EventArgs) Handles Pict ureBox1.Resize
n += 1
Debug.Print(String.Format("PictureBox1.Resize: {0} PictureBoxSize = {1} / {2}", n, PictureBox1.Width, PictureBox1.Height))
If g IsNot Nothing Then
g.Dispose()
End If
g = PictureBox1.CreateGraphics()
End Sub
Private Sub DisplayMyStuff()
Dim rect1 As Rectangle
Dim rect2 As Rectangle
Dim pt1 As New Point(50, 50)
Dim pt2 As New Point(100, 100)
Dim pt3 As New Point(150, 150)
Dim brR As New SolidBrush(Color.Red)
Dim linGradBr As New LinearGradientBrush(pt2, pt3, Color.Yellow, Color.Blue)
Dim pictBoxSize As Size
Dim sz As Size
Dim width, height As Integer
pictBoxSize = New Size(CType(PictureBox1.Size, Point))
width = CInt(pictBoxSize.Width / 2)
height = CInt(pictBoxSize.Height / 2)
sz = New Size(width, height)
n += 1
Debug.Print(String.Format("DisplayMyStuff: {0}, Half-Size = {1} / {2}", n, width, height))
g.Clear(Color.Bisque)
rect1 = New Rectangle(pt1, sz)
rect2 = New Rectangle(pt2, sz)
g.FillRectangle(brR, rect1)
g.FillRectangle(linGradBr, rect2)
brR.Dispose()
linGradBr.Dispose()
End Sub
End Class
Apparently, you are trying to draw to a picturebox (g = PictureBox1.CreateGraphics())
The reason stuff disappears is that when the size changes, or something passes over the window, the controls and form need to be repainted. This happens in the Paint event, so your code needs to do the drawing there. Unlike a PictureBox image, items drawn to a form or control are not persistent on their own, that is done by drawing in the Paint event.
This is essentially your DrawMyStuff procedure relocated to the Picbox's Paint event.
Private Sub PictureBox1_Paint(sender As Object,
e As PaintEventArgs) Handles PictureBox1.Paint
Dim pt1 As New Point(50, 50)
Dim pt2 As New Point(100, 100)
Dim pt3 As New Point(150, 150)
Dim sz As New Size(CInt(PictureBox1.Size.Width / 2),
CInt(PictureBox1.Size.Height / 2))
n += 1
Debug.Print(String.Format("DisplayMyStuff: {0},
Half-Size = {1} / {2}", n, sz.Width, sz.Height))
Dim rect1 As New Rectangle(New Point(50, 50), sz)
Dim rect2 As New Rectangle(New Point(100, 100), sz)
Using linGradBr As New LinearGradientBrush(pt2, pt3, Color.Yellow, Color.Blue)
e.Graphics.Clear(Color.Bisque)
e.Graphics.DrawRectangle(Pens.Black, rect1)
e.Graphics.DrawRectangle(Pens.Black, rect2)
e.Graphics.FillRectangle(Brushes.Red, rect1)
e.Graphics.FillRectangle(linGradBr, rect2)
End Using
End Sub
If you are actually trying to paint on the Form, then Grim's answer is the solution. There you respond to the Form Paint event. In either case, use the Graphics object provided by Windows as an EventArg.
Above, you are using the Graphics object for the PictureBox (via event args) so output is to the PictureBox.
Windows wont know you are drawing something in the Paint event, so you need to tell it that the image needs to be updated at certain times such as when the PictureBox is resized. In the resize event, add:
PictureBox1.Invalidate ' tell windows it needs to be redrawn
' or
PictureBox1.Refresh ' redraw now
Me.Refresh is a bit of overkill because the entire form likely does not need to be repainted.
As Hans Passant says. First get rid of;
Private g As Graphics
and the whole of the PictureBox1_Resize(...)... routine. Then change the following routines to be like so;
Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
DisplayMyStuff(e.Graphics)
End Sub
and
Private Sub DisplayMyStuff(pGraphics As Graphics)
Dim pt1 As New Point(50, 50)
Dim pt2 As New Point(100, 100)
Dim pt3 As New Point(150, 150)
Dim pictBoxSize As New Size(CType(PictureBox1.Size, Point))
Dim width As Integer = CInt(pictBoxSize.Width / 2)
Dim height As Integer = CInt(pictBoxSize.Height / 2)
Dim sz As New Size(width, height)
pGraphics.Clear(Color.Bisque)
Dim rect1 As New Rectangle(pt1, sz)
Dim rect2 As New Rectangle(pt2, sz)
Using linGradBr As New LinearGradientBrush(pt2, pt3, Color.Yellow, Color.Blue)
pGraphics.FillRectangle(Brushes.Red, rect1)
pGraphics.FillRectangle(linGradBr, rect2)
End Using
End Sub
.. then test. Please report back to tell me that you've learned something!! Especially.. that you don't need to create a new red brush - all 'standard' colours are built in - and that using the graphics object properly leads to better, smoother displays.

How to screenshot only the area inside an Ellipse?

I'm creating a little snipping tool-like program in VB.NET and I can screenshot any area I want provided it is a rectangle area. I select the area in the screen and save it as an image. That's easy.
My problem is that I want to be able to screenshot not only a rectangular (standard rectangle shape area), but selecting/drawing an ellipse and screenshot the inside part of it. See the image below:
is there any way to achieve this or any library I can use for that?
Here's my current code:
Public Class Form3
Private _bRubberBandingOn As Boolean = False
Private _pClickStart As New Point
Private _pClickStop As New Point
Private _pNow As New Point
Private Sub Form3_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
Me._bRubberBandingOn = Not _bRubberBandingOn
If Me._bRubberBandingOn Then
If _pClickStart = Nothing Then _pClickStart = New Point
_pClickStart.X = e.X
_pClickStart.Y = e.Y
_pNow.X = e.X
_pNow.Y = e.Y
End If
Me.Invalidate()
End Sub
Private Sub Form3_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
If Me._bRubberBandingOn Then
If _pNow = Nothing Then _pNow = New Point
Me._pNow.X = e.X
Me._pNow.Y = e.Y
Me.Invalidate()
End If
End Sub
Private Sub Form3_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseUp
Me._bRubberBandingOn = Not Me._bRubberBandingOn
If Not Me._bRubberBandingOn Then
If _pClickStop = Nothing Then _pClickStop = New Point
_pClickStop.X = e.X
_pClickStop.Y = e.Y
Me.Invalidate()
End If
End Sub
Private Sub Form3_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
Dim _rRectangle As New Rectangle
Dim _penNew As New Pen(Color.Black, 2)
_rRectangle.X = _pClickStart.X
_rRectangle.Y = _pClickStart.Y
If Me._bRubberBandingOn Then
_rRectangle.Width = Me._pNow.X - _pClickStart.X
_rRectangle.Height = Me._pNow.Y - _pClickStart.Y
Else
_rRectangle.Width = Me._pClickStop.X - _pClickStart.X
_rRectangle.Height = Me._pClickStop.Y - _pClickStart.Y
End If
_penNew.DashStyle = Drawing2D.DashStyle.Solid
e.Graphics.DrawEllipse(_penNew, _rRectangle)
End Sub
End Class
Is there any way to achieve this or any library I can use for that?
Is it any way to get a handle of that painted line/shape and then use it to create a screenshot? I actually searched about this but didn't found anything meaningful yet.
thanks in advance for your time.
Take the image that you are drawing the ellipse on top of and do the following:
Dim theBitmap As Bitmap = DirectCast(Image.FromFile("PathToFileYouAreDrawingEllipseOn.bmp"), Bitmap)
Dim theEllipseBitmap As New Bitmap(theBitmap.Width, theBitmap.Height)
Dim theGraphics As Graphics = Graphics.FromImage(theEllipseBitmap)
Dim theGraphicsPath As New GraphicsPath()
' The (10,10) coordinates here are made up, you will need to take what is drawn by the user (starting x,y; ending x,y, etc.)
theGraphicsPath.AddEllipse(10, 10, theBitmap.Width - 20, theBitmap.Height - 20)
theGraphics.Clear(Color.Magenta)
theGraphics.SetClip(theGraphicsPath)
theGraphics.DrawImage(theBitmap, New Rectangle(0, 0, theBitmap.Width, theBitmap.Height), 0, 0, theBitmap.Width, theBitmap.Height, _
GraphicsUnit.Pixel)
theGraphics.Dispose()
theEllipseBitmap.MakeTransparent(Color.Magenta)
' Save the ellipse bitmap to a PNG file format
string fileName = "PathToYourDesiredOutput.png"
theEllipseBitmap.Save(fileName, System.Drawing.Imaging.ImageFormat.Png)