powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Как программно выделить текст в TextBox-е?
4 сообщений из 29, страница 2 из 2
Как программно выделить текст в TextBox-е?
    #36694290
valdemar_ru
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Игорь Горбонос, Вы лучебы написали хотябы примерно как это сделать :)
...
Рейтинг: 0 / 0
Как программно выделить текст в TextBox-е?
    #36694426
Фотография Игорь Горбонос
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
> Автор: valdemar_ru
> Игорь Горбонос, Вы лучебы написали хотябы примерно как это сделать :)

Начну с теории
Все что делается в операционной системе виндовс делается через механизм сообщений, для этого у каждого окона(в том
числе и оконного контрола) есть функция приема и обработки этих самых сообщений. Так вот термин subclass обозначает
подмену стандартной функции обработки сообщений, на пользовательскую для придания каких-то спецефичиских особенностей,
которые невозможно получить стандартными способами.

Теперь практика:
Для реализации сабклассинга нам понадобится стандартный модуль со следующим содержанием:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
Option Explicit


' Константа для указания что мы хотим получить/установить адрес оконной функции
Private Const GWL_WNDPROC = - 4 

Private lpPrevWndProc As Long
Private gHW As Long

Public Declare Function DefWindowProc Lib "user32" Alias _
   "DefWindowProcA" (ByVal hwnd As Long, ByVal wMsg As Long, _
    ByVal wParam As Long, ByVal lParam As Long) As Long
Public Declare Function CallWindowProc Lib "user32" Alias _
   "CallWindowProcA" (ByVal lpPrevWndFunc As Long, _
    ByVal hwnd As Long, ByVal Msg As Long, _
    ByVal wParam As Long, ByVal lParam As Long) As Long
Public Declare Function SetWindowLong Lib "user32" Alias _
   "SetWindowLongA" (ByVal hwnd As Long, _
    ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

Public Sub Hook(gHW_ As Long)
    'Start subclassing.
' Сохраняем переданный hWnd для последующего возврата стандартной оконной функции
    gHW = gHW_
' Подменяем стандартную оконную функцию на пользовательскую
' Адрес старой функции сохраняется в переменной lpPrevWndProc и нужен
' для вызова стандартной функции, а так-же для возврата на место, когда все закончим :)
    lpPrevWndProc = SetWindowLong(gHW, GWL_WNDPROC, _
       AddressOf WindowProc)
End Sub

Public Sub Unhook()
    Dim temp As Long

    'Cease subclassing.
' Снимаем свой сабклассинг - возвращаем стандартную оконную функцию.
    temp = SetWindowLong(gHW, GWL_WNDPROC, lpPrevWndProc)
End Sub

Function WindowProc(ByVal hw As Long, ByVal uMsg As Long, _
   ByVal wParam As Long, ByVal lParam As Long) As Long
  ' Пользовательская оконная функция. Имя может быть произвольным, имена параметров тоже.
' Но! к таким имена все привыкли, поэтому рекомендую не менять имена параметров :)

' здесь можно написать Select Case - если много сообщений нужно обрабатывать
' или обойтись простым If

' все сообщения, которые нас НЕ интересуют должны отправлятся на обработку в стандартную оконную функцию:
        WindowProc = CallWindowProc(lpPrevWndProc, hw, uMsg, _
           wParam, lParam)
End Function
Теперь этот модуль можно подключить к проекту и задействовать механизм сабклассинга можно следующим образом:
Например нам необходимо подменять ввод символа "точка"(.) на "запятую"(,) с клавиатуры с TextBox. Для этого нам
необходимо обратится к документации (MSDN) и там выяснить, что сообщение которое передает в контрол TextBox вводимые
символы называется WM_CHAR. В wParam - передается собственно код вводимого символа(его и будем анализировать), а в
lParam - передается дополнительная информация о состоянии клавишь спец-назначения(Ctrl, Alt etc)(в данном примере она
нас не интересует). Все сообщения - это константы. Их нужно просто найти :). Найти можно в любом PlatformSDK для
виндовс. Так-же эти и многие други объявления можно найти в APIView от книги Эпплмана VB porgamming Guide to the Win32
API или с VB6 поставлялась утилита API Viewer.
Таким образом модуль сабклассинга будет выглядеть так:

