Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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
15-1254375904
VladOfMonster
2009-10-01 09:45
2009.11.29
Где найти значки для панели инструментов


2-1255334323
Kolan
2009-10-12 11:58
2009.11.29
SelLength и юникод


3-1230180063
ganda
2008-12-25 07:41
2009.11.29
Firebird и индексы


15-1252418473
Наиль
2009-09-08 18:01
2009.11.29
Кому Windows XP бесплатно?


8-1173516347
hypnotize
2007-03-10 11:45
2009.11.29
Вывести графику на Canvas с Anti-Aliasing ом





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский