Centura Web Publishing Products FAQ

Last updated June 2nd, 1999
Copyright © 1998-1999 Thomas Althammer. All rights reserved.
No part of this document should be reproduced, distributed or altered without my permission.

Contents

General

net.db

General

Layout

Database Access

Web Developer

General

Layout

Development

Deployment


General

Where can I find information about Centura's database products and the Year 2000 problem?
The newest releases are all Year 2000 compliant. Check www.centurasoft.com/support/tech_info/bulletins/cli2000.htm for further information.
Even though SQLBase is Y2K compliant, your client-side applications that access SQLBase may not be. Use a utility available for download at ftp.centurasoft.com/products/utilities/y2ksqlb.zip to analyze your SQLBase databases to help with your Y2K efforts. Please read the ReadMe.txt and License.txt files after extracting them from the .ZIP file.

Are there any problems I might face when working with Windows 98?
Centura Software Corporation is in the process of certifying its 32-bit products on Windows 98. Visit http://www.centurasoft.com/support/tech_info/bulletins/win98warn.html to obtain further information.

When I attempt to run the SETUP.EXE of a Centura product I get 'Installation Aborted", "Internal Error". How can I avoid this?
The Wise installer makes extensive use of the TEMP directory during any installation. Make sure that:
- The directory pointed to by the TEMP (or TMP) environment variable exists.
- Make sure that this directory is writable by the current user.
Sadly, there's no way to code around this in the installer, since the error occurs before the first line of code is executed.


net.db

General

 


Layout

Is it possible to exchange the default toolbar with a customized one?
The following information applies to Version 1.1x of Centura net.db.
The first step is to hide the toolbar without actually switching it off.
Why must we do that?
net.db security says that if you turn off the 'new' button (for example), not only does it go away, but all Inserts are banned, however they may come about. This means that even if you've managed to create a button which mimics the net.db 'New' button, you won't be able to use it if the 'New' button is disabled - you'll get an 'Access Denied' error message.
How do we hide the toolbar without switching it off?
We need to create some HTML which looks a bit like this:
<html>
<head>
<title>Centura net.db</title>
</head>
<frameset cols="*,0">
<frame
src="http://yourmachine/yourscripts/ndrun.exe?wi=ma&book=yourbook&page=pgYOURPAGE&request=new"
name="ma" marginheight=10 marginwidth=10>
<frame
src="http://yourmachine/yourscripts/ndrun.exe?wi=tb&book=yourbook&page=pgYOURPAGE"
name="tb" marginheight=4 marginwidth=4 noresize scrolling=no
frameborder=0>
</frameset>
</html>
Save this off into an HTML file. Make sure you change the URLs/book filename/pagename to something appropriate.
If you load this HTML file into your browser, you'll be taken to (perhaps via a login screen) the insert screen of the given page. You'll also notice the nicely hidden toolbar (in Netscape, it may appear as a thin grey strip down the right hand side of the screen. But we can't do anything... we need some buttons!
Now, we have a choice to make. You can either:
-  Implement some save/new buttons (or hyperlinks, or clickable gifs, etc.) in the designer, so they appear on the page
-  Set up a further frameset to give you a 'toolbar' of your own.

The first one is easier, so we'll deal with that one first.
First, go to the toolbar properties, and turn on the 'save' and 'new' buttons.
Then, add a new HTML object to your detail screen. Call it what you like, but add this as the HTML:
<script language=javascript>
function InsertRecord()
{
this.location="ndrun.exe?book=" + book + "&page=" + page + "&c=" + c +
"&request=new&wi=ma"
}
</script>
<input type=button value="New Record" onClick="InsertRecord();">
<input type=button value=Save onClick='if( Validate( pgYOURPAGE ) )
submit();'>
This gives us an insert button. and a save button. The net effect is that you can insert a record and re-save it to your heart's content until you hit 'New Record' again. Of course, you're free to change the buttons to gifs, hyperlinks, whatever.

The second course of action requires a bit more typing. You'll need to create a frameset document with two frames (call them 'left' and 'right' for the sake of the example). In one frame ('right'), load in the frameset document we created above. In the other ('left'), load up the following HTML:
<html>
<head></head>
<body>
<script language=javascript>
function InsertRecord()
{
parent.right.ma.location=
"http://yourmachine/yourscripts/ndrun.exe?book=" + parent.right.ma.book +
"&page=" + parent.right.ma.page + "&c=" + parent.right.ma.c +
"&request=new&wi=ma";
}
</script>
<form>
<input type=button value="New Record" onClick="InsertRecord();">
<input type=button value=Save onClick='if( parent.right.ma.Validate(
parent.right.ma.document.pgYOURPAGE ) )
parent.right.ma.document.pgYOURPAGE.submit();'>
</form>
</body>
</html>
The buttons ought to perform as before. 'Gotchas':
-  Make sure there's absolutely no way to get to the index screen. This will mess up all our toolbar hiding.
-  It's best if you don't have any link buttons on your page. There is grave risk that these too could mess up our hidden toolbar.
-  Make sure you have an appropriate method in hand to generate unique primary keys.


