Текущий архив: 2005.02.20;
Скачать: CL | DM;
ВнизКак научить консоль говорить по русски в XP? Найти похожие ветки
← →
GrayZeeCat © (2005-01-30 16:26) [0]Всем здрасте. Вопрос такой. Есть консольное приложение написанное на делфи. врайтлн строку которая в редакторе введена по русски в консоли выводит кракозябры. Есть функция SetConsoleOutputCP() которая судя по справке работает в НТ, но в ХР она не помогает. Как научить консоль говорить по русски? Или только через CharToOem или перехват процедуры вывода?
← →
rdm © (2005-01-31 03:40) [1]А что тебе мешает писать все сообщения в dos кодировке (через FAR), а уже потом компилировать в Delphi. Понимаю, что немного геморойно, но зато самый быстрый способ и работать будет везде.
← →
Просто Джо © (2005-01-31 03:48) [2]
> Или только через CharToOem
А чем CharToOem не подходит? Напиши себе вокруг нее wrapper вроде
WriteLn (S: string);
begin
CharToOem (..,..);
System.WriteLn (...)
end;
← →
Чапаев © (2005-01-31 12:56) [3]После установки страницы SetConsoleOutputCP(1251) русские буквы будут -- но только если выставить шрифтом консоли Lucida Console. Со стандартным точечным шрифтом поможет только CharToOem() aka AnsiToOem().
← →
jack128 © (2005-01-31 14:00) [4]Радикальное решение.
DiamondShark © (09.12.04 14:09) [Ответить]
Субж вопросов типа: "А почему у меня в консоли кракозябры и как с ними бороться".
unit conio;
interface
implementation
uses
Windows;
// To avoid importing SysUtils
const
fmClosed = $D7B0;
fmInput = $D7B1;
fmOutput = $D7B2;
fmInOut = $D7B3;
type
PTextBuf = ^TTextBuf;
TTextBuf = array[0..127] of Char;
TTextRec = packed record
Handle: Integer;
Mode: Integer;
BufSize: Cardinal;
BufPos: Cardinal;
BufEnd: Cardinal;
BufPtr: PChar;
OpenFunc: Pointer;
InOutFunc: Pointer;
FlushFunc: Pointer;
CloseFunc: Pointer;
case integer of
0: (OldOpenFunc, OldInOutFunc, OldFlushFunc, OldCloseFunc: Pointer);
1: (
UserData: array[1..32] of Byte;
Name: array[0..259] of Char;
Buffer: TTextBuf);
end;
TTextFunc = function(var F: TTextRec): Integer;
function InOutFunc(var F: TTextRec): Integer;
begin
case F.Mode of
fmOutput: begin
AnsiToOemBuff(F.BufPtr, F.BufPtr, F.BufPos);
Result := TTextFunc(F.OldInOutFunc)(F);
end;
fmInput: begin
Result := TTextFunc(F.OldInOutFunc)(F);
if F.BufEnd > 0 then
OemToAnsiBuff(F.BufPtr, F.BufPtr, F.BufEnd);
end;
else
Result := TTextFunc(F.OldFlushFunc)(F);
end;
end;
function FlushFunc(var F: TTextRec): Integer;
begin
case F.Mode of
fmOutput: begin
AnsiToOemBuff(F.BufPtr, F.BufPtr, F.BufPos);
Result := TTextFunc(F.OldFlushFunc)(F);
end;
else
Result := TTextFunc(F.OldFlushFunc)(F);
end;
end;
function OpenFunc(var F: TTextRec): Integer;
begin
Result := TTextFunc(F.OldOpenFunc)(F);
with F do
begin
OldInOutFunc := InOutFunc;
OldFlushFunc := FlushFunc;
OldCloseFunc := CloseFunc;
InOutFunc := @conio.InOutFunc;
FlushFunc := @conio.FlushFunc;
end;
end;
procedure InitConsoleIO;
begin
with TTextRec(Output) do
begin
OldOpenFunc := OpenFunc;
OpenFunc := @conio.OpenFunc;
end;
with TTextRec(Input) do
begin
OldOpenFunc := OpenFunc;
OpenFunc := @conio.OpenFunc;
end;
end;
initialization
InitConsoleIO;
end.
Для побеждения кракозябров просто прописать первым в uses проекта.
← →
PZ (2005-01-31 20:22) [5]А вот простейшая функция:
Function Rus(Mes : String) : String;
// Функция для русификации консольных программ
// Ansi : коды русских букв 192..255
// Asссi : коды русских букв 126..175, 224..239
Var I : Integer;
Begin
For I := 1 to Length(Mes) do
Case Mes[I] of
"А".."п" : Mes[I] := Chr(Ord(Mes[I]) - 64);
"р".."я" : Mes[I] := Chr(Ord(Mes[I]) - 16);
end; { Case }
Result := Mes;
End; { Rus }
Использование в консоли:
Writeln(Rus("Всем здрасте. Вопрос такой. Есть консольное приложение написанное на делфи."));
← →
Anatoly Podgoretsky © (2005-01-31 20:39) [6]Просто Джо © (31.01.05 03:48) [2]
Ну ну, а как насчет WriteLn(A,B, ...N);
← →
Просто Джо © (2005-01-31 23:48) [7]
> Ну ну, а как насчет WriteLn(A,B, ...N);
Суть была в написании простейшего wraper"a. Никто не мешает сделать так:procedure WriteLn (Arr: array of const);
← →
Просто Джо © (2005-02-01 05:17) [8]Скажем, что-то вроде:
procedure Write (const Args: array of const);
var
I: Integer;
S: string;
{для быстрого перевода}
function BoolToStr (const B: Boolean): string;
const
ArrFalseTrue: array [False..True] of string = ("False","True");
begin
Result := ArrFalseTrue[B]
end;
begin
for I := 0 to High(Args) do
begin
case Args[I].VType of
vtInteger:
S := S + IntToStr(Args[I].VInteger);
vtInt64:
S := S + IntToStr(Args[I].VInt64^);
vtExtended:
S := S + FloatToStr (Args[I].VExtended^);
vtAnsiString:
S := S + string(Args[I].VAnsiString);
vtChar:
S := S + Args[I].VChar;
vtBoolean:
S := S + BoolToStr(Args[I].VBoolean);
vtCurrency:
S := S + CurrToStr(Args[I].VCurrency^);
// два изврата подряд - rather geeky:)
vtClass:
S := S + Args[I].VClass.ClassName;
vtObject:
S := S + Args[I].VObject.ClassName;
// vtXXX:
// добавьте по вкусу другие типы принимаемых аргументов
else
S := S + "<unsupported value>" // а мы ограничимся этим
end; // of case
end;
if S <> "" then
CharToOem (PChar(S),PChar(S));
System.Write (S);
end;
procedure WriteLn (const Args: array of const);
begin
Write (Args);
System.Writeln
end;
пример использования
WriteLn ([
"Строка", // кириллическая строка в кодировке 1251
123, // Integer
20.34, // Extended
True, // Boolean
Int64(999666), // Int64
TObject // изврат вдогонку
]);
← →
GrayZeeCat © (2005-02-01 19:24) [9]Всем спасибо.
2 rdm.
По твоему способу почему то не работает. :(
2 Чапаев.
Про Lucida Console спасибо. Сам почему не допер. :-((
2 Просто Джо.
CharToOem() не хотелось бы использовать по нескольким причинам: некоторое захламление текста программы явным вызовом фильтрующих процедур. Задача становится совсем неприятной, когда предстоит «русифицировать» уже готовое приложение со многими обращениями к Write.
Всем.
Вот нашел еще готовое решение данной проблемы.
{
Модуль “русификации“ консольных приложений
(c) Eugene Kasnerik, 1999
e-mail: eugene1975@mail.ru
}
unit EsConsole;
interface
implementation
uses
Windows;
{
Описание структуры приведено здесь с единственной целью –
не подключать SysUtils и, соответственно, код инициализации
этого модуля. Консольные приложения обычно малы и 25К кода
обработки исключений – несколько высокая плата за описание
единственной структуры.
}
type
TTextRec = record
Handle: Integer;
Mode: Integer;
BufSize: Cardinal;
BufPos: Cardinal;
BufEnd: Cardinal;
BufPtr: PChar;
OpenFunc: Pointer;
InOutFunc: Pointer;
FlushFunc: Pointer;
CloseFunc: Pointer;
UserData: array[1..32] of Byte;
name: array[0..259] of Char;
Buffer: array[0..127] of Char;
end;
function ConOutFunc(var Text: TTextRec): Integer;
var
Dummy: Cardinal;
SavePos: Integer;
begin
SavePos := Text.BufPos;
if SavePos > 0 then
begin
Text.BufPos := 0;
CharToOemBuff(Text.BufPtr, Text.BufPtr, SavePos);
if WriteFile(Text.Handle, Text.BufPtr^, SavePos, Dummy, nil) then
Result := 0
else
Result := GetLastError;
end
else
Result := 0;
end;
initialization
Rewrite(Output); // Проводим инициализацию файла
{ И подменяем обработчики. Есть в этом что-то от
хака, но цель оправдывает средства }
TTextRec(Output).InOutFunc := @ConOutFunc;
TTextRec(Output).FlushFunc := @ConOutFunc;
end.
Для русификации приложения достаточно лишь подключить вышеуказанный модуль в любом месте программы (как правило, в проекте), после чего вывод ANSI-символов будет осуществлен в ожидаемом виде. Однако следует иметь в виду, что не будут доступны символы псевдографики (для них нет аналогов в ANSI, т.е. в редакторе их не введешь) и часть диакритических знаков (для них нет аналогов в OEM). Впрочем, для модификации значений выводимых символов не обязательно использовать системные функции, что открывает простор для консольного вывода в самых разных кодировках.
Страницы: 1 вся ветка
Текущий архив: 2005.02.20;
Скачать: CL | DM;
Память: 0.5 MB
Время: 0.036 c