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.
General
Layout
Database Access
General
Layout
Development
Deployment
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.
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.
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.
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.
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.
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.
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 youve 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.