|
-
Dec 20th, 2024, 12:15 AM
#1
Thread Starter
PowerPoster
Prevent Mouse from changing caret location in Textbox.
I want my textbox to be read-only. I've got that part.
The Locked property takes care of that but only that.
But the user can still move the caret around which can screw up the text if it's in the middle of putting something on screen.
In the Keydown sub I just set the Keycode to 0 so they can't do it using keys, but they still can using the mouse.
This comes up because I have a "typing" algorithm that simulates typing by putting down one character at a time with a random, very short pause after each character.
During that time the user can click on the textbox and change where the text ends up - usually right in the middle of something else.
This is not a serious app so it's not a huge big deal but I'd still like to know how to do it without actually turning off the mouse which could be maybe a little bit rude to the user.
Code:
Public Sub SimulateTyping(ByRef Token As String, ByRef Textbox As VB.Textbox, Optional ByRef PauseMS As Long = 150)
Dim n As Long
Dim s As String
' Adds delay between characters to simulate typing.
' Starts 'typing' wherever the caret is.
If Len(Token) = 0 Then Exit Sub
With Textbox
For n = 1 To Len(Token)
.SelText = Mid$(Token, n, 1)
Sleep RollDie(PauseMS)
Next n
End With
End Sub
Public Function RollDie(ParamArray Die()) As Long
Dim nValue As Long
Dim nTotal As Long
Dim n As Long
' Returns Sum of all Die Rolled.
nTotal = 0
For n = LBound(Die) To UBound(Die)
nValue = Int(Rnd * Die(n)) + 1
nTotal = nTotal + nValue
Next n
RollDie = nTotal
End Function
Last edited by cafeenman; Dec 20th, 2024 at 03:38 AM.
-
Dec 20th, 2024, 12:26 AM
#2
Thread Starter
PowerPoster
Re: Prevent Mouse from changing caret location in Textbox.
PS. There are other parts of the code that add text that can be interrupted in the same way so what I really want is to make this a function of the textbox instead of having every single thing that could possibly interrupt it having to dance around it which would create a lot of spaghetti code.
also too, if you want to try the above code then create a new project, plop a textbox and command button on it.
In the command button click event add
SimulateTyping "I'm a competent typist typing competently", Text1
Last edited by cafeenman; Dec 20th, 2024 at 03:12 AM.
-
Dec 20th, 2024, 02:42 AM
#3
Re: Prevent Mouse from changing caret location in Textbox.
Set the SelStart property to Len(Text1.Text) before adding more text with SelText.
-
Dec 20th, 2024, 02:58 AM
#4
Re: Prevent Mouse from changing caret location in Textbox.
 Originally Posted by cafeenman
I want my textbox to be read-only. I've got that part.
The Locked property takes care of that but only that.
But the user can still move the caret around which can screw up the text if it's in the middle of putting something on screen.
If you don't want the User to be able to anything with the TextBox (other than manually read it), try putting the TextBox inside a Frame and disable that Frame.
Regards,
Phill W.
-
Dec 20th, 2024, 03:03 AM
#5
Thread Starter
PowerPoster
Re: Prevent Mouse from changing caret location in Textbox.
 Originally Posted by Eduardo-
Set the SelStart property to Len(Text1.Text) before adding more text with SelText.
I can't do that because sometimes the typing starts in the middle.
For example I'm framing something like this:
Code:
*********************************************** ' <- This border
The Extraordinary Tale of Sterling Soupforkinöv ' <- This is slowtyped in *after* the borders are created.
*********************************************** ' <- and this border are typed into the textbox first.
That's just one example. I have stuff like this all over the place. Trying to save the position of every bit of text the program is adding so I can restore the position if the user moves it will be a nightmare.
Last edited by cafeenman; Dec 20th, 2024 at 03:08 AM.
-
Dec 20th, 2024, 03:10 AM
#6
Thread Starter
PowerPoster
Re: Prevent Mouse from changing caret location in Textbox.
 Originally Posted by Phill.W
If you don't want the User to be able to anything with the TextBox (other than manually read it), try putting the TextBox inside a Frame and disable that Frame.
Regards,
Phill W.
I'll try that in a test project because putting the textbox into the frame will mean a lot of code to add to get the frame positioned properly when the form resizes and the textbox resizing in the frame.
I'm doing a ton of that already - all my forms are resizable within reason, but I don't want to mess up what I've got now if that doesn't work out.
If it does, then no problem making the change in the app.
Thanks.
-
Dec 20th, 2024, 03:20 AM
#7
Thread Starter
PowerPoster
Re: Prevent Mouse from changing caret location in Textbox.
Actually now that I think about it (this is air code), this might work.
**** Edit
Nope. It mostly works but if I start frantically clicking on the textbox then the caret moves.
If I behave like a reasonable person then it seems to work ok.
Not a great solution in other words. But I'm leaving it for your judgement.
******
Code:
Public Sub SimulateTyping(ByRef Text As String, ByRef Textbox As VB.Textbox, Optional ByRef PauseMS As Long = 150)
Dim n As Long
Dim s As String
dim nStartPos as long
' Adds delay between characters to simulate typing.
' Starts 'typing' wherever the caret is.
If Len(Text) = 0 Then Exit Sub
With Textbox
nStartPos = .Selstart
For n = 1 To Len(Text)
.Selstart = nStartPos + n ' This *might* put the caret back before typing the next thing in the wrong place?
.SelText = Mid$(Text, n, 1)
Sleep RollDie(PauseMS)
Next n
End With
End Sub
Last edited by cafeenman; Dec 20th, 2024 at 03:25 AM.
-
Dec 20th, 2024, 03:58 AM
#8
Re: Prevent Mouse from changing caret location in Textbox.
Or use a Label instead of a Textbox.
-
Dec 20th, 2024, 04:11 AM
#9
Thread Starter
PowerPoster
Re: Prevent Mouse from changing caret location in Textbox.
-
Dec 20th, 2024, 04:26 AM
#10
Thread Starter
PowerPoster
Re: Prevent Mouse from changing caret location in Textbox.
Also too, a feature I'm dying to add to my typing simulator is a Typo simulator.
Basically it makes random typos, types some more, backspaces and corrects it and moves along.
I already have it making random typos but not random corrections.
Instead if it makes a typo (something like a 1/10 chance of that happening) then it calls itself recursively with the original token to try again and so on until no typos are made and it backs out.
The trick is finding a line that leans strongly toward amusing and not toward annoying. So used seldom and judiciously.
-
Dec 20th, 2024, 08:58 AM
#11
Re: Prevent Mouse from changing caret location in Textbox.
Just internally track where you want your SelStart (independent of the TextBox), and set it each time your code inserts more text into the TextBox.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
-
Dec 20th, 2024, 10:01 AM
#12
Re: Prevent Mouse from changing caret location in Textbox.
Have you tried just setting the .Text property?
Code:
With Textbox
For n = 1 To Len(Text)
.Text = .Text & Mid$(Text, n, 1)
Sleep RollDie(PauseMS)
Next n
End With
-
Dec 20th, 2024, 12:09 PM
#13
Re: Prevent Mouse from changing caret location in Textbox.
I guess I don't get what you're asking. Here's my "fix":
Code:
Option Explicit
'
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
'
Private Sub Form_Click()
SimulateTyping "asdfasdfasdfasdfasdf", Text1
End Sub
Public Sub SimulateTyping(ByRef Token As String, ByRef Textbox As VB.Textbox, Optional ByRef PauseMS As Long = 150)
Dim n As Long
Dim s As String
' Adds delay between characters to simulate typing.
' Starts 'typing' wherever the caret is.
If Len(Token) = 0 Then Exit Sub
With Textbox
For n = 1 To Len(Token)
.SelStart = &HFFFF& ' <--- Added to make sure we're always adding to the end.
.SelText = Mid$(Token, n, 1)
Sleep RollDie(PauseMS)
Next n
End With
End Sub
Public Function RollDie(ParamArray Die()) As Long
Dim nValue As Long
Dim nTotal As Long
Dim n As Long
' Returns Sum of all Die Rolled.
nTotal = 0
For n = LBound(Die) To UBound(Die)
nValue = Int(Rnd * Die(n)) + 1
nTotal = nTotal + nValue
Next n
RollDie = nTotal
End Function
Just added one line of code.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
-
Dec 20th, 2024, 01:04 PM
#14
Re: Prevent Mouse from changing caret location in Textbox.
Because no one seems to be paying attention...
 Originally Posted by cafeenman
