Best way to use transparent controls as invisible triggers - vb.net

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.

Related

How to screen a rectangle with a keyup event?

The sun is still above the horizon. With 7:43 from Baden Austria i try to mention my titel question with some additional example.
Following the Window10 environment build 19041.985 Visual Studio Community Version 4.8.04084,
the predfined Keys of a Logitech Deluxe 250 Keyboard are not altered with the visual basic method
Sub Kein_Stress_beim_Essen(e As KeyEventArgs)
Select Case e.KeyCode
Case Keys.Space
Dim Kautchuj As Drawing.Graphics = Me.CreateGraphics
Kautchuj.DrawRectangle(New Pen(Color.PaleGreen, 2), 250, 150, 100, 50)
End Select
End Sub
.
To strengthen the sum for physical exercises, pull the sholder bladebones to the rising sun balance until pushing back without regret where i need them, the DrawRectangle is set with the form property CreateGraphics.
For more then one property i search, to use, the GDI+ objects that can be set to link a Me.KeyUp delegate with the event literature.
For my personal argument i use an additional cross to start and end a even, odd number disscusion.
I try to screen a rectangle through the case Keys.Space. While CreateGraphics is, literally, used for the aim of controls in visual basic with a rectangle object i can imagine a paint event and do not know if the key event can also be used for a object.
I have a search pattern to concatenate operators a not named function. It is not possible that everything is an object. Even with some energy exercises. To aim i fade the predefined color names to build an enum naming convention. Some dictionary brainstorm words are delegate, event eventargs, tupel, keys, select, property, method and instance.
I do not concider the possibility to make new fonts because an ime substitution is not an additional information for me.
It seems like you're asking how to draw boxes on the KeyUp event. In that case, here's a quick demo of how it should be done:
Private ReadOnly points As New List(Of Point)
Private ReadOnly rng As New Random
Private Const BOX_DIMENSION As Integer = 10
Private Sub Form1_KeyUp(sender As Object, e As KeyEventArgs) Handles MyBase.KeyUp
Select Case e.KeyCode
Case Keys.Space
'Draw a new box at a random location.
Dim x = rng.Next(ClientSize.Width)
Dim y = rng.Next(ClientSize.Height)
points.Add(New Point(x, y))
'Repaint just the area that will be occupied by the new box.
Invalidate(New Rectangle(x, y, BOX_DIMENSION + 1, BOX_DIMENSION + 1))
Case Keys.Escape
'Erase all boxes.
points.Clear()
'Repaint the whole form.
Invalidate()
End Select
End Sub
Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
'Draw a box at each location.
For Each point In points
e.Graphics.DrawRectangle(Pens.Red, point.X, point.Y, BOX_DIMENSION, BOX_DIMENSION)
Next
End Sub
As you can see, all the drawing is done in the Paint event handler. The KeyUp event handler updates the data that represents the drawing and then forces a repaint.

How to make a Control move left/right only using the mouse pointer?

