Are you one of those people who think the Internet is just a fad, something that will never last? If so, let me tell you something...you're wrong! The Internet is huge and it's getting bigger every day. In part, the Internet is about the Web and about people spending hour after hour browsing the Web. But the Internet is also about file transfers, email, and electronic commerce. The Internet is big business. It isn't going away anytime soon, so you might want to polish your Internet programming skills. Thankfully, Delphi makes it easy to experiment with Internet programming and to do serious Internet programming as well.
Today, you look at some aspects of Internet programming with Delphi. There's a whole world waiting out there on the Internet, so let's get to it.
The Internet components in Delphi are located on the Internet page of the Component palette and come in two categories. The first category is a group of components provided by NetMasters. With one exception, these are native VCL components. The exception is the THTML control, which is an ActiveX control. Table BD.1 lists the NetMasters controls and provides a description of each control. The controls are listed in the order in which they appear on the Component palette.
Control | Description |
TNMDayTime | Obtains the date and time from Internet daytime servers. |
TNMEcho | Sends text to and receives text from Internet echo servers. |
TNMFinger | Obtains information about a user from an Internet finger server. |
TNMFTP | Performs file transfers between networked machines using FTP (File Transfer Protocol). |
TNMHTTP | Performs file transfers using HTTP (Hypertext Transport Protocol). Hypertext documents are normally viewed in a Web browser. You use THTTP to retrieve Web documents that don't need to be displayed in a Web browser. |
TNMMsg | Sends simple ASCII text messages using TCP/IP. |
TNMMSGServ | Receives messages sent with the TNMMsg control. |
TNMNNTP | Sends messages to and receives messages from Internet news servers using NNTP (Networking News Transfer Protocol). |
TNMPOP3 | Retrieves email messages from mail servers using POP3 (Post Office Protocol). |
TNMUUProcessor | Encodes or decodes MIME or uuencoded files. |
TNMSMTP | Sends email through SMTP (Simple Mail Transfer Protocol) mail servers. |
TNMStrm | Sends data streams to a network or Internet stream server. |
TNMStrmServ | Receives streams sent by the TNMStrm control. |
TNMTime | Obtains the date and time from Internet time servers. |
TNMUDP | Transfers data across networks using UDP (User Datagram Protocol). |
TPowersock | Encapsulates the Winsock API. |
TNMGeneralServer | Used for general TCP/IP servers. |
THTML | Displays HTML (Hypertext Markup Language) files. This is a Web |
browser component. | |
TNMURL | Converts URL data to a readable string and string data to URL format. |
The second category of controls includes native VCL components provided by Borland. The TClientSocket and TServerSocket components come with both the Professional and Client/Server versions of Delphi. The Web Broker components (TWebDispatcher, TPageProducer, TQueryTableProducer, and TDataSetTableProducer) come with only the Client/Server version. The VCL Internet components are listed in Table BD.2.
Component | Description |
TClientSocket | Manages a TCP/IP client socket connection. |
TServerSocket | Manages a TCP/IP server socket connection. |
TWebDispatcher | Converts an ordinary data module to a Web module. |
TPageProducer | Enables building of dynamic HTML pages. |
TQueryTableProducer | Takes TQuery results and generates an HTML document from them. |
TDataSetTableProducer | Takes TDataSet records and generates an HTML document from them. |
These two groups of controls give you all the power you need to build high-quality Internet applications.
One of the most visible Internet programming tasks is building a Web browser. Certainly it's the most glamorous. The good news is that it can also be the easiest.
You might be wondering why anyone would want to build a Web browser. After all, the world already has Netscape Navigator and Internet Explorer, so who needs another browser? True enough, you probably aren't going to try to build a Web browser that competes with Netscape or Microsoft. On the other hand, consider a company that has hundreds or even thousands of employees who need access to the Web. It can be very costly to license thousands of copies of a commercial Web browser. On the other hand, you can write a quality Web application with Delphi in just a few hours, thereby saving the company a lot of money.
Another reason a company might want a custom Web browser is to restrict access to the Web. For example, there might be sites on the Internet that employees have to visit from time to time. A custom Web browser enables access to authorized sites on the Web but not to any other (unauthorized) sites. In fact, a custom browser is perfect for your kids!
Finally, one of the most compelling reasons for a custom Web browser is an intranet. An intranet is a Web site that is local to a particular network. An intranet can contain a variety of information for a company's internal use--information on company benefits, company policies, an employee address book, meeting schedules, or even information on the company bowling league. A custom Web application can provide access to an intranet and prevent access to the Internet.
So with that in mind, you'll build a simple Web browser. You'll probably be surprised how easy it is.
The THTML control is a ready-to-use Web browser. All you have to do is place one of these controls on a form and call the RequestDoc method. Well, that might be a little oversimplified, but you can display a Web document from anywhere on the Internet as easily as that. With that in mind, let me show you how quickly you can write a Web browser application. Here are the first steps:
FIGURE BD.1. Your new Web browser after the first steps.
if URLComboBox.Text <> `' then HTML.RequestDoc(URLComboBox.Text);
if Key = Char(VK_RETURN) then begin Key := #0; if URLComboBox.Text = `' then Exit; URLComboBoxClick(Sender); end;
Wow! A Web browser in 15 minutes! Notice that the browser acts like any other Web browser...well, sort of. You need to add a lot of functionality, but it's a start.
NOTE: If you are fortunate enough to have a full-time Internet connection, your new browser will work immediately. If you are using dial-up networking with auto dial enabled, the dialer will start automatically and connect to your Internet service provider (ISP). If you don't have dial-up networking installed, you have to connect to the Internet manually before running the program.
You now have a good start on your Web browser. One of the features you are missing is some status information on each page as it loads. What you'll do is add a routine that updates the status bar as a page loads. You make use of the THTML control's OnUpdateRetrieval and OnEndRetrieval events to obtain periodic status updates. You will use the GetBytesTotal and GetBytesDone methods to calculate a percentage and then display the percentage loaded in the status bar. Ready?
procedure TWebMain.HTMLUpdateRetrieval(Sender: TObject); var Total : Integer; Done : Integer; Percent : Integer; begin Total := HTML.RetrieveBytesTotal; Done := HTML.RetrieveBytesDone; if (Total = 0) or (Done = 0) then Percent := 0 else Percent := ((Done * 100) div Total); StatusBar.SimpleText := Format( `Getting Document: %d%% of %dK', [Percent, Total div 1024]); end;
StatusBar.SimpleText := `Done';
Take a closer look at the code in step 1. There isn't very much to it. The GetBytesTotal method tells you how many bytes are in the document or the embedded object currently being loaded (objects include images). The GetBytesDone method gives the number of bytes that have been retrieved for the page or object up to this point. From there it's a simple matter to calculate the percentage of the object that has been retrieved. Finally, you format a string with the information obtained from the HTML control and send it to the status bar. The code in step 2 simply updates the status bar after the entire document has been loaded.
Run the program again and watch what happens when you load a page. The status bar shows the percentage loaded for the page and for any embedded objects.
Now for some finishing touches. First, you'll add some buttons beneath the URL combo box. (For a peek at the finished product, see Figure BD.2.) Here goes:
URLComboBoxClick(Self);
HTML.Cancel(0);
StatusBar.SimpleText := `Done';
URLComboBoxClick(Self);
HTML.ViewSource := not HTML.ViewSource; if HTML.ViewSource then SourceBtn.Caption := `View Document' else SourceBtn.Caption := `View Source';
Your form should now look like the one shown in Figure BD.2.
FIGURE BD.2. The EZ Web Browser with buttons in place.
These steps introduce a couple of new THTML elements. The Cancel method stops the process of loading a document. The ViewSource property is used to toggle between viewing the document as HTML source or as a regular HTML document.
Now run the program again. Check out the new buttons and see what they do. In particular, give the View Source button a try.
Okay, you're almost done with your Web browser. Let's add a couple of more features. You are going to respond to two more events of the THTML control in order to provide more status information.
StatusBar.SimpleText := `Connecting to ` + URL + `...';
StatusBar.SimpleText := `Connected...'; URLComboBox.Items.Insert(0, URLComboBox.Text);
In this sequence, step 1 makes use of the OnDoRequestDoc event, which is generated when a document is requested. The URL parameter of the DoRequestDoc event handler is the URL of the site to which you are connected. As long as the URL is provided, you can use it to build a string to display in the status bar. Step 2 adds a little more status information when the document actually starts to load. It also takes the URL and adds it to the URL combo box's list. You need to make sure that you have connected to a site before adding the URL to the list of visited sites.
Congratulations, you have finished (or nearly finished) your first Internet application. Figure BD.3 shows the EZ Web Browser in operation.
FIGURE BD.3. The finished EZ Web Browser displaying a page.
Hey, that's good work! There are some things that your Web browser doesn't do, but it does a lot, so you can be proud. Stand back and admire your work. You can take your new creation and add some new features of your own. One feature you might want to add is a list of URLs that can be used to implement browse buttons (back and next). You could also replace the standard buttons with a toolbar and add glyphs to the toolbar's buttons. If you really want to add the ultimate touch, provide an animation while the document is loading so that your users can tell when your browser is doing something. You can do that most easily with a TImageList component, although the TAnimate component would work, too.
The THTML control has several properties that I didn't cover. Most of these properties have to do with user preferences such as background color, the color of links, the color of visited links, the various fonts used for each heading size, and so on. I'm not going to explain those properties because they are easy to figure out. For the most part you can just accept the default values for these properties. If you want to customize your browser further, though, you can certainly spend some time reviewing the properties list for the THTML control.
Listing BD.1 lists the browser program's main unit.
unit WebBrwsU; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, OleCtrls, NMHTML, ComCtrls; type TWebMain = class(TForm) Panel1: TPanel; URLComboBox: TComboBox; StatusBar: TStatusBar; HTML: THTML; GoBtn: TButton; StopBtn: TButton; ReloadBtn: TButton; SourceBtn: TButton; procedure URLComboBoxClick(Sender: TObject); procedure URLComboBoxKeyPress(Sender: TObject; var Key: Char); procedure HTMLUpdateRetrieval(Sender: TObject); procedure HTMLEndRetrieval(Sender: TObject); procedure Gobtnclick(Sender: Tobject); procedure StopBtnClick(Sender: TObject); procedure ReloadBtnClick(Sender: TObject); procedure SourceBtnClick(Sender: TObject); procedure HTMLDoRequestDoc(Sender: TObject; const URL: WideString; Element: HTMLElement; DocInput: DocInput; var EnableDefault: WordBool); procedure HTMLBeginRetrieval(Sender: TObject); private { Private declarations } public { Public declarations } end; var WebMain: TWebMain; implementation {$R *.DFM} procedure TWebMain.URLComboBoxClick(Sender: TObject); begin if URLComboBox.Text <> `' then HTML.RequestDoc(URLComboBox.Text); end; procedure TWebMain.URLComboBoxKeyPress(Sender: TObject; var Key: Char); begin if Key = Char(VK_RETURN) then begin Key := #0; if URLComboBox.Text = `' then Exit; URLComboBoxClick(Sender); end; end; procedure TWebMain.HTMLUpdateRetrieval(Sender: TObject); var Total : Integer; Done : Integer; Percent : Integer; begin Total := HTML.RetrieveBytesTotal; Done := HTML.RetrieveBytesDone; if (Total = 0) or (Done = 0) then Percent := 0 else Percent := ((Done * 100) div Total); StatusBar.SimpleText := Format( `Getting Document: %d%% of %dK', [Percent, Total div 1024]); end; procedure TWebMain.HTMLEndRetrieval(Sender: TObject); begin StatusBar.SimpleText := `Done'; end; procedure TWebMain.GoBtnClick(Sender: TObject); begin URLComboBoxClick(Self); end; procedure TWebMain.StopBtnClick(Sender: TObject); begin HTML.Cancel(0); StatusBar.SimpleText := `Done'; end; procedure TWebMain.ReloadBtnClick(Sender: TObject); begin URLComboBoxClick(Self); end; procedure TWebMain.SourceBtnClick(Sender: TObject); begin HTML.ViewSource := not HTML.ViewSource; if HTML.ViewSource then SourceBtn.Caption := `View Document' else SourceBtn.Caption := `View Source'; end; procedure TWebMain.HTMLDoRequestDoc(Sender: TObject; const URL: WideString; Element: HTMLElement; DocInput: DocInput; var EnableDefault: WordBool); begin StatusBar.SimpleText := `Connecting to ` + URL + `...'; end; procedure TWebMain.HTMLBeginRetrieval(Sender: TObject); begin StatusBar.SimpleText := `Connected...'; URLComboBox.Items.Insert(0, URLComboBox.Text); end;
end.
If you have Microsoft Internet Explorer installed on your system, you can use it as an ActiveX control. The first thing you need to do is import the control into Delphi's Component palette. After that, you can place it on a form just as you would any control. First, let me show you how to import Internet Explorer. (I showed you how to import ActiveX controls on Day 15, "COM and ActiveX," but it doesn't hurt to review.) Here are the steps:
FIGURE BD.4. The Import ActiveX dialog box.
Delphi builds the package and then displays a dialog box saying that the TWebBrowser control has been installed. Now you can try out the control:
WebBrowser1.Navigate(`http:\\www.turbopower.com', EmptyParam, EmptyParam, EmptyParam, EmptyParam););
When the program runs, click the form's button. The Web page will load and be displayed in the WebBrowser control.
When you install this control, Delphi creates a unit called SHDocVw_TLB.pas. You can look at this unit to see what properties and methods are available for TWebBrowser.
TIP: You can find documentation for the WebBrowser control on Microsoft's Web site. Search the Microsoft site for the text Reusing the WebBrowser Control.
Notice that you can't redistribute the TWebBrowser control itself without obtaining a license from Microsoft. However, if you know your users have Internet Explorer installed on their systems, your application will work because the control is already installed. You still have to register the control on your user's machine for your application to run. See "Deploying Internet Applications" later in this chapter for more information on registering ActiveX controls.
There are many reasons you might want to send mail from one of your applications. The good news is that sending email isn't difficult at all. Maybe you want your program users to be able to email you with any problems they encounter. In that case, your application could pop up a form containing a Memo component and a Send button. Your users can type text in the Memo component, press the Send button, and the message is emailed to you. You can even go so far as to attach a log file from your application to diagnose any problems the user is having.
The TNMSMTP control is used for sending mail through an SMTP server. SMTP is an odd protocol in that it doesn't require authenticated logon to the server (at least on most SMTP servers). You can simply connect to any mail server, send the email message, and disconnect. The Host property is used to specify the host name of the mail server to which you want to connect. Most of the time, you can just use mail as the host name. Specifying mail tells the TNMSMTP control to connect to your local mail server, whether it's your ISP's mail server or your company's mail server.
If you want, you can specifically set the mail server name (such as mail.mycompany.com), but it isn't usually necessary. If you specify an incorrect mail server, you get an ESockError exception. The Port property is used to specify the port on which to connect. The default SMTP port is port 25. The Port property defaults to a value of 25, so you shouldn't have to change this property.
All the pertinent information for the mail message itself is contained in the PostMessage property. This property is a class that contains properties such as ToAddress, FromAddress, Subject, Body, and so on. You fill in the appropriate fields of the PostMessage property and then send the message.
Before you can send a mail message, you need to connect to the SMTP server. This is done with the Connect method:
SMTP.Host := `mail'; SMTP.Connect;
After you're connected, you can send the email. The OnConnect event handler is a good place for this code because you know that you are connected to an SMTP server. For example:
procedure TMainForm.SMTPConnect(Sender: TObject); begin with SMTP.PostMessage do begin FromAddress := `bilbo@baggins.com'; ToAddress.Add(`gandolf@baggins.com'); Subject := `Test'; Body.Add(`This is a test'); end; SMTP.SendMail; end;
This code sets up the FromAddress, ToAddress, Subject, and Body parameters of the PostMessage property and then sends the message with the SendMail method. It's as simple as that. Notice that the ToAddress and Body properties of PostMessage are TStringLists. The mail message body can contain several lines of text, so it's not surprising that the Body property is a TStringList. The ToAddress property is also a TStringList, so you can specify several recipients for the message.
NOTE: The FromAddress and ToAddress fields are required fields. All other fields (even the message body) are optional.
After you know the message has been sent successfully, you can disconnect from the SMTP server. The OnSuccess event is generated when the mail has been sent. Your OnSuccess event handler might be as simple as the following:
You can send several messages per connection, of course. If you have several messages to send, you don't have to disconnect from the server and reconnect for each message. Just connect once, send all your messages, and then disconnect from the server.
Your mail message might go through without incident, or it might fail in one way or another. In either case, you must be prepared to disconnect from the server. The OnFailure event is generated if the mail message fails to go through, so you can use that event to disconnect from the server as well as the OnSuccess event. The book's code, found at http://www.mcp.com/info, contains a simple mail program that illustrates how to send mail with TNMSMTP.
If your Internet application uses only the VCL Internet components, there is nothing special to do when you deploy your application unless you are using runtime packages. If you are using runtime packages, you need to ship INET40.BPL, and if you are using the page producer components, ship INETDB40.BPL as well.
Deploying an application that uses ActiveX controls, however, requires more work. ActiveX controls must be registered on the machine on which your application will run. The easiest way to register ActiveX controls is with a good installation program. InstallShield Express comes with Delphi Professional and Client/Server versions, so you should try that program. Another good installation program is Wise Install from Great Lakes Business Solutions. The better installation programs register, as part of the installation process, the ActiveX controls that your application uses.
If you don't use a commercial installation program, you have to manually register any ActiveX controls your application uses. The TREGSVR.EXE utility is used to register and unregister ActiveX and OCX controls. This utility is in your Delphi 4\Bin directory. For example, to install the EZ Web Browser application you created earlier today, you ship the following files:
HTML.OCX NMOCOD.DLL NMSCKN.DLL NWM3VWN.DLL NMORENU.DLL WEBBROWS.EXE
After you install all these files, you have to run TREGSVR.EXE on the HTML.OCX and NMOCOD.DLL files to register them. From the command line, you type
TREGSVR HTML.OCX
Do the same for NMOCOD.DLL. The THTML control is now registered on your user's machine and your program will run as intended.
NOTE: If you don't register your ActiveX controls properly, your users will see a message box that says, "Class not registered." when they attempt to run your program. Your application will then terminate, leaving your users wondering what went wrong.
To unregister a control, use the /u switch as follows:
TREGSVR /u HTML.OCX
Here again, a good installation program will have an uninstall option that takes care of this for you.
As you can see, ActiveX controls require a bit of work to install after your application is built. If you aren't aware of the fact that you need to register the ActiveX controls, it can lead to confusion for both you and your users. By the way, the files needed to deploy an application using the THTML control total about 900KB, so using ActiveX controls can be expensive in terms of disk space. I prefer to use native VCL controls whenever possible for exactly this reason.
Today you learned about the Internet components provided in Delphi. You built a simple but usable Web browser with the THTML control, and you learned how to send mail using the TNMSMTP control. Internet programming is big business right now. It certainly can't hurt to have some Internet programming experience.
The Workshop contains quiz questions to help you solidify your understanding of the material covered and exercises to provide you with experience in using what you have learned. You can find the answers to the quiz questions in Appendix A, "Answers to the Quiz Questions."
© Copyright, Macmillan Computer Publishing. All rights reserved.