How can I place/drop an image evertime you click the mouse button using vb.net? - vb.net

I looked at "How do I place an image with a mouse-click in Javascript?" but it had a small snippet of Java; immensely larger than my knowledge of Java. And that is the closest I've come to finding an answer in the past week.
Here's what I would like to do (don't know if its even possible):
I have a panel and a toolstrip with 3 buttons. Each button represents a different image. I want to click on a button (once) and then move into the panel and everytime I click the mouse button it drops the image where ever I clicked. This only ends when either I click back on the same button or one of the other buttons. I do not want to drag an image into the panel each time. In other words the button stays depressed and the event/action stays active.
Any help would be greatly appreciated.

Here is an example application. It's just a form with a ToolStrip on it, along with a couple of buttons with an image added to each button. The key property for each button is CheckOnClick=True, which will keep the button pressed down.
There isn't a radio button like feature for ToolStrips, so you have to "uncheck" the other ToolStripButtons yourself, which I have handled in the ItemClicked event.
Public Class Form1
Private _ActiveImage As Image = Nothing
Private Class ImagePoint
Public Location As Point
Public Image As Image
Public Sub New(ByVal image As Image, ByVal location As Point)
Me.Image = image
Me.Location = location
End Sub
End Class
Private _Images As New List(Of ImagePoint)
Public Sub New()
InitializeComponent()
Me.DoubleBuffered = True
End Sub
Private Sub Form1_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles MyBase.Paint
For Each imageItem As ImagePoint In _Images
e.Graphics.DrawImage(imageItem.Image, imageItem.Location)
Next
End Sub
Private Sub ToolStrip1_ItemClicked(ByVal sender As Object, ByVal e As ToolStripItemClickedEventArgs) Handles ToolStrip1.ItemClicked
For Each toolButton As ToolStripButton In ToolStrip1.Items.OfType(Of ToolStripButton)()
If toolButton.CheckOnClick Then
If e.ClickedItem.Equals(toolButton) Then
_ActiveImage = e.ClickedItem.Image
Else
toolButton.Checked = False
End If
End If
Next
End Sub
Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) Handles MyBase.MouseDown
If _ActiveImage IsNot Nothing AndAlso e.Button = MouseButtons.Left Then
_Images.Add(New ImagePoint(_ActiveImage, e.Location))
Me.Invalidate()
End If
End Sub
End Class
This example just uses a simple class to hold which image was placed at what location and the paint event just loops through the list and paints the image.
If deleting images is in your future, then you would have to call e.Graphics.Clear(Color.White) before painting any images.

For the button UI, check out the alternate style for radio buttons/check boxes. They have a "toggle button" mode which sounds like exactly what you need.
You could go through the motions of detecting mouse down events on the panel, getting the coordinates, creating an image control, and placing a copy of the image in it, but there's a better approach.
Fill the panel with a single image control (fill so that it handles resizes, the image control should always be the same size as the panel). Create a new Bitmap the same size as the image control and associate it with it (set the Image property). Obtain a Graphics object for the Bitmap (Graphics.FromImage() I think). Clear() it with the background color (Color.White?).
Preload your three images on startup and write the code to toggle between them, selecting the "active one" every time a different button is selected. On the mouse down event, you can get the coordinates of the click easily. Use myGraphics.DrawImage(...) to draw the active image at that location onto the Bitmap. You can then save the Bitmap to a file or do whatever you want with it. All of these concepts have lots of examples, Google them.
If you want to interact with the images after you "drop" them (like move them around again or something), then you will need to maintain a data structure that tracks what and where you've dropped. A simple class that has a Point and Image reference will be sufficient. Each drop should add an entry to a List(Of ...) these objects. You'll probably then need to write code such as "which image is under the current mouse location?". This can be accomplished by iterating through the list and doing point/rectangle intersection testing.

Private Sub ToolStripSound_Click(sender As Object, e As EventArgs) Handles ToolStripSound.Click
If ToolStripSound.Checked = False Then
ToolStripSound.Checked = True
Else
ToolStripSound.Checked = False
End If
End Sub
Private Sub ToolStripSound_CheckedChanged(sender As Object, e As EventArgs) Handles ToolStripSound.CheckedChanged
' ToolStripSound.Checked = True
If ToolStripSound.Checked = True Then
Me.ToolStripSound.Image = Global.Traffic_Lights.My.Resources.Resources.Oxygen_Icons_org_Oxygen_Status_audio_volume_high
Else
Me.ToolStripSound.Image = Global.Traffic_Lights.My.Resources.Resources.Oxygen_Icons_org_Oxygen_Status_audio_volume_muted
End If
End Sub

