How to use a button's event with defined picturebox - vb.net

I thought I'd make a very simple fps game. I have all the graphics but I have just one error.
The error is that you can spawn an enemy into the game by clicking a button. Using that button, you can spawn as many enemies into the game as you like. To do this I have written the following:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim enemy As New PictureBox
enemy.Image = My.Resources.enemy.png
Me.Controls.Add(enemy)
End Sub
But, to shoot the enemy, you have to click on it and I am not sure on how to make that happen as the 'enemy' variable is not actually on the form until the program is started and the button is clicked.
I have tried this but it has not brought to me any success:
Private Sub Enemy_Click(sender As Object, e As EventArgs) Handles enemy.Click

You have to add the event handler yourself:
Dim enemy As New PictureBox
enemy.Image = My.Resources.enemy.png
AddHandler enemy.Click, AddressOf Enemy_Click
Me.Controls.Add(enemy)
On the clicked method side, you would get which PictureBox was clicked by the sender object:
Private Sub Enemy_Click(sender As Object, e As EventArgs)
Dim pb As PictureBox = sender
// do stuff
End Sub

Related

Not able to clear drawings in PictureBox using VB.NET

I use the following code to make simple free-hand (brush) drawings over PictureBox1. Drawing is fine, but not able to clear the drawings I made permanently. If I click Button1 the drawings will be cleared, but once I move over PictureBox1 all old drawings (and PictureBox1 image) appear again. Any suggestions?
Private Sub PictureBox1_MouseDown(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseDown
If e.Button = MouseButtons.Left Then
mousePath.StartFigure()
End If
End Sub
Private Sub PictureBox1_MouseMove(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseMove
'// slide annotations
If e.Button = MouseButtons.Left Then
Try
mousePath.AddLine(e.X, e.Y, e.X, e.Y) 'Add mouse coordiantes to mousePath
Catch
End Try
End If
PictureBox1.Invalidate()
End Sub
Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
'// slide annotations
Try
'// drwaing options
myUserColor = System.Drawing.Color.Red
myAlpha = 255
myPenWidth = 3
CurrentPen = New Pen(myUserColor, myPenWidth)
e.Graphics.DrawPath(CurrentPen, mousePath)
Catch
End Try
End Sub
Private Sub Button1_Click_2(sender As Object, e As EventArgs) Handles Button1.Click
Dim g As Graphics
g = PictureBox1.CreateGraphics()
g.Clear(PictureBox1.BackColor)
g.Dispose()
End Sub
NEVER call CreateGraphics. ALWAYS do ALL your drawing in the Paint event handler. Your are creating a Graphics object in your Click event handler and clearing that, but what use is that when you do the drawing again in Paint event handler the next time that event is raised?
What you need to do is store all the data that represents your drawing in one or more fields, update that data whenever you want to change the drawing and draw using that data in the Paint event handler. If you want to clear the drawing, you clear that data and then force a repaint by calling Invalidate. In your Paint event handler you are drawing a GraphicsPath stored in the mousePath field. That means that, in your Click event handler, you need to clear that GraphicsPath and then call Invalidate. That will then prompt a Paint event that will first clear the existing drawing and then do the new. As there is no new to do, it will remain clear.

Controlling program-order when using a TabControl

Here is a simple VB.Net Forms program. The form contains a TabControl, which has 2 pages. On TabPage1 there is a Button, and a PictureBox, which contains a small 'Waiting' image. Initially the PictureBox is hidden. The TabControl starts by showing TabPage1.
What I would like to happen is that when the Button is pressed, the PictureBox is made visible, then, my SlowRoutine() is called, then the PictureBox is hidden, then I swap to TabPage2.
What actually happens is that when the Button is pressed, we wait 2 seconds, then we swap to TabPage2. I never see the PictureBox.
If I uncomment the MessageBox line, just to add a halt to the program-flow, then press the Button, the following occurs: 2 seconds passes, and then the PictureBox and the MessageBox appear. Clicking on the MessageBox closes it, and we go to TabPage2. Flipping back to TabPage1 shows that the PictureBox has been hidden.
The order of events is not happening in a logical way. How can I fix this, please?
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
PictureBox1.Visible = False
PictureBox1.Hide()
PictureBox1.SendToBack()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
PictureBox1.Visible = True
PictureBox1.Show()
PictureBox1.BringToFront()
SlowRoutine()
' MessageBox.Show("I am waiting")
PictureBox1.Visible = False
PictureBox1.Hide()
PictureBox1.SendToBack()
TabControl1.SelectTab("TabPage2")
End Sub
Private Sub SlowRoutine()
' My SLOW ROUTINE: wait 2 seconds
Threading.Thread.Sleep(2000)
End Sub
End Class
Thanks to all. Here is the working code based on those comments, in case anyone else needs to do a similar task:
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
PictureBox1.Visible = False
End Sub
Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
PictureBox1.Visible = True
Await SlowRoutineAsync()
PictureBox1.Visible = False
TabControl1.SelectTab("TabPage2")
End Sub
Private Async Function SlowRoutineAsync() As Task
' My SLOW ROUTINE: wait 2 seconds
Await Task.Delay(2000)
End Function
End Class

VB Stopwatch Controlled by Mouse

Im making a stop watch to measure how long it takes for certain weapons to empty their clip in CS:GO. I have the stopwatch programmed, but it only seems to work if im clicking within the bounds of the window. If its possible, does anyone know how to make it able to start/stop even while in another program? Ill post the code below.
Public Class Form1
Dim WithEvents timer As New Timer
Dim milliseconds As Integer
Private Sub Form1_MouseDown(sender As Object, e As MouseEventArgs) Handles MyBase.MouseDown
Timer1.Start()
End Sub
Private Sub Form1_MouseUp(sender As Object, e As MouseEventArgs) Handles MyBase.MouseUp
Timer1.Stop()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
totalTime.Text = 0.0
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
totalTime.Text = totalTime.Text + 0.01
End Sub
End Class
The MouseDown and MouseUp events only happen when the mouse clicks within your application so you can't use them as events to track the time the mouse is held down in another application.
You may be able to do what you want using a global mouse hook or by looking at windows messages such as the Mouse Down and Mouse Up messages

How do i pass keyUp/keyDown events to panel in visual basic?

I have created a game in visual basic, and have decided to expand by adding multiple rooms on the game. Each room will be a panel that shows when the user enters a certain area. To start, I created a class that inherits panel properties, then added it to my main Form. I then added all the items to the panel controls. My issue is that i cannot control the player when it is in the panel controls. I have tried all sorts, but couldn't get it to work.
I did some reading and found that panel does not come with keyUp() and keyDown() events. However, I would like to know if there is a way round this.
Thanks in advance!
Code of mainRoom() class (my panel):
Public Class mainRoom
Inherits Panel
Sub New()
With Me
.SetBounds(0, 0, Form1.Width, Form1.Height)
.SendToBack()
End With
End Sub
Public Sub mainRoom_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles Me.Paint
e.Graphics.FillRectangle(Brushes.DarkOrange, block)
End Sub
End Class
In main form class:
Sub setMap()
main = New mainRoom()
Me.Controls.Add(main)
End Sub
You can set the KeyPreview=True on the main form, and then handle the key up/down events from the form:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.KeyPreview = True
End Sub
Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles MyBase.KeyDown
'key down code.
e.Handled = True
End Sub
Private Sub Form1_KeyUp(sender As Object, e As KeyEventArgs) Handles MyBase.KeyUp
'key up code.
e.Handled = True
End Sub
Note: if you don't want other controls' key up/down event handlers to fire after your form event handlers do, then set e.Handled=True as I have in the above example.
See MSDN for more info on KeyPreview.
BEWARE - when moving (cut/paste) existing controls via the IDE from a form into a new panel control, the event handlers are not carried across as they become children of the parent control (the new panel). So this happens:
Private Sub Button1_Click(sender As Object, e As EventArgs)
Add the event handlers back and don't spend an age googling why keypress events suddenly stop firing in panels ...
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

button click not firing it's method VB.NET

Hello I'm having a problem with my button. When I click it, the button's not firing the method:
Private Sub button1_Click(sender As System.Object, e As System.EventArgs)
'Initialize the capture device
grabber = New Capture()
grabber.QueryFrame()
'Initialize the FrameGraber event
AddHandler Application.Idle, New EventHandler(AddressOf FrameGrabber)
button1.Enabled = False
End Sub
What am I missing in here?
There should be something like
Private Sub button1_Click(sender As System.Object, e As System.EventArgs) Handles button1.Click
or
AddHandler button1.Click, AddressOf button1_Click
I suppose its vb.net and winforms. With VB6 or WPF is a solution little bit different.
Go to the Forms designer.
Select the Button.
In the Properties Pane, bottom right by default, click the "Lightning Bolt" Icon.
Find the "Click" entry.
Click the small dropdown arrow to the right and select "button1_click".
The handler should now be again associated with your buttons click event.
Change the declaration like this:
Private Sub button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click