Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Проблемы русского языка в проектах Delphi 6-9


Автор: Snowy 1.2.2006, 19:02
 Постоянно возникает вопрос о проблеме с превращением русских символов в проекте в ?????????.
Не всегда помогает и установка чарсета в RUSSIAN_CHARSET.
Вот сейчас лично столкнулся с данной проблемой.
Как оказалось проблема решается довольно просто.
Корни ее в том, что при запуске на нерусской системе, уникод ресурсов нашей программы переводится в анси, согласно языку, установленному в системе.
Менять настройки системы некультурно.
Поэтому всего лишь нужно заставить нашу программу думать, что она запускается на русской системе.
Делается сия манипуляция элементарно.
1. Открываем наш dpr файл. (главный файл проекта, если кто не знает. Например Project1.dpr)
2. В Uses добавляем Windows.
3. Самой первой строчкой после 'begin' пишем:
Код
SetThreadLocale(1049);

Все. Программа будет культурно работать даже в китайской винде.
Главное не забывать добавлять эту строчку в каждый ваш новый проект.
Новый проект будет выглядеть примерно так:
Код
program Project1;

uses
  Forms, Windows,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

begin
  SetThreadLocale(1049);
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.


Далее. У каждой формы нужно сменить Font. MS Sans Serif, поставленный там по умолчанию, не является юникодным шрифтом. Я рекомендую, например Tahoma.
При смене шрифта не забудьте установить Charset в RUSSIAN_CHARSET.

Автор: ivan219 1.2.2006, 23:20
Во за это большое спасибо smile

Автор: DemoCode 2.2.2006, 19:07
А если у меня при запуске на нерусской винде все символы (включая английские) превращаются в ?????????. На русской винде всё ок. Твой метод поможет? Или тут что-то другое. (Delphi6)

Автор: Snowy 2.2.2006, 20:26
Именно. Поэтому я и создал новую тему, чтобы она не терялась.
Достаточно вставить эту строчку и сделать у форм RUSSIAN_CHARSET.
Это лечит все проблемы.
Плюс к этому это решает вообще все проблемы с перекодированием из юникода в ANSI и наоборот.
А это уже затрагивает Delphi 1-7.
Не затрагивает только BDS2006 - там проблем нет изначально.

Автор: Quadr0 2.2.2006, 22:33
...

Автор: Poseidon 2.2.2006, 23:23
Лучше в FAQ добавить...

Автор: Bog d`An 5.2.2006, 22:17
А фишку с копированием в буфер русских букв при английской расскладке клавиатуры и последующей вставкой ?????? ?? ?????? решает? Вроде там тоже проблемы с перекодированием в ANSI?

Автор: remax 5.2.2006, 23:37
Просто супер! smile smile

Автор: Snowy 6.2.2006, 10:59
Цитата(Bog d`An @ 5.2.2006, 22:17 Найти цитируемый пост)
А фишку с копированием в буфер русских букв при английской расскладке клавиатуры и последующей вставкой ?????? ?? ?????? решает? Вроде там тоже проблемы с перекодированием в ANSI?

Решает все проблемы, связанные с автоматическим конвертированием из юникода в анси и наоборот.
С буфером обмена по идее тоже должно все работать.
По крайней мере под WMVare у меня все корректно отработало.
Если кто столкнется с обратным - пишите.

