Delphi 2009中的Unicode控制台应用程序

10

我怎样才能使用Delphi 2009创建Unicode控制台应用程序?

如果我像这样做:

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

我得到以下内容:

ougsc ???????
6个回答

11

Delphi 2009中的Writeln仍使用ANSI编码(见System TTextRec),但您可以使用UTF8Encode并调用SetConsoleOutputCP(CP_UTF8)更改控制台的输出编码为UTF-8。您还需要一个好的字体来实际显示Unicode字符。


真不可思议!谢谢,它能正常工作了。我不知道Windows控制台支持多字节字符集,例如UTF-8。 - Tim Sullivan

9

我不确定这是否符合您的要求,但是您可以使用Windows API函数在所有32位Delphi版本中创建Unicode控制台应用程序。我刚刚尝试了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字符串的工作方式...


我试过你的代码。它不能工作。你有为非ANSI Unicode字符(例如widechar($416) -“Ж”,widechar($11f) -“ğ”,widechar($633) -“س”)进行测试吗? - Tim Sullivan
抱歉,我忘记了控制台字体(我在调试模式下运行它)。谢谢,现在使用矢量字体可以正常工作了(我将我的控制台矢量字体更改为“Courier New”)。 - Tim Sullivan
1
WriteConsole 不适用于重定向输出(如 app.exe > file.txt),因此最好检查 WriteConsole 是否返回 False,然后改用 WriteFile。使用 WriteFile,您可以编写 Unicode 或 ANSI。通常大多数应用程序在这种情况下使用 ANSI。 - Alex

5
您不能这样做(至少不能使用标准库)。控制台函数是Delphi 2009中唯一的非Unicode函数。

如果 Delphi 2009 真的是全 Unicode 的,那一定有方法可以做到。 - Tim Sullivan
不,控制台是唯一不支持Unicode的部分。我从CodeGear的一位演讲者那里直接得到了这个信息。 - Toon Krijthe

1

抱歉,我忘记了控制台字体(我在调试模式下运行了它)。谢谢,现在使用矢量字体正常了(我将我的控制台矢量字体更改为“Courier New”)。 - Tim Sullivan

0

Windows控制台无法显示Unicode字符,因此请尝试将输出发送到文件中:

my_app.exe > unicode_file.txt

并尝试使用好的文本编辑器查看unicode_file.txt文件。


窗口控制台可以显示Unicode字符。有几个程序使用Unicode控制台。将输出重定向到文件会产生相同的损坏ANSI文本。 - Tim Sullivan

0
实际上,有一种方法可以使用标准的WriteLn()调用来完成这个任务,但它涉及到修补Delphi 2009 RTL中的一个错误。 问题在于,Delphi对WriteLn进行了一些编译器魔法。对于UnicodeString参数,这会导致调用_WriteUString。该方法可以在System.pas中看到,尽管您不能直接调用它。在其中,您将看到对_WriteLString的调用,但是该方法接收一个AnsiString参数。因此,在进行此调用时,您的UnicodeString被降级为AnsiString。
解决方案是将此UnicodeString->AnsiString转换为UnicodeString->UTF8String转换。
现在,当您将控制台设置为UTF8时,所有字符都将不受影响地通过(是的,当然您需要具有支持要显示的字符的字体):
SetConsoleOutputCP(CP_UTF8)

针对这个RTL修复,您需要进行一些巧妙的代码挂钩。我已经完成了这个过程,我的一个同事正在忙于撰写一篇关于此的文章。一旦它在线上可用,我会发布链接。

干杯!


这似乎是在重新发明轮子,因为已经有一篇读起来像《荷马史诗》的文章了:http://edn.embarcadero.com/article/39022 - mjn
也许你没有注意到,但这正是我所指的文章——我的同事Marjan Venema写的那篇(如果你仔细看的话,我的名字确实出现了几次)。无论如何,感谢添加链接,有时候我会忘记这些事情。而且,确实读起来像一场奥德赛! - PatrickvL

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接