Консольное приложение Unicode в Delphi 2009

Как я могу создать консольное приложение Unicode с помощью Delphi 2009?

Если мне это нравится:

{$APPTYPE CONSOLE}
uses
  SysUtils;
begin
  writeln('öüğşç سيمانتت');
end.

Получаю следующее:

ougsc ???????

person Community    schedule 05.11.2008    source источник


Ответы (6)


Я не уверен, что это именно то, что вам нужно, но вы можете создавать консольные приложения Unicode во всех 32-битных версиях Delphi, используя функции Windows API. Я только что пробовал с Delphi 4:

program test;

{$APPTYPE CONSOLE}

uses
  Windows;

var
  s: WideString;
  i: integer;
  Written: Cardinal;
begin
  SetLength(s, 80);
  for i := 1 to 80 do
    s[i] := WideChar(48 + i);
  WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), PWideChar(s), 80, Written,
    nil);
end.

У меня нет Delphi 2009, чтобы попробовать, как работает ввод строк Unicode в редакторе ...

person mghie    schedule 05.11.2008
comment
Я пробовал твой код. Не работает. Вы тестировали его для символов Unicode, отличных от ANSI (например, widechar (416 долларов США) -, widechar (11f долларов США) - ğ, widechar (633 доллара США) - س)? - person ; 06.11.2008
comment
Извините, забыл про консольный шрифт (запускал в режиме отладки). Спасибо, он работает с векторным шрифтом (я изменил свой векторный шрифт консоли на Courier New). - person ; 06.11.2008
comment
WriteConsole не будет работать с перенаправленным выводом (например, app.exe ›file.txt), поэтому вам лучше проверить, возвращает ли WriteConsole значение False, а затем использовать WriteFile вместо этого. С помощью WriteFile вы можете писать как в юникоде, так и в ansi. Обычно в этом случае большинство приложений используют ansi. - person Alex; 04.07.2009

Writeln в Delphi 2009 по-прежнему использует ANSI (см. System TTextRec), но вы можете использовать UTF8Encode и изменить кодовую страницу вывода консоли на UTF8, вызвав SetConsoleOutputCP (CP_UTF8). Вам также понадобится хороший шрифт для отображения символов Юникода.

person Ondrej Kelle    schedule 06.11.2008
comment
Невероятный! Спасибо, это работает. Я не знал, что консоль Windows поддерживает многобайтовый набор символов, такой как UTF-8. - person ; 06.11.2008

Вы не можете (по крайней мере, не со стандартной библиотекой). Консольные функции - единственные не Unicode функции в Delphi 2009.

person Toon Krijthe    schedule 05.11.2008
comment
Если Delphi 2009 действительно полностью поддерживает юникод, должен быть способ сделать это. - person ; 05.11.2008
comment
Нет, консоль - это единственная часть, не юникод. У меня есть эта информация непосредственно от докладчика codegear на конференции. - person Toon Krijthe; 06.11.2008

@Kabrol: С установленным растровым шрифтом я не вижу ни одного символа, но с Lucida Console я вижу как минимум widechar ($ 11f) - «ğ».

См. «SetConsoleOutputCP только для шрифтов Unicode» и общее описание функций консольного API на «Справочник по консоли».

person mghie    schedule 06.11.2008
comment
Извините, забыл про консольный шрифт (запускал в режиме отладки). Спасибо, он работает с векторным шрифтом (я изменил свой векторный шрифт консоли на Courier New). - person ; 06.11.2008

Консоль Windows не может отображать символы Unicode, поэтому попробуйте отправить вывод в файл с помощью:

my_app.exe > unicode_file.txt

и попробуйте просмотреть unicode_file.txt в хорошем текстовом редакторе.

person Michał Niklas    schedule 05.11.2008
comment
Оконная консоль может отображать символы Юникода. Есть несколько программ, которые используют консоль Unicode. Перенаправление вывода в файл дает тот же поврежденный текст ansi. - person ; 05.11.2008

На самом деле есть способ сделать это с помощью стандартных вызовов WriteLn (), но он включает исправление ошибки в Delphi 2009 RTL. Дело в том, что Delphi творит чудеса компилятора для WriteLn. Для аргументов UnicodeString это приводит к вызову _WriteUString. Этот метод можно увидеть в System.pas, хотя вы не можете вызвать его напрямую. В нем вы увидите вызов _WriteLString, но этот метод получает аргумент AnsiString. Итак, когда происходит этот вызов, ваш UnicodeString понижается до AnsiString.

Решение состоит в том, чтобы изменить приведение UnicodeString-> AnsiString в приведение UnicodeString-> UTF8String.

Теперь, когда вы устанавливаете консоль в UTF8, все ваши символы останутся нетронутыми (и да, конечно, вам понадобится шрифт с поддержкой символов, которые вы хотите показать):

SetConsoleOutputCP(CP_UTF8)

Для этого исправления RTL вам нужно будет произвести некоторую изящную привязку кода. Я уже сделал это, и мой коллега занят написанием статьи об этом. Я отправлю ссылку, как только она станет доступна в Интернете.

Ваше здоровье!

person PatrickvL    schedule 10.11.2008
comment
Это похоже на изобретение велосипеда, поскольку уже есть статья, похожая на «Одиссею Гомера»: edn.embarcadero.com/ article / 39022 - person mjn; 16.11.2009
comment
Возможно, вы не заметили, но это именно та статья, которую я имел в виду, - ту, которую написал мой коллега Марьян Венема (если вы присмотритесь, мое имя действительно появляется там несколько раз). В любом случае, спасибо, что добавили ссылку - иногда я забываю эти вещи. И да, это действительно похоже на одиссею! - person PatrickvL; 18.11.2009