Я создал ОЧЕНЬ сложный (графически, во всяком случае) отчет и только что обнаружил, что это не выводится как положено на экране и на принтере во время выполнения программы (хотя это и корректно отображается в окне предварительного просмотра в режиме проектирования). Ошибка возникает только в том случае, если в Windows 95 установлены большие (LARGE) системные шрифты! Ну и что мне теперь прикажете делать?
У меня тоже была такая же серьезная проблема, но только при печати под Win 95 на офисный HP 4M и при просмотре отчета под NT 4.0. Но то же самое приложение у меня прекрасно работало под NT 3.51 SP5.
Я видел дискуссию по поводу этой ошибки, возникающей в GDI коде под NT 4.0, поэтому я не удивился, обнаружив ее у себя. Мне пришлось засучить рукава и очень тесно познакомиться с кодом QuickReports, особенно с процедурой первичного вывода текста, когда программа изменяет шрифт в каждой выводимой области. Вот этот злосчастный сегмент кода в методе TQRCustomControl.Print:
QRPrinter.Canvas.Font:=Font;QRPrinter.Canvas.Font.size:=trunc(abs(parentreport.xpos(font.size)));QRPrinter.Canvas.brush.Color:=Color; |
Теперь те из нас, которые истратили слишком много времени на изучение исходного кода VCL узнали, что VCL поддерживает кэш ресурса через менеджера дескрипторов в Graphics.pas и что попытки уменьшения количества используемых ресурсов Windows сводятся к методу подсчета ссылок на дескрипторы многократно испольуемых ресурсов. Коду, приведенному выше, отлично удалось это обойти! Каждый раз холст принтера устанавливает шрифты полей, таким образом уменьшая счетчик используемых ресурсов в ноль с дальнейшим его освобождением и затем масштабирует размер шрифта для соответствия его метрике принтера, таким образом требуя размещения нового шрифтового ресурса.
Всдедствие этого _каждое_ поле отчета использует для вывода собственный шрифт, тратя для этого каждый раз системные ресурсы и вгоняя в штопор систему (регистратор метафайлов), пытающуюся уследить за бешенным ритмом смены шрифтов и массовым съеданием ресурсов.
В качестве эксперимента я создал непечатаемую этикетку с тем же самым размером шрифта, что и у масштабируемого шрифта принтера, тем самым заставляя ресурс кэшироваться - ошибка исчезла как страшный сон! Это доказывает идентичность проблемы в NT 4.0 - те же действующие лица: регистратор расширенных метафайлов и огромное количество изменений шрифтов.
Лучшее решение я увидел в следующем:
// При установке нового шрифта сохраняем шрифт принтераSaveFont := TFont.Create;SaveFont.Assign(QRPrinter.Canvas.Font); QRPrinter.Canvas.Font:=Font;QRPrinter.Canvas.Font.size:=trunc(abs(parentreport.xpos(font.size)));QRPrinter.Canvas.brush.Color:=Color; // Освобождаем сохраненный шрифт принтера. Теперь работа сделана.SaveFont.Free;SaveFont := nil; |
Дополнительными строками нам удается проверить тот факт, что шрифт принтера уже используется или же для холста принтера выбирается тот же самый шрифт. Это работает уже вполне корректно и позволяет печатать правильные отчеты под NT 4.0. Некоторым странным совпадением можно считать устранение зашитых жирных шрифтов, изменившее шрифты, печатаемые под Win95.
Так, если у вас есть зарегистрированная версия QuickReports, вы можете сделать коррекцию исходных файлов, и вы увидите, что ваши отчеты будут генериться быстрее, выглядеть "мягче" и не будет ошибок и издержек шрифтовых ресурсов из-за ограничения кода расширенных метафайлов и GDI.
[000217]