Change text on mouse hover event - vb.net

I have a Rich text box having a translation of English paragraph to pig Latin and I need when hovering on any word in this text box the word changes temporarily to its original and to be highlighted at the same time.
So, I'm taking it step by step now the first step is to get the index of the character that is at the location of the mouse and then get the character of the index. but unfortunately the first step is not working :(. here is the code.
Private Sub TransRTBox_MouseMove(sender As Object, e As MouseEventArgs) Handles TransRTBox.MouseMove
GetWordUnderMouse(TransRTBox, e.Location.X, e.Location.Y)
End Sub
Friend Sub GetWordUnderMouse(ByRef Rtf As System.Windows.Forms.RichTextBox, x As Integer, y As Integer)
Dim point As New Point(x, y)
Dim pos As Integer
Dim ltr As String
point.X = x
point.Y = y
pos = Rtf.GetCharIndexFromPosition(point)
ltr = Rtf.Text.Chars(pos)
MessageBox.Show(ltr)
End Sub
the problem is that it always returns the first letter and the pos always equal to 0 no matter where the mouse points or hover, can any one help me in that??

You need to say Dim point As New Point(x,y) because the point is not being instantiated

Related

Loading up to 32768 Pictureboxes in Visual Basic

I have a app which is loading between 32^2 to 32768 8x8 px pictureboxes. All pictureboxes are on screen so I need to load them all and can't just load some.
As it stands, my program won't even run. Is there a better way to load that many pictureboxes?
I would like to share with you my project, but I don't know how to.............
Thanks though!
You'd likely run into a MemoryOverflowException with this design. From the sound of it, you're probably trying to render a map of some sort if that's the case then this answer is for you (otherwise just ignore it).
At a high level you should only create the number of PictureBox controls that can fit on the screen at any given time. You can calculate this with the following function:
Private Function CalculateSizeToFitParent(ByVal parent As Control, ByVal childSize As Size) As Size
Return New Size(parent.Width \ childSize.Width, parent.Height \ childSize.Height)
End Sub
You would implement it as such to create a PictureBox to fill up the visible area of the current Form:
Dim pictureBoxSize As Size = New Size(8, 8)
Dim visibleArea(pictureBoxSize.Width - 1, pictureBoxSize.Height - 1) As PictureBox
Dim numberOfPictureBoxes As Size = CalculateSizeToFitParent(Me, pictureBoxSize)
For x As Integer = 0 To numberOfPictureBoxes.Width - 1
For y As Integer = 0 To numberOfPictureBoxes.Height - 1
visibleArea(x, y) = New PictureBox() With {
.Location = New Point(x * pictureBoxSize.Width, y * pictureBoxSize.Height)
.Size = pictureBoxSize
}
Me.Controls.Add(visibleArea(x, y))
Next
Next
The next part is two-fold:
You need to keep track of where the top-left corner of the current visible are is
You will need to reload the images in the respective visual area of the map.
This assumes that you have a 2D array that stores your images. And please note that you don't recreate the PictureBox controls but rather you just reload the image of the existing control:
Private _currentLocation As Point = New Point(0, 0) ' If you're starting somewhere else change it here
Public Property CurrentLocation As Point
Get
Return _currentLocation
End Get
Set(ByVal value As Point)
If (value <> _currentLocation) Then
_currentLocation = value
Me.OnCurrentLocationChanged()
End If
End Set
End Property
Protected Overridable Sub OnCurrentLocationChanged()
RaiseEvent CurrentLocationChanged(Me, EventArgs.Empty)
End Sub
Public Event CurrentLocationChanged(ByVal sender As Object, ByVal e As EventArgs)
Private Sub MyForm_CurrentLocationChanged(ByVal sender As Object, ByVal e As EventArgs) Handles Me.CurrentLocationChanged
If (visibleArea Is Nothing) Then
Throw New Exception("The visible area has not been generated yet.")
End If
If (_currentLocation Is Nothing) Then
Throw New Exception("The CurrentLocation cannot be null.")
End If
Dim widthUpperBounds As Integer = My2DArrayOfImageLocations.GetUpperBounds(0) - 1
Dim heightUpperBounds As Integer = My2DArrayOfImageLocations.GetUpperBounds(1) - 1
For x As Integer = 0 To visibleArea.GetUpperBounds(0) - 1
For y As Integer = 0 To visibleArea.GetUpperBounds(1) - 1
If (x + _currentLocation.Width > widthUpperBounds OrElse y + _currentLocation.Height) Then
'This "block" is outside the view area (display a blank tile?)
Else
visibleArea(x, y).Load(My2DArrayOfImageLocations(x + _currentLocation.Width, y + _currentLocation.Height))
End If
Next
Next
End Sub
Now whenever you reset the CurrentLocation property (however you'd do that, e.g. arrow keys, asdw, etc.) it will redraw the visible area of the map.
Update
Please note that I "free-typed" this example and you may need to tweak it a bit. After some more thought, you'll probably also need to call the Refresh method of the PictureBox when you load in the image (I didn't test).