Related

How do I detect the left and right side of my screen?

I'm doing a project for my kitten who died...
I would like to know how I make it flip (look at the right side) when it comes to the left side of the screen, I'll leave an example in the print
Here's some code you can use to start with a single image file and display it in its original form or flipped horizontally depending on the horizontal position of its PictureBox on the screen.
'The Image to display on the left side of the screen.
Private leftImage As Image
'The Image to display on the right side of the screen.
Private rightImage As Image
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'Assume that the original image is the one to display on the left.
leftImage = Image.FromFile("file path here")
'Create a mirror image to display on the right.
rightImage = leftImage.Clone()
rightImage.RotateFlip(RotateFlipType.RotateNoneFlipX)
End Sub
Private Function IsPictureBoxOnLeftSideOfScreen() As Boolean
Dim screenMiddle = Screen.PrimaryScreen.WorkingArea.Width \ 2
Dim pictureBoxMiddle = PictureBox1.PointToScreen(Point.Empty).X + PictureBox1.Width \ 2
Return screenMiddle > pictureBoxMiddle
End Function
Private Sub SetImage()
PictureBox1.Image = If(IsPictureBoxOnLeftSideOfScreen(), leftImage, rightImage)
End Sub
Private Sub Form1_FormClosed(sender As Object, e As FormClosedEventArgs) Handles Me.FormClosed
rightImage.Dispose()
leftImage.Dispose()
End Sub
Where you call that SetImage method depends on exactly how you're moving the PictureBox, which you never showed us. If you're moving the form then you might do so in the LocationChanged event handler of the form. If you're moving the PictureBox then you might do so in the LocationChanged event handler of the PictureBox.

Best way to use transparent controls as invisible triggers

Once I develop a vb6 code to use transparent controls (Dont remember if I use Buttons or PictrureBoxes) with coordinates as invisible tags & invisible labels to show the names of eachone at groupal photos like facebook does. Now Im trying to recreate the same code at vb.net but I can't reach to get it work..
If I use Buttons with transparent .backcolor, no-text and no-borders, flat style, etc. to mark the photo area, they become opaque when I move the mouse over the control. if I disable becomes invisible for the mouse-over function.
If I use empty PictureBoxes instead for the same purpouse, as are empty they became invisible at runtime also for the "mouse over" function...
I dont know wich empty or invisible control must use to this finality. any suggestion?
Here is an example of what I was talking about in my comments:
Public Class Form1
Private ReadOnly actionsByRectangle As New Dictionary(Of Rectangle, Action)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'If the user clicks near the top, left corner, display a message.
actionsByRectangle.Add(New Rectangle(10, 10, 100, 100),
Sub() MessageBox.Show("Hello World"))
'If the user clicks near the bottom, right corner, minimise the form.
actionsByRectangle.Add(New Rectangle(ClientSize.Width - 110,
ClientSize.Height - 110,
100,
100),
Sub() WindowState = FormWindowState.Minimized)
End Sub
Private Sub Form1_MouseClick(sender As Object, e As MouseEventArgs) Handles Me.MouseClick
For Each rectangle As Rectangle In actionsByRectangle.Keys
If rectangle.Contains(e.Location) Then
'We have found a rectangle containing the point that was clicked so execute the corresponding action.
actionsByRectangle(rectangle).Invoke()
'Don't look for any more matches.
Exit For
End If
Next
End Sub
'Uncomment the code below to see the click targets drawn on the form.
'Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
' For Each rectangle As Rectangle In actionsByRectangle.Keys
' e.Graphics.DrawRectangle(Pens.Black, rectangle)
' Next
'End Sub
End Class
Note that I have added code there that can draw the boxes on the form if you want to see them, but those are just representations of the areas, not the Rectangle values themselves.

Button collision event vb.net