Database Access

When attempting to connect to SQLBase 7.0.1 using net.db, I get error 422 "Invalid servername length". How can I avoid this?
This problem occurs when not using TCP/IP for database connectivity to SQLBase. In particular, it is suspected to be a direct result of having comdll=SQLAPIPE
under the [win32client.dll] section of SQL.INI.
Make sure that you are using TCP/IP (Windows Sockets) connectivity to SQLBase. To do this, ensure you have the following entries in SQL.INI
[win32client.dll]
comdll=sqlws32
[win32client.ws32]
serverpath=server1,127.0.0.1/*
Note that above, the IP address 127.0.0.1 assumes that SQLBase server is on the same machine as net.db. If this is not the case, substitute 127.0.0.1 with the IP address of the server machine.
If you reconfigure net.db to talk TCP/IP, you may also need to configure your SQLBase server to "listen" on TCP/IP. To do this you will need to make changes to the SQL.INI on the machine that SQLBase resides, as follows. (This example assumes you have SQLBase server for NT - 1 client) ...
[dbnt1sv]
servername=server1,sqlws32
dbname=ISLAND,SQLWS32
[dbnt1sv.dll]
comdll=sqlws32

If you make changes to net.db or SQLBase configurations, don't forget that they need to be stopped and re-started for these changes to take effect.

Why do I get "Access Denied" errors when trying to connect to net.db, although the normal database connection works fine?
The "Access Denied" message is coming from net.db (rather than the database). This means that your login name is not in the list of users authorised to use net.db designer. Try adding the desired username to the comma delimited list of users in the registry under:
HKEY_LOCAL_MACHINE\Software\Centura\netdb\Server Components\designerUsers
This is the list of users who are authorised to use the net.db designer. If you are using the "Argosy" Beta of Centura net.db 1.2, there is a configuration program (netdbservercfg.exe) to make this process of editing the registry easier. Once you've made the change, you'll need to restart net.db.


Web Developer

General

Do I need to know languages like HTML, JavaScript, VBScript, and Java to use CWD effectively?
No, you do not. Many CWD applications are written simply as Windows applications, and have all the necessary functionality to handle your business logic and create an HTML user interface to the Web. But you will find a knowledge of HTML useful if you want to add polish and pizzazz to your Web pages. And you will find a knowledge of scripting language like JavaScript or VBScript useful if you want to add client-side functionality to your Web application's interface.

I applied PTF2 to CWD 1.1.0 and now I can't create an executable. How can I fix this?
Please see http://www.centurasoft.com/support/tech_info/bulletins/cwd11andptf2.html for further information.


Layout

How does CWD position objects on the Web pages it generates?
CWD uses an HTML table object (the <table> tag). This table is invisible because it is specified as having no border. CWD's layout manager performs calculations of the X and Y coordinates of all the objects on your window, then creates an HTML table "grid" to fit the location of all the objects as closely as possible. Sometimes objects fit within a single row and column of this layout table, and sometimes they are too large to fit in one cell, so they are specified to span multiple rows and columns.
In your browser, you can view the source HTML generated by CWD and look at the <table>, <tr> (table row), and <td> (table data or column) tags that are present.

I just looked at the page's source HTML, and I see that none of the layout table's column tags (<td>) has a width specified. How does CWD ensure that these columns are the proper width to position the objects correctly on the page?
At the time the CWD layout manager was created, Netscape's Navigator and Microsoft's Internet Explorer, the two main browser brands, supported different ways to specify the table column width. There was no way at the time to specify width within the <td> tag that would work consistently in all browsers. The only reliable method to make a column a certain width was to place an object of a certain size, like a picture or a text string, in the column.
Therefore, the CWD designers chose to use a trick – in the last row of the layout table, CWD places a string of preformatted space characters (enclosed between <pre> and </pre> tags). Preformatted text is fixed-width text, in which all the characters are the same width. Placing a string of preformatted spaces in the column forces the column to be the width of the string, and has no visual impact on the page, since the spaces are invisible.
The most recent versions of the two most popular browsers appear to support the "width" attribute of the <td> tag the same way, so future versions of CWD will probably support this method of sizing columns, which is much more accurate.

The layout of fields on the Web page looks different from the way I positioned them in the window layout. How can I ensure that layout is as WYSIWYG as possible?
Positioning objects in HTML is less precise than in Windows, so you can expect some "give" in the HTML layout. In Windows, locations are absolute, but to place objects on a Web page, Web Developer must generate an HTML table and place objects in it. The HTML table doesn't present as fine a layout grid as is possible in Windows.
Objects that are placed too close together or are not lined up perfectly may confound CWD's grid calculations, and be more likely to end up in the "wrong" row or column of the HTML layout table. You can make the layouts resemble each other more closely by setting your grid size to 4x4 (go into Tools/Preferences and select the Grid tab to change this setting). The distance between objects will then more closely resemble what can be accomplished in HTML, and it will be easier to align objects perfectly

How can I center objects with respect to the entire page, when Web Developer places all the objects within a "grid"?
You can center an object by creating your own class of object (image, data field, and so on) and deriving it from the Web version, then overriding the CreateWebString() function like this:
Function: CreateWebString
   Description:
   Returns
   Parameters
      Receive String: strWebString
   Static Variables
   Local variables
      String: strValue
   Window Handle: hWndParent
   Actions
      Call __cWebItem.CreateWebString( strWebString )
      Set strWebString="</TD></TR>
            <TR>
            <TD COLSPAN=10 ALIGN=CENTER>" || strWebString
This adds to the existing HTML that Web Developer creates, which puts objects into an HTML layout table column. By the time this function is called, a new table column and table row has already been started, so the first thing the function does is close the new row and column (using the </TD> and </TR> tags) so that it can start over with its own table and row definition.
It makes a new row in the layout table (<TR>), and puts the object into a new column that spans the width of the layout table (<TD COLSPAN=10 ALIGN=CENTER>). Getting the number of columns to span (COLSPAN) is a trial-and-error process; you will first have to run the app and view the source in your browser to see how many HTML table columns are generated for the layout.
This function does not add closing tags for the table row and column (</TD>, </TR>) because the layout function adds these after each object when generating the page layout.


Development

My application(s) crashed! I tried to restart them in AppConsole, but they wouldn't start. What do I need to do?
If the application did not exit gracefully, an instance of the app may still be running. If something goes wrong and the application refuses to respond initially to the Web App Manager's polite request to terminate, then after two minutes the Web App Manager will forcibly shut it down, and you can then try restarting the application.
If after two minutes the application process continues to run, you can try to kill the process by using the NT Task Manager. If the Task Manager does not let you stop the application, it is probably because the user ID you logged in with is not the application's owner. By default, the "Centura Web App Manager" service runs under the "LocalSystem" account. Instead of accepting the default, you can change the service Startup settings to run under your administrator account. Then, when you log in as administrator, you will be able to kill apps that this service started, if necessary.

An ounce of prevention is worth a pound of cure. What are some ways I can make sure that my Web applications do not crash?
If your application accesses a database, you can help ensure a well-behaved application by managing the database access very carefully. Always disconnect all SQL handles at every point of exit in the application – before any call to WebQuit(), for example. If your application has no defined exit point, disconnect SQL handles as soon as they are no longer needed. Disconnect all SQL handles explicitly; do not assume that functions such as WebQuit() will disconnect them for you (they do not). Make sure all SQL handles use isolation levels that do not hold locks during selects, if appropriate to your database brand. Always make sure your application can handle SQL errors. The new application template for Web Developer already includes an appropriate SQL error handler. (You can change the behavior of this error handler, but first you should study how it works so that you don't inadvertently leave out important steps in the error handling.)

How can I debug applications while they are running in Web mode?
Some code problems do not come to light until an application has been deployed to the Web and is being accessed by multiple users. Get others to participate in a "crash test" session – have everyone try to use your application at once and observe how it behaves. By using the WebLogEvent function at critical points in your code, you can generate debugging statements to help you spot and fix bugs. Use the NT Event Viewer to see the messages that the application generates.
On Windows '95, these messages are written to a DOS console, because Windows '95 does not have an event viewer. You can also view the events in a DOS console in NT by starting the Web App Manager from the command line with the -c option (for console mode) or holding down the control key while you click "Start App Manager" from AppConsole.

How can I embed cool web stuff like Java applets, ActiveX objects, movies, sounds, or JavaScript in my Web Developer applications?
Embedding objects is simply a matter of using the HTML <embed> tag. You just need to use a cWebHTML object to supply the HTML reference to the file you want to embed, and your Web server and browser will do the work to resolve the link and present the object. For example:
<embed src="http://server/path/movie.avi">
As long as your Web server can locate the file "movie.avi", and your browser knows how to render it, you will see the movie in the resulting Web page.
The object does not get embedded in the CWD application itself, but in the HTML that is generated from the application. For this reason, the object is a "black box" to your application, and your application does not interact with it.
You can also use scripting languages like JavaScript with your application to create applications that have some client-side functionality. Refer to the book "Building Web Applications With Centura", page 4-6, for details on integrating script with your application. There is a sample application that comes with CWD called Script.app which demonstrates this feature. You can refer to Netscape's JavaScript Authoring Guide at http://home.netscape.com/eng/mozilla/Gold/handbook/javascript/index.html for a JavaScript reference.

I have images are stored in a database. How can I display them on my Web page?
Pictures stored in databases can be retrieved and displayed in the browser, as long as they are a Web-friendly image format (JPEG or GIF). Use the WebPicSetFile() or WebPicSetString() functions described in the Web Developer online help. (Use PIC_FormatBitmap as the picture format.)

How can I generate reports from a Web Developer Application?
If you're satisfied with plain text, you can use SalReportPrintToFile with the ASCII option to generate a plain text report. Browsers are able to display plain text files as well as HTML, so you would just need to make sure the report file is created in a location that you Web server can access, then present a link to it.
If you want more than plain text, embed HTML tags in your report template. For example, for headings, use <h1> or <h2>. For columnar data, use <table>, <tr> and <td> tags. Put a <br> or <p> tag at the end of every line. (This will require some knowledge of HTML.) Make sure the file you generate has a .HTML or .HTM extension rather than a .TXT extension, and the browser will interpret the HTML appropriately.
You might experiment with using the RTF option of SalReportPrintToFile. There are publicly available RTF to HTML converters, but most of them are fairly basic and will not render sophisticated enough HTML. Your best bet is to leave the files in RTF format, and if your users do not have Microsoft Word to view the file, supply a link to allow them to download the Word Viewer from Microsoft's site.


Deployment

Why doesn't the Reset button blank out all the fields?
The Reset button resets fields to their default values, rather than blanking them out. When the page is downloaded, each of the input items has some sort of value (which may be empty, or may be a default value). The Reset button refreshes each of the inputs to its initial value. When you look at an HTML page (via View Source) you only see the original page, even if you’ve entered data in the fields. Only when you hit the ‘submit’ button is the data copied from your browser and submitted to the server.

Why does my application complain that it can't find an image when I am debugging it, but when I run the application in Web mode the image appears in the browser with no problems?
There are two possible reasons for this problem: image type and image location.
Centura's image library does not support interlaced GIF files. This means that if your image is of this type, your application will not be able to load it during your debugging session in Windows. However, your Web server and browser will have no problems dealing with images of this type. If you want to be able to load the image in Windows, save the GIF file in noninterlaced format.
Also, during development your image needs to be in a location where your application can find it, and when you deploy your application to the web, your image needs to be where the Web server can find it. At designtime, you can put the path to your images in the Include File Path (go to Tools/Preferences to edit this path). For Web mode, you can provide path relative to your Web server's document root by editing the Web Server Relative Picture Path in the Web Manager Form's properties.

When I repopulate a table window, the table in the Web page shows some rows from the middle of my table window rather than beginning with the first rows. Why?
By default, the table window will display rows beginning with the context row, whatever that might be. If you want the table to display rows beginning with row zero, you need to call SalTblSetContext( ) explicitly after repopulating your table.

My application seems to work beautifully when I debug it in Windows, but it crashes or hangs when I deploy it to the Web. Why?
This can happen when you use Windows-specific functions and messages rather than their Web equivalents, such as SalEndDialog instead of WebEndDialog, and SAM_Create instead of Web_Create. Refer to Chapter 4 of "Building Web Applications" with Centura for the complete list of Web functions and messages that you should use instead of the Windows ones.

My application is going to be accessed by a lot of people. If I write my application using modal dialogs, each user gets his own dedicated instance, and I don't have the server memory and power to manage that many instances of the app. What can I do?
Avoid modal dialogs. Use only form windows (cWebForm), and make sure they are shareable by overriding the CanReuseApp() function in the window and returning TRUE. This will make sure multiple users can share the same application instance.

But if users share the same application instance, can't they see each other's data?
Not if you maintain the state of the application programmatically. You can define state variables that hold information relevant to each user. Call StateVarCreate() when a window is first rendered, for example on WEB_Create the form. You will also need to override StateVarSetValue() and call SaveState() to save a user's state, and override StateVarGetValue() and call RefreshState() to restore the user's state. You will need to do this for every reusable form in your application.

How can I be sure there is only one instance of the application running at all times?
In AppConsole, make sure that the minimum and maximum number of processes are set to "1". This way, one process will be prestarted, and no more than one will ever be running.

Under what conditions will the Web App Manager try to start additional instances of my application?
This can happen if you have nonreusable form windows or if you use modal dialog boxes, either explicitly or implicitly. Even if your application contains only reusable forms, using WebMessageBox() or the default SQL error handler will cause the application process to become dedicated to the current user until the dialog is dismissed, because both use modal dialogs. If another user requests the application during this time, a Web App Manager will attempt to create a new instance for that user. If you have set maximum processes to "1", Web App Manager will not be able to create a new instance and the second user will see a message saying that the application is busy.

I replaced all the modal dialogs with form windows, and I replaced my SalModalDialog() calls with SalCreateWindow(). But now I find that when many users are sharing the application, I lose track of which windows are opened and closed by what user. What should I do?
The easiest thing to do is to keep all the windows open. Then, rather than calling SalCreateWindow() to transfer control to a new window, call the RenderMe() function in the WebManager form to make a window active. For example:
frmWebManager.RenderMe( frmOtherWindow)
(To have the behavior work in Windows as well, you will need to call SalSetFocus( frmOtherWindow ) afterwards.)

Where can I find an example of maintaining user state in a shareable application?
Refer to the sample application called StateVar.app.

My application works fine when run in Windows mode, but in Web mode, it can't connect to the database/print/access files on the network. What's wrong?
Are you running the Web App Manager as an NT service? If so, check the Startup settings for this service and see which user ID it's running under. If it's running as Local System (the default), chances are it can't communicate with the database/printer/network server.   Change it to run under a specific user's account -- like Administrator -- or at least a user that has the proper access priveleges.