Проблема кратко:
При использовании XPmanifest у контрола GroupBox криво выводится РУССКИЙ заголовок.
Язык для non-Unicode программ: русский;
Стандарты и форматы: ENGLISH (UNITED STATES)
Ситуация:
Создаём новый проект и кидаем на пустую форму GroupBox и XPmanifest.
У GroupBox'а задаём какой-либо русский заголовок, например, "Мой групбокс".
На этом всё - приложение запускается, XP-стили срабатывают - ура. ;-) Но вот проблема: заголовок нашего GroupBox'a превратился в "||| ||||||||" - в мусор.
Также проверяем в региональных и языковых настройках Windows:
- язык для non-Unicode программ: русский;
- стандарты и форматы: ENGLISH (UNITED STATES);
Если стандарты и форматы поставить на русские - все OK. Однако это не корректно и хотелось бы избежать этого глюка XPmanifest'a.
Уважаемые гуру и просто программисты, помогите, пожалуйста.
Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице. Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.
22-01-2006 04:07 | Комментарий к предыдущим ответам
Если не ошибаюсь у вас случилось вот это: http://qc.borland.com/wc/qcmain.aspx?d=8565
Соответственно пути решения: перейти на Delphi 5 или 2005, пропатчить и перекомпилировать System.pas.
Весь корень "зла", по всей видимости, заключён был в том, что в Delphi используется какая-то стандартная "встроенная" функция перевода текста ANSI <=> Unicode. Таким образом, когда в программе встречается подобный код:
var
A : AnsiString; // Строка типа ANSI
B : WideString; // Строка типа Unicode
begin
{ . . . }
B := A; // (1)
{ . . . }
end;
то в строке (1) происходит неявное преобразование типов ANSI -> Unicode с использованием этой скрытой в Delphi функции.
Но это только предположение, которое не важно сейчас.
Таким образом, путь к решению был простой: во всех подобных (1) местах поставить некую APIфункцию преобразования ANSI -> Unicode. Я написал свою, с использованием оной:
Function TranslateAnsiToUnicode(Src: string): WideString;
var
i : integer;
S : AnsiChar;
D : WideChar;
R : WideString;
begin
R := '';
for i := 1 to Length(Src) do
begin
S := Src[i];
// API function. Unit Windows
MultiByteToWideChar(CP_ACP, 0, @S, 1, @D, 1);
R := R + D;
end;
Result := R;
end;
А затем в классе TGroupBox, я просто перекрыл метод Paint и перед строками
if Text <> '' then
ThemeServices.DrawText(Handle, Details, Text, CaptionRect, DT_LEFT, 0);
этого метода я поставил преобразование "входящего" ANSI-текста в Unicode.
Аналогично я исправил баг в VirtualStringTree, исправив извелечение строки в методе события OnGetText.
To Cepгей Poщин:
Спасибо, попробовал: Locale ID уже стоял $0419, но и установка RUSSIAN_CHARSET, к сожалению, не помогла. :- To Kalan J. Bobrick:
М! Интересная вещица. Пропробовал - действительно, с GroupBox'ом всё прокатывает на ура.
Но, прошу прощения, что заострил внимание только на стандартных контролах.
Дело в том, что такая штука у меня проявляется ещё на одном моём любимом и используемом в данный момент контроле: Virtual String Tree.
Очень хорошая вещь, но, к сожалению, даёт вот такие промашки. :-(
Хорошо, что с TNT-контролами идут исходники, - попытаюсь расковырять, разобраться.
Но быть может, существуют какие-либо невизуальные контролы (наподобие XPmanifest'a), которые устраняли бы такой non-Unicod'овский баг?
Надо писать под Unicode...
поищи TNT Unicode Controls в гоогле и радуйся :)
кстати туда можно пихать иврит, японский, etc :)
И XPManifest они поддерживают без проблем. Сам пользуюсь :)
В программе Font.Charset должен быть не DEFAULT_CHARSET, как предлагается по умолчанию, а RUSSIAN_CHARSET;
В свойствах проекта Project/Options/Locale Id должно быть 0419.
Возможно поможет.
Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter. Функция может не работать в некоторых версиях броузеров.