C++Builder 5 Developers Guide

   

WebSnap is a new extension of the WebBroker Technology, but is not very well documented. It does combine lots and lots of possibilities with a significant learning curve, and is best demonstrated in practice. I have done some experiments with WebSnap and this section starts my (multipart) coverage of this Web server development featureset. This time, I will show you step-by-step how to write a simple WebSnap application that requires us to write very few lines of custom code (if any at all). In the next sections, I will focus on the alternative choices and steps that are possible along the way, including master-detail relationships (which are a bit more tricky than the simple table that we're using this time).

WebSnap can be compared with InternetExpress in that it's an extension of WebBroker, and it clearly uses some of the same ideas (which isn't too strange , if you consider that Jim Tierney, the architect of WebSnap, is also the same person who designed InternetExpress a few years ago).

WebSnap Components

To start a new WebSnap application, we need to click File, New ”Other, and go to the WebSnap tab of the Object Repository. Here, we'll see three icons that make up the WebSnap wizards: one for a WebSnap application, one for a WebSnap Data Module, and one for a WebSnap Page Module, as can be seen in Figure 22.4:

Figure 22.4. WebSnap Application, Data Module, and Page Module.

The difference will be made clear in a moment, but let's start with a new WebSnap application first. The New WebSnap Application wizard (of Figure 22.5) is a big dialog compared to the old WebBroker Application dialog (of Figure 22.1). It asks for a lot of information, but right now we should only specify the type of application (a CGI standalone executable), the Application Module Components being used (a Page Module instead of just a Data Module), and the Page Name itself, which can be set to Home.

Figure 22.5. New WebSnap application.

We can specify some additional different options by clicking the Components button or the Page Options button, but these will be covered in more detail later in this chapter.

WebSnap Web Module

For now, just click the OK button to generate the new CGI project and Web module for our WebSnap application, which can be seen in Figure 22.6.

Figure 22.6. Home WebModule.

The Web module already contains five components: TPageProducer , TWebAppComponents , TApplicationAdapter , TPageDispatcher , and TAdapterDispatcher .

Now, save the new Web module in file pmHome.cpp and the project in file CGI.bpr , so we don't have to do it later.

WebSnap Data Module

We must now create a WebSnap data module, so we can actually add some datasets to connect to data (like the biolife table). We can do this by doing another File, New ”Othe r , moving to the WebSnap tab of the Object Repository again, but this time selecting the second icon for the WebSnap data module. This will present us with the following dialog for a New WebSnap Data Module, as can be seen in Figure 22.7.

Figure 22.7. New WebSnap data module .

If we just leave it at the default settings and click OK, a new WebSnap data module has been added to our WebSnap CGI project. Save it in file wDataMod.cpp . Now, drop any datasets on this data module, such as a regular TClientDataSet component from the Data Access tab of the C++Builder 6 Component Palette. Set the Name property to cdsBiolife , and connect its Filename property to C:\Program Files\Common Files\ Borland Shared\data\biolife.xml for the biolife table with memo field and picture, among others.

Now, right-click the cdsBiolife component and start the Fields Editor. Right-click again and select Add all Fields. To let the WebSnap client application maintain its own state, we must now specify a primary key field (one that the client can use to tell the WebSnap server which record we want to work on). For the cdsBiolife table, we can just select the Species No field as keyfield, although generally any unique field would do. To specify that Species No is the key field, we need to select Species No in the fields editor, go to the Object Inspector, open up the ProviderFlags property, and set the pfInKey subproperty value to true .

DataSetAdapter

