Last updated March 1st,
1998
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.