Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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.51 MB
Время: 0.049 c
4-1105057690
Unleashed
2005-01-07 03:28
2005.02.20
Нагрузка процессора


14-1107186515
quickblack
2005-01-31 18:48
2005.02.20
Доступ в инет через Мегафон


4-1104840564
Xattab
2005-01-04 15:09
2005.02.20
Использование функции LockFileEx


3-1106645184
DimonNew
2005-01-25 12:26
2005.02.20
Проверить - существует ли параметр в ADOCommand


14-1106763171
BZsder
2005-01-26 21:12
2005.02.20
Создание окна