Автор: Bog d`An 16.2.2006, 03:47
мда... а я то думал тут чтото новое... Кстати, Snowy, разя я уже тут, спешу порадовать - с буфером обмена, тьфу-тьфу-тьфу, проблема исчезла.
зы: правда я винды переставил

Автор: ZBugz 17.2.2006, 10:24
А если в программе реализованна мультиязыковая поддержка, то это не повлияет на отображение других языков ?

Автор: Snowy 17.2.2006, 11:06
Конечно повлияет. Наборы ведь разные.
Причем это НУЖНО делать. Иначе из всех языков будет работать только язык системы.
SetThreadLocale можно давать в любом месте программы. Она изменяет правила процесса юникодных перекодировок.
Для чего она дается в начале программы: чтобы формы при создании поднимали dfm в корректной кодировке.
Но можно дать SetThreadLocale и при смене языка, только код языка указать нужный. 1049 - это русский. Остальные коды можно посмотреть в MSDN или в реестре.
Также при смене языка потребуется сменить чарсет на всех формах.
Это уже сложней. Но что делать. Если этого не сделать, то вы хоть 10 раз выберите японский язык, но в индийской винде он никогда не сработает.
Так что SetThreadLocale и смену чарсета у форм нужно делать обязательно, иначе ваше "многоязыковое" приложение будет корректно отображать язык только в своей винде и только этот язык.

Автор: ivan219 17.2.2006, 16:40
А если много окон то возможны глюки так как моё преложение на немецкой винде норамльно отображает только основную форму а все остальные с ?????? и это при том что я зделал всё что ты скозал и RUSSIAN_CHARSET на всех формах и SetThreadLocale(1049); прописал что делать smile

Автор: Snowy 17.2.2006, 16:58
У меня в приложении десятки форм. Работают корректно.
Возможные причины:
1. У контролов не стоит ParentFont = true, соответственно не выставлен RUSSIAN_CHARSET.
2. Надписи в контролы добавляются динамически, а не в DisignTime. Ошибка может быть там.
3. Часть проекта (или весь) писалась не в русской винде. Или в русской, но с переключенными юникодными настройками. В данном случае в контролы проекта пропишется неверно закодированный юникод, который при декодировании будет некорректно декодирован. Я имею ввиду, что язык системы, в которой написан проект (или его часть) не 1049.
Что тут можно сделать...
Возьми приаттаченный файлик. При помощи него ты сможешь конвертнуть свои dfm файлы.

Автор: ivan219 18.2.2006, 15:58
1. Всё стоит все контролы RUSSIAN_CHARSET
2. Нет надпись статична один раз написал и всё незименно
3. Всё писалось на одной ОС настройки неменялись лиш иногда менял раскладку клавиатуры Alt+Shift Ру En чтоб писать соответственно русским и английским но это я думаю не влияет

Фаил попробую и напешу о результате спасибо.

Автор: s-mike 17.5.2006, 10:55
Цитата(Snowy @  1.2.2006,  19:02 Найти цитируемый пост)
Корни ее в том, что при запуске на нерусской системе, уникод ресурсов нашей программы переводится в анси, согласно языку, установленному в системе.

Практически было установлено, что если в настройках системы установлен английский язык для программ, не поддерживающих юникод, то ни один из этих способов не помогает. Проверено на WinXP SP2 Rus с измененными настройками, BDS2006 Update 2. 

Автор: Snowy 17.5.2006, 11:12
Цитата(s-mike @  17.5.2006,  10:55 Найти цитируемый пост)
Проверено на WinXP SP2 Rus с измененными настройками, BDS2006 Update 2.
Я и не говорил, что этот способ работает для BDS2006.
В заголовке темы указаны версии с 6-9.
С 7-кой проверял на виндах с 98 по 2005. Работает отлично.
2006 еще не исследовал. Все еще работаю на 7-ке.
Возможно там можно будет найти другое решение. 

Автор: s-mike 17.5.2006, 11:21
Моя реплика относится к этой фразе:
Цитата(Snowy @  2.2.2006,  20:26 Найти цитируемый пост)
Не затрагивает только BDS2006 - там проблем нет изначально. 

Хотя насколько я помню в этой версии проблем с языками стало меньше, но не помню точно в каком месте smile Но вот от неправильных юникодных настроек она, увы, не спасает. 

Автор: forever 14.9.2006, 06:23
Цитата(Snowy @  17.5.2006,  11:12 Найти цитируемый пост)
2006 еще не исследовал. Все еще работаю на 7-ке.
Возможно там можно будет найти другое решение. 

Не нашлось пока решения?

Использую Delphi 10Lite. Такая проблема: копирую в проводнике путь к файлу, вставляю в стандартный TEdit - кириллица заменяется на ????.
RUSSIAN_CHARSET и SetThreadLocale(1049) ничего не дают. В остальном проблем с русским нет.
Как побороть вставку?

Автор: Alexeis 14.9.2006, 07:45
Цитата(forever @  14.9.2006,  06:23 Найти цитируемый пост)
RUSSIAN_CHARSET и SetThreadLocale(1049) ничего не дают

Так эти настройки должны относится к делфи, а не проекту, ведь редактор их коряво отображает. Обычно, перед копированием переключают раскладку на "RU" анолгично при вставке, после чего текст уже проблемы исчезают smile 

Автор: forever 14.9.2006, 08:45
alexeis1, 
Цитата(alexeis1 @  14.9.2006,  07:45 Найти цитируемый пост)
Так эти настройки должны относится к делфи, а не проекту, ведь редактор их коряво отображает.

Юзеру на это с высокой колокольни.


Цитата(alexeis1 @  14.9.2006,  07:45 Найти цитируемый пост)
 Обычно, перед копированием переключают раскладку на "RU" анолгично при вставке, после чего текст уже проблемы исчезают

1. Если попробовать последовать сказанному - результат ничтожен.
2. Даже если бы так было - как объяснить юзеру что он должен танцевать с бубном и как ответить на его здоровое недоумение "зачем?". Ведь в тот же Блокнот все вставляется нормально - почему здесь криво?

Автор: Alexeis 14.9.2006, 09:04
forever, а все это я неправельно понял, я думал проблема при копировании текста в редактор кода делфи, просто и такая тоже встречается...

Добавлено @ 09:08 
Так это и на семерке тоже не помогает, тот же глюк.

Автор: forever 14.9.2006, 09:36
alexeis1, 
Цитата(alexeis1 @  14.9.2006,  09:04 Найти цитируемый пост)
Так это и на семерке тоже не помогает, тот же глюк.

Хм... У меня есть 7-е приложения (не мои) где это работает. В них тот же самый текст из буфера вставляется нормально, без ???. Исходников не имею, но авторы ссылаются именно на способ описанный здесь.

Автор: Alexeis 14.9.2006, 10:53
forever, 
Попробуйте вставлять текст из буфера обмена нажатием кнопки
Код

procedure TForm1.FormCreate(Sender: TObject);
begin
  SetThreadLocale(1049);
end;

procedure TForm1.btn1Click(Sender: TObject);
var
  count, i   : Integer;
  formatlist : array of Integer;
  wstr       : PWideChar;
  astr       : PAnsiChar;
  format     : Cardinal;

begin
  OpenClipboard(edt1.Handle);
  count := CountClipboardFormats();
  SetLength(formatlist, count);
  formatlist[0] := EnumClipboardFormats(0);
  For i := 1 to count - 1
  do
    formatlist[i] := EnumClipboardFormats(formatlist[i-1]);

  format := GetPriorityClipboardFormat(formatlist[0], count);

  if format = CF_UNICODETEXT
  then
    Begin
      wstr := PWideChar(GetClipboardData(format));
      edt1.Text := wstr;
    end
  else
    Begin
      astr := PAnsiChar(GetClipboardData(format));
      edt1.Text := astr;
    end;

  CloseClipboard();
end;


Добавлено @ 10:56 
У меня сработало, если сработает и у вас, то можно будет сделать перехват
WM_TEXT всего приложения с тем чтобы исправить эту проблему для всех полей ввода сразу.

Автор: Alexeis 14.9.2006, 11:39
Кстати эту проблему действительно надо решать вручную, поскольку это глюк windows а не борланд! Я только что проверил вставку того же текста в поле едит созданое на MFC абсолютно тот же эффект, просто сам windows контрол edit не верно обрабатывает сообщение WM_PASTE, т.е. не верно конвертирует юникодную строку в ansi строку, вероятно он не использует для этого настройки локализации.

Добавлено @ 11:47 
От этой проблемы изначально избавлены юникодные версии контролов
Например вот такой Едит отлично вставляет русский текст
Код

  CreateWindowExW(WS_EX_CLIENTEDGE, 'edit',
                  nil, WS_CHILD or WS_VISIBLE or WS_BORDER or
                  ES_LEFT or ES_AUTOHSCROLL,
                  50, 35, 200, 25,
                  Form1.Handle, 1, HInstance, nil);

Автор: Snowy 14.9.2006, 12:20
SetThreadLocale(1049) это также WinAPI комманда, а не борланда.
Мы говорим винде, что для юникодной конвертации мы хотим использовать русскую локаль.
В этом и смысл данной строки.

Замечено: если приложение использует XP манифест, то используется локаль, указанная там.
По умолчанию - это локаль 0 - нейтральная.
Пока этот вопрос не исследовал.

Я может ещё не проснулся, но не пойму о чём спор...

Автор: Alexeis 14.9.2006, 12:52
Snowy, а фокус в том что при копировании пути содержащего русские буквы из проводника в буффер обмена, они сохраняются в юникоде, а при вставке их в поле едита при помощи отправки сообщения WM_PASTE, едит игнорирует локаль и ставит свою дефолтную, потому текст и получается с вопросами.

Автор: forever 2.10.2006, 02:28
Цитата(forever @  14.9.2006,  06:23 Найти цитируемый пост)
Такая проблема: копирую в проводнике путь к файлу, вставляю в стандартный TEdit - кириллица заменяется на ????.
RUSSIAN_CHARSET и SetThreadLocale(1049) ничего не дают. В остальном проблем с русским нет.
Как побороть вставку?

Тут такой полтергейст проявился: у товарища D7 и XP SP1, у меня D10 и XP SP2. Компилю прогу - в эдитах кириллица вставляется как ??????, отправляю exe ему - у него на системе кириллица вставляется в эдиты без проблем (в скомпиллированном у меня exe!). Неразбериху вносит обратный эксперимент: в скомпиллированный у него exe и у меня кириллица вставляется нормально. Где копать?

Автор: Fedia 2.10.2006, 03:36
Цитата(forever @  2.10.2006,  02:28 Найти цитируемый пост)
ут такой полтергейст проявился: у товарища D7 и XP SP1, у меня D10 и XP SP2. Компилю прогу - в эдитах кириллица вставляется как ??????, отправляю exe ему - у него на системе кириллица вставляется в эдиты без проблем (в скомпиллированном у меня exe!). Неразбериху вносит обратный эксперимент: в скомпиллированный у него exe и у меня кириллица вставляется нормально. Где копать?

У меня точно такая же проблема. Глюк с искажением текста при копировании в буфер происходит на скомпилированных на моем рабочем ПК проектах. Причем если проект скомпилирован у меня, то искажение происходит на всех ПК. Если проект компилируется у моего коллеги, то проблем c искажением текста нет ни на одном ПК.

Цитата(alexeis1 @  14.9.2006,  11:39 Найти цитируемый пост)
это глюк windows а не борланд!

Скорее вcего так, вопрос в том, имеется ли возможность этот глюк преодолеть ?

Автор: Alexeis 2.10.2006, 07:56
Fedia, я же привел рабочий код вставки из буфера обмена от http://forum.vingrad.ru/index.php?showtopic=82093&unread=1&st=15&hl=#
Напишите наследника в котором переопределена обработка WM_PASTE.

Либо пишите на апи с использованием юникодных компонентов

Автор: Fedia 3.10.2006, 04:06
Я разобрался. Спросил у более опытного коллеги на работе, он удивился, что я до сих пор не в курсе, как эта проблема устраняется, и рассказал мне вот что:
1. Запускаем regedit.
2. Производим поиск значений параметров, содержащих 1252.
3. Заменяем эти значения на 1251.
4. Перезагружаемся.
5. Проводим тест и радуемся smile

Автор: forever 3.10.2006, 05:52
Fedia, 
Цитата(Fedia @  3.10.2006,  04:06 Найти цитируемый пост)
2. Производим поиск значений параметров, содержащих 1252.

Так это стародавняя проблема. Вот не думал, что она и здесь скажется. Но не нужно менять все вхождения 1252 - достаточно  
HKLM\SYSTEM\CurrentControlSet\Control\Nls\CodePage\1252 заменить c_1252.nls на c_1251.nls

Цитата(Fedia @  3.10.2006,  04:06 Найти цитируемый пост)
5. Проводим тест и радуемся

Радость омрачается тем, что на других компах скомпиллированные у меня проги ведут себя по прежнему: у кого были ??? - так и остались, у кого было нормально - тоже без изменений.

Автор: Alexeis 3.10.2006, 09:18
Fedia, Это решение давно извесно и было выложено н форуме, но это не выход. Тем более у него бывают побочные эффекты связаные с использованием других языков. У некоторых установлено по 3 языка и больше, а программа должна нормально функционировать на любой машине. Проблему предлогаю решить установкой локального (внутрипрограмного) перехватчика сообщеня WM_PASTE, который будет ловить сообщения до передачи их соотв. компоненту.

Автор: Romero 15.4.2007, 11:57
Как я понимаю, проблема так и не решена до конца.
Как же заставить текст правильно копироваться в буфер? Прога, скомпиленная в D6, имеет Memo с установленным RUSSIAN_CHARSET, и строка SetThreadLocale(1049) прописана. Однако, при запуске на 2000 винде скопированный ИЗ ОКНА (а не В ОКНО) программы текст вставляется в блокнот коряво. То же приложение нормально ведет себя на ХР (возможно, дело не в версиях винды, а в локализациях, но это не суть вопроса).

Автор: mai62 15.4.2007, 12:48
У меня тоже были проблемы с кодировкой при копировании в буфер.  Где-то нашел такой рецепт, у меня работает.
Код

type

TLangClipboard = class(TClipboard)
private
  procedure SetCodePage(const CodePage: longint);
public
  procedure Open; override;
  procedure Close; override;
end;

implementation

procedure TLangClipboard.Close;
begin
  SetCodePage(LangManager.LanguageID);
  inherited;
end;

procedure TLangClipboard.Open;
begin
  inherited;
  SetCodePage(LangManager.LanguageID);
end;

procedure TLangClipboard.SetCodePage(const CodePage: longint);
var Data: THandle;
    DataPtr: Pointer;
begin
  Data:= GlobalAlloc(GMEM_MOVEABLE + GMEM_DDESHARE, 4);
  try
    DataPtr := GlobalLock(Data);
    try
      Move(CodePage, DataPtr^, 4);
      SetClipboardData(CF_LOCALE, Data);
    finally
      GlobalUnlock(Data);
    end;
  except
    GlobalFree(Data);
  end;
end;

initialization

  FClipboard:= TLangClipboard.Create;
  OldClipboard:= SetClipboard(FClipboard);
  if OldClipboard <> nil then OldClipboard.Free;


LangManager.LanguageID - это у меня переключатель языка интерфейса от DKLang.

Автор: Alexeis 15.4.2007, 13:01
Цитата(Romero @  15.4.2007,  11:57 Найти цитируемый пост)
То же приложение нормально ведет себя на ХР (возможно, дело не в версиях винды, а в локализациях, но это не суть вопроса).

  Пробовали при копировании и при вставке текста переключатель языков винды установить в положение "RU"? Это позволяет винде правильно определить таблицу перекодировки юникод -> Ansi. Иначе прийдется перехватывать вставку текста и самостоятельно конвертировать юникод в анси. Это вылечить невозможно, так этими вещами управляет винда, а не сам делфи. Тоже самое происходит, например, и в редакторе от Microsoft Visual C++ 6. Тут лечить нужно программистов Microsoft от криворукости. 

Автор: Romero 15.4.2007, 13:22
Хм, с RichEdit таких проблем не наблюдается. При этом никаких танцев с бубном, строкой SetThreadLocale(1049) и установкой RUSSIAN_CHARSET не требуется. Странно!

Автор: Alexeis 15.4.2007, 13:33
Romero, Ну он передает информацию в буфер обмена в формате RTF, где к для каждого символа можно узнать сопроводительную информацию, т.е. шрифт, размер, цвет, абзац, выравнивание, возможно еще и номер таблицы.

Автор: EvilsInterrupt 13.11.2007, 19:52
Да, занятная тема ;) В вашем полку прибыло ;) 
Вобщем приведу сразу код:
Код

  procedure TfrmLog.ilmCopyToClipbrdClick(Sender: TObject);
  const
    clrf : String = Char(13)+Char(10);
  var
    Event     : PVSTEvent;
    EventTxt  : string;
    Clipbrd   : TClipboard;
  begin
    Event := vstEventLog.GetNodeData(vstEventLog.FocusedNode);
    if Assigned(Event) then
    begin
      Clipbrd := Clipboard;
      if Assigned(Clipbrd) then
      begin
        with frmAbout do
        begin
          EventTxt := 
               'Application ver.: '+lbAppVerValue.Caption+clrf+
               'Application BuildDate: '+lbBuildDate.Caption+clrf+clrf+
               'Event Information: '+clrf+clrf+
               'Date: '+FormatDateTime('yyy-mmmm-dd',Event.Date)+clrf+
               'Time: '+FormatDateTime('hh:nn:ss:ms',Event.Time)+clrf+
               'Text: '+Event.Event;
        end;
        Clipbrd.AsText := EventTxt;
        FreeAndNil(Clipbrd);
      end;
    end; // Assigned
  end;

Суть этой функции в обработчике попуп-меню окна лога закинуть в буфер обмена выделенное в VTV нод с событием. Как видно из кода, я из формы с эбаутом достаю версию и время билда, он отображается нормально! А вот когда копируется в буфер обмена, то все его русские буквы становятся, даже не вопросами, а какиме-то крякозябрами ;(
Этот же код, на другой ЭВМ отрабатывает на ура, есно после сборки на той машине.

Все что оговаривалось выше не помогает, а правка в реестре мне не подойдет, т.к. я пишу мультиязычную программу. Пока вот хочу попробовать метод от mai62, но вдруг еще какие-нибудь мысли есть?

Автор: EvilsInterrupt 13.11.2007, 20:29
Все, проблему решил, увидел строки в DRKB:
Цитата

Как вставить русский текст в буфер обмена Windows 2000, Windows XP
 
Для указания языка текста в clipboard используется специальный формат CF_LOCALE. Данные в этом формате - это LocaleID: word. При вставке текста в формате CF_TEXT, или CF_OEMTEXT, нужно просто добавить LocaleID в формате CF_LOCALE, после чего Windows сможет правильно преобразовать имеющийся текст в недостающие форматы (например в CF_UNICODETEXT), да и просто будет корректно вставлен в самом CF_TEXT.

Сразу стало понятно, что товарищь mai62 предложил хороший способ ;) Спасибо

Автор: WaReZMEN 14.11.2007, 01:19
http://forum.vingrad.ru/forum/topic-180473.html

Добавлено через 9 минут и 1 секунду
Цитата(Snowy @  3.2.2006,  04:26 Найти цитируемый пост)
Именно. Поэтому я и создал новую тему, чтобы она не терялась.
Достаточно вставить эту строчку и сделать у форм RUSSIAN_CHARSET.
Это лечит все проблемы.
Плюс к этому это решает вообще все проблемы с перекодированием из юникода в ANSI и наоборот.
А это уже затрагивает Delphi 1-7.
Не затрагивает только BDS2006 - там проблем нет изначально.

а вот у меня какраз токи в 2006. Messegedlg показывает вопросы и что интересно из 50 компьютеролв тока на одном... 

Автор: aktuba 14.11.2007, 02:19
Цитата(WaReZMEN @  14.11.2007,  02:19 Найти цитируемый пост)
что интересно из 50 компьютеролв тока на одном... 

Может там винда не русская стоит?

Автор: EvilsInterrupt 14.11.2007, 08:59
aktuba, Можешь подскажешь выход из такой ситуации:
Если у меня выбрана русская раскладка, то в буфер обмена копируется и последующая вставка куда-либо(к примеру сюда в окно поста сообщения на форум), то все отображается отлично и никакой крякозябрины. Но если же я выберу английскую раскладку, то после копирования в буфер и последующей вствки куда-либо(к примеру сюда в окно поста сообщения на форум), то крякозябры ;(

Я конечно догадываюсь,что англичание не должны шарить о существовании русского языка. Но как пользователю же пофиг на это! ;)
Может имеет смысл насильно перекодировать на русский в самом буфере обмена, если конечно выбран русский язык или какой-либо другой, к примеру китайский ?

Автор: EvilsInterrupt 14.11.2007, 15:53
Проблема решена, MetalFan подсказал.
Код

  function TfrmLog.SetClipboardText( const AText: string ): Boolean;
  var
    hClipbrd : THandle;
  begin
    Result := True;
    Clipboard.Open;
    Clipboard.AsText := AText;
    hClipbrd := Clipboard.GetAsHandle(CF_TEXT);
    if hClipbrd = INVALID_HANDLE_VALUE then
       Result := False
    else  SetClipboardData(CF_LOCALE, hClipbrd);
    Clipboard.Close;
  end;

ведь по идее:

Автор: Ymnuk 27.7.2009, 19:52
А подскажите такой момент пожалуста.
Есть сервер с DB2 UDB 8.2. Кодировка стоит 1251 и в программе весь русский отображается прекрасно на всех компьютера без исключений, но есть 2 компа, на которых стоит Novel-клиент. На них весь русский язык отображается нормально, кроме выгрузки данных в Excel. Сам файл-шаблон отображается нормально, а вот выгруженные данные отображаются непонятной кодировкой (я так и не выяснил какая кодировка). При использовании Shell API и выборе директории с русским названием появляется та же непонятная кодировка.
Может кто знает как исправить это в программе?

Автор: Akella 26.9.2010, 09:38
Если в Windows открыть Панель управления, а там апплет "Язык и региональные стандарты", то на закладке "Дополнительно" можно лицезреть кодовую страницу для неюникодных программ. В нешем случае там всегда установлен "Русский (Россия)".

Так вот. Как узнать, какая кодовая страница установлена на данный момент в системе?
Есть примеры в интернете, которые позволяют узнать активный язык(раскладку клавиатуры), но это не то. В какую сторону копать?

В общем это связано с тем, что перед началом какой-либо обработки текста нужно установить какую-либо активную раскладку клавиатуры. Для русского языка это:
Код

Var
  Layout: array[0.. KL_NAMELENGTH] of char;
begin
LoadKeyboardLayout(StrCopy(Layout, '00000419'), KLF_ACTIVATE);

А если винда, например, чешская, то нужно активировать чешский язык. Т.е. вместо '00000419' нужно подставить код чешского языка.

Добавлено через 4 минуты и 9 секунд
Цитата(Snowy @  1.2.2006,  19:02 Найти цитируемый пост)
SetThreadLocale(1049);

можно ещё
Код
SetThreadLocale($0419);


Добавлено через 9 минут и 16 секунд
О, нашёл
Код

with SysLocale do
    ShowMessage(Format('DefaultLCID  = %.8x', [DefaultLCID]));

Автор: Akella 26.9.2010, 09:59
Теперь при старте программы достаточно выполнить такую процедуру:
Код

procedure SetProgramLocale();
var
 sLocale: string;
begin
  //узнаем кодовую страницу, которая указана в региональных настройках системы для неюникодных программ и устанавливаем для текущей программы
  with SysLocale do
  sLocale := (Format('%.4x', [DefaultLCID]));
  SetThreadLocale(StrToInt('$'+ sLocale));
end;

Автор: PsiMagistr 11.8.2011, 08:28
Я вот свою игрушку отюникодить пытаюсь. Пока безрезультатно.  Проверять приходится перестройкой Windows с Russian на любую другую кодировку. Выходит много чего, от ошибок баз, до неверных отображений символов (вопросы)

Версия: Delphi XE

Используются компоненты для работы с БД (AdoTable, AdoQuery)

Используются динамически создаваемые контролы.

Автор: Akella 11.8.2011, 09:20
И в чём вопрос?

Автор: PsiMagistr 11.8.2011, 09:41
Akella, да вопрос прост. 

как ее заюникодить все-таки?

Автор: CodeMonkey 12.8.2011, 01:47
Цитата(PsiMagistr @  11.8.2011,  10:41 Найти цитируемый пост)
как ее заюникодить все-таки? 


У меня встречный вопрос: а как вы умудрились сделать обратное?

Автор: Akella 12.8.2011, 08:43
Цитата(PsiMagistr @  11.8.2011,  09:41 Найти цитируемый пост)
как ее заюникодить все-таки? 

Что именно и откель юникодить?

Автор: PsiMagistr 12.8.2011, 14:34
Мне нужен русский интерфейс на любой винде.

Ваши предложения, господа.

Автор: Alexeis 12.8.2011, 16:00
PsiMagistr напрягая телепатические возможности предположу что у вас таблицы в БД в Ansi кодировке и осуществляется преобразование Ansi -> Unicode с неправильной таблицей символов, точнее говоря с кодовой таблицей по умолчанию, которая может не совпадать с кириллической. 

Автор: PsiMagistr 12.8.2011, 17:03
Alexeis, И каков выход?

Автор: Keeper89 12.8.2011, 17:43
Перевести все на юникод.

Автор: CodeMonkey 12.8.2011, 20:26
Цитата(PsiMagistr @  12.8.2011,  15:34 Найти цитируемый пост)
Мне нужен русский интерфейс на любой винде.


А русский шрифт-то на этой винде есть?

Добавлено через 5 минут и 24 секунды
Цитата(PsiMagistr @  12.8.2011,  15:34 Найти цитируемый пост)
Ваши предложения, господа. 


Какие могут быть предложения?

Вам же сказали, что Delphi 2009 и выше (включая Delphi XE) ситуация по умолчанию: ваша программа одинаково работает на любой системе. При условии, что в системе стоит шрифт с кириллицей. Скажем, unicode-шрифт.

Если же у вас не так - это значит, что вы у себя в коде что-то делаете не так.

Внимание, вопрос: КАК мы можем это знать?

Мы можем лишь угадывать, чем (гаданием) и занимается Alexeis в своём последнем посте.

Автор: Alexeis 12.8.2011, 21:27
Цитата(CodeMonkey @  12.8.2011,  21:26 Найти цитируемый пост)
При условии, что в системе стоит шрифт с кириллицей. Скажем, unicode-шрифт.

  Да вроде как шрифты по умолчанию и так юникодные. 

  Если такие дело в БД, то наилучшим решением будет конвертация таблиц в utf8. Так чтобы при загрузке строк не требовалось кодовых таблиц. Если такое решение не подходит то пробуйте приведенный выше вариант с SetThreadLocale . 

Автор: CodeMonkey 12.8.2011, 21:30
Цитата
 Да вроде как шрифты по умолчанию и так юникодные. 


На старых системах Unicode шрифты ставились только с офисом или расширенной поддержкой символов. Т.е. по дефолту их может не быть.

Автор: Akella 13.8.2011, 20:18
Цитата(PsiMagistr @ 12.8.2011,  14:34)
Мне нужен русский интерфейс на любой винде.

Ваши предложения, господа.

Использовать юникодную среду разработки D2009+ или Юникодные компоненты, aka TNT или TMS

Добавлено @ 20:19
Цитата(Alexeis @ 12.8.2011,  16:00)
PsiMagistr напрягая телепатические возможности предположу что у вас таблицы в БД в Ansi кодировке и осуществляется преобразование Ansi -> Unicode с неправильной таблицей символов, точнее говоря с кодовой таблицей по умолчанию, которая может не совпадать с кириллической.

Использовать нормальные СУБД, а не какую-то там недоСУБД.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)