TextBox.SelStart / SelLength и длинные строки - PullRequest
0 голосов
/ 05 октября 2018

У меня есть форма в базе данных Access (Access 2013).В этой форме есть TextBox, где пользователь может ввести текст.Одним нажатием кнопки я хотел бы что-то сделать с текстом в TextBox (например, вставить текст).Для этого я использую свойства SelStart и SelLength TextBox, чтобы определить, куда поместить мой новый текст.

Но, к сожалению, оба свойства (SelStart и SelLength) являются VBA Integer значения, это означает, что, пока длина текста в моем TextBox ниже Integer.MaxValue (= 32.767) SelStart является правильным, но как только я превышаю Integer.MaxValue SelStart, происходит переход к zu Integer.MinValue (= -32,768) и отсчитывать от этого числа.Итак, если длина моего текста составляет 40 000, то SelStart обеспечивает -25,535.

Есть ли способ получить правильные значения для SelStart и SelLength независимо от длины строки?Может быть, с функцией API вместо ошибочных свойств Access?

Ответы [ 2 ]

0 голосов
/ 05 октября 2018

Публикация этого отдельного ответа, потому что он полностью отличается

. Вы можете использовать функцию SendMessage WinAPI с константой EM_GETSEL, чтобы получить выбор текущего активного элемента управления.

Объявления:

(поскольку мы не работаем со строками, не имеет значения, используете ли вы SendMessageA или SendMessageW, эти объявления предназначены только для VBA7)

Public Declare Function SendMessage Lib "User32.dll" Alias "SendMessageW" (ByVal hWnd As LongPtr, ByVal Msg As Integer, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As LongPtr
Public Declare Function GetFocus Lib "User32.dll" () As LongPtr
Public Const EM_SETSEL As Integer = &HB1
Public Const EM_GETSEL As Integer = &HB0

Реализуйте это:

Public Sub GetSelection()
    Dim StartSel As Long
    Dim EndSel As Long
    Dim hWnd As LongPtr
    hWnd = GetFocus
    SendMessage hWnd, EM_GETSEL, VarPtr(StartSel), VarPtr(EndSel)
    Debug.Print StartSel
    Debug.Print EndSel
End Sub

Это печатает выбор текущего активного элемента управления.

Я проверил это для текстовых полей свыделение 32768-го символа, результат совпадает с моим первым решением (StartSel = UIntToLong(Control.SelStart) = True, и EndSel = UIntToLong(Control.SelStart + Control.SelLength) также верно.

Я рекомендую другое решение по сравнению с этим решением WinAPI, так как этоиспользует текущий активный элемент управления и не выдает ошибку, если это неверно, использует внешние вызовы API и, вероятно, имеет немного больше накладных расходов.

Это решение имеет поддержку текстовых полей с более чем 2 ^ 16 символовНо в этом случае Access ведет себя странно, и я рекомендую не использовать встроенный элемент управления textbox для таких больших текстовых полей.

0 голосов
/ 05 октября 2018

Звучит так, как будто это целое число без знака.

VBA не поддерживает типы без знака, поэтому, когда бит знака установлен (для 2-байтового целого числа, как только значение становится выше (2 ^ 15)) -1), вдруг становится отрицательным.Тем не менее, вы можете использовать базовые функции для работы с ними.

Я написал эти функции для работы с целыми числами без знака некоторое время назад, вы можете использовать их для преобразования long в целое число без знака и обратно:

Public Function LongToUInt(lIn As Long) As Integer
    If lIn >= 2 ^ 16 Then Exit Function 'Overflow, might want to raise an error
    If lIn < 0 Then Exit Function 'Unsigned type doesn't support negatives, might want to raise an error
    If lIn > (2 ^ 15) - 1 Then 'Set sign bit, then store remainder in an integer
        LongToUInt = (-2 ^ 16) + lIn
    Else
        LongToUInt = lIn
    End If
End Function

Public Function UIntToLong(iIn As Integer) As Long
    'No checks, an UINT always fits inside a long
    If iIn < 0 Then
        UIntToLong = iIn + 2 ^ 16
    Else
        UIntToLong = iIn
    End If
End Function

Реализуйте их:

Textbox.SelStart = LongToUInt(40000)

Dim theStart As Long
theStart = UIntToLong(Textbox.SelStart)

Как отметил Густав, по-прежнему существует проблема с переполнением, если значение больше (2 ^ 16) -1 (максимальное значение2-байтовое целое без знака)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...