Вверх ↑
Этот топик читают: Гость
Ответов: 70
Рейтинг: 1
#31: 2020-09-07 14:38:18 ЛС | профиль | цитата
Netspirit писал(а):
Проблема с кодировкой при чтении. В какой-то момент происходит конвертация. Проблема примерно та же что и с Буфером обмена по Ctrl+C/Ctrl+V.
Поставьте в примере из первого поста действие на кнопку и проверьте при английской раскладке, потом переключитесь на российскую. На тех системах, у кого работает, просто по-умолчанию стоит русская раскладка клавиатуры.
Как побороть - пока не знаю

Результат тотже что в первом посте.

Netspirit писал(а):
Пока нашел такое решение - отключение юникодных символов через EM_SETTEXTMODE в THIRichEdit.Init().
Пробуйте.

Работает
карма: 1

0
Ответов: 4628
Рейтинг: 749
#32: 2020-09-07 14:52:33 ЛС | профиль | цитата
Pavel писал(а):
Результат тотже что в первом посте.

Схема из первого поста на оригинальном RichEdit работает, если поставить российскую раскладку клавиатуры. Для этого перебор списка в той схеме надо поставить на кнопку и посмотреть работу при английской раскладке и после переключения на российскую.
карма: 26

0
Ответов: 4628
Рейтинг: 749
#33: 2020-09-08 11:24:49 ЛС | профиль | цитата
Обратите внимание на мой метод _Get() - чтобы избежать предварительного определения длины строки я использую буфер заведомо большего размера.
Это может добавлять немного производительности, но максимальная длина строки будет ограничена размером буфера (в данном случае 4 Кб).

Для выбора - моя оптимизированная версия изначального варианта с предварительным определением длины:
function THIRichEdit._Get(var Item: TData; var Val: TData): Boolean;
var
Ind, L: Integer;
Text: string;
begin
Ind := ToIntIndex(Item);
Result := (Ind >= 0) and (Ind < Control.Count);

if Result then
begin
L := Control.Perform(EM_LINELENGTH, Ind, 0); // Посчитать длину строки
if L > 0 then
begin
Inc(L, 2); // Размер буфера с запасом SizeOf(Word) (иначе не работает)
SetLength(Text, L);
PWord(Pointer(Text))^ := L; // В первом Word буфера - размер буфера