I'm currently making a game, it contains a paddle (called base) that must move from left to right only.
I found a piece of code that allowed the platform to move, however it moves in all directions and isn't synced with my mouse pointer properly:
Private Sub Form1_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseMove
base.Location = MousePosition
End Sub
What do I need to change or add in order for the paddle to only move horizontally?
Assume your paddle (I'm naming the Control paddle here, base is not a good name) is placed near the bottom of the Form, its Height ~25 pixels and its bottom distance from the Form's bottom side ~10-20 pixels.
You can clip the Cursor to a narrow band right above it when the Mouse enters the Form.
You can then move the Cursor without intersecting other Controls in the Form, which could interfere with the generation of MouseMove events.
You can also hide the Cursor, so the arrow pointer doesn't become visually obnoxious (unless it's required for something else, of course).
When the Cursor is moved, the movement is translated to the middle of the paddle Control, which is moved only to the left or right, in relation to the current Cursor offset:
(PointToClient(Cursor.Position).X - (paddle.Width \ 2))
When the Form closes, restore the Cursor and the clipping region.
Paste this code inside the Form that contains the paddle (and rename base to paddle):
Protected Overrides Sub OnMouseEnter(e As EventArgs)
MyBase.OnMouseEnter(e)
ClipCursor()
End Sub
Protected Overrides Sub OnMouseMove(e As MouseEventArgs)
MyBase.OnMouseMove(e)
paddle.Left = PointToClient(Cursor.Position).X - (paddle.Width \ 2)
End Sub
Protected Overrides Sub OnFormClosing(e As FormClosingEventArgs)
ShowCursor()
MyBase.OnFormClosing(e)
End Sub
Private Sub ClipCursor()
Dim bandLocation = New Point(
Left + 8 + (paddle.Width \ 2),
Bottom - paddle.Height * 2 - Cursor.Size.Height)
Dim bandSize = New Size(ClientSize.Width - paddle.Width, 20)
Cursor.Clip = New Rectangle(bandLocation, bandSize)
Cursor.Hide()
End Sub
Private Sub ShowCursor()
Cursor.Clip = Rectangle.Empty
Cursor.Show()
End Sub
You can accomplish this by only assigning the X coordinate to the location property:
base.Location = New Point(Cursor.Position.X, Button1.Location.Y)
This will ignore the Y coordinate, resulting only in horizontal movement. Also, be aware that depending on your situation, you may have to translate the mouse pointer coordinates relative to the window. So, in case the result is distorted, do it like this:
base.Location = New Point(PointToClient(Cursor.Position).X, Button1.Location.Y)
This will translate the mouse coordinates (from e.g. Cursor.Position property) into window-relative coordinates.

How to use the Paint event more than once on a form?

