Как мне записать строку Unicode в экранный буфер консоли? - PullRequest
2 голосов
/ 30 марта 2012

Учитывая дескриптор (здесь 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, которая обращается к экранному буферу консоли?

1 Ответ

4 голосов
/ 30 марта 2012

Одна проблема заключается в том, что вам нужно указать длину в байтах , а не символах .Поэтому используйте ByteLength вместо Length.На данный момент то, что вы передаете в len, составляет половину размера байта буфера.

Я также считаю, что вам не следует использовать одну и ту же переменную для параметров nNumberOfBytesToWrite и lpNumberOfBytesWritten.

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.

...