По-хорошему, я бы рекомендовал переименовать компонент, к примеру, в RepeatChar или FillChar
Этот топик читают: Гость
Разработчик
Ответов: 26163
Рейтинг: 2127
|
|||
карма: 22 |
|
Ответов: 4630
Рейтинг: 749
|
|||
Это называется "StrPad"
|
|||
карма: 26 |
|
Разработчик
Ответов: 26163
Рейтинг: 2127
|
|||
Netspirit писал(а): Это называется "StrPad"Ну, можно и так, но никак не SetLength |
|||
карма: 22 |
|
Ответов: 9906
Рейтинг: 351
|
|||
Netspirit писал(а): То-есть, когда изменение строки, полученной по ReadString недопустимо (в каких случаях одна и та же TData используется в нескольких компонентах)?Думаю, что win-ХАК недопустим вообще. Мы же работаем "из гарантий". По крайней мере - должны. Ну вот, например
Хотя, наверняка - есть какая-нибудь функция из System... А теперь предположим, что нет у нас еще элементов, которые поймали бы этот win-ХАК. Типа, протестировали -- ай-ай-ай как все хорошо! Вот именно такой подход и есть "радиолюбительство"... Профессионально: достаточно увидеть отсутствие ГАРАНТИЙ того, что кто-то, когда-нибудь не использует повторно такую строку. И не надо даже искать - есть уже такие элементы, или нет. Это не очень-то и важно. В Инженерной культуре это называется: "Не планируй себе проблемы. Попробуй сначала справиться с теми, которые возникнут и без твоего планирования" |
|||
карма: 9 |
|
Ответов: 4630
Рейтинг: 749
|
|||
Вот демонстрация того, как это изменение строки влияет на другие компоненты: code_35424.txt
(третье событие хаба должно выдавать то же, что и первое, но не выдаёт) |
|||
карма: 26 |
| ||
файлы: 1 | code_35424.txt [1.2KB] [621] |
Разработчик
Ответов: 26163
Рейтинг: 2127
|
|||
Получается из той же оперы, что в WinAPI нельзя пихать строку нулевой длины, те Pchar(s), при length(s)=0 вызывает крэш. Netspirit, попробуй отключить в своей схеме данные от Edit, тут же получишь RunTime Error
|
|||
карма: 22 |
|
Ответов: 5227
Рейтинг: 587
|
|||
Netspirit, проблема решаема http://delphi.scps.ru/string/str5234.htm
|
|||
карма: 4 |
|
Ответов: 4630
Рейтинг: 749
|
|||
nesco писал(а): Получается из той же оперыНет, это особенность самой CharLower (в справке описана интерпретация параметра). А вот другая опера. Что в данном Inline Code получается, если в потоке нет данных? Правильно, переменной s присваивается пустая строка ''. Если бы вместо пустой строки дать какую-нибудь не пустую, CharLower должна бы отработать нормально. Но нет, потому что это константа. А константы где у нас расположены? В памяти только для чтения. И эта функция будет пытаться менять данные в памяти для чтения. То-есть, CharLower(PChar('ABC')) недопустимо. andrestudio писал(а): проблема решаемаКстати, вот ещё способ: SetLength(s, Length(s)); |
|||
карма: 26 |
|
Ответов: 9906
Рейтинг: 351
|
|||
nesco писал(а): Получается из той же оперы, что в WinAPI нельзя пихать строку нулевой длины, те Pchar(s), при length(s)=0Неправда твоя, nesco! Pchar(s), при length(s)=0 -- честно-благородно выдает ненулевой указатель на нулевой символ. Вот Pointer(s), при length(s)=0 -- действительно, выдает nil. Как при этом будет вести себя WinApi -- MSDN читать надо... Всякое WinApi бывает. Может все и кошерно будет |
|||
карма: 9 |
|
Разработчик
Ответов: 26163
Рейтинг: 2127
|
|||
Galkov писал(а): Pchar(s), при length(s)=0 -- честно-благородно выдает ненулевой указатель на нулевой символ.А я ничего про указатели и не писал. Я просто констатировал факт, что CharLower выдает ошибку при пустой строке. Те вот такой код выдает ошибку
|
|||
карма: 22 |
|
Ответов: 4630
Рейтинг: 749
|
|||
Такой тоже даст ошибку:
s := 'ABC';
CharLower(PChar(s)); |
|||
карма: 26 |
|
Разработчик
Ответов: 26163
Рейтинг: 2127
|
|||
Netspirit писал(а): Такой тоже даст ошибку:А вот это тогда почему выдает
s, в данном случае, уже не ссылается на константу |
|||
карма: 22 |
|
Ответов: 4630
Рейтинг: 749
|
|||
Так вроде ж выяснили выше: CharLower не любит строки с 0-вой длиной. Возможно по причине той же константы: при PChar(s) с 0-вой длиной Delphi передаёт в функцию валидный адрес, по которому лежит #00. Этот адрес, вероятно, лежит в области констант. Другие API функции это вполне нормально воспринимают, а вот CharLower может пытаться писать по этому адресу.
Если в последнем случае написать CharLower(Pointer(s)) то ошибки не будет: в этом случае Delphi передаст не указатель на константный символ #00, а именно 0, как адрес строки. А согласно MSDN, если аргумент CharLower меньше $FFFF (в данном случае 0), то она считает аргумент одним символом, результат преобразования которого и возвратит (не запишет по адресу, так как был передан не адрес, а код символа):
s := Char(CharLower(Pointer(65))); |
|||
карма: 26 |
|
Разработчик
Ответов: 26163
Рейтинг: 2127
|
|||
Netspirit писал(а): Другие API функции это вполне нормально воспринимаютА в этом есть стопроцентная уверенность Может еще какая функция не любит строки нулевой длины |
|||
карма: 22 |
|
Ответов: 4630
Рейтинг: 749
|
|||
По каждой функции идёт описание, как она себя ведет, если ей передать nil или строку 0-вой длины (а это не одно и то же).
Обобщить можно лишь так: если API функция изменяет содержимое переданного ей буфера (в описании многих функций можно встретить предупреждение, что функция изменяет данные в буфере), то в такие функции нельзя передавать: - PChar(<константа>), Pointer(<константа>) - PChar(s) с 0-вой длиной строки. Но в зависимости от функции можно передавать Pointer(s), что не исключает предыдущего случая. Пример: MessageBox(0, PChar('Text'), PChar(''), 0); // В качестве заголовка пустая строка (адрес строки 0-вой длины, состоящей из одного символа #00)
MessageBox(0, PChar('Text'), nil, 0); // В качестве заголовка 0-вой адрес (нет никакой строки, даже пустой) - система проставит стандартный заголовок |
|||
карма: 26 |
|