Visit our Sponsor   Visit our Sponsor
delphi3000.com - the free delphi knowledge platform
delphi3000.com - the free delphi knowledge platform
Have a look at your member-status

connecting people's knowledge


  - Recent ArticlesRSS feed for Recent Articles on delphi3000.com
  - List of All Articles
  - Top Viewed Articles
  - Articles (+Attachem.)
  - Articles Of Interest
  - Categories
  - Top Uploader
  - Search
  - Index

  - My Home
  - Submit an Article
  - My Articles
  - My Personal Data
  - My Bookmarks
  - Activities
  - Login/Logout

  - Sign Up
  - Why Sign Up
  - Newsletter

  - Press
  - Advertise

  - Contact
  - Feedback



Community
Borland
ClubeDelphi
Dr. Bob
UK-BUG
Delphi Meetings
Planeta Delphi








Share this article with friendsShare this article with friends
Rate this articleRate this article - to keep the quality of delphi3000.com !
Comment this article or read through previous comments (14)


WebSnap I: The unknown powerfulFormat this article printer-friendly!Bookmark function is only available for registered users!
RAD
Product:
Delphi 6.x (or higher)
Category:
WebSnap
Skill Level:
Scoring:
Last Update:
08/21/2002
Search Keys:
delphi delphi3000 article borland vcl code-snippet WebSnap internet HTML web-development web
Times Scored:
11
Visits:
5727
Uploader: Eber Irigoyen
Company: BTXSys
Reference: N/A
 
Question/Problem/Abstract:
Websnap I: the unknown powerful
  I've been looking all over for information on websnap... not much people seems to have played around much with this technology so, I decided to give it a try my self
Answer:



First I'll make some notes:
- you dont want to use BDE as your database motor, I'm telling you... you'll get all kinds of errors.
- Websnap is not a RAD tool
- if you want a RAD tool for design web pages within Delphi, stop reading this article and look at the following links:

  Intraweb
  ASP Express 4 Delphi
  devexpress

All these guys have done a really good job in creating a Web-development-RAD tool for Delphi
(actually Intraweb is included on Delphi 7 studio Architect)
I have tested 2 of those products and even that it seems really easy, I had many problems just because they don't give you the source code, so sometimes you get errors and that's it, can't do anything about it
besides I have websnap... my company paid 3,000 USD for Delphi 6... so, why not use it
- I created a small ACCESS database, I'll send it to the editor together with the source code; but mean while, If is not on the download link soon, here's the definition: (database name: example1.mdb)
2 Tables:
Table1:
Name:employees
fields:
EmpNo: Text(5), Indexed = YES No duplicates
EmpName: Text(50), Allow Zero Lenght = Yes, Indexed = YES Duplicates OK
Shift: Text(1), Required = Yes, Allow Zero Lenght = No, Indexed = YES Duplicates OK
This last field should contain "N" for night, "M" for morning, or "A" for afternoon
Put some data on this table so you'll have something to play with

Table2:
Name:Production
Fields:
ItemNo: Number, Required = YES, Indexed = YES no duplicates
ProcessDate: Date/Time, Required = YES, Indexed = YES (duplicates ok)

Websnap is a very powerful technology, but is not that easy as we're so used with Delphi... at least, not at first, once you cross the learning curve, it all becomes very easy
another thing is that you don't really get to know what's going on just by looking at the examples, and the examples that came with Delphi don't really show much so I'm gonna show you how to create an application that includes all the elements of a functional page... enough talking... let's start

Delphi menu:
File | New | Other, Websnap
choose WebSnap Application

Note: If you're gonna be working with Websnap I recommend you right click on the Delphi tool bar and select Internet, that way you'll have the 3 basic thing needed in Websnap:
New web application, New websnap page module, new websnap data module

you should see a dialog: New WebSnap application:
select Server type: Web App Debugger executable
on the CoClass Name type:ProdExample

on the Application Module Options | Page Name, type:Production

Note:here's the first cool thing, Delphi lets us create our web page as if it is an application, it creates an executable which we will be able to put break points and it will stop when loading the pages; and you don't have to unload the DLL to make changes when debugging; people that have fooled around with ISAPI development know the pain it is to debug DLLs

