Showing Download Progress in Delphi SOAP
Download the code for this white paper (dlprogress.zip, 12 KB)
Abstract
This paper talks about how you can show a download "progress" bar (like many download utilities do) when using SOAP to transfer data. I’ve used Delphi 7 in this article, and made some code changes to the source code, so this might not work with any other version of Delphi.Introduction
If you’ve read the paper in http://www.agnisoft.com/white_papers/SOAP2.asp#binaryfile which tells you how you can transfer binary data using SOAP. In Delphi 7, you can also use the TSOAPAttachment class. But what if you need to use a progress bar to display data being transferred?There’s an event in the THTTPRio.HTTPWebNode, called OnReceivingData. This event gives you a Size and a Total parameter, but they’re always the same…so you can’t use it to determine the actual download status. Or can you?
Digging into Delphi
Looking at the Delphi SOAP Source code, I realized that I could modify the way this event was being called, and sending real data - where Size would mean the amount that’s currently been downloaded, and Total would give you the expected total size of the download.
Looking into SOAPHTTPTrans.pas (located in the SourceSoap folder under your Delphi 7 install), I found that the procedure Receive was calling the OnReceivingData event. I had to make some modifications to the code as follows: (In the Receive procedure)
Note: Please backup this file before makign any changes.
1. Declare variables, TotalSize and TotalRead as DWORD:
|
|
|
3. Further down, within the repeat loop, you’ll see the following code:
|
|
4. Remember to include $(DELPHI)SourceSOAP in your client project search path, so that these changes will be compiled into your application.
Demo
I’ve created a simple WAD based server which allows you to download files in the same directory as the WAD application with an IDownloader interface. There’s a function in the interface, DownloadFile implemented as follows:
|
What that piece of code does is to look in the folder (where the server application resides) for the existence of a file with the name given in the FileName parameter. If a file is found, its contents are returned in a dynamic array of bytes.
If you’re wondering what GetCurrentDirectory does:
|
The Client Application
I’m skipping the part where you create a new application, import this WSDL etc. I’ve created a form with an edit box for the file name, a Download button, and a progress bar indicator and panel. Here’s the code for the download button: |
A file is requested from the server, and if it does arrive, we save it to a file in the same folder as the client application. (Here Application.ExeName is ok, because this is a client application that will always be an EXE) I’ve used another CompressHelper function to save the response byte array to disk.
But the code to actually populate the progress bar is in an event - THTTPRio.HTTPWebNode.OnReceivingData:
|
The reason I have Application.ProcessMessages; in there is so that you can actually see the user interface change - otherwise the progress bar does not get updated. (But you probably knew that already)
What have we got?
This.
Caveats?
- This works only for Delphi SOAP that uses WinInet. If you use INDY, there’s probably a different approach to making it work.
- You can’t use this with a client built using the SOAP package. That’s because your source code changes to SOAPHTTPTrans.pas don’t change the package.
- I have also included a Download as Attachment to demonstrate that the changes you made work even with TSOAPAttachments. The source code reveals all.
Who’s Deepak Shenoy?
He’s part of the big pointy haired team at Agni. Update: Deepak now works at FLOvate Technologies.Download the code for this white paper (dlprogress.zip, 12 KB)
Share This | Email this page to a friend
Posted by Deepak Shenoy on February 4th, 2006 under Uncategorized |3 Responses to “Showing Download Progress in Delphi SOAP”
Leave a Comment
Server Response from: blog1.codegear.com

RSS Feed
April 20th, 2006 at 9:51 am
thakns, but i have some trouble using this:
at Digging into Delphi Section
2. In the code for the Receive procedure, after the line:
HTTP_QUERY_CONTENT_Length or
HTTP_QUERY_FLAG_NUMBER,
@TotalSize, Len, Index<);
TotalRead := 0;
Index< raise a exception :
Expression Needed But ) Found
April 20th, 2006 at 10:12 am
Oh, remove the "<"
April 20th, 2006 at 7:30 pm
Thanks for your answer, it works now
I’m using D6,as u see, HttpRIO in D6 doesn’t support a HTTPWebNode1ReceivingData event .
I wonder if I can repalce the httprio component in d6 with the one you gived above?
To make a new Dcu or just to replace the .pas files in d6’s src folder? i’ve no idea