I'm trying to make some buttons move around in a rapid manner. Each click of a specific button should "reward" the player with a certain quantity of points (both positive or negative). This is a similar idea to some of the aspects in some of the "idiot test games" you see online.
How can I perform collision checks with the buttons?
I know it's possible with picture boxes to perform event collisions, with the following code picObject1.bounds.intersectsWith(picObject2.bounds).
However, when I tried using that function for buttons, they didn't register as a collision. I do not know if that is because buttons don't have bounds (though that doesn't sound right) or due to some other hidden detail that I have missed.
Any pointers in the right direction would be extremely useful!
Handle the Click event for the buttons. The code might look something like this:
Public Class Form1
Private PlayerScore As Integer = 0
Private Buttons() As Button
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
Buttons = Enumerable.Range(0,10).
Select(Function(i)
i = New Button()
AddHandler i.Click, AddressOf ScoreClick
Me.Controls.Add(i)
Return i
End Function)
End Sub
Dim rnd As New Random()
Private Sub ScoreClick(ByVal sender As Object, ByVal e As EventArgs)
Dim button As Button = DirectCast(sender, Button)
PlayerScore += rnd.Next(-10, 10)
End Sub
End Class
Now just add a timer to to the form to move the buttons around.

Dynamically changing image in picture box not working

I've been trying to figure this out off-and-on for weeks.
In my VB 2010 Forms application, I have a number of picture boxes which are populated with images from other picture boxes using the drag-and-drop method. That's no problem, it works fine. The picture boxes are all in a groupbox container.
The problem is trying to swap images between two picture boxes on a drag-and drop operation. In other words pBox1 has image.x and pBox2 has image.y. Drag the image from pBox2 to pBox1, and drop it; pBox1 will then have image.y from pBox2 and pBox2 will have image.x from pBox1.
With this example, here's the code I have so far:
Private Sub pBox2_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles pBox1.MouseDown
strImageSource = "pBox2" 'strImageSource is a global string variable
[other stuff]
end sub
^ This saves the name of the source picture box to a global string.
Private Sub pBox1_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles pBox1.DragDrop
For Each Control as PictureBox in GroupBox1.Controls.OfType(of PictureBox)()
if Control.Name = strImageSource then
Control.Image = pBox1.Image
end if
next
dim imgTarget as Image = CType((e.Data.GetData(DataFormats.Bitmap)), Bitmap)
pBox1.image = imgTarget
End Sub
^ This searches for the picture box as named by the strImageSource ("pBox2") and copies the contents of pBox1 into it, and then drops the image that was in pBox2 into pBox1.
I hope this makes sense.
This correctly places the image from pBox2 into pBox1, but it does not switch the image from pBox1 into pBox2. pBox2 is just blank. However, debugging shows that the image in pBox2 is not nothing; it does contain a bitmap. It's just not visible.
Now, just as a test, I added a line to the For Each section that would change the background color of the picture box:
For Each Control as PictureBox in GroupBox1.Controls.OfType(of PictureBox)()
if Control.Name = strImageSource then
Control.Image = pBox1.Image
Control.BackColor = color.red
end if
next
And the back color does change. This tells me that the For Each section is working -- it's finding the control and changing the back color. It's just not showing the image.
Is there something I am overlooking?
Thanks!
Instead of using strImageSource, use a global variable defined as a Picturebox
Private tmpPictureBox As PictureBox
Then store that picturebox reference so you can set its image on DragDrop
Private Sub pBox2_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles pBox1.MouseDown
'store the picturebox reference
tmpPictureBox = sender
[other stuff]
end sub
Private Sub pBox1_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles pBox1.DragDrop
'set the first image to the second
tmpPictureBox.Image = sender.image
'set the second image to the first
pBox1.image = CType((e.Data.GetData(DataFormats.Bitmap)), Bitmap)
End Sub
You should call Control.Refresh() on the PictureBox controls in order to update the images.
OK, this was stupid.
I was doing everything right with one really boneheaded exception. In another part of the code, inexplicably, I was clearing the picture boxes of content after the image was replaced. It may have been a remnant of something I was trying to do unrelated to this problem, and I just never corrected it.
My apologies for that, and thanks for all the responses.

How to clear a textbox if i drag the text out

I have code to drag files into a textbox, but I would also like to have code to drag the file out of the textbox, thus clearing it.
Anybody have any ideas?
You can use the DoDragDrop method to do a drag & drop operation. It returns a DragDropEffects value that specifies if the data actually has been dropped somewhere in which case you can clear the text box.
Since a drag & drop operation shouldn't start before the mouse has been moved a bit while pressing the mouse button you need to check for that in the MouseDown and MouseMove events. SystemInformation.DragSize tells you how far the mouse should be moved before a drag & drop operation starts.
In the MouseDown event check if you actually want to start a drag (i.e left button is pressed and text box actually contains text). Then create a rectangle using the mouse location and the size given by SystemInformation.DragSize. In the MouseMove event check if the mouse is dragged outside the rectangle and call DoDragDrop:
Private _dragStart As Boolean
Private _dragBox As Rectangle
Private Sub srcTextBox_MouseDown(sender As Object, e As MouseEventArgs) Handles srcTextBox.MouseDown
' a drag starts if the left mouse button is pressed and the text box actually contains any text
_dragStart = e.Button = MouseButtons.Left And Not String.IsNullOrEmpty(srcTextBox.Text)
If _dragStart Then
Dim dragSize As Size = SystemInformation.DragSize
_dragBox = New Rectangle(New Point(e.X - (dragSize.Width \ 2),
e.Y - (dragSize.Height \ 2)), dragSize)
End If
End Sub
Private Sub srcTextBox_MouseUp(sender As Object, e As MouseEventArgs) Handles srcTextBox.MouseUp
_dragStart = False
End Sub
Private Sub srcTextBox_MouseMove(sender As Object, e As MouseEventArgs) Handles srcTextBox.MouseMove
If Not _dragStart Or
(e.Button And MouseButtons.Left) <> MouseButtons.Left Or
_dragBox.Contains(e.X, e.Y) Then Return
Dim data As New DataObject()
data.SetData(srcTextBox.Text)
' you can optionally add more formats required by valid drag destinations:
' data.SetData(DataFormats.UnicodeText, Encoding.Unicode.GetBytes(srcTextBox.Text))
' data.SetData("UTF-8", Encoding.UTF8.GetBytes(srcTextBox.Text))
' data.SetData("UTF-32", Encoding.UTF32.GetBytes(srcTextBox.Text))
Dim dropEffect As DragDropEffects = srcTextBox.DoDragDrop(data, DragDropEffects.Move)
If (dropEffect = DragDropEffects.Move) Then
srcTextBox.Text = ""
End If
_dragStart = False
_dragBox = Rectangle.Empty
End Sub
Private Sub destTextBox_DragOver(ByVal sender As Object, ByVal e As DragEventArgs) Handles destTextBox.DragOver
If e.Data.GetDataPresent(GetType(String)) Then
e.Effect = e.AllowedEffect And DragDropEffects.Move
Else
e.Effect = DragDropEffects.None
End If
End Sub
Private Sub destTextBox_DragDrop(ByVal sender As Object, ByVal e As DragEventArgs) Handles destTextBox.DragDrop
If e.Data.GetDataPresent(GetType(String)) Then
destTextBox.Text = e.Data.GetData(GetType(String)).ToString()
End If
End Sub
Dragging the mouse in a TextBox usually starts text selection. The above code changes this behavior. Users can't use the mouse any more to select text. This is obviously not a good idea since users wouldn't expect that. To allow both text selection with the mouse and dragging you need to control the selection mechanism. This means you need to create your own text box class.
I would suggest a different approach: Use a label that shows the value as the dragging source and/or destination. To allow editing you can create a hidden text box. If the user double clicks on the label you hide the label and show the text box. After the user finishes editing (by hitting enter or cancel) or if the text box looses focus you hide the text box and show the label again.
Check out the DragLeave Event on the TextBox
Easiest way will probably be to store it as a variable or in clip board if leaving app.
Private Sub TheTextBox_DragLeave(sender As System.Object, e As System.EventArgs) Handles TheTextBox.DragLeave
Clipboard.SetText(TheTextBox.Text)
TheTextBox.Clear() 'Optional
End Sub
Then you'll need to code what happens when you mouse up of course, or drag into or whatever. You could clear the textbox in one of these steps. Depends on your implementation.