Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.02.20;
Скачать: [xml.tar.bz2];

Вниз

Как научить консоль говорить по русски в 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.045 c
1-1107409966
fynjy1984
2005-02-03 08:52
2005.02.20
DBGridEh и копирование


3-1106402538
Desdechado
2005-01-22 17:02
2005.02.20
ClientDataset.PacketRecords и EOF


3-1106499763
Fin
2005-01-23 20:02
2005.02.20
Хранимые процедуры.


1-1107846225
Zhekson
2005-02-08 10:03
2005.02.20
XP Manifest


1-1107715687
Andrey M
2005-02-06 21:48
2005.02.20
несколько вопросов





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский