且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

在Delphi Web服务器后生成带有快速报告的PDF

更新时间:2022-10-29 11:43:01

我正在猜测 QReport.Client 在代码的稍后位置使用,并且由于修改后的代码不再将其分配给AProgress,您最终会出错。



确定要修改QuickReport源吗?我已经在Windows服务中使用QuickReport来生成PDF文件,然后将其附加到电子邮件中,并且一切正常,而无需修改QR源。我不记得确切要进行哪些设置,但是它是在Delphi 6和QR 4.06中完成的。


I have a Delphi web server providing some web services*. One of them is supposed to generate and return a PDF report.

The PDF creation is done with a QReport that is then exported into a PDF file with the ExportToFilter procedure.

The routine works fine when called from within an application, but when called behind a TIdTCPServer, it hangs and never finishes. Debugging it, I got tho the hanging point:

(note: I'm home right now and I don't have the source code. I'll try to reproduce quickrpt.pas' source as accurrate as I can remember).

procedure TCustomReport.ExportToFilter(TQRDocumentFilter filter);
  ...
  AProgress := TQRFormProgress.Create(Application); // Hangs on this line
  AProgress.Owner := QReport;
  if ShowProgress then AProgress.Show;
  QReport.Client := AProgress;
  ...

Searching the web, I found in this page (1) the suggestion to set ShowProgress to False, and edit the code so that it does not create the progress form when ShowProgress is set to false (apparently, this is due to QReport not being threadsafe).

So, I edited the code, and now I have this:

procedure TCustomReport.ExportToFilter(TQRDocumentFilter filter);
  ...
  if ShowProgress then
  begin
    AProgress := TQRFormProgress.Create(Application);
    AProgress.Owner := QReport;
    AProgress.Show;
    QReport.Client := AProgress
  end;
  ...

Now, the report comes out. But then the service gets to an Invalid Pointer Exception (which I can't trace). Following calls to the service complete successfully, but when I shut down the service** it starts whining again with Invalid Pointer Exceptions, then the "MyServer has commited an invalid action and must be closed" windows message, then again a couple of times more, then just the pointer exception, then comes to error 216 (which as far as I could find out, is related to Windows access permissions).

Thanks!

Update (jan 5): Thanks Scott W. for your answer. Indeed, after some research, I found another suggestion that only the main thread can access some components. So I set the QR code back to normal and called the main method from a Synchronize call inside a TThread (so that way the main thread would handle it). But I still get the same error.

You mention you were able to generate PDF as a service with QR 4. Maybe that's why it's not working for me, since I'm using QR 3. On the other hand, you don't mention if you're doing that behind a TIdTCPServer (which is my case, providing web services) or if you run it by itself (for instance, during a batch process).

Anybody knows whether my QR version might be the problem? Thanks!

* Running Delphi 7 and QuickReport 3 on a Windows XP SP2. The server is based on Indy.

** I have two versions of the server: a Windows application and a Windows Service. Both call the same inner logic, and the problem occurs with both versions.

Update (mar 8): After all, my problem was that my printing routine was in another dll, and the default memory management module is somewhat crappy. Setting the first uses of my .dpr to be ShareMem overrides the memory management module with Borland's implementation, and solved my problem.

uses
    ShareMem, ...

(1): http://coding.derkeiler.com/Archive/Delphi/borland.public.delphi.thirdpartytools.general/2006-09/msg00013.html

I'm guessing that QReport.Client is used somewhere later in the code, and with your modified code no longer assigning it to AProgress, you end up with an error.

Are you sure that you have to modify the QuickReport source? I have used QuickReport in a Windows Service to generate a PDF file and then attach to email message and all worked fine without having to modify the QR source. I don't recall exactly which settings had to be made, but it was done with Delphi 6 and QR 4.06.