How do I prevent Graphics.DrawImage from scaling the picture? - vb.net

I am using a code that creates an image tooltip when the user hovers over the button. However, for some reason, for some of the buttons, the image gets scaled larger and doesnt completely fit in the tooltip window. I have no idea why some images are getting scaled and not others. Here is the code:
Protected Overrides Sub OnLoad(e As EventArgs)
MyBase.OnLoad(e)
ToolTip1.OwnerDraw = True
For Each ctrl As Control In Controls
If TypeOf ctrl Is Button Then
ToolTip1.SetToolTip(ctrl, " ")
End If
Next
End Sub
Private Sub ToolTip1_Popup(sender As Object, e As PopupEventArgs) Handles ToolTip1.Popup
Dim oTemplate As String = e.AssociatedControl.Name
Dim ButtonPic As Image = Image.FromFile(System.IO.Path.GetFullPath("TemplatesResources\MouseHoverPics\" & oTemplate & ".png"))
e.ToolTipSize = New Size(ButtonPic.Size.Width, ButtonPic.Size.Height)
End Sub
Private Sub ToolTip1_Draw(sender As Object, e As DrawToolTipEventArgs) Handles ToolTip1.Draw
Dim oTemplate As String = e.AssociatedControl.Name
Dim ButtonPic As Image = Image.FromFile(System.IO.Path.GetFullPath("TemplatesResources\MouseHoverPics\" & oTemplate & ".png"))
e.Graphics.Clear(SystemColors.Info)
e.Graphics.DrawImage(ButtonPic, New System.Drawing.Point(0, 0))
End Sub
The results:
Looking good at first.
Scaling begins....
Even more scaling the further right I go... could it possibly have to do with the button placement? I cant see why the code would take that into consideration
Any help would be appreciated.

That happens because when you call
e.ToolTipSize = New Size(ButtonPic.Size.Width, ButtonPic.Size.Height)
you set [size of the popup = size of the image]. But what happens if you don't have enough space between your mouse cursor and the border of the window? The popup resize itself, and when you load the image inside of it, the image scale itself to match the current width/height
e.Bounds()
So all you have to do is to check the Bounds of the popup and scale manteining the ratio before call DrawImage() method.
Here's and example
Private Sub ToolTip1_Draw(sender As Object, e As DrawToolTipEventArgs) Handles ToolTip1.Draw
Dim oTemplate As String = e.AssociatedControl.Name
Dim ButtonPic As Image = Image.FromFile(System.IO.Path.GetFullPath("TemplatesResources\MouseHoverPics\" & oTemplate & ".png"))
e.Graphics.Clear(SystemColors.Info)
If ButtonPic.Width > e.Bounds.Widht Or ButtonPic.Height > e.Bounds.Height Then
[code to rescale, make it as you prefer]
End If
e.Graphics.DrawImage(ButtonPic, New System.Drawing.Point(0, 0))
End Sub

Related

Download Image under the Mouse pointer via WebBrowser

I'm navigating to Google Images using a WebBrowser control. The aim is to be able to right click on any image and download and populate a PictureBox background.
I have my own ContextMenuStrip with Copy on it and have disabled the built in context menu.
The issue I am having is that the coordinate returned from CurrentDocument.MouseMove are always relative to the first (top left) image.
So my code works correctly if the Image I want is the very first image on the page, however clicking on any other Images always returns the coordinates of the first image.
It would appear that the coordinates are relative to each Image rather than the page.
Private WithEvents CurrentDocument As HtmlDocument
Dim MousePoint As Point
Dim Ele As HtmlElement
Private Sub Google_covers_Load(sender As Object, e As EventArgs) Handles MyBase.Load
WebBrowser1.IsWebBrowserContextMenuEnabled = False
WebBrowser1.ContextMenuStrip = ContextMenuStrip1
End Sub
Private Sub WebBrowser1_Navigated(sender As Object, e As WebBrowserNavigatedEventArgs) Handles WebBrowser1.Navigated
CurrentDocument = WebBrowser1.Document
End Sub
Private Sub CurrentDocument_MouseMove(sender As Object, e As HtmlElementEventArgs) Handles CurrentDocument.MouseMove
MousePoint = New Point(e.MousePosition.X, e.MousePosition.Y)
Me.Text = e.MousePosition.X & " | " & e.MousePosition.Y
End Sub
Private Sub ContextMenuStrip1_Opening(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles ContextMenuStrip1.Opening
Ele = CurrentDocument.GetElementFromPoint(MousePoint)
If Ele.TagName = "IMG" Then
CopyToolStripMenuItem.Visible = True
Else
CopyToolStripMenuItem.Visible = False
End If
End Sub
Private Sub CopyToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles CopyToolStripMenuItem.Click
Dim ToImg = Ele.GetAttribute("src")
mp3_row_edit.PictureBox1.BackgroundImage = New System.Drawing.Bitmap(New IO.MemoryStream(New System.Net.WebClient().DownloadData(ToImg)))
ToImg = Nothing
End Sub
This code allow to use a standard WebBrowser control to navigate to the Google Image search page and select/download an Image with a right-click of the Mouse.
To test it, drop a WebBrowser Control and a FlowLayoutPanel on a Form and navigate to a Google Image search page.
Things to know:
WebBrowser.DocumentCompleted: This event is raised each time one of the Sub-Documents inside a main HtmlDocument page is completed. Thus, it can be raised multiple times. We need to check whether the WebBrowser.ReadyState = WebBrowserReadyState.Complete.
Read these note about this: How to get an HtmlElement value inside Frames/IFrames?
The images in the Google search page can be inserted in the Document in 2 different manners: both using a Base64Encoded string and using the classic src=[URI] format. We need to be ready to get both.
The mouse click position can be espressed in either absolute or relative coordinates, referenced by the e.ClientMousePosition or e.OffsetMousePosition.
Read the notes about this feature here: Getting mouse click coordinates in a WebBrowser Document
The WebBrowser emulation mode can be important. We should use the most recent compatible mode available in the current machine.
Read this answer and apply the modifications needed to have the most recent Internet Explorer mode available: How can I get the WebBrowser control to show modern contents?.
Note that an event handler is wired up when the current Document is completed and is removed when the Browser navigates to another page. This prevents undesired calls to the DocumentCompleted event.
When the current Document is complete, clicking with the right button of the Mouse on an Image, creates a new PictureBox control that is added to a FlowLayouPanel for presentation.
The code in the Mouse click handler (Protected Sub OnHtmlDocumentClick()) detects whether the current image is a Base64Encoded string or an external source URI.
In the first case, it calls Convert.FromBase64String to convert the string into a Byte array, in the second case, it uses a WebClient class to download the Image as a Byte array.
In both cases, the array is then passed to another method (Private Function GetBitmapFromByteArray()) that returns an Image from the array, using Image.FromStream() and a MemoryStream initialized with the Byte array.
The code here is not performing null checks and similar fail-proof tests. It ought to, that's up to you.
Public Class frmBrowser
Private WebBrowserDocumentEventSet As Boolean = False
Private base64Pattern As String = "base64,"
Private Sub frmBrowser_Load(sender As Object, e As EventArgs) Handles MyBase.Load
WebBrowser1.ScriptErrorsSuppressed = True
WebBrowser1.IsWebBrowserContextMenuEnabled = False
End Sub
Private Sub WebBrowser1_DocumentCompleted(sender As Object, e As WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted
If WebBrowser1.ReadyState = WebBrowserReadyState.Complete AndAlso WebBrowserDocumentEventSet = False Then
WebBrowserDocumentEventSet = True
AddHandler WebBrowser1.Document.MouseDown, AddressOf OnHtmlDocumentClick
End If
End Sub
Protected Sub OnHtmlDocumentClick(sender As Object, e As HtmlElementEventArgs)
Dim currentImage As Image = Nothing
If Not (e.MouseButtonsPressed = MouseButtons.Right) Then Return
Dim source As String = WebBrowser1.Document.GetElementFromPoint(e.ClientMousePosition).GetAttribute("src")
If source.Contains(base64Pattern) Then
Dim base64 As String = source.Substring(source.IndexOf(base64Pattern) + base64Pattern.Length)
currentImage = GetBitmapFromByteArray(Convert.FromBase64String(base64))
Else
Using wc As WebClient = New WebClient()
currentImage = GetBitmapFromByteArray(wc.DownloadData(source))
End Using
End If
Dim p As PictureBox = New PictureBox() With {
.Image = currentImage,
.Height = Math.Min(FlowLayoutPanel1.ClientRectangle.Height, FlowLayoutPanel1.ClientRectangle.Width)
.Width = .Height,
.SizeMode = PictureBoxSizeMode.Zoom
}
FlowLayoutPanel1.Controls.Add(p)
End Sub
Private Sub WebBrowser1_Navigating(sender As Object, e As WebBrowserNavigatingEventArgs) Handles WebBrowser1.Navigating
If WebBrowser1.Document IsNot Nothing Then
RemoveHandler WebBrowser1.Document.MouseDown, AddressOf OnHtmlDocumentClick
WebBrowserDocumentEventSet = False
End If
End Sub
Private Function GetBitmapFromByteArray(imageBytes As Byte()) As Image
Using ms As MemoryStream = New MemoryStream(imageBytes)
Return DirectCast(Image.FromStream(ms).Clone(), Image)
End Using
End Function
End Class

programmatically select and highlight a row of a ListView in VB.NET

I want to do something seemingly simple - programmatically select and highlight a row of a ListView in VB.NET.
VB.NET: How to dynamically select a list view item?
tells me what should to be all that is needed, but it isn't. The row is selected, but not highlighted.
http://vbcity.com/forums/t/28260.aspx
tells me about the "HideSelection" property and the .Focus() method (also referenced at Select programmatically a row of a Listview), which sounded hopeful, but the best I can get is the faint highlight mentioned, I want the full monty. I tried a Noddy example with just a ListView, in Details mode, FullRowSelection = true, HideSelection = False, one columnheader defined and then
ListView1.Items.Add("Red")
ListView1.Items.Add("Orange")
ListView1.Items.Add("Yellow")
ListView1.Items.Add("Green")
ListView1.Items(2).Selected = True
I get this
but I want this
I can simulate highlighting by adding these lines
ListView1.SelectedItems(0).BackColor = Color.CornflowerBlue
ListView1.SelectedItems(0).ForeColor = Color.White
but then how can I be sure to undo the artificial highlight if the row can be implicitly as well as explicitly deselected? Do I have to think of all the possible cases? That's too much work for what should be a simple operation. Plus, since I want to color-code my rows, there is an additional challenge that when I undo the highlight color, I have to figure out what color is appropriate at that point. Is there a better, simpler way?
You can access the Graphics object used to draw each item, and draw them yourself.
Make a new project with a Button and ListView. Paste the following code:
Form_Load to use multiple subitems
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.ListView1.OwnerDraw = True ' or else can't handle DrawItem event
ListView1.Columns.Add("ColumnHeader1")
ListView1.Columns.Add("ColumnHeader2")
ListView1.Columns.Add("ColumnHeader3")
Me.ListView1.Items.Add("Red")
Me.ListView1.Items.Add("Orange")
Me.ListView1.Items.Add("Yellow")
Me.ListView1.Items.Add("Green")
ListView1.Items(0).SubItems.Add("Strawberry")
ListView1.Items(0).SubItems.Add("Apple")
ListView1.Items(1).SubItems.Add("Pepper")
ListView1.Items(1).SubItems.Add("Apricot")
ListView1.Items(2).SubItems.Add("Plum")
ListView1.Items(2).SubItems.Add("Banana")
ListView1.Items(3).SubItems.Add("Apple")
ListView1.Items(3).SubItems.Add("Lime")
End Sub
Three handlers for the ListView's drawing related events. Code copied from this answer
Private Sub listView1_DrawColumnHeader(sender As Object, e As DrawListViewColumnHeaderEventArgs) Handles ListView1.DrawColumnHeader
e.DrawDefault = True
End Sub
Private Sub listView1_DrawSubItem(sender As Object, e As DrawListViewSubItemEventArgs) Handles ListView1.DrawSubItem
Const TEXT_OFFSET As Integer = 1
' I don't know why the text is located at 1px to the right. Maybe it's only for me.
Dim listView As ListView = DirectCast(sender, ListView)
' Check if e.Item is selected and the ListView has a focus.
If Not listView.Focused AndAlso e.Item.Selected Then
Dim rowBounds As Rectangle = e.SubItem.Bounds
Dim labelBounds As Rectangle = e.Item.GetBounds(ItemBoundsPortion.Label)
Dim leftMargin As Integer = labelBounds.Left - TEXT_OFFSET
Dim bounds As New Rectangle(rowBounds.Left + leftMargin, rowBounds.Top, If(e.ColumnIndex = 0, labelBounds.Width, (rowBounds.Width - leftMargin - TEXT_OFFSET)), rowBounds.Height)
Dim align As TextFormatFlags
Select Case listView.Columns(e.ColumnIndex).TextAlign
Case HorizontalAlignment.Right
align = TextFormatFlags.Right
Exit Select
Case HorizontalAlignment.Center
align = TextFormatFlags.HorizontalCenter
Exit Select
Case Else
align = TextFormatFlags.Left
Exit Select
End Select
TextRenderer.DrawText(e.Graphics, e.SubItem.Text, listView.Font, bounds, SystemColors.HighlightText, align Or TextFormatFlags.SingleLine Or TextFormatFlags.GlyphOverhangPadding Or TextFormatFlags.VerticalCenter Or TextFormatFlags.WordEllipsis)
Else
e.DrawDefault = True
End If
End Sub
Private Sub listView1_DrawItem(sender As Object, e As DrawListViewItemEventArgs) Handles ListView1.DrawItem
Dim listView As ListView = DirectCast(sender, ListView)
' Check if e.Item is selected and the ListView has a focus.
If Not listView.Focused AndAlso e.Item.Selected Then
Dim rowBounds As Rectangle = e.Bounds
Dim leftMargin As Integer = e.Item.GetBounds(ItemBoundsPortion.Label).Left
Dim bounds As New Rectangle(leftMargin, rowBounds.Top, rowBounds.Width - leftMargin, rowBounds.Height)
e.Graphics.FillRectangle(SystemBrushes.Highlight, bounds)
Else
e.DrawDefault = True
End If
End Sub
Button click handler to simulate item(2) selected
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Me.ListView1.Items(2).Selected = True
End Sub
This will draw the background color regardless of focus. You have a lot of control over other colors and fonts going this route too.
Here, the button has been clicked, to select item 2, while the button still has focus, and item 2 is selected.
Easiest thing,
Just allocate the LST_ItemIndex = lstList.FocusedItem.Index everytime you select a different item
and then fire the below whenever you want the highlight
If lstList.Items.Count > 0 Then
lstList.Items(LST_ItemIndex).Selected = True
lstList.Items(LST_ItemIndex).EnsureVisible()
End If

Enable other event while dragging an object

I'm developing a console where I want to drag a button to a grid:
To drag the button, I use the following procedure:
Public drag As Boolean = False
Public ptX As Integer = 0
Public ptY As Integer = 0
Public btn As Button
Private Sub MoveButton_MouseDown(sender As Object, e As MouseEventArgs) Handles MoveButton.MouseDown
drag = True
btn = CType(sender, Button)
ptX = e.X : ptY = e.Y
End Sub
Private Sub MoveButton_MouseMove(sender As Object, e As MouseEventArgs) Handles MoveButton.MouseMove
If drag Then
btn.Location = New Point(btn.Location.X + e.X - ptX, btn.Location.Y + e.Y - ptY)
Me.Refresh()
End If
End Sub
Private Sub MoveButton_MouseUp(sender As Object, e As MouseEventArgs) Handles MoveButton.MouseUp
drag = False
End Sub
So far, so good! This works fine for that matter.
However, I'm trying to highlight the cell while hoovering the button on it like this:
To do so, I tried to do the following:
Private Sub CellA1_MouseHover(sender As Object, e As EventArgs) Handles CellA1.MouseHover
If drag Then
CellA1.BackColor = Color.Red
End If
End Sub
Of course I can't do that, unless I, somehow, enable the CellA1.MouseHover event while dragging the MoveButton.
Can anyone help me with this?
If, however, you're having a struggling will to help me further, my last goal is to place the MoveButton on the red cell place:
But feel free to don't help me at all with this part of the procedure since I have no code to perform this yet.
Any help will be very appreciated. And, as always, thank you all in advance.
Since your mouse is not actually on the PictureBox when you drag the button it will never raise any mouse events. What you can do instead is to call the GetChildAtPoint() method of your form to get the control behind the button. Once you have that just verify that the name starts with "Cell" and change the back color.
To snap to the cell's location you'll need to indicate to MouseUp which cell we're currently at. Simply store the cell control in a variable and you can then just set yourButton.Location = currentCell.Location
Here are the changes I've made to your code, commented for clarity:
Public drag As Boolean = False
Public ptX As Integer = 0
Public ptY As Integer = 0
Public btn As Button
Public prevCtrl As Control = Nothing 'Store the previous Cell the button was dragged over.
' We need this to be able to reset the BackColor of the Cell,
' and also so that you can snap to its location once you drop the button.
Private Sub MoveButton_MouseDown(sender As Object, e As MouseEventArgs) Handles MoveButton.MouseDown
'No changes made here.
drag = True
btn = CType(sender, Button)
ptX = e.X : ptY = e.Y
End Sub
Private Sub MoveButton_MouseMove(sender As Object, e As MouseEventArgs) Handles MoveButton.MouseMove
If drag Then
btn.Location = New Point(btn.Location.X + e.X - ptX, btn.Location.Y + e.Y - ptY)
'Go 1 pixel up, or else GetChildAtPoint() will return the button instead of the control behind it.
Dim LookPoint As Point = Point.Subtract(btn.Location, New Size(0, 1))
'Get the control located below/behind the button.
Dim ControlBelow As Control = Me.GetChildAtPoint(LookPoint, GetChildAtPointSkip.Invisible Or GetChildAtPointSkip.Disabled) 'Ignore invisible or disabled controls.
'Check so that the previous cell is not also the current cell. If they're the same then we won't change anything.
If prevCtrl IsNot ControlBelow Then
'Ok, the current cell and the previous cell are not the same.
'Now check if there was any previous cell at all.
If prevCtrl IsNot Nothing Then
'There was a previous cell, but since the button
'is no longer hovering over it we reset its BackColor.
prevCtrl.BackColor = Color.White
prevCtrl = Nothing
End If
'Check that there infact is a control behind the button,
'and also check that its name starts with "Cell".
If ControlBelow IsNot Nothing AndAlso ControlBelow.Name.StartsWith("Cell", StringComparison.OrdinalIgnoreCase) Then
'The control behind the button is a valid Cell. Change its BackColor.
ControlBelow.BackColor = Color.Red
prevCtrl = ControlBelow 'The previous cell is now the current cell.
End If
End If
'Me.Refresh() - this is a very unnecessary call, it will just eat CPU. The form does not need to be redrawn at this point.
End If
End Sub
Private Sub MoveButton_MouseUp(sender As Object, e As MouseEventArgs) Handles MoveButton.MouseUp
'Check if we dragged the button. At this point prevCtrl is the current cell (if it's not Nothing).
If drag = True AndAlso prevCtrl IsNot Nothing Then
btn.Location = prevCtrl.Location 'Snap to the cell's location.
prevCtrl.BackColor = Color.White 'Reset the cell's BackColor.
prevCtrl = Nothing 'Reset this since we're no longer dragging the button.
End If
drag = False
End Sub
And it works like a charm!

Making labels in charts selectable/editable in VB

Just like in excel for a graph you can double click on a title, series name, or axis label and then you are able to type in that space. What do I need to do so I can do that for my charts? Clueless on where to start. Seems I may have to create a custom label?
Use the HitTest method of the chart.
Imports System.Windows.Forms.DataVisualization.Charting
Public Class Form1
Private Sub Chart1_MouseDoubleClick(sender As Object, e As MouseEventArgs) Handles Chart1.MouseDoubleClick
Dim h As HitTestResult = Chart1.HitTest(e.X, e.Y) 'Perform the HitTest with the mouse position that was clicked
If h.ChartElementType = ChartElementType.AxisTitle OrElse _
h.ChartElementType = ChartElementType.Axis Then 'Check the type of the element of the chart that was clicked
Dim s As String = InputBox("Please enter a new title!", "", h.Axis.Title) 'Prompt for a new title
If s <> "" Then h.Axis.Title = s 'Assign the new title
End If
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
For i = 1 To 20 'Put some data in the chart to make the axes visible
Chart1.Series(0).Points.AddXY(i, i ^ 2)
Next
End Sub
End Class
You basically use the mouse location for the HitTest method. The ChartElementType defines what element was clicked at the position. If it's the title of the axis or the axis itself it will prompt you with an InputBox for a new title and assigns this title.
The InputBox is pretty old and shouldn't really be used but I was lazy and it works :-)
Apparently, what I'm referring to lives in DataVisualization.Charting.TextAnnotation. Along with that one, are many more type of annotations.
A TextAnnotation allows: AnchorMoving, Moving, PathEditing, Resizing, Selecting, and TextEditing. All of which I'm looking for.
Simple setup:
Dim anno As New DataVisualization.Charting.TextAnnotation
anno.AllowTextEditing = true
anno.AllowSelecting = true
anno.AllowMoving = true
anno.AllowResizing = true
anno.x = 50
anno.y = 50
anno.text = "Your Text"
chart.annotations.add(xAxisAnno)

detect when left mouse button is down while hovering over a button in Visual Basic.net

So I'm attempting to create a schedule grid in VB.net (exactly like the scheduler in UTorrent, if anyone is familiar) in a 24x7 layout. I want to be able to click down and drag over a series of squares to change the values of them.
I've been able to find this sample code that mostly works.
Private Sub DataGridView3_MouseHover(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DataGridView3.CellMouseMove
Dim grvScreenLocation As Point = DataGridView3.PointToScreen(DataGridView3.Location)
Dim tempX As Integer = DataGridView.MousePosition.X - grvScreenLocation.X + DataGridView3.Left
Dim tempY As Integer = DataGridView.MousePosition.Y - grvScreenLocation.Y + DataGridView3.Top
Dim hit As DataGridView.HitTestInfo = DataGridView3.HitTest(tempX, tempY)
cellX = hit.RowIndex
cellY = hit.ColumnIndex
TextBox3.Text = cellX
TextBox14.Text = cellY
End Sub
As written, this produces the desired results, however I need to have it only return cellx and celly to the text boxes only when the mouse button is down.
This can be accomplished by handling mouse left button down, mouse move and mouse left button up.
When you receive a mouse left button down event on the grid, record the mouse position and set a flag. In the mouse move handler if the flag is set, highlight all cells between the initial position and the current mouse position. On receiving a mouse left button up (on the grid when the grid is set) commit the cell selection (and clear the flag).
I've used this technique successfully for a fractal zoom.
Here's a rough outline of what you need to do:
Dim isSelecting As Boolean
Dim selectionStart As Point
Protected Overrides Sub OnMouseLeftButtonDown(e As MouseButtonEventArgs)
MyBase.OnMouseLeftButtonDown(e)
Dim position = e.GetPosition(Me)
Dim hit = VisualTreeHelper.HitTest(MyGrid, position)
If hit IsNot Nothing Then
isSelecting = True
selectionStart = position
End If
End Sub
Protected Overrides Sub OnMouseMove(e As MouseEventArgs)
MyBase.OnMouseMove(e)
If isSelecting Then
Dim position = e.GetPosition(Me)
' Update selection
End If
End Sub
Protected Overrides Sub OnMouseLeftButtonUp(e As MouseButtonEventArgs)
MyBase.OnMouseLeftButtonUp(e)
If isSelecting Then
Dim position = e.GetPosition(Me)
' Commit selection
End If
End Sub
This gave me what I wanted.
Private cellX As Integer = 0
Private cellY As Integer = 0
Private Sub DataGridView3_MouseHover(ByVal sender As System.Object, ByVal e As MouseEventArgs) Handles DataGridView3.CellMouseMove
Dim grvScreenLocation As Point = DataGridView3.PointToScreen(DataGridView3.Location)
Dim tempX As Integer = DataGridView.MousePosition.X - grvScreenLocation.X + DataGridView3.Left
Dim tempY As Integer = DataGridView.MousePosition.Y - grvScreenLocation.Y + DataGridView3.Top
Dim hit As DataGridView.HitTestInfo = DataGridView3.HitTest(tempX, tempY)
cellX = hit.RowIndex
cellY = hit.ColumnIndex
If e.Button = Windows.Forms.MouseButtons.Left Then
TextBoxX.Text = cellX
TextBoxY.Text = cellY
DataGridView3.Rows(cellX).Cells(cellY).Style.BackColor = Color.Red
End If
End Sub