I'm making a color picker and I want it so on button press it will disable everything but the program (like what snipping tool does, but not add grey to the screen).
So when I click somewhere, it can capture the color from mouse pointer, and re-enable all other programs. The reason why I want it to disable all other programs is so when you click to pick the color then it won't interfere with anything and change the color.
Any help is very much appreciated.
In this sample, there are two form FrmDesktopDisplay and FrmCaller
Public Class FrmDesktopDisplay
Public myResultStts As Boolean = False
Public myResultValue As Integer = -1
Private Sub FrmDesktopDisplay_Click(sender As Object, e As EventArgs) Handles Me.Click
'Here your code, not just in click event, you must modify according to your need
'And for example the result as follow:
myResultStts = True
myResultValue = 30
Me.Hide()
End Sub
Private Sub FrmDesktopDisplay_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
If e.KeyCode = Keys.Escape Then
'Here Just Hide, don't be closed or disposed, because you need the result
Me.Hide()
End If
End Sub
Private Sub FrmDesktopDisplay_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'First you must hide this form, to take desktop image
Me.Hide()
'This to make borderless
Me.FormBorderStyle = Windows.Forms.FormBorderStyle.None
Me.Refresh()
Dim g As Graphics
Dim bmp As Bitmap
'This to take size of screen
Dim myWidth As Integer = My.Computer.Screen.Bounds.Size.Width
Dim myHeight As Integer = My.Computer.Screen.Bounds.Size.Height
'This to make this form's Size is same as screen size
Me.Width = myWidth
Me.Height = myHeight
'Create Blank Bitmap with size as same as screen size
bmp = New Bitmap(myWidth, myHeight)
'Create graphic with composition of bitmap
g = Graphics.FromImage(bmp)
'Take Image from screen, and move to graphic g
g.CopyFromScreen(0, 0, 0, 0, bmp.Size)
'Relocate this form to (0,0)
Me.Top = 0
Me.Left = 0
'Set this form's backgroundimage with bitmap of bmp, that have been taken by graphic g
Me.BackgroundImage = bmp
Me.Show()
Me.Refresh()
End Sub
End Class
The Caller Form
Public Class FrmCaller
Private Sub ButtonToPick_Click(sender As Object, e As EventArgs) Handles ButtonToPick.Click
'Hide the caller form if don't need this form when you run your sniff or clip
Me.Hide()
FrmDesktopDisplay.ShowDialog()
'To show again this form
Me.Show()
'Take the result from FrmDesktopDisplay, you can do it, because the form still active
Dim myResultStts As Boolean = FrmDesktopDisplay.myResultStts
Dim myResultValue As Integer = FrmDesktopDisplay.myResultValue
'Here you close the FrmDesktopDisplay
FrmDesktopDisplay.Close()
FrmDesktopDisplay.Dispose()
PictureBox1.Visible = False
End Sub
End Class
'Here you must have PictureBox1 in Your Form, and the form must be as parent container
Private Sub ButtonToPick_Click(sender As Object, e As EventArgs) Handles ButtonToPick.Click
PictureBox1.Visible = False
Me.Refresh()
Dim g As Graphics
Dim bmp As Bitmap
bmp = New Bitmap(Me.Width, Me.Height)
g = Graphics.FromImage(bmp)
Dim myFRect As Rectangle
myFRect = Me.RectangleToScreen(Me.DisplayRectangle)
g.CopyFromScreen(myFRect.Left, myFRect.Top, 0, 0, bmp.Size)
PictureBox1.Top = 0
PictureBox1.Left = 0
PictureBox1.Width = Me.Width
PictureBox1.Height = Me.Height
PictureBox1.Image = bmp
PictureBox1.Visible = True
PictureBox1.BringToFront()
'Me.Refresh()
End Sub
Private Sub PictureBox1_Click(sender As Object, e As EventArgs) Handles PictureBox1.Click
'Here you process before picture box be hidden again
PictureBox1.Visible = False
End Sub
Related
I'm trying to create a simple game where my character has deal with a maze, in visual basic 2019
I cannot stop my character(picturebox) from passing through a wall(picturebox).
I have to say that I am far away from an expert and it's just an important project for school.
I tried this
Dim colliding As Boolean = False
For Each PictureBox In Me.Controls
If PictureBox1.Bounds.IntersectsWith(PictureBox.Bounds) Then
colliding = True
Else
colliding = False
End If
Next
and this
Dim colliding As Boolean = False
For Each PictureBox In Me.Controls
If PictureBox IsNot PictureBox1 AndAlso PictureBox21.Bounds.IntersectsWith(PictureBox.Bounds) Then
colliding = True
Else
colliding = False
End If
Next
in both attends I failed hard, and my character (picturebox1) can still pass through a wall
Code assumes that all PictureBoxes are DIRECTLY contained by the Form itself (they are not inside another container like a Panel), and that anything besides PictureBox1 is a wall:
Dim colliding As Boolean = False
For Each PB As PictureBox In Me.Controls.OfType(Of PictureBox)
If PB IsNot PictureBox1 Then
If PB.Bounds.IntersectsWith(PictureBox1.Bounds) Then
colliding = True
Exit For
End If
End If
Next
An alternate approach using a bit of LINQ:
Public Class Form1
Private Walls As New List(Of PictureBox)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Walls = Me.Controls.OfType(Of PictureBox).Where(Function(pb) pb IsNot PictureBox1).ToList
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim colliding As Boolean = Walls.Any(Function(pb) pb.Bounds.IntersectsWith(PictureBox1.Bounds))
End Sub
End Class
Here is another option for dealing with the collision.
This assumes 4 buttons to move the 'character'
Private Enum MoveDirection
Left
Down
Right
Up
End Enum
Private Sub RightButton_Click(sender As Object, e As EventArgs) Handles RightButton.Click
MovePicBox(CharacterPicBox, MoveDirection.Right)
End Sub
Private Sub LeftButton_Click(sender As Object, e As EventArgs) Handles LeftButton.Click
MovePicBox(CharacterPicBox, MoveDirection.Left)
End Sub
Private Sub UpButton_Click(sender As Object, e As EventArgs) Handles UpButton.Click
MovePicBox(CharacterPicBox, MoveDirection.Up)
End Sub
Private Sub DownButton_Click(sender As Object, e As EventArgs) Handles DownButton.Click
MovePicBox(CharacterPicBox, MoveDirection.Down)
End Sub
Private Sub MovePicBox(PicBox As PictureBox, movement As MoveDirection)
'save the old location to move the pic box back if a clash occurs
Dim oldLocation As Point = PicBox.Location
Dim newLocation As Point
Dim stepSize As Integer = 50
'calculate new position
Select Case movement
Case MoveDirection.Down
newLocation.X = oldLocation.X
newLocation.Y = oldLocation.Y + stepSize
Case MoveDirection.Left
newLocation.X = oldLocation.X - stepSize
newLocation.Y = oldLocation.Y
Case MoveDirection.Up
newLocation.X = oldLocation.X
newLocation.Y = oldLocation.Y - stepSize
Case MoveDirection.Right
newLocation.X = oldLocation.X + stepSize
newLocation.Y = oldLocation.Y
End Select
'move the picture box
PicBox.Location = newLocation
'check if it has collided
For Each wallPicBox As PictureBox In Me.Controls.OfType(Of PictureBox)
If wallPicBox Is PicBox Then
Continue For
End If
If PicBox.Bounds.IntersectsWith(wallPicBox.Bounds) Then
'move it back
PicBox.Location = oldLocation
End If
Next
End Sub
I am currently solving a bug that will remove the created rectangle on the PictureBox. The problem is that when I click an Item on the PictureBox and Resize the windows form, the rectangle does not move on with the item selected. This is the code creating the rectangle:
Private Sub paintRectangle(pictBox As System.Windows.Forms.PictureBox, pic As Image)
If pic Is Nothing Then Exit Sub
pictBox.Image = pic
If m_rect_x = -1 And m_rect_y = -1 Then
Return
End If
Dim graphic As System.Drawing.Graphics
Dim redselpen As System.Drawing.Pen
Dim yNegative As Integer = 3
redselpen = New System.Drawing.Pen(Color.Blue)
redselpen.DashStyle = Drawing2D.DashStyle.DashDot
If pictBox.Image IsNot Nothing Then
graphic = System.Drawing.Graphics.FromImage(pictBox.Image)
graphic.DrawRectangle(redselpen, m_rect_x, m_rect_y - yNegative, SystemConfig.iRectWidth, SystemConfig.iRectHeight + 2)
pictBox.Image = pictBox.Image
End If
End Sub
After Resizing the Form, I want to remove the create a rectangle on the PictureBox.
I tried this solution but the Rectangle is still in the PictureBox.
How to remove all the drawn rectangles on the picture box? (Not on the image)
But it does not work, the rectangle is still in the picturebox.
Here's a simple example showing the Paint() event of a PictureBox being used to draw a rectangle that can be moved and turned on/off:
Public Class Form1
Private yNegative As Integer = 3
Private pt As New Nullable(Of Point)
Private drawRectangle As Boolean = False
Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
If drawRectangle AndAlso pt.HasValue Then
Using redselpen As New System.Drawing.Pen(Color.Blue)
redselpen.DashStyle = Drawing2D.DashStyle.DashDot
e.Graphics.DrawRectangle(redselpen, pt.Value.X, pt.Value.Y - yNegative, SystemConfig.iRectWidth, SystemConfig.iRectHeight + 2)
End Using
End If
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
pt = New Point(25, 25)
drawRectangle = True
PictureBox1.Invalidate()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
drawRectangle = Not drawRectangle ' toggle the rectangle on/off
PictureBox1.Invalidate()
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
pt = New Point(150, 25)
drawRectangle = True
PictureBox1.Invalidate()
End Sub
End Class
The Problem
I have a simple form with 2 PictureBoxes
I allow the user to draw on PictureBox1
When I click a Button on the form I want to capture the image in PictureBox1 and store it in PictureBox2
The issue is that if I add the line:
PictureBox2.Image = PictureBox1.Image
Any updates to PictureBox1 are immediately reflected in PictureBox2 ?!?
I just want to capture the image in PictureBox1 at that moment in time so that I can use it to 'Undo'
Tech
It's a Windows Forms App in Visual Basic, .Net 4.7.2 using Visual Studio 2019 Preview
Code
Public Class Form1
Dim drawMouseDown = False ' Set initial mouse state to not clicked
Dim drawMyBrush As New Pen(Brushes.White, 20) 'Set up the Brush
Public drawCanvas As New Bitmap(245, 352) 'Set up Bitmap Canvas
Private Sub btn_Color_Yellow_Click(sender As Object, e As EventArgs) Handles btn_Color_Yellow.Click
drawMyBrush.Brush = Brushes.Yellow
drawMyBrush.Width = 20
End Sub
Private Sub PictureBox1_MouseDown(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseDown
drawMouseDown = True
End Sub
Private Sub PictureBox1_MouseUp(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseUp
drawMouseDown = False
End Sub
Private Sub PictureBox1_MouseMove(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseMove
Dim g As Graphics = Graphics.FromImage(drawCanvas)
Static coord As New Point
If drawMouseDown Then
g.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
drawMyBrush.StartCap = Drawing2D.LineCap.Round
drawMyBrush.EndCap = Drawing2D.LineCap.Round
g.DrawLine(drawMyBrush, coord.X, coord.Y, e.X, e.Y)
g.Dispose()
PictureBox1.Image = drawCanvas
Me.Refresh()
End If
coord = e.Location
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
PictureBox2.Image = PictureBox1.Image 'Why does this not just update the PicBox2 image once?!? (or only when the Button is clicked)
End Sub
End Class
Expectation
When Button1 is clicked I expect PictureBox2 to contain the PictureBox1 image, when I continue to draw on PictureBox1 I do NOT expect it to keep updating PictureBox2 as the user is drawing on the other!
As you suspect, PictureBox2.Image = PictureBox1.Image makes the former a reference to the latter.
What you can do instead is clone the image:
PictureBox2.Image = DirectCast(PictureBox1.Image.Clone(), Image)
Because you are referencing the Image property of PictureBox2 to PictureBox1.Image. So when they both point to the same reference, any changes to either of the PictureBox's image property, will affect the other's.
In order to avoid his, make a new instance of Bitmap object based on the PictureBox1.Image and set it to PictureBox2.Image:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
PictureBox2.Image = New Bitmap(PictureBox1.Image)
End Sub
Okay, I am currently have an app where I can draw on it. I use radio buttons to select the color and drawing size of the "Pen" for the drawing. I would like to get rid of these radio buttons and use a MenuStrip on a MDI form to affect the color and size of the pen on a new child form within the MDI form.
Currently, this is what I have for the form that I can draw on that includes the radio buttons.
Public Class Form1
Private shouldPaint As Boolean = False
Dim paintColor As Color
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.MdiParent = ParentMdiForm
'Color Radio Buttons
Me.redRadio.Tag = Color.Red
Me.blueRadio.Tag = Color.Blue
Me.greenRadio.Tag = Color.Green
Me.blackRadio.Tag = Color.Black
Me.blackRadio.Checked = True
'Size Radio Buttons
Me.smallRadio.Checked = True
End Sub
'Draw while mouse button is pressed
Private Sub Painter_MouseDown(sender As Object, e As MouseEventArgs) Handles MyBase.MouseDown
shouldPaint = True
End Sub
'Stop drawing when mouse button is not pressed
Private Sub Painter_MouseUp(Sender As Object, e As MouseEventArgs) Handles MyBase.MouseUp
shouldPaint = False
End Sub
'Change the size of the pen
Private Sub Painter_MouseMove(sender As Object, e As MouseEventArgs) Handles MyBase.MouseMove
If (shouldPaint) Then
If smallRadio.Checked = True Then
Using g As Graphics = CreateGraphics()
g.FillEllipse(New SolidBrush(paintColor), e.X, e.Y, 4, 4)
End Using
ElseIf mediumRadio.Checked = True Then
Using g As Graphics = CreateGraphics()
g.FillEllipse(New SolidBrush(paintColor), e.X, e.Y, 8, 8)
End Using
ElseIf largeRadio.Checked = True Then
Using g As Graphics = CreateGraphics()
g.FillEllipse(New SolidBrush(paintColor), e.X, e.Y, 12, 12)
End Using
End If
End If
End Sub
Private Sub RadioButton_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles redRadio.CheckedChanged, blueRadio.CheckedChanged, greenRadio.CheckedChanged, blackRadio.CheckedChanged
If CType(sender, RadioButton).Checked = True Then
paintColor = CType(CType(sender, RadioButton).Tag, Color)
End If
End Sub
Private Sub SizeRadioButton_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles smallRadio.CheckedChanged, mediumRadio.CheckedChanged, largeRadio.CheckedChanged
If CType(sender, RadioButton).Checked = True Then
End If
End Sub
End Class
My question is, how do I use the menustrip to select the size for my drawings? I figured out how to do it with the color but I cannot figure out the size. I am just not understanding how to code this.
I have a project that can create a picturebox control but I want every picturebox the user creates to have events already set in place such as the mouse down and mouse up events. But since the control hasnt been created yet, I can't refer to it in the code without getting an error and the form not being able to load because of it. In other words, after the user creates a picturebox, they can move the picturebox around the screen and draw on it. Then they can create another picturebox and move it around and draw on it as well and arrange the pictureboxes as they please. Any ideas? Thanks.
here is my code:
Private Sub AddCanvasToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AddCanvasToolStripMenuItem.Click
Dim canvas As New PictureBox
Dim i As Integer = 0
i = i + 1
canvas.Name = "canvas"
canvas.BackColor = Color.White
canvas.BorderStyle = BorderStyle.FixedSingle
canvas.Image = Nothing
canvas.Height = 200
canvas.Width = 200
AddHandler canvas.MouseDown, AddressOf PictureBox1_MouseDown
AddHandler canvas.MouseMove, AddressOf PictureBox1_MouseMove
canvas.Top = Panel2.Bottom
canvas.Left = Panel1.Right
Controls.Add(canvas)
End Sub
Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
If RadioButton1.Checked = True Then
xpos = Cursor.Position.X - PictureBox1.Location.X
ypos = Cursor.Position.Y - PictureBox1.Location.Y
End If
If RadioButton2.Checked = True Then
down = True
If down = True Then
PictureBox1.CreateGraphics.FillEllipse(mybrush, e.X, e.Y, 2, 2)
End If
End If
End Sub
Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
If RadioButton1.Checked = True Then
If e.Button = Windows.Forms.MouseButtons.Left Then
pos = MousePosition
pos.X = pos.X - xpos
pos.Y = pos.Y - ypos
PictureBox1.Location = pos
End If
End If
If down = True Then
PictureBox1.CreateGraphics.FillEllipse(mybrush, e.X, e.Y, 2, 2)
End If
End Sub
But this only makes what I want to happen to canvas happen to picturebox1.
I dont even want picturebox1 to exist in the first place. I want them to create a new picturebox out of nowhere with events already programmed into it. So the user can create a new picturebox and then move it and draw on it.
Create events dynamically too, Like this:
Private Sub AddCanvasToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AddCanvasToolStripMenuItem.Click
Dim canvas As New PictureBox
Dim i As Integer = 0
i = i + 1
canvas.Name = "canvas"
canvas.BackColor = Color.White
canvas.BorderStyle = BorderStyle.FixedSingle
canvas.Image = Nothing
canvas.Height = 200
canvas.Width = 200
AddHandler canvas.MouseDown, AddressOf pic_MouseDown
canvas.Top = Panel2.Bottom
canvas.Left = Panel1.Right
Controls.Add(canvas)
End Sub
Private Sub pic_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs)
'Do Something
End Sub
The above is perfect, but just to expand a little bit more:
Private Sub btnAddPictureBox_Click(sender As Object, e As EventArgs) Handles btnAddPictureBox.Click
Dim newPicBox As New PictureBox
Me.Controls.Add(newPicBox)
newPicBox.Location = New Point(50, 50)
newPicBox.Height = 100
newPicBox.Width = 100
newPicBox.BackColor = Color.White
newPicBox.BorderStyle = BorderStyle.FixedSingle
AddHandler newPicBox.MouseClick, AddressOf PictureBoxMouseClick
End Sub
Private Sub PictureBoxMouseClick(sender As Object, e As MouseEventArgs)
'Access the control the raised the event
'In this case we are changing the background colour to red
DirectCast(sender, PictureBox).BackColor = Color.Red
End Sub