Модуль сабклассинга
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
Option Explicit


' Константа для указания что мы хотим получить/установить адрес оконной функции
Private Const GWL_WNDPROC = - 4 
' Константа идентифицирующая сообщение
Private Const WM_CHAR& = &H102

Private lpPrevWndProc As Long
Private gHW As Long

Public Declare Function DefWindowProc Lib "user32" Alias _
   "DefWindowProcA" (ByVal hwnd As Long, ByVal wMsg As Long, _
    ByVal wParam As Long, ByVal lParam As Long) As Long
Public Declare Function CallWindowProc Lib "user32" Alias _
   "CallWindowProcA" (ByVal lpPrevWndFunc As Long, _
    ByVal hwnd As Long, ByVal Msg As Long, _
    ByVal wParam As Long, ByVal lParam As Long) As Long
Public Declare Function SetWindowLong Lib "user32" Alias _
   "SetWindowLongA" (ByVal hwnd As Long, _
    ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

Public Sub Hook(gHW_ As Long)
    'Start subclassing.
' Сохраняем переданный hWnd для последующего возврата стандартной оконной функции
    gHW = gHW_
' Подменяем стандартную оконную функцию на пользовательскую
' Адрес старой функции сохраняется в переменной lpPrevWndProc и нужен
' для вызова стандартной функции, а так-же для возврата на место, когда все закончим :)
    lpPrevWndProc = SetWindowLong(gHW, GWL_WNDPROC, _
       AddressOf WindowProc)
End Sub

Public Sub Unhook()
    Dim temp As Long

    'Cease subclassing.
' Снимаем свой сабклассинг - возвращаем стандартную оконную функцию.
    temp = SetWindowLong(gHW, GWL_WNDPROC, lpPrevWndProc)
End Sub

Function WindowProc(ByVal hw As Long, ByVal uMsg As Long, _
   ByVal wParam As Long, ByVal lParam As Long) As Long
  ' Пользовательская оконная функция. Имя может быть произвольным, имена параметров тоже.
' Но! к таким имена все привыкли, поэтому рекомендую не менять имена параметров :)

' здесь можно написать Select Case - если много сообщений нужно обрабатывать
' или обойтись простым If
    If uMsg = WM_CHAR Then
        If wParam = Asc(".") Then
            wParam = Asc(",")
        End If
    End If
' все сообщения, которые нас НЕ интересуют должны отправлятся на обработку в стандартную оконную функцию:
        WindowProc = CallWindowProc(lpPrevWndProc, hw, uMsg, _
           wParam, lParam)
End Function

Добавляем этот модуль к проекту, добавляем на форму TextBox и в форме прописываем следующий код:
Модуль формы
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
Option Explicit


Private Sub Form_Load()
' Делаем подмену оконной функции
Hook Text1.hwnd
End Sub

Private Sub Form_Unload(Cancel As Integer)
' Возвращаем стандартную оконную функцию
Unhook
End Sub

Запустив, легко убедится, что ввести точку с клавиатуры никак не получится.

Это самый простой вариант, так сказать азы. Но! Нужно очень внимательно продумывать сабклассинг, потому что малейшая
ошибка будет приводить к падению как программы, так и среды разработки.

З.Ы. Тебе осталось выяснить какими сообщениями делается выделение в текстбоксе и заблокировать их. Дерзай

Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Как программно выделить текст в TextBox-е?
    #36694579
kiv-1980
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Игорь Горбонос ,

Поэтому и указал простой вариант.
При использовании сабклассинга, необходимость в таймере полностью отсутсвует. Но и пользоваться им нужно аккуратней, проект вылетает на ура :) Да и кода поболее будет.
Если автор немного покапается думаю и его прикрутит.
...
Рейтинг: 0 / 0
Как программно выделить текст в TextBox-е?
    #36696000
valdemar_ru
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Игорь Горбонос,

Спасибо, попробую разобраться (думаю это будет не просто :))
...
Рейтинг: 0 / 0
4 сообщений из 29, страница 2 из 2
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Как программно выделить текст в TextBox-е?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]