Okay, so I am trying to make a program that each time you click (doesn't matter where) a random colored, and sized circle appears where you happened to click. however, the only way I can add a shape is via Paint event. here is the code I have now:
Private Sub Form1_Paint(ByVal Sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
Using Brush1 As New SolidBrush(Color.Orange)
e.Graphics.FillEllipse(Brush1, MousePosition.X, MousePosition.Y, 100, 100)
End Using
End Sub
I need to know a line of code that I can use in a mouse click event, that will re-run this sub. I know how to change the size, and make it random, I just don't know how to run this sub multiple times, more precisely; run this sub once after each mouse click. If someone can help, I would appreciate it!
Just as Plutonix explained, a refresh is handled by calling the Invalidate method.
The thing you need to remember is that whatever is painted on a surface is not persistent, so you need to redraw the whole screen every time. There are, of course, many ways in which this can be optimized for performance purposes, as this process can be extremely CPU intensive; specially, since GDI+ is not hardware accelerated.
So, what you need to do is:
Record every click (x, y position) and store it
Since the radius of each circle is random, determine the radius when the user clicks the form, then store it along with the x, y position of the click
Then, have the Paint event re-draw each stored sequence of clicks (with their respective radii) and re-draw each circle over and over.
Here's an implementation that will do the trick. Just paste this code inside any Form's class to test it:
Private Class Circle
Public ReadOnly Property Center As Point
Public ReadOnly Property Radius As Integer
Public Sub New(center As Point, radius As Integer)
Me.Center = center
Me.Radius = radius
End Sub
End Class
Private circles As New List(Of Circle)
Private radiusRandomizer As New Random()
Private Sub FormLoad(sender As Object, e As EventArgs) Handles MyBase.Load
Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True) ' Not really necessary in this app...
Me.SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
Me.SetStyle(ControlStyles.ResizeRedraw, True)
Me.SetStyle(ControlStyles.UserPaint, True)
End Sub
Private Sub FormMouseClick(sender As Object, e As MouseEventArgs) Handles Me.MouseClick
circles.Add(New Circle(New Point(e.X, e.Y), radiusRandomizer.Next(10, 100)))
Me.Invalidate()
End Sub
Private Sub FormPaint(sender As Object, e As PaintEventArgs) Handles Me.Paint
Dim g As Graphics = e.Graphics
g.Clear(Color.Black)
Using p As New Pen(Color.White)
For Each c In circles
g.DrawEllipse(p, c.Center.X - c.Radius \ 2, c.Center.Y - c.Radius \ 2, c.Radius, c.Radius)
Next
End Using
End Sub
Here's what you'll get after a few clicks on the form

Find position of mouse relative to control, rather than screen

I have a Picture Box called BGImage. I hope that when the user clicks on this I can capture the position of the mouse relative to BGImage.
I've tried using MousePosition, only to find it gives the mouse location on the screen, not on the PictureBox.
So I also tried using PointToClient:
Dim MousePos As Point = Me.PointToClient(MousePosition)
But this gives me the location {X=1866,Y=55} whereas I actually clicked on the PictureBox at around {X=516,Y=284}.
I think the problem arises because I have full-screened my program and set the position of the PictureBox to be at the centre of the screen (BGImage.Location = New Point((My.Computer.Screen.WorkingArea.Width / 2) - (1008 / 2), ((My.Computer.Screen.WorkingArea.Height / 2) - (567 / 2))))
I should also mention that the size of the PictureBox is 1008 By 567 pixels and my screen resolution is 1366 by 768.
Is there any way I can get the mouse position relative to BGImage's position?
Add a mouse click event to your picture box
Then use the MouseEventArgs to get the mouse position inside the picture box.
This will give you the X and the Y location inside the picture box.
Dim PPoint As Point
Private Sub PictureBox1_MouseClick(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseClick
PPoint = New Point(e.X, e.Y)
MsgBox(Convert.ToString(PPoint))
End Sub
I have before the same problem and just solved with the help of some friends.
Give a look Here mouse position is not correct
Here its the code that give you the correct position of the Mouse Based On A Picture.
Tanks to #Aaron he have give a final solution to this problem.
This will put a red dot on the exact point you click. I wonder how useful setting the cursor position will be though, as they will almost certainly move the mouse after clicking the button (inadvertently or not).
Setting the Cursor position needs to be in Screen coordinates - this converts back to client coordinates for drawing. I don't believe the PointToClient is necessary for the cursor position. In the below code, it is an unnecessary conversion, as you just go back to client coordinates. I left it in to show an example of each conversion, so that you can experiment with them.
Public Class Form1
Private PPoint As Point
Public Sub New()
' This call is required by the designer.
InitializeComponent()
PictureBox1.BackColor = Color.White
PictureBox1.BorderStyle = BorderStyle.Fixed3D
AddHandler PictureBox1.MouseClick, AddressOf PictureBox1_MouseClick
AddHandler Button8.Click, AddressOf Button8_Click
' Add any initialization after the InitializeComponent() call.
End Sub
Private Sub Button8_Click(sender As Object, e As EventArgs)
Dim g As Graphics = PictureBox1.CreateGraphics()
Dim rect As New Rectangle(PictureBox1.PointToClient(PPoint), New Size(1, 1))
g.DrawRectangle(Pens.Red, rect)
End Sub
Private Sub PictureBox1_MouseClick(sender As Object, e As MouseEventArgs)
PPoint = PictureBox1.PointToScreen(New Point(e.X, e.Y))
Label8.Text = PPoint.X.ToString()
Label9.Text = PPoint.Y.ToString()
End Sub
End Class
Instead of using:
Dim MousePos As Point = Me.PointToClient(MousePosition)
You should be using:
Dim MousePos As Point = BGImage.PointToClient(MousePosition)
It will give you mouse position in BGImage coordinates, whereas the first code gives you the mouse position in the Form's coordinates.

How can I place/drop an image evertime you click the mouse button using 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