FR в Dll + DataSet
Я пишу в среде Delphi7, отчет пишу на FR 3.18, использую для доступа к данным FIB6.2. Модуль подготовки, формирования и печати отчета вынес в Dll где описал функцию:
function ShowReport
(
HandleMain : cardinal; //- Хэндл главного окна
FullPathReport: string; //- Полный путь к шаблону отчета
masterDataSet: TDataSet //- Датасет который выдает линейную таблицу
): PChar; stdcall;
... //- все переменные описываю
try
SaveHandle := Application.Handle; //- Сохраняю родной хэндл
Application.Handle := HandleMain; //- форме присваиваю хэндл вызывающего приложения
FormReport := TFormReport.Create(Application); //- Создаю форму
Application.ProcessMessages; //- На которой я разместил компоненты:
frxFIBMaster.DataSet:=masterDataSet; //- TfrxReport, TfrxDBDataset, TfrxDesigner и на всякий случай TfsDBCtrlsRTTI,TfsDBRTTI
frxReport.LoadFromFile(FullPathReport) //- Загружаю шаблон отчета
frxReport.ShowReport(true); //- Показываю уже сформированный отчет
//- Все работает. Супер!! Но как только я его закрываю обламывается всё приложение как по цепной реакции, хотя везде стоят try
except on E: Exception do
Result := PChar(E.Message);
end;
Application.Handle := SaveHandle; //- Возвращаю свой хэндл
FormReport.Free; //- Высвобождаю форму
Вопрос состоит в том как сделать что бы не происходило обвала приложения и модуля вызывающего Dll которая содержит отчет FR?
Выслушаю всех и всё.
function ShowReport
(
HandleMain : cardinal; //- Хэндл главного окна
FullPathReport: string; //- Полный путь к шаблону отчета
masterDataSet: TDataSet //- Датасет который выдает линейную таблицу
): PChar; stdcall;
... //- все переменные описываю
try
SaveHandle := Application.Handle; //- Сохраняю родной хэндл
Application.Handle := HandleMain; //- форме присваиваю хэндл вызывающего приложения
FormReport := TFormReport.Create(Application); //- Создаю форму
Application.ProcessMessages; //- На которой я разместил компоненты:
frxFIBMaster.DataSet:=masterDataSet; //- TfrxReport, TfrxDBDataset, TfrxDesigner и на всякий случай TfsDBCtrlsRTTI,TfsDBRTTI
frxReport.LoadFromFile(FullPathReport) //- Загружаю шаблон отчета
frxReport.ShowReport(true); //- Показываю уже сформированный отчет
//- Все работает. Супер!! Но как только я его закрываю обламывается всё приложение как по цепной реакции, хотя везде стоят try
except on E: Exception do
Result := PChar(E.Message);
end;
Application.Handle := SaveHandle; //- Возвращаю свой хэндл
FormReport.Free; //- Высвобождаю форму
Вопрос состоит в том как сделать что бы не происходило обвала приложения и модуля вызывающего Dll которая содержит отчет FR?
Выслушаю всех и всё.
Комментарии
Тогда я скажу. Поигравшись с параметрами, вспомнил что в dll вместо string лучше передавать pchar, а уже внутри его преобразовать.
Пробовал и так и сяк
// FullPathReport:= String(fFullPathReport);
// StrCopy(FullPathReport, fFullPathReport);
но проблему не решило.
Ещё кто выскажется?
Но если я из программы вызываю модуль dll, а потом из модуля dll вызываю отчет FR в другом dll, следует обвал по закрытию. Причем запуская под дебагером пару раз ексепшн был не из-за виолешн-а, а что то типа "слишком много трэй эксепшенов".
Вот начал переоборудовать, упрощать, убирал параметры, но ошибки остались.
Помогите пожалуста.
Я думаю интересно было бы использовать FR в dll.
Поробовать как вариант поручить ехе вызывать две dll и печатать через основную программу. Парюсь дальше.
Есть варианты?
function GetFieldAliases(сDataSet: TDataSet) : string;
var k : integer;
begin
Result := сDataSet.Fields[0].Name+'='+сDataSet.Fields[0].FieldName;
for k:=1 to сDataSet.FieldCount-1 do
Result := Result+ #13 + сDataSet.Fields[k].FieldName+'='+сDataSet.Fields[k].DisplayName;
end;
...
; if not (masterDataSet=nil)
; then begin
; frxFIBMaster.DataSet:=masterDataSet;
; frxFIBMaster.FieldAliases.Text := GetFieldAliases(masterDataSet);
; end;
...
Как поправлю всё выложу рабочий вариант что бы другие могли тоже им воспользоваться.
PS. Учится лучше на чужих ошибках.
Какая интересная реализация...
Это не только интересно, но и полезно, сам так делаю
А зачем вообще так все усложнять, понятно, что будут ошибки с распределением памяти, высвобождением ресурсов etc, не проще ли начать с того, что есть екзе, а есть длл с ФР, и все сначала оттестировать так, а уже потом усложнять. Кста, когда создаете объекты в ДЛЛках, кого указываете в качестве родителя, случаем не Аппликатион?
Другое дело что есть ряд ограничений которые наклыдываются на объекты экспортируемые из Dll. Указываю хэндл аппликэйшина, не указывать же мне хэндл винды. А если не присваивать в модуле никакого хэндла, то на панели задач появляется его иконка , а при закрытии модуля аппликэйшн сворачивается.
Это всё лирика, а корень зла лежал ещё глубже. Дело в том что в самом репорте выводятся строчки содержащие StringField-ы. Упс, а я должен всё передать через Pchar (одно из ограничений). Вот после этого все и ложилось.
Действительно, было бы замечательно из любого модуля, пусть то ехе или dll, вызывать FR из dll. Всё было бы ничего но та функциональность которая испольфуется в FR пересекается с ограничениями передаваемой информации из/в dll.
Повторюсь что когда идет вызов FR(dll) из exe, отчет формируется нормально и имеющиеся ексепшены отрабатывают нормально.
Если вызовается FR(dll) из другой dll, то вступают в действия ограниения и получается я не могу спокойно передать в отчет датасеты содержащие стринговые fields.
плюс общие пакеты run-time
Приложение с плагинной архитектурой на основе Jedi (компонент JvPluginManager)
Плагины реализованы как dll
Разные плагины через интерфейс пользуют движок отчетов FR, реализованный в одной dll.
Все нормально, проблем со строками нет.