CorelDraw X6 Macro to insert Date using DTPicker Control

I'm trying to insert a date into a label. I have written the following code. I can select a date by clicking on the arrow and the calendar pops up. The "CANCEL" button is working, but when I click "OK" I cannot get it to insert on the label. The label is a regular Corel document with text and images. I tried inserting a rectangle toolbox to see if I can get it to insert the date in there by using X,Y coordinates but that didn't work.
I basically need to know how to insert DTPicker.Value onto the label.
Sub ShowIt()
Calendar.Show
End Sub
Private Sub Cancel_Click()
Unload Me
End Sub
Private Sub OK_Click()
a = DTPicker1.Value
b = Format(DTPicker1.Value, "mm/dd/yy")
Unload Me
End Sub
Private Sub DTPicker1_CallbackKeyDown(ByVal KeyCode As Integer, ByVal Shift As Integer, ByVal CallbackField As String, CallbackDate As Date)
DTPicker1.Value = Format(DTPicker1.Value, "mm/dd/yy")
End Sub
Private Sub Calendar_Activate()
Me.DTPicker1.Value = Date
End Sub
Thank you!
Try to run the previous code separated from your code.
Sub Macro1()
ActiveDocument.ReferencePoint = cdrCenter
XPos = Activeselection.PositionX
YPos = Activeselection.PositionY
Set s = ActiveLayer.CreateArtisticText(0, 0, CStr(Date))
s.PositionX=XPos
s.PositionY=YPos
End Sub
Select the rectangle
Click macro
The macro should work perfectly to create and place date at center on rectangle. BUT, the date is NOW (date when macro executed).
Then you should modify " CStr(Date)" to the value where the date is referred.
Try This :
1. Add a button on macro form
2. Select the rectangle
3. Click the button
4. Macro will read X, Y Pos of the rectangle, then create text and positioning it on the center of the rectangle
ActiveDocument.ReferencePoint = cdrCenter
XPos = Activeselection.PositionX 'XPos of the rect
YPos = Activeselection.PositionY 'YPos of the rect
Set s = ActiveLayer.CreateArtisticText(0, 0, CStr(Date))
s.PositionX=XPos
s.PositionY=YPos
The below code should work as requested :
ActiveDocument.ReferencePoint = cdrCenter
XPos = Activeselection.PositionX 'XPos of the rect
YPos = Activeselection.PositionY 'YPos of the rect
Set s = ActiveLayer.CreateArtisticText(0, 0, CStr(Date))
s.PositionX=XPos
s.PositionY=YPos
BUT :
He did not use Corel Draw..... :)
https://community.coreldraw.com/talk/coreldraw_community/f/101/t/51007
"Object variable or With block variable not set".
No Active document there.
I think you should create NEW Document first

How to find the highest number in all textboxes

I'm close to finishing a small program that i started, but got stuck with the last part. And I'm just starting to learn programming, so might be a stupid question.
How can i get the text box with the highest number out of 16 boxes,each having its own number, but at the same time keep track of which one still has the highest number every second? Quite confused about the updating it every second part.
All help is appreciated!
Code suggestion
Private Sub findTopTextBox()
Dim topValue As Integer
Dim topTextBox As TextBox
For Each ctrl As Control In Me.Controls 'all the controls on your form
If TypeOf ctrl Is TextBox Then
Dim thisValue As Integer
If Integer.TryParse(DirectCast(ctrl, TextBox).Text, thisValue) Then
If thisValue > topValue Then
topValue = thisValue
topTextBox = DirectCast(ctrl, TextBox)
End If
End If
End If
Next
Debug.Print(String.Concat(topTextBox.Name, " has the top value at: ", topValue))
End Sub
In order to test it each second, you'll need to add a Timer and call this method repeatedly.
You don't really need to check every second only check when a change was made in one of those textboxes
You could handle all your textboxes LostFocus event (using the same method to handle them all) ; get it's text, verify it's a number and if it's greater than the current max update it (along with it's "location" : the textbox control)
That way you always know which one is the greatest
Something along this should do it (typed directly here so not tested) :
Dim maxNumber As Integer, maxTextBox As TextBox
Sub TextBoxes_LostFocus(sender As Object, e As EventArgs) Handles textbox1.LostFocus, textbox2.LostFocus ' ... for all textboxes
Dim tbSender = DirectCast(sender, TextBox)
Dim number As Integer
' Should we update maxTextBox if number = maxNumber ? (if yes change the > to >=)
If Integer.TryParse(tbSender.Text, number) AndAlso number > maxNumber Then
maxNumber = number
maxTexBox = tbSender
End If
End Sub

