Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 如何将Unicode字符串写入控制台屏幕缓冲区?_Delphi_Winapi_Delphi Xe_Windows Console - Fatal编程技术网

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

Delphi 如何将Unicode字符串写入控制台屏幕缓冲区?,delphi,winapi,delphi-xe,windows-console,Delphi,Winapi,Delphi Xe,Windows Console,给定标准输出设备的句柄(此处为hStdOut),我使用以下两个过程从控制台应用程序写入任意字符串: 摘录: 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; 我的麻烦:

给定标准输出设备的句柄(此处为hStdOut),我使用以下两个过程从控制台应用程序写入任意字符串:

摘录:

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;
我的麻烦:

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...');
我的问题:

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;

是否存在“代码”>写文件的“宽字符串”重载,还是应该考虑另一个Unicode感知的函数来访问控制台屏幕缓冲区?

< P>一个问题是需要用字节而不是字符来指定长度。因此,请使用而不是
长度
。此时,您传入的
len
是缓冲区字节大小的一半

我还认为,对于
nNumberOfBytesToWrite
lpnumberOfBytesWrite
参数,不应使用相同的变量

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;
您需要发送到标准输出设备的确切内容取决于它所期望的文本编码,我不知道这一点


最后,如果这是您正在写入的控制台,那么您应该简单地使用。

一个问题是,您需要以字节而不是字符为单位指定长度。因此,请使用而不是
长度
。此时,您传入的
len
是缓冲区字节大小的一半

我还认为,对于
nNumberOfBytesToWrite
lpnumberOfBytesWrite
参数,不应使用相同的变量

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;
您需要发送到标准输出设备的确切内容取决于它所期望的文本编码,我不知道这一点


最后,如果这是您正在编写的控制台,您只需使用即可。

谢谢您的回答。长度问题是通过使用ByTeleneth解决的,但我仍然有麻烦:字符串的每个字符都有一个额外的空格字符。@menjaraz是的,我想这是因为您的标准输出设备需要ANSI。尝试答案中的第二段代码。关于您正在使用的输出设备的类型,您是否有更多信息可供我们参考。WriteConsole完全符合我的期望。谢谢,谢谢你的回答。长度问题是通过使用ByTeleneth解决的,但我仍然有麻烦:字符串的每个字符都有一个额外的空格字符。@menjaraz是的,我想这是因为您的标准输出设备需要ANSI。尝试答案中的第二段代码。关于您正在使用的输出设备的类型,您是否有更多信息可供我们参考。WriteConsole完全符合我的期望。非常感谢。