2014-11-11 2 views
6

У меня возникли проблемы с неправильным отображением символов Юникода в моем пользовательском интерфейсе. У меня есть только ресурсная библиотека, содержащая строковую таблицу, используемую для локализации пользовательского интерфейса. Я создаю DLL в Delphi XE3 с DLL-проектом (просто имеет {$R 'lang.res' 'lang.rc'} в DPR-файле и дает мне lang.dll). Я подтвердил, что мой файл lang.rc находится в формате UTF-8 с разрывами строк Windows CRLF. Когда я загружаю строки из DLL, символы Unicode смешиваются с интерфейсом. Вот некоторые подробности.Настройка кодировки Unicode из таблицы строк DLL ресурсов

фрагмент из таблицы строки:

STRINGTABLE 
{ 
59,"180˚" 
60,"90˚ CW" 
61,"90˚ CCW" 
} 

Вот фрагменты кода, которые иллюстрируют проблема у меня с символами Unicode:

// explicitly assigning the degrees character shows 180˚ properly 
ImageMenu180Action.Caption := '180˚'; 

// getting the resource from the DLL shows some weird two-character string for the degrees character 
ImageMenu90CWAction.Caption := TLangHelper.LoadStr(IDS_ImageMenuRotationCW90); 

// OutputDebugString shows the degrees character in the debugger output correctly 
OutputDebugString(PChar('IDS_ImageMenuRotationCW90: '+TLangHelper.LoadStr(IDS_ImageMenuRotationCW90))); 

Вот моя функция Delphi используется для загрузки строк от источника DLL:

class function TLangHelper.LoadStr(ResourceId: Integer):String; 
var 
    Buff: String; 
    L: Integer; 
begin 
    Result := ''; 
    if LangDllHandle = 0 then begin 
    LangDllHandle := LoadLibrary(LANGUAGE_DLL_LOCATION); 
    if LangDllHandle = 0 then begin 
     ShowMessage('Error loading language localization resources.'); 
    end; 
    end; 
    if LangDllHandle <> 0 then begin 
    L := 1024; 
    SetLength(Buff, L+1); 
    LoadString(LangDllHandle, ResourceId, PChar(Buff), L); 
    Result := String(PChar(Buff)); 
    end; 
end; 

Любые предложения?

FOLLOW-UP:

Для китайских иероглифов, я должен был добавить предшествующую L для определения строки в файле .rc так, что DLL сборник признал их Unicode. Например (английский, китайский традиционный, китайский упрощенный, французский):

STRINGTABLE 
{ 
35,"Status Bar" 
1035,L"狀態欄" 
2035,L"状态栏" 
3035,"Barre d'état" 
} 
+1

Не должны ли строки UTF-16, а не UTF-8? –

+0

Где вы видели, что использование UTF-8 в вашем .rc-файле приведет к правильной кодировке в файле .res? Я нашел [ссылку с 2002 года] (http://www.delphipages.com/forum/archive/index.php/t-63889.html), в которой говорится, что вам нужно использовать специальный параметр командной строки для brcc32 ('- c65001'), чтобы указать кодировку файла .rc. Я сомневаюсь, что IDE использует этот параметр по умолчанию. –

+1

@RobKennedy Это сработало, очень его ценит. Из-за отсутствия документации, указывающей в противном случае (я не мог найти ее), я предположил, что brcc32 по умолчанию будет использовать текстовое кодирование файла. Плохое предположение. Похоже, этот материал должен быть лучше документирован. Я не могу быть единственным, кто пытается это сделать. Я приму ответ, если вы захотите написать его. – spurgeon

ответ

6

a reference from 2002 я нашел о том, что вам необходимо сообщить компилятору ресурсов, как закодированный файл .rc. Для UTF-8, это код страницы 65001, так что вы бы запустить это:

 
brcc32 -c65001 lang.rc 

Тогда, конечно, вы бы удалить 'lang.rc' часть из $R директивы в вашем коде, потому что вы больше не хотите IDE для вызова самого компилятора ресурсов.

Если версия Delphi достаточно недавно, то вы можете сохранить полную $R директивы и вместо того, чтобы установить -c65001 опции в resource-compiler configuration ваших вариантах проекта.

Трудно узнать кодировку файла, просто взглянув на него. Могут быть много действительных догадок. Опция -c документирована, но the documentation не упоминает, когда вам нужно будет ее использовать, или что использует IDE, когда это запускает компилятор ресурсов. IDE, вероятно, просто использует значение по умолчанию, то же самое, что и файл brcc32.exe, который является кодовой страницей кода ANSI по умолчанию.

+0

Не можете ли вы просто установить Project -> Options -> Resource Compiler -> Дополнительные параметры для '-c65001' (используя Delphi XE3 здесь)? Это сработало для меня. – spurgeon

+0

Спасибо, что упомянули об этом. Я обновил ответ. Последняя версия Delphi, которую я использовал, не имела такого варианта. –

+0

Очень хороший ответ на очень хороший вопрос! –