Форум: "Начинающим";
Текущий архив: 2009.11.29;
Скачать: [xml.tar.bz2];
ВнизSelLength и юникод Найти похожие ветки
← →
Kolan © (2009-10-12 11:58) [0]Здравствуйте!
Была у меня функция в потомке ричэдита. Она выделала вставляемую строку указанным цветом:
procedure TColorRichEdit.AddLine(S: string; Color: TColor);
var
Start: Integer;
begin
if Assigned(FBeforeLineAddEvent) then
FBeforeLineAddEvent(Self, S);
if FDelimiter <> "" then
AddDelimiter(S);
if FIsAddTime then
AddTime(S);
if FIsAddDate then
AddDate(S);
if FIsNumberLines then
AddNumber(S);
Start := Length(Text);
Lines.Add(S);
SelStart := Start;
SelLength := Length(Text) - Start;
SelAttributes.Color := Color;
SelStart := 0;
if FIsScrollToBottom then
Perform(WM_VSCROLL, SB_BOTTOM, 0);
if Assigned(FAfterLineAddEvent) then
FAfterLineAddEvent(Self, S);
end;
С появлением юникода строки стали выделяться не верно. Новый цвет начинался в середине и т. д.
Дело в том, что дело в том, что «Read SelLength to determine the length, in bytes, of the selected text.» и написал так:procedure TColorRichEdit.AddLine(S: string; Color: TColor);
var
Start: Integer;
begin
if Assigned(FBeforeLineAddEvent) then
FBeforeLineAddEvent(Self, S);
if FDelimiter <> "" then
AddDelimiter(S);
if FIsAddTime then
AddTime(S);
if FIsAddDate then
AddDate(S);
if FIsNumberLines then
AddNumber(S);
Start := Length(Text)*SizeOf(Char);
Lines.Add(S);
SelStart := Start;
SelLength := Length(Text)*SizeOf(Char) - Start;
SelAttributes.Color := Color;
SelStart := 0;
if FIsScrollToBottom then
Perform(WM_VSCROLL, SB_BOTTOM, 0);
if Assigned(FAfterLineAddEvent) then
FAfterLineAddEvent(Self, S);
end;
Строки стали выделяться оп другому, но все так же не правильно.
А как правильно?
← →
DVM © (2009-10-12 12:39) [1]
> Read SelLength to determine the length, in bytes
Че-то у меня сомнение в этом, ибо глупо так делать.
← →
Kolan © (2009-10-12 13:44) [2]Вы думаете английский язык и кавычки — это понты такие? :) Это цитата из справки.
«Description
Read SelLength to determine the length, in bytes, of the selected text. This is the same as the number of characters, unless you are using a multi-byte character set. Set SelLength to change the selection to consist of the first SelLength bytes starting at SelStart.
Note: Setting SelLength to a value greater than the number of characters from SelStart to the end of the text results in the selection of all characters from SelStart to the end of the text. Reading SelLength immediately after setting it to a value greater than the number of available characters returns the number of characters actually selected, not the value that was just set. »
← →
Инна (2009-10-12 13:45) [3]в уникоде 2 байта на букву а в анси 1
← →
Kolan © (2009-10-12 13:55) [4]В юникоде нет байт, это просто коды символов. Байты есть в кодировке. По умолчанию в Делфи используется UTF-16, которая действительно двухбайтовая и мне казалось я это учел написав SizeOf(Char). Но, видимо, я не прав, только не пойму где.
← →
Инна (2009-10-12 14:06) [5]
> В юникоде нет байт
бгг, байты есть везде
> По умолчанию в Делфи используется UTF-16
уверен ?
> мне казалось я это учел написав SizeOf(Char)
для уникода WChar
← →
KilkennyCat © (2009-10-12 14:14) [6]вообще-то, length возвращает количество элементов, и ему похрен, сколько байтов и ли килограмм на элемент.
а во-вторых, утф и юникод - не одно и тоже.
← →
KilkennyCat © (2009-10-12 14:15) [7]
> Инна (12.10.09 13:45) [3]
> в уникоде 2 байта на букву а в анси 1
в уникоде может быть сколько угодно байт на одну букву, причем одновременно.
← →
Kolan © (2009-10-12 14:20) [8]>бгг, байты есть везде
Some people are under the misconception that Unicode is simply a 16-bit code where each character takes 16 bits and therefore there are 65,536 possible characters. This is not, actually, correct. It is the single most common myth about Unicode, so if you thought that, don"t feel bad.
Джоэл понятно рассказывает об этом: http://www.joelonsoftware.com/articles/Unicode.html
>уверен ?
Конечно.The type string is an alias for UnicodeString. UnicodeString data is encoded in UTF-16.
>для уникода WChar
Уже не обязательно.For Delphi, Char and PChar types are WideChar and PWideChar types, respectively.
← →
Игорь Шевченко © (2009-10-12 14:21) [9]в Memo, которое ANSI, строки состоят из однобайтовых символов.
в Memo, которое Unicode, строки состоят из двухбайтовых символов.
EM_GETSEL всегда возвращает позиции символов, вне зависимости от их размера.
Не знаю, как реализовано в тех версиях Delphi, которые используют по умолчанию юникодные строки, но в 2006, например, Sellength - это разница между позициями, возвращаемыми EM_GETSEL, то есть, все расчеты выполняются в символах, вне зависимости от их размера.
Насколько мне известно, операции выделения в Edit Controls (в том числе и в RichEdit), оперируют тоже позициями символов, а не величинами в байтах.
← →
Kolan © (2009-10-12 14:22) [10]KilkennyCat, ну, то есть Length(Text) вернет кол-во символов, а в SelLength нужно записать кол-во байт. То есть надо умножить на кол-во байт в символе.
← →
Kolan © (2009-10-12 14:25) [11]
function TCustomEdit.GetSelLength: Integer;
var
Selection: TSelection;
begin
{$IF DEFINED(CLR)}
SendGetSel(Selection.StartPos, Selection.EndPos);
{$ELSE}
SendMessage(Handle, EM_GETSEL, WPARAM(@Selection.StartPos), LPARAM(@Selection.EndPos));
{$IFEND}
Result := Selection.EndPos - Selection.StartPos;
end;
Кажется и сейчас так, Игорь. Только почему тогда старый код перестал выделять как положено?
← →
Игорь Шевченко © (2009-10-12 14:27) [12]
> Кажется и сейчас так, Игорь. Только почему тогда старый
> код перестал выделять как положено?
Раз и сейчас так, тогда у тебя все операции тоже должны быть в символах, без учета размера символа. Соответственно, размер своего текста ты тоже должен считать в символах, а не в байтах.
← →
Kolan © (2009-10-12 14:41) [13]Тогда код в сабже должен был работать, но не работает.
Сейчас заметил интересную особенность. С каждой новой строкой выделение смещается на один символ.
Скриншот: http://img-fotki.yandex.ru/get/3806/ksoftware.d/0_341f9_647128df_L.jpg
← →
Игорь Шевченко © (2009-10-12 16:59) [14]
> Тогда код в сабже должен был работать, но не работает.
Отладчик на что в руки даден ?
← →
Kolan © (2009-10-13 11:10) [15]Как это отладить я не придумал. Я ему ясно говорю выдели столько-то символов и это раньше работало, а теперь нет, хотя логика осталась прежней.
Тем не менее, копаясь в справке я нашел элегантное решение самой задачи, которое не требует вычисления и выделения диапазонов.
Было:Start := Length(Text);
Lines.Add(S);
SelStart := Start;
SelLength := Length(Text) - Start;
SelAttributes.Color := Color;
SelStart := 0;
Стало:
SelAttributes.Color := Color;
Lines.Add(S);
Благодарю за обсуждение.
← →
clickmaker © (2009-10-14 09:49) [16]> > В юникоде нет байт
>
> бгг, байты есть везде
это биты есть везде )
← →
Anatoly Podgoretsky © (2009-10-14 11:26) [17]Все дело, что UTF-16 только продекларирован, а работа ведется с ucs-2 - это не рекламируется, но народ раздолбал код и экспериментами подтвердил. В итоге точный размер умножением N*W получить нельзя, как и наоборот. В АПИ почти тоже самое.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2009.11.29;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.004 c