Now that we have a cdsBiolife dataset on the WebSnap data module, we can drop a TDataSetAdapter component next to it (third component from the left of the WebSnap tab), and call it dsaBiolife . We should assign the cdsBiolife to the DataSet property of the dsaBiolife TDataSetAdapter component. Next, open the TDataSet Adapter in the Object Treeview (new in C++Builder 6). Right-click the Actions to add all eleven possible actions ( DeleteRow , FirstRow , PrevRow , NextRow , LastRow , EditRow , BrowseRow , NewRow , Cancel , Apply , and RefreshRow ). Next, right-click the Fields to add all fields. The adapter fields that are generated correspond to the dataset fields from the cdsBiolife . This is an important moment of your design. If you want to hide some fields from your view (from the view that will be represented by this particular TDataSetAdapter ), you should remove these fields now. If there are some fields that you don't ever want to use, you should remove them even from the persistent field list of the TClientDataSet ”you should not wait until they appear in the TDataSetAdapter field list.

For the list of actions you should also consider carefully which actions you want to allow (that is, make available) for the end users, using this particular TDataSetAdapter . You might have correctly guessed by now that you can actually have more than one TDataSetAdapter connected to a T(Client)DataSet , each of these different TDataSetAdapter components corresponding to a different view (showing potentially a different set of fields, with potentially a different set of actions to apply on these fields). For the example, at this time we want to enable all actions and show all fields (so we don't have to delete anything).

WebSnap Page Module

It's now time to add the actual content-generating page modules to our WebSnap Web module application. We can do this with the third and last icon on the WebSnap tab of the Object Inspector: the WebSnap Page Module wizard (see Figure 22.8).

Figure 22.8. New WebSnap Page Module Wizard.

To work with our previously constructed TDataSetAdapter , do not leave the default properties set (still shown in the previous figure), but select an AdapterPageProducer instead of the regular PageProducer , give it a nice Name and Title such as Biolife . The Name , however, might not contain any spaces (it must be a valid identifier), but the Title can, of course. Make sure you keep the Published property enabled, so the page module will be made visible with a link from our Home page that we created earlier. Also, if like me, you selected a CGI application, don't bother with the Login Required feature, since it does not work with CGI applications! This is caused by the fact that the Login feature uses a session component that is kept in the memory of the Web server application, so it has to remain up-and-running between requests (and a CGI application exits after each request). Later in this Clinic, I'll show you some more of the Login Required details (for ISAPI DLL s), but you don't have to select it for now.

After you click the OK button, a new Page Module is created for us, including an AdapterPageProducer component that we selected. Save the file in pmBiolife.cpp . Now, go to the Object TreeView, and open up the AdapterPageProducer . Right-click WebPageItems and select the New Component dialog. The New Component dialog will always only show the new components that are relevant for the particular situation. In this particular situation, we can add either an AdapterForm or a LayoutGroup . A LayoutGroup can be used to specify some layout options, and will be available at other locations as well. For now, add an AdapterForm . Right-click the AdapterForm , and this time add an AdapterFieldGroup (to show fields from cdsBiolife ) as well as an AdapterCommandGroup (to operate on cdsBiolife , using the actions that we added to the dsaBiolife TDataSetAdapter component earlier).

We now still need to make a few connections. For the AdapterCommandGroup , we must assign its DisplayComponent property to point to the AdapterFieldGroup . The only thing left now is to make sure that the AdapterFieldGroup connects to the dsaBiolife TDataSetAdapter (from the unit wDataMod ). To do so, we must first include the header of the wDataMod unit to the current unit (for example, using Alt+F11 or File, Include Unit Hdr...), and then assign the Adapter property of the AdapterFieldGroup to WebDataModule1->dsaBiolife to make the final connection.

Deployment

Before you can deploy WebSnap applications on a Web server (machine), there are two special files that have to be installed and deployed on that machine first. For more information, you should always read deploy.txt in your CBuilder6 directory. Basically, you must register WebBrokerScript.tlb as well as stdvdl40.dll on the Web server machine using tregsvr.exe “ ”all found in the CBuilder6\bin directory. Also, WebSnap applications require the Microsoft Active Scripting Engine, which is included in IE5 and later, and installed on Windows 2000 and later (but if it's not on your Web server, you can download it from http://msdn.microsoft.com/scripting).

And finally, you must ensure that the XML files that the ClientDataSets are using are also available on the Web server (if you remove the PATH portion in the FileName property, then you can put them in the same directory as your Web server application).

After these preparations , let's turn to the CGI.exe project. By default, all C++Builder projects have their options set to generate small executes, by using the dynamic RTL as well as runtime packages. However, this results in additional files that you have to deploy on the Web server. And, because I do not want to do that (I always want to limit the number of files that I have to deploy), we should start the Project, Options dialog. On the Compiler tab, click the Release button; on the Linker tab, uncheck the Use dynamic RTL option, and finally on the Packages tab, uncheck the Build with runtime packages option. Now, do Project, Build CGI to build the project. This should result in a CGI.exe of 2,096,128 bytes ” mainly caused by the fact that the wDataMod.dfm is 2,487,537 bytes big if the ClientDataSet is open at design time (so the data is made persistent inside this .dfm file). But, even without an active ClientDataSet, the WebSnap executable will still be over one megabyte in size . Without having written one line of C++ code!

Anyway, we now need to deploy both the executable CGI.exe as well as all .html files: pmHome.html (for the Home page) and pmBiolife.html (for the biolife Page Module). These two .html files are the ones that can be modified using Dreamweaver or FrontPage. Deploying the files means moving them to the cgi-bin or Scripts directory of your Web server. If you do this on your local machine, the URL to view the CGI.exe can be something like http://localhost/Scripts/CGI.exe or http://localhost/ cgi-bin/CGI.exe . You can view the results of the CGI.exe in a browser and get the main home page, which is still empty because we didn't do anything special with the TPageProducer component on the main WebModule, see Figure 22.9.

Figure 22.9. CGI.exe .

Next to the home page is a link to the Biolife page, and when you click it, you get the real results of the WebSnap application, as can be seen Figure 22.10.

Figure 22.10. Output of WebSnap application in Internet Explorer.

Remember that we added all fields to the DataSetAdapter, which explicitly included the Graphic field. If we hadn't made sure to add all fields at that place, the Graphic field would not have been part of the displayed fields (even if by default you get all fields when you didn't select any). My best guess is that it's part of some helpful default optimization rule.

Tweaking

We haven't yet written a single line of C++ code. But this is about to change because we do need some tweaking at this point. The project source code that has been generated so far contains a little bug that prevents the command buttons from operating. Click the NextRow or LastRow button and you'll see what I mean ”we are still at the first record! Believe me when I tell you that the problem is not related to the fact that we have been building CGI standalone executable targets because you will also be unable to move to the next record with an ISAPI Dynamic link library or a Web App Debugger executable.

The problem has to do with multipart requests, and specifically the ReqMulti.obj file, which isn't linked with our application. If you take a look at the WebSnap demos in CBuilder6\Examples\WebSnap , you'll notice that these projects all work just fine, but their source code differs slightly from the source code generated by C++Builder 6.

To make a long story short ”to fix the problem, do Project, View Source, and add one line of code (under the three #pragma lines that are already present in CGI.bpr ):

#pragma link "ReqMulti.obj"

Now, save, recompile, and redeploy the CGI project, as can be seen in Figure 22.11. Now you can use the buttons to navigate through the Biolife table (First, Prev, Next, and Last), or even edit the content of these fields and make changes to the bitmap. In case of the bitmap, you need to specify a filename on your local disk, which will be sent to the Web server application after you click the Apply button (which is shown if you click the Edit button first). You then want to continue to the browse state, using the BrowseRow button.

Figure 22.11. Edit WebSnap output in Internet Explorer.

If you don't see the correct new picture, you might need to refresh the page before you see it (for some reason, I always have to “ ”probably an Internet Explorer 6 issue).

Let's see how this all works by examining the WebSnap Architecture, Adapters, and Components from the ground up. While we do this, we'll discover some handy properties to make it look even better (the output of Figures 22.10 and 22.11 was much too wide because of the long captions on the buttons, for example).


   
Top

Категории