Click on the Page Options button:
Another dialog comes up: "Application Module Page Options"; the dropdown options on the "Type" are:
AdapterPageProducer: This allows us to create pages that are linked somehow to databases
DataSetPageProducer: This one allows us to create grids displaying contents of querys, all the formatting is automatic
PageProducer(default):You can use this one to create general purpose pages (main page, forms, etc), you can also fill up these pages with data-grids that you create your self; As we go on we'll see which Type is more suitable for the page we need
InetXPageProducer and XLSPageProducer: these ones seem to be really cool... but they're tied to other things I'm not gonna cover on my articles =o(
Note that you can put the page header here: (Page Title), but more likely you'll change that later; Also notice the Published and the Login Required check boxes, we'll see later where that is on the code

That's it on this dialog, I just wanted to give you a brief explanation of it (we will need it later)
click Ok (make sure you left Producer Type=PageProducer)
Leave the rest untouched and click OK

You should see a normal form now, that's because we're creating an application, we're not gonna use that form, so you can go ahead make it small and close it so it won't bother, we won't use that form for anything

Delphi Menu File | Save All
Name the "Unit1" as ConsoleU, the "Unit2" as HomeU and the "Project1" as ProdSever
Now, you got your self a web page... that does nothing; but the following steps we will need trhough the whole development;

Bringing your page up
Run your program, Click on your Delphi menu Tools | Web App Debugger, If you have an active link on the "Default URL", click on it, if not, click on the "Start" button and then click on the link
Then you get a list (probably two items there), click on the "ProdServer.Production", and click on "Go"
Voila... there's your first web page... ok, that's not exciting, I admit it, but I needed to show you how to get your web page up

Go ahead and close your application (Form1 that came up when you ran the program)
Ok, now, let's create another page so we'll see some interesting things
Menu File | New | Other | WebSnap | WebSnap Page Module
on the Page Name type: shift
leave the rest untouched and click OK

Save All, and save your new Unit as "shiftU.pas"
Now run your application again, bring up your web page (I won't explain again how to do this, is up there: Bringing your page up); Now on your main page you'll see a link to the page you just created: shift, and if you click on the shift link, you'll see a link to the Production (main) page... how fun... Delphi provides this links from/to all the pages you create by default (if you specify the Published check box... remember that somewhere on the dialogs?) But we don't care about these links, we'll take 'em out of there and put them wherever we want

Close your program and let's see where those links come from
Click on your "HomeU" unit and at the bottom click on "HomeU.html", Delphi provides a descent HTML editor for WebSnap applications
you should see this code now:

   <h1><%= Application.Title %></h1>
  

<% if (EndUser.Logout != null) { %>
  <% if (EndUser.DisplayName != '') { %>
  <h1>Welcome <%=EndUser.DisplayName %></h1>
  <% } %>
  <% if (EndUser.Logout.Enabled) { %>
  <a href="<%=EndUser.Logout.AsHREF%>">Logout</a>
  <% } %>
  <% if (EndUser.LoginForm.Enabled) { %>
  <a href=<%=EndUser.LoginForm.AsHREF%>>Login</a>
  <% } %>
  <% } %>
<h2><%= Page.Title %></h2>
<table cellspacing="0" cellpadding="0">
  <td>
  <% e = new Enumerator(Pages)
  s = ''
  c = 0
  for (; !e.atEnd(); e.moveNext())
  {
  if (e.item().Published)
  {
  if (c>0) s += '&nbsp;|&nbsp;'
  if (Page.Name != e.item().Name)
  s += '<a href="' + e.item().HREF + '">' + e.item().Title + '</a>'
  else
  s += e.item().Title
  c++
  }
  }
  if (c>1) Response.Write(s)
  %>
  </td>
  </table>


... Kinda ugly uh?... that's JScript, look at the code and find the for statement... that's what is showing all the links to all the published pages that we create... mmmm... also at the top you see the "Application.Title"... mmm... interesting, but boring; I'm not gonna get into detail on JScript, if you're interested on what you can do using JScript, you can read this document from Borland (the whole WebSnap "documentation"... yeah... right)
Delphi Documentation

ok, back to our program, go ahead and delete all that ugly code (from the page.Title line to where the table ends) , also delete the line of "Application.Title" , so you'll only leave the html and the stuff that says something about login/logout; you may need that later if you want to implement logins to your web page
You can do the same thing with the shiftU unit, I'll let you do that one

Now, you're gonna have to grab some HTML code from somewhere (the logo for your page, which will very likely be the one of your company), we need a header.htm and a footer.htm (at least a header), so we can give our pages a professional look once you get that save those files on the same directory where you have your web application

Notes:
- You'll have to create an "images" folder for the images on your logo
- The HTML inside those two files has to be HTML with no sections
- At runtime, the pictures (jpg, gif, etc...) are expected to be in a virtual directory called images. If you are running the application under webappdbg.exe then you'll need to include the directory of the pictures files in Web App Debugger's search path (Web App Debugger application Menu Server | Options).

<html><head><title></title></head>
<body>
You only want the code from here!
</body>
</html>

Now, let's put those header and footer inside our pages; click on your HomeU unit, and click on it's homeU.html tab at the bottom; right before the body closing, put this:
  <!-- #include file="header.htm" -->
  <!-- #include file="footer.htm" -->

Do the same with shiftu unit
And add:<#EMPLIST> between your header and footer, I'll just tell you that that's a "html transparent tag" which we will replace from Delphi with Some data (the employees list =op), that section on your shiftu.html should look like this:

  <!-- #include file="header.htm" -->
  <#EMPLIST>
  <!-- #include file="footer.htm" -->

Now let's put something useful;Delphi Menu File | New | Other | Web Snap | Doble click the Web Snap Data Module, click OK
Save All, and call this new unit: datamoduleu
This is just like a regular datamodule, but for Web Snap, ok, drop an ADO Connection and an ADOQuery, connect the ADO Query to the ADO Connection and make the connection to the database "example1.mdb", set the following properties:

ADOConnection1.LoginPrompt = False
ADOQuery1.SQL = 'SELECT * FROM Employees WHERE Shift = paShift'

Test your connection to the database, and set
ADOConnection1.Connected = False

Click on the WebDataModule1, set the OnCreate Event Like this:

procedure TWebDataModule1.WebDataModuleCreate(Sender: TObject);  begin
  ADOConnection1.Connected:=True
end;

On the OnDestroy event write:
ADOConnection1.Connected:=False

put this unit on that directory where you have your project:


Unit sharvarsu;
Interface
Var ScriptName:String;
Implementation
End.


And add it to the uses clause of HomeU and shiftU
Ok, now click on your homeu unit, click on the html code and insert these lines (between the header and the footer):
  <a href="<#MODULE>/shift?Shift=N">Night Shift</a>
  |
  <a href="<#MODULE>/shift?Shift=M">Morning Shift</a>
  |
  <a href="<#MODULE>/shift?Shift=A">Afternoon Shift</a>

Click on the HomeU.pas, press F12, click on the white area (the page module), and on the OnCreate Event write this code:

  
  Procedure TProduction.WebAppPageModuleCreate(Sender: TObject);
  Var
    FN: Array[0..MAX_PATH- 1] Of char;
  Begin
    SetString(ScriptName, FN, GetModuleFileName(hInstance, FN, SizeOf(FN)));
    ScriptName := ExtractFileName(ScriptName);
  End;
  


Press F12 again, click on the PageProducer, and on the OnHTMLTag event write this code:

   Procedure TProduction.PageProducerHTMLTag(Sender:
  TObject; Tag: TTag;
    Const TagString: String; TagParams: TStrings; Var ReplaceText:
  String);
  Begin
    If (TagString='MODULE') Then
      ReplaceText:=ScriptName
  End;
  


we're almost there, click on your shiftu unit, include the datamoduleu on the uses clause; press F12 so you see the PageProducer, click on it and on the OnHTMLTag Event write this:

Procedure Tshift.PageProducerHTMLTag(Sender: TObject; Tag: TTag;
  Const TagString: String; TagParams: TStrings; Var ReplaceText: String);
Var Par, EmpList, Shift, EmpNo:String;
Begin
  Try
    If (TagString = 'EMPLIST') Then
    Begin
      If (Request.QueryFields.IndexOfName('Shift')>-1) Then
        Par:=Request.QueryFields.Values['Shift']
      Else
        Par:='M'; //default
      Case Par[1] Of
        'M':Shift:='Morning';
        'N':Shift:='Night';
        'A':Shift:='AfterNoon'
      End;
      With WebDataModule1.ADOQuery1 Do
      Begin
        Try
          Parameters.ParamValues['paShift']:=Par[1];
          Open;
          If (RecordCount>0) Then
          Begin
            //Put some header for this list
            EmpList:='List Of employees For the <b>'+Shift+'</b> shift <br>';
            EmpList:=EmpList+'<table border="1" cellspacing="1">'+
                     '<tr>'+
                     '<th>Emp #</th><th>Name</th>'+
                     '</tr>';
            //Add the employees list with links to queries to individual employees
            While Not (EOF) Do
            Begin
              EmpNo:=FieldValues['EmpNo'];
              EmpList:=EmpList+Format('<tr><td><a href="/%s/empprod?EmpNo=%s">%s</a></td><td>%s</td> </tr>',
                       [ScriptName, EmpNo, EmpNo, FieldValues['EmpName']]);
              Next
            End;
            EmpList:=EmpList+'</table>';
            ReplaceText:=EmpList
          End
          Else
            ReplaceText:='No employees found For the '+Shift+' shift'
        Finally
          Close
        End
      End
    End
    Else If (TagString = 'MODULE') Then
      ReplaceText:=ScriptName
  Except
    On E:Exception Do
      ReplaceText:='Error during process: '+E.Message
  End
end;

Run your application, bring up your page, and click on any of the 3 links, I included links to query at the Employee level, but we haven't implemented this page yet, I will publish more articles following this one, addressing other issues, like

- The continuation of this project,
- The issues with images that don't come up right (I'm sure you'll run into this one)
- Retrieving data from the user using forms (running queries with information entered by the user)
- Converting your application to an ISAPI and publishing it on a web server

There's still a lot more that can be done, however it is very extensive to write it on a single article


On the next articles I will try to cover just about everything you need to create a fully functional web page using only Delphi and HTML

mean while, keep up coding

salu2

EberSys





Please rate this article!
Skill level:
BeginnerExpert

Useful:
No!Very!

Overall rating:
PoorExcellent



Comments to this article
Write a new comment
Scriptname
    Carl Stoepker (Oct 27 2007 10:51PM)

Scriptname is populated with ProdServer.exe.
But when using Web App Debugger the module is called 'ProdServer.ProdExample'. Therefor I had to hardcode the right name into Scriptname (haven't figured out how to do it dynamically):

    // ScriptName := ExtractFileName(ScriptName);
    ScriptName := 'ProdServer.ProdExample';
Respond

Scriptname
    Carl Stoepker (Oct 27 2007 10:50PM)

Scriptname is populated with ProdServer.exe.
But when using Web App Debugger the module is called 'ProdServer.ProdExample'. Therefor I had to hardcode the right name into Scriptname (haven't figured out how to do it dynamically):

// ScriptName := ExtractFileName(ScriptName);
    ScriptName := 'ProdServer.ProdExample';
Respond

Query parameter
    Carl Stoepker (Oct 27 2007 10:45PM)

I had to use :paShift to make it work in Delphi 7:
ADOQuery1.SQL = 'SELECT * FROM Employees WHERE Shift = :paShift'

Respond

RE: Query parameter
Carl Stoepker (Oct 27 2007 10:52PM)

This is another comment:

Scriptname is populated with ProdServer.exe.
But when using Web App Debugger the module is called 'ProdServer.ProdExample'. Therefor I had to hardcode the right name into Scriptname (haven't figured out how to do it dynamically):

    // ScriptName := ExtractFileName(ScriptName);
    ScriptName := 'ProdServer.ProdExample';
Respond

GetModuleFileName function
    burndata (Feb 25 2005 11:17AM)

seems when I compile the project I get a error

GetModuleFileName is an undeclared variable, that routine  in the system library..  tryed some things and nothing worked so far.
Respond

RE: GetModuleFileName function
Carl Stoepker (Oct 23 2007 4:20AM)

Same for me......anybody???
Respond

RE: RE: GetModuleFileName function
Carl Stoepker (Oct 25 2007 5:22AM)

Fixed by including 'uses Windows' in HomeU.pas

Respond

Bringing your page up
    anonymus (Jun 4 2003 9:14AM)

I must say straight up what a great article.
I followed the steps up to "Bringing your page up", I got the page with the dropdown (Then you get a list (probably two items there), ) but only one item, I click go and I get the page, cool, I then go back and (I explored what else was on the page...as programmers do...) I hit the close hyperlink under the dropdown - this expanded with some extra text and I click that hyperlink (forgot what it says now), now this is the problem, the pages do not come up. Did I kill a service or something, I restarted but still get the same problem - 404 page not found.
Any info will be fantastic, and I promise not to do it again !! Cheers.
Respond

RE: Bringing your page up
yo mate (Jun 5 2003 12:58AM)

Fixed, the serverinfo.exe was not being invoked after I cleared the registered server.
Starting the serverinfo.exe in the bin folder re-registers everything.
Cheers.
Respond

MAX_PATH
    Phil Oneacre (Apr 15 2003 9:30PM)

When compling I receive an error 'un delclared identifier.

I am at a loss what to do.
Respond

RE: MAX_PATH
Phil Oneacre (Apr 15 2003 10:47PM)

I figured it out. Sould have done a little more digging before leaving a comment.
Respond

RE: RE: MAX_PATH
Carl Stoepker (Oct 25 2007 5:21AM)

Fixed by including 'uses Windows' in HomeU.pas
Respond

Excellent Article!!!
    Marcus Neves (Oct 13 2002 4:41AM)

Very good article Eber. Please, keep up the good work and write the continuation of it!!
Respond

great !!!!
    PEPS ^^ (Aug 23 2002 3:52PM)

hi Eber,

thank you very much for this great article !!

bernhard

DELPHI3000 - Admin


Respond














 
Sign up to consume product discounts for Bronze memberships !

read more


  Visit our Sponsor

 

  Community Ad of
S. Carter
 
   














 







     
  Copyright © 2000 - 2007 delphi3000.com - All rights reserved. Terms of use. || Privacy
delphi3000.com is a service by bluestep.com IT-Services GmbH (Vienna)