2012-03-30 3 views
2

Учитывая ручку (hStdOut здесь) на стандартное устройство вывода , я использую следующие 2 процедуры, чтобы написать произвольную строку из консольного приложения:Как написать строку Unicode в буфер экрана консоли?

Выдержки:

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 или я должен рассмотреть другую функцию Юникод, что доступ к буферу экрана консоли?

ответ

4

Одна из проблем заключается в том, что вам нужно указать длину в байт, а не символов. Поэтому используйте 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.

+0

Благодарим за ответ. Проблема длины адресуется с помощью ByteLength, но у меня все еще есть проблемы: каждый символ строки визуализируется с дополнительным символом пробела. – menjaraz

+0

@menjaraz Да, это потому, что ваше устройство stdout ожидает ANSI, я думаю. Попробуйте второй фрагмент кода в ответе. У вас есть дополнительная информация о том, с каким типом устройств вывода вы работаете. –

+0

Вы правы, он ожидает ANSI. – menjaraz