What is the starting position of cell in DataGridView

I have 10 columns in DataGridView.
If i click first cell,popup window's starting position should be near first cell.
If i click 2nd cell,popup window's starting position should be near 2nd cell.
If i click 3rd cell,popup window's starting position should be near 3rd cell.
how to change RowIndex and ColumnIndex accordingly?
Used following code in Datagridview_CellClick
sub
mPopup.Show(datagridview.PointToScreen(New Point(e.RowIndex , e.ColumnIndex )))
end sub
Since this is .NET all indexes start at 0.
The value range for both e.RowIndex and e.ColumnIndex would only be 0-2.
I would imagine that your results are that your selected point ends up being in the upper left hand corner.
You'll need to calculate where the actual cell is first, then apply that value to the New Point method.
This post has a good example
Current Selected Cell Position
According to that post, you only need to call
Dim rect as Rectangle = DataGridView.GetCellDisplayRectangle(e.RowIndex, e.ColumnIndex)
Dim left as int = rect.Left
Dim top as int = rect.Top
to get the correct Point values.
then pass that back to
datagridview.PointToScreen(New Point(top,left))
Be sure to check my syntax, its been a while since I wrote VB.
You need to add up all the position offsets to get the correct point.
This code shows a contextmenu at the bottom right corner of a cell that is clicked on:
Private Sub DataGridView1_CellClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellClick
Dim rect As Rectangle = DataGridView1.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, False)
Dim formBorderWidth As Integer = CInt((Me.Width - Me.ClientSize.Width) / 2)
Dim formTitlebarHeight As Integer = Me.Height - Me.ClientSize.Height - 2 * formBorderWidth
Dim left As Integer = Me.Left + formBorderWidth + DataGridView1.Left + rect.Left + rect.Width
Dim top As Integer = Me.Top + formTitlebarHeight + formBorderWidth + DataGridView1.Top + rect.Top + rect.Height
Dim pt As New Point(left, top)
ContextMenuStrip1.Show(pt)
End Sub
I feel there is probably an easier way to do this but this works for now.

Changing the pixel color in a VB.net form?

How would I change the colour of individual pixels in a VB.NET form?
Thanks.
A hard requirement for Winforms is that you should be able to redraw the form whenever Windows asks it to. Which will happen when you minimize and restore the window. Or on older versions of Windows when you move another window across yours.
So just setting pixels on the window isn't good enough, you are going to lose them all when the window redraws. Instead use a bitmap. An additional burden is that you are going to have to keep the user interface responsive so you need to do your calculations on a worker thread. The BackgroundWorker is handy to get that right.
One way to do this is to use two bitmaps, one you fill in the worker and another that you display. Every, say, one row of pixels make a copy of the in-work bitmap and pass that to ReportProgress(). Your ProgressChanged event then disposes the old bitmap and stores the new passed one and calls Invalidate to force a repaint.
You might benefit from these resources: Setting background color of a form
DeveloperFusion forum , and extracting pixel color
Here's some demo code. It's slow to repaint, for the reasons Hans mentioned. A simple way to speed it up would be to only recalculate the bitmap after a delay.
Public Class Form1
Private Sub Form1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
'create new bitmap
If Me.ClientRectangle.Width <= 0 Then Exit Sub
If Me.ClientRectangle.Height <= 0 Then Exit Sub
Using bmpNew As New Bitmap(Me.ClientRectangle.Width, Me.ClientRectangle.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb)
'draw some coloured pixels
Using g As Graphics = Graphics.FromImage(bmpNew)
For x As Integer = 0 To bmpNew.Width - 1
For y As Integer = 0 To bmpNew.Height - 1
Dim intR As Integer = CInt(255 * (x / (bmpNew.Width - 1)))
Dim intG As Integer = CInt(255 * (y / (bmpNew.Height - 1)))
Dim intB As Integer = CInt(255 * ((x + y) / (bmpNew.Width + bmpNew.Height - 2)))
Using penNew As New Pen(Color.FromArgb(255, intR, intG, intB))
'NOTE: when the form resizes, only the new section is painted, according to e.ClipRectangle.
g.DrawRectangle(penNew, New Rectangle(New Point(x, y), New Size(1, 1)))
End Using
Next y
Next x
End Using
e.Graphics.DrawImage(bmpNew, New Point(0, 0))
End Using
End Sub
Private Sub Form1_ResizeEnd(sender As Object, e As System.EventArgs) Handles Me.ResizeEnd
Me.Invalidate() 'NOTE: when form resizes, only the new section is painted, according to e.ClipRectangle in Form1_Paint(). We invalidate the whole form here to form an entire form repaint, since we are calculating the colour of the pixel from the size of the form. Try commenting out this line to see the difference.
End Sub
End Class