如何将Unicode字符串写入控制台屏幕缓冲区?

时间:2012-03-30 15:30:03

标签: delphi winapi delphi-xe windows-console

标准输出设备句柄(hStdOut),我使用以下2个过程从控制台应用程序中写入任意字符串:

摘录:

procedure Send(const s: string);
var
  len: cardinal;
begin
  len:=Length(s);
  WriteFile(hStdOut,s[1],len,len,nil);
end;

procedure SendLn(const s: string);
begin
  Send(s + #13#10);
end;

我的麻烦:

此语句未按预期正确呈现字符串:

SendLn('The harder they come...');

我的问题:

是否存在WriteFile的“WideString”重载,还是应该考虑另一个访问控制台屏幕缓冲区的Unicode感知函数?

1 个答案:

答案 0 :(得分:4)

一个问题是您需要以 bytes 而不是字符指定长度。因此,请使用ByteLength而不是Length。在len传递的内容是缓冲区字节大小的一半。

我还认为您不应对nNumberOfBytesToWritelpNumberOfBytesWritten参数使用相同的变量。

procedure Send(const s: string);
var
  NumberOfBytesToWrite, NumberOfBytesWritten: DWORD;
begin
  NumberOfBytesToWrite := ByteLength(s);
  if NumberOfBytesToWrite>0 then
    WriteFile(hStdOut, s[1], NumberOfBytesToWrite, NumberOfBytesWritten, nil);
end;

如果stdout期待UTF-16编码文本,则上述情况正常。如果没有,如果它期望ANSI文本,那么你应该切换到AnsiString。

procedure Send(const s: AnsiString);
var
  NumberOfBytesToWrite, NumberOfBytesWritten: DWORD;
begin
  NumberOfBytesToWrite := ByteLength(s);
  if NumberOfBytesToWrite>0 then
    WriteFile(hStdOut, s[1], NumberOfBytesToWrite, NumberOfBytesWritten, nil);
end;

您需要发送到标准输出设备的具体内容取决于它所期望的文本编码,我不知道。

最后,如果这是您要写的控制台,那么您应该只使用WriteConsole