L := Control.Perform(EM_GETLINE, Ind, Longint(Pointer(Text)));
if (L <> 0) and (Text[L] = #13) then Dec(L); // Выдаёт также символ #13 в конце
if (L <> Length(Text)) then SetLength(Text, L); // В L - действительная длина строки (обычно меньше выделенного размера)
end
else
Text := '';

dtString(Val, Text);
end;
end;

Редактировалось 3 раз(а), последний 2020-09-09 10:35:11
карма: 26

0
Ответов: 70
Рейтинг: 1
#34: 2020-09-08 20:11:33 ЛС | профиль | цитата
Netspirit писал(а):
Pavel писал(а):
Результат тотже что в первом посте.

Схема из первого поста на оригинальном RichEdit работает, если поставить российскую раскладку клавиатуры. Для этого перебор списка в той схеме надо поставить на кнопку и посмотреть работу при английской раскладке и после переключения на российскую.


не работает при любой раскладке на оригинальном RichEdit

Снимок RU-EN-RU-EN.PNG

Снимок1.PNG

Снимок3.PNG

Редактировалось 3 раз(а), последний 2020-09-08 20:26:33
карма: 1

0
Ответов: 1926
Рейтинг: 172
#35: 2020-09-09 04:24:41 ЛС | профиль | цитата
nesco, так что, правим на SVN?
карма: 9
0
Ответов: 4628
Рейтинг: 749
#36: 2020-09-09 10:31:34 ЛС | профиль | цитата
Pavel писал(а):
не работает при любой раскладке на оригинальном RichEdit
Вероятно из-за PWORD( Buf )^ := L + 1 в KOL. Я то пробовал на модифицированном L+4 - там, вроде, будет описанное мной поведение.

Редактировалось 1 раз(а), последний 2020-09-09 15:12:03
карма: 26

0
Разработчик
Ответов: 26113
Рейтинг: 2126
#37: 2020-09-09 13:02:52 ЛС | профиль | цитата
3042 писал(а):
так что, правим на SVN?

Мне вот интересно, а вот эта вся фигамотина будет работать с любыми кодовыми страницами или только с системными? Прикол RichEdit был именно в возможности отображать любые кодовые страницы. Не изменится ли возможность отображения страниц вот после этой правки в Init


Control.Perform(EM_SETTEXTMODE, TM_RICHTEXT or TM_MULTILEVELUNDO or TM_SINGLECODEPAGE, 0);
карма: 22

0
Ответов: 4628
Рейтинг: 749
#38: 2020-09-09 13:44:58 ЛС | профиль | цитата
nesco писал(а):
Не изменится ли возможность отображения страниц вот после этой правки в Init
Изменится.
nesco писал(а):
Прикол RichEdit был именно в возможности отображать любые кодовые страницы.
А смысл, если то, что он отображает, нельзя прочесть и обработать в программе?
карма: 26

0
Разработчик
Ответов: 26113
Рейтинг: 2126
#39: 2020-09-09 14:30:53 ЛС | профиль | цитата
Netspirit писал(а):
А смысл, если то, что он отображает, нельзя прочесть и обработать в программе?

А если нужно именно просто отображать? А не вариант программно конвертнуть UNICOD в UTF8 и выдавать по _Get уже в формате UTF8? Конвертеры UTF8 в ANSI у нас вроде есть.
карма: 22

0
Ответов: 4628
Рейтинг: 749
#40: 2020-09-09 16:10:54 ЛС | профиль | цитата
nesco писал(а):
А если нужно именно просто отображать?
Ну, а как туда из программы вывести текст в Unicode? А если пользователь только может ввести с клавиатуры текст или загрузить из файла, то какой смысл? Хотя, грузить из файла для отображения может кому-то понадобиться.

nesco писал(а):
А не вариант программно конвертнуть
Получить отдельные строки с помощью SendMessageW(EM_GETLINE) не получилось - приходит уже сконвертированным. Вероятно, знает что окно создавалось с помощью CreateWindowA. Только что попробовал через GetWindowTextW - аналогично: юникодный текст уже содержит "?" на месте не входящих в текущую кодовую страницу символов (кстати, даже с Control.Perform(EM_SETTEXTMODE) оно отображает юникодные символы):
Add(MainForm,2953706,49,133)
{
Width=397
Height=371
}
Add(RichEdit,7915306,224,119)
{
Left=15
Top=20
Width=330
Height=75
Font=[Microsoft Sans Serif,8,0,0,204]
Strings=#5:Текст|
Point(Handle)
}
Add(Button,9785529,175,175)
{
Left=15
Top=110
link(onClick,11970995:doGetREText,[])
}
Add(InlineCode,11970995,245,175)
{
WorkPoints=#11:doGetREText|
EventPoints=#10:onTextANSI|11:onTextANSI2|10:onTextUTF8|9:onTextUni|
DataPoints=#8:REHandle|
Code=#15:unit HiAsmUnit;|0:|9:interface|0:|4:uses|29: Windows, KOL, Share, Debug;|0:|4:type|29: THiAsmClass = class(TDebug)|11: private|0:|10: public|26: REHandle: THI_Event;|17: onTextANSI,|18: onTextANSI2,|16: onTextUni,|31: onTextUTF8: THI_Event; |59: procedure doGetREText(var _Data: TData; Index: Word);|6: end;|0:|14:implementation|0:|84:function WideStringToAnsiString(const S: WideString; TargetCP: Integer): AnsiString;|3:var|18: L, DestL: DWord;|7:begin |15: Result := '';|22: if S = '' then Exit;|0:|17: L := Length(S);|77: DestL := WideCharToMultiByte(TargetCP, 0, Pointer(S), L, nil, 0, nil, nil);|19: if DestL > 0 then|7: begin|29: SetLength(Result, DestL);|97: if WideCharToMultiByte(TargetCP, 0, Pointer(S), L, Pointer(Result), DestL, nil, nil) = 0 then|28: Result := ''; // Error|6: end;|4:end;|0:|0:|0:|65:procedure THiAsmClass.doGetREText(var _Data: TData; Index: Word);|3:var|13: H: THandle;|13: L: Integer;|17: WS: WideString;|13: S: string; |5:begin|0:|39: H := ReadInteger(_Data, REHandle, 0);|2: |80: // Стандартный способ с автоматической конвертацией в текущую кодовую страницу|31: L := GetWindowTextLengthA(H);|15: if L > 0 then|7: begin|21: SetLength(S, L); |46: {L :=} GetWindowTextA(H, Pointer(S), L+1);|45: //if L <> Length(S) then SetLength(S, L);|5: end|6: else|12: S := '';|2: |30: _hi_OnEvent(onTextANSI, S); |2: |24: // Получение в Unicode|31: L := GetWindowTextLengthW(H);|15: if L > 0 then|7: begin|22: SetLength(WS, L); |47: {L :=} GetWindowTextW(H, Pointer(WS), L+1);|47: //if L <> Length(WS) then SetLength(WS, L);|5: end|6: else|14: WS := ''; |2: |42: // В WS - текст в Unicode. Конвертируем:|0:|45: // Автоматически в текущую кодовую страницу|10: S := WS;|30: _hi_OnEvent(onTextANSI2, S);|2: |20: // Вручную в UTF-8|43: S := WideStringToAnsiString(WS, CP_UTF8);|29: _hi_OnEvent(onTextUTF8, S);|2: |21: // Выдаём в Unicode|18: L := Length(WS);|2: |15: if L > 0 then|7: begin|41: L := L * 2; // В 1-байтовых символах |21: SetLength(S, L); |25: Move(WS[1], S[1], L);|5: end|6: else|13: S := ''; |2: |28: _hi_OnEvent(onTextUni, S);|2: |0:|4:end;|0:|0:|0:|4:end.|
link(onTextANSI,8368524:doEvent1,[])
link(onTextANSI2,8368524:doEvent2,[])
link(onTextUTF8,8368524:doEvent3,[])
link(onTextUni,6834885:doEvent1,[(293,202)(293,314)])
link(REHandle,7915306:Handle,[])
}
Add(Memo,9409052,525,175)
{
Left=15
Top=140
Width=330
Height=170
}
Add(Hub,8368524,483,175)
{
InCount=4
OutCount=1
link(onEvent1,9409052:doAdd,[])
}
Add(Charset,10912153,343,315)
{
Type=9
link(onCharset,16573114:doEvent2,[])
}
Add(Charset,6781189,315,203)
{
Type=7
}
Add(Hub,6834885,308,308)
{
link(onEvent1,15541894:doConvert,[(332,314)(332,279)])
link(onEvent2,10912153:doCharset,[])
}
Add(Hub,16573114,406,308)
{
InCount=2
OutCount=1
link(onEvent1,8368524:doEvent4,[(452,314)(452,202)])
}
Add(StreamConvertor,15541894,343,273)
{
Mode=2
link(onResult,16573114:doEvent1,[(391,279)(391,314)])
}

Редактировалось 1 раз(а), последний 2020-09-09 16:11:27
карма: 26

0
Ответов: 1926
Рейтинг: 172
#41: 2020-09-12 14:07:02 ЛС | профиль | цитата
Заглохла тема?Netspirit, есть подвижки? А то почти всё готово, а воз и ныне там.
карма: 9
0
Разработчик
Ответов: 26113
Рейтинг: 2126
#42: 2020-09-12 22:01:57 ЛС | профиль | цитата
3042 писал(а):
А то почти всё готово, а воз и ныне там

Можно не торопиться. Я в отпуске до середины октября, раньше все равно добавить не смогу.
карма: 22

0
Ответов: 1926
Рейтинг: 172
#43: 2020-09-13 20:50:15 ЛС | профиль | цитата
А что ж из дома? Вот как раньше было: обновления и исправления быстренько на сервак. А сейчас всё тя-янется... Эх, старые добрые времена
карма: 9
0
Ответов: 4628
Рейтинг: 749
#44: 2020-09-14 10:32:47 ЛС | профиль | цитата
nesco, можешь проверить отображение Юникода. Вроде, после правок ничего принципиально не изменилось.
карма: 26

0
Разработчик
Ответов: 26113
Рейтинг: 2126
#45: 2020-09-14 11:03:39 ЛС | профиль | цитата
3042 писал(а):
Вот как раньше было: обновления и исправления быстренько на сервак

А за нами разве кто-то гонится? Столько лет висело, а тут месяц потерпеть не может.
карма: 22

0
45
Сообщение
...
Прикрепленные файлы
(файлы не залиты)