I can't do that because sometimes the typing starts in the middle.
For example I'm framing something like this:
Code:
*********************************************** ' <- This border
The Extraordinary Tale of Sterling Soupforkinöv ' <- This is slowtyped in *after* the borders are created.
*********************************************** ' <- and this border are typed into the textbox first.
The new text isn't always at the end...
-tg
-
Dec 20th, 2024, 01:18 PM
#15
Re: Prevent Mouse from changing caret location in Textbox.
 Originally Posted by techgnome
The new text isn't always at the end...
Then, if it's not the user, what's determining where it is?
And, as I stated before, keep track of your own SelStart, and set it whenever you add new text.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
-
Dec 20th, 2024, 01:38 PM
#16
Re: Prevent Mouse from changing caret location in Textbox.
 Originally Posted by cafeenman
That's just one example. I have stuff like this all over the place. Trying to save the position of every bit of text the program is adding so I can restore the position if the user moves it will be a nightmare.
Then make an UserControl and encapsulate all that functionality in one place.
-
Dec 21st, 2024, 08:23 AM
#17
Thread Starter
PowerPoster
Re: Prevent Mouse from changing caret location in Textbox.
I could try that except that I've never messed with user controls and I've never met one that didn't suck. So I actively avoid them because every time I think I've found one that will do just what I want it to do (per the author's description), all I end up with is an app filled with sadness.
It's all good. I was just hoping someone would know some api call that could handle it or something like that.
And it's not like users should be clicking all over the textbox anyway. There's no reason to do a lot of it except maybe to highlight and copy or something.
But if they just keep clicking it for giggles then they're either enjoying the havoc they're causing or they'll learn to stop doing it. Or whatever.
-
Dec 21st, 2024, 09:03 AM
#18
Re: Prevent Mouse from changing caret location in Textbox.
Another option, add a timer of 50 ms.
Code:
Private Type POINTAPI
X As Long
Y As Long
End Type
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
Private Declare Function ScreenToClient Lib "user32" (ByVal hWnd As Long, lpPoint As POINTAPI) As Long
Private Declare Function GetWindowRect Lib "user32" (ByVal hWnd As Long, lpRect As RECT) As Long
Private Sub Text1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
Text1.Enabled = False
Timer1.Enabled = True
End Sub
Private Sub Timer1_Timer()
Dim iPT As POINTAPI
Dim iRC As RECT
GetCursorPos iPT
GetWindowRect Text1.hWnd, iRC
If (iPT.X < iRC.Left) Or (iPT.X > iRC.Right) Or (iPT.Y < iRC.Top) Or (iPT.Y > iRC.Bottom) Then
Timer1.Enabled = False
Text1.Enabled = True
End If
End Sub
-
Dec 21st, 2024, 09:08 AM
#19
Thread Starter
PowerPoster
Re: Prevent Mouse from changing caret location in Textbox.
I think that will be a lot of flashing as the text changes color every time the textbox is enable and disabled.
I still haven't tried the potential solution of putting the textbox in a container. A frame was recommended but I'd probably use a picturebox.
Thanks for helping.
-
Dec 21st, 2024, 02:10 PM
#20
Re: Prevent Mouse from changing caret location in Textbox.
 Originally Posted by cafeenman
I still haven't tried the potential solution of putting the textbox in a container. A frame was recommended but I'd probably use a picturebox.
That would work.
Also, for the UserControl solution, if you want to try, you could use this project to encapsulate a TextBox into an UserControl.
-
Dec 22nd, 2024, 04:52 PM
#21
Fanatic Member
Re: Prevent Mouse from changing caret location in Textbox.
Simple solution:
Code:
Option Explicit
Private PrevLocation As Long
Private Sub Form_Load()
Text1.Text = "Hello"
PrevLocation = Len(Text1.Text)
Debug.Print "Form_Load: " & Text1.SelStart, Text1.SelLength
End Sub
Private Sub Text1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
Text1.SelStart = PrevLocation
Debug.Print "Text1_MouseDown: " & Text1.SelStart
End Sub
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|