TextBox для WindowsForm-отслеживание положение курсора

Язык Visual Basic на платформе .NET.

Модераторы: Ramzes, Sebas

Ефрейтор
Обычный пользователь
Обычный пользователь
 
Сообщения: 65
Зарегистрирован: 11.02.2005 (Пт) 12:43
Откуда: Алтай

TextBox для WindowsForm-отслеживание положение курсора

Сообщение Ефрейтор » 14.04.2006 (Пт) 7:53

Люди добрые, трабла такая. Возможноли сделать, что когда ведёшь указателем мыши над текстбоксом, то чтобы курсор в текстбоксе отслеживал текущее положение мыши (естественно курсор в текстбоксе должен перемещаться дискретно-"прыгать" через буквы)
Может кто-нибудь что-нибудь скажет?

Sebas
Неуловимый Джо
Неуловимый Джо
Аватара пользователя
 
Сообщения: 3626
Зарегистрирован: 12.02.2002 (Вт) 17:25
Откуда: столько наглости такие вопросы задавать

Сообщение Sebas » 14.04.2006 (Пт) 8:02

а. В событии Move посылать клики?

б. В событии Move получать координинаты мыши, рассчитывать через Graphics букву и переводить селекшен
- Я никогда не понимал, почему они приходят ко мне чтобы умирать?

sebas<-@->mail.ru

Ефрейтор
Обычный пользователь
Обычный пользователь
 
Сообщения: 65
Зарегистрирован: 11.02.2005 (Пт) 12:43
Откуда: Алтай

Сообщение Ефрейтор » 14.04.2006 (Пт) 10:37

Ну событие MouseMove для текстбокса я просматривал, да там есть координаты курсора относительно текстбокса.
А вот через Graphics что то не подумал. Ну хоть так
Благодарствую, добрый человек

Ефрейтор
Обычный пользователь
Обычный пользователь
 
Сообщения: 65
Зарегистрирован: 11.02.2005 (Пт) 12:43
Откуда: Алтай

Сообщение Ефрейтор » 14.04.2006 (Пт) 19:48

Спасиба ещё раз. Всё вообщем то получилось с событием MouseMove.
Небольшой вопрос уточнение. На сколько я понял работа с размерами формы идёт в пикселях?

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Сообщение Viper » 15.04.2006 (Сб) 6:32

в событиях формы всегда в пикселях
Весь мир матрица, а мы в нем потоки байтов!

Ефрейтор
Обычный пользователь
Обычный пользователь
 
Сообщения: 65
Зарегистрирован: 11.02.2005 (Пт) 12:43
Откуда: Алтай

Сообщение Ефрейтор » 15.04.2006 (Сб) 8:38

Хмм...небольшая трабла. Сделал отслеживание положения курсора под мышью в текстбоксе. Но почему то курсор в тестбоксе всё время "убегает" от мыши. Вроде всё мериется в пикселях. Немог бы кто нибудь посмотреть и поправить мой код? Я выкинул с примера всё лишнее и оставил саму суть проблемы, поэтому понять что я там сотворил будет несложно.
Вложения
WindowsApplication1.rar
Проект MouseMove
(24.56 Кб) Скачиваний: 51

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Сообщение Viper » 15.04.2006 (Сб) 10:23

проблема здесь в том, что MeasureString вызвращает размер строки с некоторым запасом (что отмечено в хелпе). Попробуй покопать в сторону метода MeasureCharacterRanges
Весь мир матрица, а мы в нем потоки байтов!

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Сообщение Viper » 15.04.2006 (Сб) 10:40

