TJSergio
Junior Member | Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору Багрепорт и багофикc FastReport 4. Проблема Unicode, charsets и настройка Windows "Чарсет для Non-Unicode программ". Предисловие: Как написанно на FastReportе, при использовании Unicode могут некоректно печатать принтера и данные из базы выводятся в том charset который установлен в Windows. Значит надо использовать Russian_charset. Как получить баг? Создаем отчет с Russian_charset в memo на Windows с локалью 1251. Все показывает и печатает. Переносим готовую программу на Windows с локалью 1257, и вместо текста видим знаки вопросов "?". И сразу понимаем, что в НЕ-уникодовые проперти присваиваются уникодовские строки "влоб"! FastReport отличный компонент и я хочу, купить и использовать его. Но моя программа "работает" в прибалтийских странах и ближней европе. Значит локаль у них будет точно другой и у всех разной! а если я предложу им её сменить - просто не купят программу! Ещё проблема: А если в одном отчете нужны Memo с разным charset? Начав искать проблемму и читая эту тему я сразу нашел одно из мест. QuickeneR предложил замену: Код: ...FOptions, @FScaledRect, PChar(String(s)) + j, i - j, nil);... | Модифицированный вариант от этого я нашел в текущих исходниках FastReport! Код: if FWysiwyg then//было ExtTextOut(C.Handle, X + Round(add1 * SinA), Y + Round(add1 * CosA), FOptions, @FScaledRect, PChar(String(s)) + j, i - j, @FTempArray[j]) else ExtTextOut(C.Handle, X + Round(add1 * SinA), Y + Round(add1 * CosA), FOptions, @FScaledRect, PChar(String(s)) + j, i - j, nil); | Господа, ну также нельзя. String(s) - Преобразование типов которое недопустимо при работе с уникодом. Корректно вместо PChar(String(s)) нужно писать: Код: if FWysiwyg then//fix ExtTextOut(C.Handle, X + Round(add1 * SinA), Y + Round(add1 * CosA), FOptions, @FScaledRect, PChar(WideStringToStringEx(s,CharSetToCodePage(C.Font.Charset))) + j, i - j, @FTempArray[j]) else ExtTextOut(C.Handle, X + Round(add1 * SinA), Y + Round(add1 * CosA), FOptions, @FScaledRect, PChar(WideStringToStringEx(s,CharSetToCodePage(C.Font.Charset))) + j, i - j, nil); | WideStringToStringEx - функция преобразования строки по указанной локали, которую мы получаем через функцию FastReporta CharSetToCodePage. Код: function WideStringToStringEx(const WS: WideString; CodePage: Cardinal): AnsiString; var InputLength, OutputLength: Integer; begin InputLength := Length(WS); OutputLength := WideCharToMultiByte(CodePage, 0, PWideChar(WS), InputLength, nil, 0, nil, nil); SetLength(Result, OutputLength); WideCharToMultiByte(CodePage, 0, PWideChar(WS), InputLength, PAnsiChar(Result), OutputLength, nil, nil); end; | После этого мы получаем корректный результат в не завмсимости от локали! Но это начало пути. Редактор Memo тоже не корреткно зачитывает строки из-за: Код: Memo.Text := FMemoView.Text;//было | Переделываем: Код: //fix Memo.Text := WideStringToStringEx(FMemoView.Text,CharSetToCodePage(Memo.Font.charset)); | Ну и пишет тоже: Код: FText := Memo.Text;//было | Переделываем: Код: //fix FText := AnsiToUnicode(Memo.Text,CharSetToCodePage(Memo.Font.charset)); | AnsiToUnicode - функция FastReporta. Ну вот теперь у нас корректное открытие формы, печать и редактирование! Это не просто исправление бага, это целое продвижение FastReporta на качественно новый уровень - реальная поддержка unicode (т.е. мего багфикс) P.S.Единственное в чем я не уверен, что "вылавил" все места в FastReporte (А может все?), но думаю этой информации достаточно чтобы сделать нормальным весь остальной код P.S.S. а про вопрос с OEM_CHARSET сложнее, т.к. из в досовской БД может быть любой charset, а у Delphi нет OEM_RUSSIAN_CHARSET, OEM_BALTIC_CHARSET. Но все равно решения придумать можно.... | Всего записей: 58 | Зарегистр. 22-08-2002 | Отправлено: 16:40 28-09-2007 | Исправлено: TJSergio, 16:47 28-09-2007 |
|