For this article we will use the Biolife table that can be found in the DBDEMOS Alias that comes standard with Delphi.
Starting the Project
- Start a new Web Server Application using the Delphi wizard.
- Choose CGI in the dialog box (you can choose ISAPI also. There will be no change in the code)
- Choose the Project menu from the IDE.
- Choose Options from the Project menu.
- In the Project Options dialog, click on the Directories/Conditionals page.
- Set the Output directory to - C:\inetpub\scripts (or your scripts folder of you web server).
- Create 2 action items by double clicking on the Web Data Module.
- Set the PathInfo property of the first action item to /Fish, the Name to waFish and the defalt property to True.
- Set the PathInfo of the second action item to /SendImage and the Name to waSendImage.
- Drop a TQuery component onto the Web Data Module and set its DatabaseName property to DBDEMOS.
In the OnAction event of the waFish action item, type the following code:
procedure TWebModule1.WebModule1waFishAction(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
begin
try
with Query1 do
begin
Close;
SQL.Clear;
SQL.Add('SELECT BIOLIFE."Species No", Common_Name FROM BIOLIFE');
Open;
Response.Content := Response.Content
'<h2>The various species of Fish</h2><br>' #13#10
'Click on the hyperlinks below to see the picture of the given species<P>';
while not Eof do
begin
Response.Content := Response.Content
Format('<a href="%s/%s?No=%s">%s</a><br>' #13#10,
[Request.ScriptName,
'SendImage',
Fields[0].AsString,
Fields[1].AsString]);
Next;
end; { while not Eof }
Close;
end; { with Query1 do }
except
on E : Exception do
Response.Content := '<b>ERROR</b><br>' #13#10
E.Message;
end;
end;
In this event we query the Biolife table. We use only two fields in this case. The "species no" field and the Common Name field. The common name field is what we display in the browser while the Species no field is used to send back as a "parameter" to the /SendImage action of our application. I use the Format function here to construct the HTML string to be returned to the web browser. Each record of the table will generate a string that looks like :
<A HREF="/scripts/Fish.exe/SendImage?No=90030">Red Emperor</A><BR>
This is standard HTML. Notice here that the /SendImage action is called sending it a parameter -"No=90030". We will "extract" the value of "No" from this to use in the next query that we will build dynamically in the /SendImage action's OnAction event.
The /SendImage action's OnAction event looks like this :
procedure TWebModule1.WebModule1waSendImageAction(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
var
JPEG : TJPEGImage;
MemStrm: TMemoryStream;
Bitmap : TBitmap;
begin
{ In this action event, I "extract" the Species No parameter from the QueryFields
property of the Request object and use that to get the image from the
table.
Then I stream out the image as a Jpeg image
}
try
JPEG := TJPEGImage.Create;
MemStrm := TMemoryStream.Create;
Bitmap := TBitmap.Create;
try
with Query1 do
begin
Close;
SQL.Clear;
SQL.Add('SELECT Graphic FROM BIOLIFE');
SQL.Add('WHERE BIOLIFE."Species No" = :LastName');
Params[0].AsInteger := StrToInt(Request.QueryFields.Values['No']);
Open;
{ Assign the image from the database to a Bitmap object since the
field type is a TGraphicField.}
Bitmap.Assign(FieldByName('GRAPHIC'));
JPEG.Assign(Bitmap);
JPEG.SaveToStream(MemStrm);
MemStrm.Position := 0;
{ The content type needs to be set !! }
Response.ContentType := 'image/jpeg';
Response.ContentStream := MemStrm;
end;
finally
JPEG.Free;
{ Do not Free MemStrm. The Web server will take care of it. }
Bitmap.Free;
end;
except
on E : Exception do
Response.Content := '<b>ERROR</b><br>' #13#10
E.Message;
end;
end;
The code above is commented to explain what is going on. If one had instantiated the fields of the Query object than one could have assigned the field object (for the image field) directly to the bitmap. The code for that would look like Bitmap.Assign(Query1Graphic). In this particular example, you shouldn't/can't instantiate the field object explicitly since we use the same Query object for different SQL queries that return different sets of fields.
The ContentType property of the Response object can be set to 'image/gif' if you want to send gif images. The various ContentType values can be found in the HTTP specifications.
Another interesting Project is the next project where we reduce the image size just before we send the image. This technique is very useful and effective is real world ISAPI application development. Check it out.