Вот код с использованием MeasureCharacterRange:
Код: Выделить всё
Private Function GetCursorPosition(ByVal MousePositionX As Integer, ByVal Text As String) As Integer
        'Доступ к графике
        Dim G As Graphics = txtDown.CreateGraphics()
        G.PageUnit = GraphicsUnit.Pixel

        Dim i As Integer = 1
        Dim PartText As String

        'Нахождение координаты точки вставки курсора
        For i = 1 To Len(Text)
            PartText = Mid(Text, 1, i)
            Dim sFormat As New StringFormat()
            Dim cr() As CharacterRange = {New CharacterRange(0, i)}
            sFormat.SetMeasurableCharacterRanges(cr)
            'получить размеры 
            Dim r() As Region = G.MeasureCharacterRanges(Text, Me.txtDown.Font, New RectangleF(0, 0, txtDown.Width, txtDown.Height), sFormat)

            If r(0).GetBounds(G).Width > MousePositionX Then
                Exit For
            End If
        Next
        Return i
    End Function


на первый взгляд вычисляет проложение курсора достаточно точно (конечно стоит покапаться и исправить возможные ошибки, если они найдуться)
Весь мир матрица, а мы в нем потоки байтов!

Ефрейтор
Обычный пользователь
Обычный пользователь
 
Сообщения: 65
Зарегистрирован: 11.02.2005 (Пт) 12:43
Откуда: Алтай

Сообщение Ефрейтор » 15.04.2006 (Сб) 13:35

!Viper!
Спасибо за участие. Функция действительно работает достато точно.
Правда есть ньанс:
если текст больше по размеру чем текстбокс, то как можно узнать какая чатсть отобразается в данный момент? тоже считать через графический объект?

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 15.04.2006 (Сб) 14:34

Вот, а у нас в VB6 есть EM_CHARFROMPOS, которая сразу возвращает букву, соответствующую точке...
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Nord777
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1144
Зарегистрирован: 22.02.2004 (Вс) 13:15
Откуда: Подольск

Сообщение Nord777 » 15.04.2006 (Сб) 18:27

To GSerg
А вот у нас в VS2005 тоже есть функция GetCharIndexFromPosition(ByVal pt As System.Drawing.Point) As Integer
которая сразу возвращает позицию символа :D

To Ефрейтор
К сожалению не помню есть ли эта функция в VS2003.

Код: Выделить всё
'Узнать индекс
txtDown.SelectionStart = txtDown.GetCharIndexFromPosition(New Point e.X, e.Y))

'Узнать сколько символов влезло в TextBox
Dim СколькоСимволовВлезло As Integer = txtDown.GetCharIndexFromPosition(New Point _(txtDown.ClientSize.Width - 1, 0))
Microsoft Visual Studio 2008
Microsoft .NET Framework 3.5

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 15.04.2006 (Сб) 18:30

Нету её там.

Потому что MS добавляет возможности к FW "медленно и печально" (c) Чтобы интерес к каждой новой версии студии не ослабевал...
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Nord777
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1144
Зарегистрирован: 22.02.2004 (Вс) 13:15
Откуда: Подольск

Сообщение Nord777 » 15.04.2006 (Сб) 18:34

вот как делает это VS2005:

Код: Выделить всё
Public Overridable Function GetCharIndexFromPosition(ByVal pt As Point) As Integer
      Dim num1 As Integer = Util.MAKELONG(pt.get_X, pt.get_Y)
      Dim num2 As Integer = CType(UnsafeNativeMethods.SendMessage(New HandleRef(Me, MyBase.Handle), 215, 0, num1), Integer)
      num2 = Util.LOWORD(num2)
      If (num2 < 0) Then
            Return 0
      End If
      Dim text1 As String = Me.Text
      If (num2 >= text1.Length) Then
            num2 = Math.Max((text1.Length - 1), 0)
      End If
      Return num2
End Function


Отправляется тоже самое сообщение, так что при желании можно сделать и в VS2003
Microsoft Visual Studio 2008
Microsoft .NET Framework 3.5

Ефрейтор
Обычный пользователь
Обычный пользователь
 
Сообщения: 65
Зарегистрирован: 11.02.2005 (Пт) 12:43
Откуда: Алтай

Сообщение Ефрейтор » 15.04.2006 (Сб) 20:06

Всем спасибо за разговор. Посижу поковыряюсь.


Вернуться в Visual Basic .NET

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 90

    TopList  
cron