2

给定标准输出设备的句柄(此处为 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...');

我的问题:

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

4

1 回答 1

4

一个问题是您需要以字节而不是字符为单位指定长度。所以使用ByteLength而不是Length. 目前,您传入的len是缓冲区字节大小的一半。

我也相信你不应该对nNumberOfBytesToWriteandlpNumberOfBytesWritten参数使用相同的变量。

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.

于 2012-03-30T15:41:23.520 回答