Страница 1 из 1
[РЕШЕНО] ShowMessage не отображает табуляцию
Добавлено: 11.08.2021 21:38:16
artem78
Почему диалоговое окно не отображает табуляцию как в Delphi, а выводит два слова слитно?

- 20210811_213408.png (18.05 КБ) 27684 просмотра
Re: ShowMessage не отображает табуляцию
Добавлено: 11.08.2021 22:48:34
Seenkao
{$mode delphi} - поможет?
вероятнее всего "не читаемый" символ (что довольно странно, как минимум пробел должен быть).
Может ещё из-за кодировки? Хотя... (по моему мнению) не должно. Но стоит попробовать.
Re: ShowMessage не отображает табуляцию
Добавлено: 12.08.2021 00:21:14
runewalsh
Dialogs.ShowMessage работает через WinAPI TaskDialog (а не ShowMessageW), и вот сама эта TaskDialog — да, тупо игнорирует табы, только что сам проверил. Скорее всего, с этим ничего нельзя сделать, смирись и/или заменяй на пробелы руками.
Попробовал сделать хитровывернутую UTF8-версию замены на пробелы сам:
Код: Выделить всё
{$mode objfpc} {$h+} {$codepage utf8}
const
Tab = #9;
function ReplaceTabs(const s: utf8string; tabWidth: SizeUint): utf8string;
var
pass: boolean;
sp, se, rp, sLitStart: pChar;
curWidth, nSpaces: SizeUint;
cpLen: SizeInt;
begin
result := '';
for pass in boolean do
begin
sp := pChar(pointer(s)); se := sp + length(s); sLitStart := sp; rp := pChar(pointer(result));
curWidth := 0;
while sp < se do
case sp^ of
#13, #10:
begin
sp += 1;
rp += 1;
curWidth := 0;
end;
#9:
begin
nSpaces := tabWidth - curWidth mod tabWidth;
if pass then
begin
Move(sLitStart^, (rp - (sp - sLitStart))^, (sp - sLitStart) * sizeof(char));
FillChar(rp^, nSpaces, ' ');
end;
sp += 1;
sLitStart := sp;
rp += nSpaces;
curWidth += nSpaces;
end;
else
begin
cpLen := UTF8CodepointLen(sp, se - sp, true);
if cpLen <= 0 then begin sLitStart := sp; break; end;
sp += cpLen;
rp += cpLen;
curWidth += 1;
end;
end;
if pass then Move(sLitStart^, (rp - (sp - sLitStart))^, (sp - sLitStart) * sizeof(char));
if not pass then
if sLitStart = pChar(pointer(s)) then exit(s) else SetLength(result, rp - pChar(pointer(result)));
end;
end;
begin
writeln(ReplaceTabs('Hello' + Tab + 'World' + LineEnding + 'Привет,' + Tab + 'мир.', 9));
end.
Правда, она не будет такой красивой для пропорциональных шрифтов (с переменной шириной символов), какие, собственно, используются в GUI.
Re: ShowMessage не отображает табуляцию
Добавлено: 12.08.2021 05:18:52
скалогрыз
runewalsh писал(а):тупо игнорирует табы, только что сам проверил. Скорее всего, с этим ничего нельзя сделать, смирись и/или заменяй на пробелы руками.
а раз это поведение системозависимое, логично, если менять табы на пробелы будет WS.
по-моему, вполне достойно багрепорта.
на крайняк, т.к. тип диалога передаётся (idDialogBase) то для такого типа использовать MessageBox()
но сами MS рекомендуют TaskDialog
Re: ShowMessage не отображает табуляцию
Добавлено: 12.08.2021 19:47:00
artem78
Seenkao писал(а):{$mode delphi} - поможет?
Не помогло.
runewalsh писал(а):Dialogs.ShowMessage работает через WinAPI TaskDialog (а не ShowMessageW)
А в Delphi 7 используется ShowMessage, как я догадываюсь?
Также проверил Application.MessageBox и MessageDlg - там то же самое.
Re: ShowMessage не отображает табуляцию
Добавлено: 12.08.2021 20:26:08
runewalsh
artem78 писал(а):А в Delphi 7 используется ShowMessage, как я догадываюсь?
Да, TaskDialog появились в Windows Vista, а Delphi 7 вышел гораздо раньше.
Более новые версии Delphi импортируют TaskDialog динамически и при его отсутствии откатываются на ShowMessageW (хотя нет, судя по статье
https://www.gunsmoker.ru/2015/12/debugg ... ase-1.html — даже не ShowMessageW, а ручную реализацию через полноценную VCL-форму). Во всяком случае, те, что поддерживают Windows XP — я не интересовался, поддерживается ли она до сих пор.
Re: ShowMessage не отображает табуляцию
Добавлено: 12.08.2021 20:54:13
artem78
runewalsh писал(а):смирись и/или заменяй на пробелы руками.
Нет уж. Тогда лучше собственный класс диалога от TForm создать.
Re: ShowMessage не отображает табуляцию
Добавлено: 13.08.2021 17:38:27
Vadim
В Linux работает.
А не пробовали вместо "#9" ставить "Char(9)"? Или ещё идея: преобразовать Вашу строку к PChar()...
Re: ShowMessage не отображает табуляцию
Добавлено: 13.08.2021 20:02:03
Сквозняк
Vadim писал(а):В Linux работает.
А не пробовали вместо "#9" ставить "Char(9)"? Или ещё идея: преобразовать Вашу строку к PChar()...
Ага, счас. Пробел есть, но маленький. Ширина таба хз от чего зависит.

Код: Выделить всё
procedure TForm1.Button1Click(Sender: TObject);
var
s5: ansistring;
q2,e2: longint;
begin
s5:=char(9);
writeln('___ ',length(s5));
for e2:=1 to length(s5) do begin val(s5[e2],q2); write(q2,#13#10) end;
ShowMessage('one' + char(9) + 'two');
end;
Зато вот так работает
Но не моноширинный шрифт гадит.
Re: ShowMessage не отображает табуляцию
Добавлено: 13.08.2021 20:34:17
Alex2013
"За что погибли мухи !"

Одну строчку добавить .
Код: Выделить всё
Procedure myShowMessage(S:String);
begin
StringReplace(S,#9,#32#32#32#32,[rfReplaceAll]);
ShowMessage(S);
end;
Re: ShowMessage не отображает табуляцию
Добавлено: 13.08.2021 20:35:35
runewalsh
СквознякИ что это значит? Ты вообще понимаешь, что делает val(s, q)? Ты пытаешься преобразовать символ табуляции (s) в число (q). Это преобразование проваливается, потому что строка из одной табуляции не содержит корректного числа, и устанавливает q в 0. У Val есть версия с тремя аргументами — Val(s, q, code), которая при успехе выставляет code = 0, а при неудаче возвращает в code номер первого символа в строке, с которого что-то пошло не так. В случае табуляции code = 2 — за концом строки (а не 1), потому что val допускает (и пропускает) пробельные символы в начале числа, и табуляция считается пробельным символом.

- dd.png (9.02 КБ) 27492 просмотра
Вообще, таб — это не просто N пробелов, таб добивает позицию в тексте до ближайшей фиксированной колонки. Например,
a(tab)b
aa(tab)bb
aaa(tab)bbb
— выровняет «b», «bb» и «bbb». По крайней мере, текстовые редакторы, в т. ч. редактор Lazarus'а, это соблюдают.

- tabs.png (584 байт) 27490 просмотров
Re: ShowMessage не отображает табуляцию
Добавлено: 13.08.2021 21:20:35
artem78
Vadim писал(а):В Linux работает.
Программа (на данный момент) предназначена только для ОС Windows, поэтому работа в других ОС меня пока не интересует.
Преобразовать табуляцию в пробелы мне не подходит, т.к. шрифт НЕ моноширный и выводимый текст такого плана:

- 20210813_205359.png (2.87 КБ) 27480 просмотров
Вообщем, решил проблему путём создания отдельной формы с Label-ом на всё окно.
Re: [РЕШЕНО] ShowMessage не отображает табуляцию
Добавлено: 13.08.2021 22:40:07
Сквозняк
runewalsh писал(а):И что это значит? Ты вообще понимаешь, что делает val(s, q)? Ты пытаешься преобразовать символ табуляции (s) в число (q). Это преобразование проваливается, потому что строка из одной табуляции не содержит корректного числа,
Нда, не так достал данные из строки/буквы, для получения гарантированного значения байта надо было использовать
Или ord использовать.