Delphi Magazine - Aug-97 PDF
Delphi Magazine - Aug-97 PDF
Creating NT Services
John Chaytor looks at how to write your
own Windows NT Services
Mik
Mik e’s Eye
Beating The System eO Vie
from rriss rep w
Ann B or
Dave Jewell shows how to ual orland’s ts
C
delve inside Zip files and in N onferen
ashv ce
ille
find what’s there
TObjec
t
RIP
Welcome to this electronic sample version of The Delphi Magazine which we hope
you enjoy. If you would like to take out a subscription you can go to the form by
CLICKING HERE FOR ANY COUNTRY or CLICKING HERE FOR USA AND CANADA.
If you would like to find out more about The Delphi Magazine or our new
publication Developers Review please visit our website at www.itecuk.com.
Contents
5 News 43 Implementing Class-Traps
Updates and product information For Delphi And C++Builder
Cyril Jandia wants to be in at the birth
8 Under Construction: and death of his objects so he came up
Delphi 3 Web Modules, Part 1 with a simple technique, encapsulated
Bob Swart begins a 2-part investigation in the TClassTrap class
into the new web modules included
with Delphi 3’s Client/Server Edition 47 Nashville BDC:
A Mike’s Eye View
17 Things You Can Do With Mike Orriss reports back on his
Standard Controls: TMenuItem experiences at Borland’s annual
Brian Long unravels more secrets of conference, held this year in Nashville,
owner draw controls, demonstrating how Tennessee
to spice up your menus with glyphs
50 More News From Nashville
22 Surviving Client/Server: Borland used their conference to make
Credit Payments, Part 2 some key announcements: here’s a
Following on from last month’s case summary
study, Steve Troxell wraps up the
project with more helpful design and 53 Review: ISGMAPI
implementation hints Your apps could have built in email
and fax capabilities at the drop of a
26 Creating NT Services hat with this component from Infinity
Services are a powerful feature of Software and a little help from MS
Windows NT, but how can you write Exchange, reviewed by Peter Hyde
your own? John Chaytor has the answers,
with example programs and Delphi 54 The Delphi Clinic
classes to make it simpler Brian Long with more answers to
your Delphi development problems,
40 Beating The System: Zip Files, including: making 256 colour bitmaps,
handing MsgDialog responses and
Peeking Under The Hood
making your apps iconic
The ubiquitous Zip file is everywhere
nowadays and Dave Jewell shows how to
delve inside and find what’s there 60 Tips & Tricks
Hints and helps from readers, including:
a typed TObject bug, modifying form files
42 One Last Compile... and BDE version incompatibilities
I love my company, and my company
loves me
64 On The Disk
Form a free trial version visit
www.ozemail.com.au/~mtntop
Microsoft Server
Application Object
TISAPIApplication
Request Object
TISAPIRequest
Response Object
TISAPIResponse
DLL (ISAPI)
web modules. If you don’t have the
Client/Server version, this article Netscape Server TISAPIApplication TISAPIRequest TISAPIResponse
may help you decide whether to DLL (NSAPI)
purchase it! Console CGI TCGIApplication TCGIRequest TCGIResponse
Web modules come with a Application
number of new components (found Windows CGI TCGIApplication TWinCGIRequest TWinCGIResponse
on the Internet tab of the Compo- Application
nent Palette) and a new Wizard for
starting a Web Module project
➤ Table 1: Web application types
(which can be found in the
Repository after a File|New).
If we select the Web Server Appli- corresponding objects. Each type
cation option the Wizard asks of application uses a type-specific
which type of Web Server applica- descendant of TWebApplication,
tion we’d like to build (Figure 1). TWebRequest and TWebResponse.
ISAPI/NSAPI DLLs have the com- For an ISAPI or NSAPI application
mon advantage that these pro- client request information is
cesses on the Web Server typically passed to the DLL as a structure
➤ Figure 1
only have to be loaded once and and evaluated by TISAPIApplica-
can remain resident after the first tion, which creates the dispatcher,
load, so they eliminate the time- TISAPIRequest and TISAPIResponse program Project1;
{$APPTYPE GUI}
intensive loading/unloading we get objects. uses
when using CGI and WinCGI web A CGI standalone application is a HTTPApp, CGIApp,
Unit1 in ‘Unit1.pas’ {WebModule1:
applications. However, since the console application that receives TWebModule};
{$R *.RES}
internal logic isn’t much different client request information on stan- begin
Application.Initialize;
(certainly not for the Delphi 3 web dard input and passes the results Application.CreateForm(
module programmer), I decided to back to the server on standard out- TWebModule1, WebModule1);
Application.Run;
build a WinCGI web application put. This data is evaluated by end.
this time, so we can use the Intra- TCGIApplication, which creates the
Bob CGI Debugger version 2.01 dispatcher, TCGIRequest and
➤ Listing 1
(available on my new website at TCGIResponse objects.
www.drbob42.com) to test it on A Win-CGI standalone applica-
our local machine without the tion is a Windows application that form). A web module is just like a
need for a local web server. receives client request informa- new form, however, since it’s
Web server applications extend tion from a configuration settings auto-created in the same way as a
the functionality and capability of (INI) file written by the server and regular form. The main project
existing web servers. The applica- writes the results to a file that the source file contains code to prove
tion receives HTTP request mes- server passes back to the client. that (Listing 1).
sages from the web server, The INI file is evaluated by TCGI- Note that this WinCGI project
performs any actions requested in Application, which creates the uses the HTTPApp and CGIApp units,
those messages and formulates re- dispatcher, TWinCGIRequest and whilst an ISAPI/NSAPI project gen-
sponses that it passes back to the TWinCGIResponse objects. erated this way will use the HTTPApp
web server. Any operation we can and ISAPIApp units. The {$APPTYPE
perform with a (non-visual) Delphi WinCGI GUI} further specifies that it’s a
application can be incorporated After we click OK in the Web Mod- WinCGI application, as opposed
into a web server application. ule Wizard, we get a new project to a standard CGI application
Table 1 shows the four types of with a new empty web module (in- that specifies {$APPTYPE CONSOLE}.
web server applications and the stead of the regular empty new Of course, in both cases the
TWebDispatcher actually merge several web actions WebAction item, we have to select
TPageProducer into one web application, instead the WebActionItem1 in the Web
TQueryTableProducer of having to write a separate web Actions property editor, which will
TDataSetTableProducer application for each action). make the Object Inspector focus
If we click the Add button, the on WebModule.Actions[0] as well.
TWebDispatcher first action item will be created, Then, go to the events page, dou-
This component is already built named WebModule1.Actions[0] of ble click on the event OnAction and
into the web module, but we need type TWebActionItem, but with an write the code shown in Listing 2.
one if we want to use an existing alias of WebActionItem1 (Figure 3). I In this OnAction event handler,
data module as a web module. We say alias because there’s some- we can fill in the Response of our We-
can’t drop a TWebDispatcher com- thing going on behind the scenes bAction, which usually generates a
ponent into a web module as there here: the Object Inspector will use dynamic HTML file. Response is of
should be only one per module. As the WebModule1.Actions[0] name in type TWebResponse, which is an
you would expect, this component the component combobox, while abstract base class for all objects
is the “dispatcher” of actions and the actual name of the component that represent HTTP messages
events. will be WebActionItem1. The form sent in response to an HTTP
The property Actions of type definition in the code editor con- request message.
TWebActionItems contains a list of tains no reference to a WebAc- Our web application automati-
all actions that this web applica- tionItem component, so it should cally creates a TWebResponse object
tion can perform. Each action has a be clear by now that we’re dealing based on the TWebRequest object
number of subproperties: Name, with a sub-component of the web for an incoming HTTP request
PathInfo, Enabled and Default. module, namely Actions[0], that message. The TWebDispatcher for
The PathInfo is the action re- for our convenience is named the application then passes the
quest that is sent to the web server WebActionItem1. TWebResponse object to the TWeb-
and can be used to identify sub- Since it’s the only WebAction ActionItem associated with the
tasks to be performed by this sin- item, it’ll be the default one as well. TWebRequest object, so that the re-
gle web application (so we can To actually write code for this first sponse can be formulated. Of the
TDataSetTableProducer
➤ Figure 6
Usually, we don’t want to put a sim-
ple HTML page on the web, but
rather the contents of a database
or the result of a dynamic query. In
that case, we can use the more so-
phisticated TDataSetTableProducer
and TQueryTableProducer (the Ta-
ble part of their names refers to
HTML table output, not to data-
base tables). These two compo-
nents can be used to produce nice
looking HTML pages, consisting of
records formatted in HTML-tables
that look like DBGrids in the web
browser.
In order to use the DataSetTable-
➤ Figure 7
Producer1 we must first connect to
it from our second WebActionItem.
procedure TWebModule1.WebModule1WebActionItem2Action(Sender: TObject; This is done as shown in Listing 6.
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
begin The DataSetTableProducer must
Response.Content := DataSetTableProducer1.Content; be connected to a DataSource,
end;
which means it’s now also time to
drop a Table (or Query) on the web
➤ Listing 6
module. Note that we don’t need a
connecting DataSource (which is
form in the main form and let it call To define a new action for our web only needed to connect visual
another action. This can be done module, we need to click the web data-aware controls to datasets).
as follows, for example: module Actions property again. In For this to work, the BDE must be
the Editing WebModule1.Actions installed on the Web Server, of
<FORM ACTION="project1.exe/table" dialog, click Add to get a WebAc- course, including the demo data-
METHOD="post"> tionItem2. Now, we need to set the bases and aliases.
Enabled property of the first action For this example, we can drop a
Now, the ACTION doesn’t consist of to False (since we have two WebAc- TTable on the web module, set the
project1.exe anymore, but has a tions and we only want to test the DatabaseName property of the TTa-
special action URL added to it: /ta- latest one) and we can specify the ble to DBDEMOS, the TableName prop-
ble. The reason that this works is PathInfo of the second WebAc- erty to BIOLIFE.DB and set the
that the Web Server is able to parse tionItem, for example as /table DataSet property of TDataSetTable-
a URI (Uniform Resource Identi- (Figure 6). Producer to Table1 so we’re ready
fier) into subparts. For example: Note that I actually had to dis- to run.
able the first WebActionItem be- In order to specify which col-
http://www.drbob42.com/cgi-bin/ cause IntraBob wasn’t able to split umns are to be used in the DataSet-
project1.exe/table?Name=DrBob the command-line into a URL, TableProducer we need to set the
Query String, Logical Path and Active property of the TTable com-
is parsed into the following parts: Physical Path. Hence, the PathInfo ponent to True. Right after that,
inside the WinCGI application was click the Columns property (type
protocol: http never set and the WebActionItem1 THTMLTableColumns) of the DataSet-
host: www.drbob42.com was always fired from IntraBob TableProducer component and we
ScriptName: /cgi-bin/project1.exe (I’m working on supporting that as end up in a new property editor in
PathInfo: /table well). A real Web Server will be able which we can design the output
Query: ?Name=DrBob to provide this information, either the way we want it (Figure 7).
➤ Listing 6
TForm1 = class(TForm)
...
procedure WMSysColorChange(var Msg: TWMSysColorChange);
message wm_SysColorChange;
...
end;
...
procedure TForm1.WMSysColorChange(var Msg: TWMSysColorChange);
begin
inherited;
{ When system colour changes, make sure }
{ the bitmap’s transparent area is the }
{ same colour as the menu background }
SetupMenus(BmpFileName)
end;
➤ Listing 7
Credits.Add(Pointer(aCreditID));
➤ Listing 4
typecasting the LongInt ID number create procedure PaymentCreditSave(iPaymentNo integer,
into a pointer. Now, our list simply iCreditNo integer, iAmount integer)
as
holds a list of integer numbers declare variable NewBalance float;
rather than a list of pointers to begin
select BalanceDue from Credits
allocated memory. where CreditNo = :iCreditNo
into :NewBalance;
NewBalance = NewBalance - :iAmount;
update Credits
OnSetEditText set BalanceDue = :NewBalance
With one exception, I won’t go into where CreditNo = :iCreditNo;
insert into PaymentCredits (PaymentNo, CreditNo,
details about how the data is Amount, BalanceDue)
values (:iPaymentNo, :iCreditNo, :iAmount, :NewBalance);
stored internally in the grids and end
transferred between the two
➤ Listing 5
application. Listing 5 shows how the choices made here. In next
we pull all this together. Notice month’s column I’ll begin to look at
Thirdly, for each credit selected that we actually add the Payment- the new database access compo-
to pay, add a single record into the Allocation records before the Pay- nent hierarchy in Delphi 3 and how
PaymentCredits table, noting the mentCredits record in order to give we may derive custom dataset
payment ID, the credit ID, the total us the opportunity to sum up the classes.
amount of payment applied to that payment total for the credit.
credit and the balance remaining
on the credit. Conclusion Steve Troxell is a Senior Software
Lastly.for each different break- Well, that wraps things up for my Engineer with TurboPower Soft-
down of payment (cash, check, little tour around our credit pay- ware. He can be reached by email
etc) against a single credit, add a ment system. My hope is that at [email protected] or on
record to the PaymentAllocation ta- you’ve picked up a few odds and CompuServe at STroxell.
ble noting the payment ID, the ends for the reasoning of some of
credit ID, the code identifying the
payment method, and the amount
of that portion of the payment.
All of these steps should be
wrapped up within a single trans-
action to ensure everything is
posted consistently.
The first step is handled by the
stored procedure shown in Listing
3. We use an InterBase generator to
produce the unique payment ID
and return that to the application
so we can bind all the other pieces
of information under the same ID.
Steps 2 and 3 involve each credit
that is being paid and are handled
by the stored procedure shown in
Listing 4.
Step 4 is a simple insert into the
PaymentAllocation table and is han-
dled by a straight SQL query in the
Service Start-Up DemoSv1. It will be called from the In the DemoSv1 example it simply
The DemoServiceMain procedure is dispatcher whenever there is a re- goes into a loop and beeps each
passed two parameters. The first is quest to change the status of the time round. Not very exciting!
the number of arguments and the service (eg pause, restart or stop) However, being a service, it will
second is a pointer to an array of or interrogate its current state. stay executing if you log off the ma-
PChars (the arguments). The first The handle returned from Regis- chine, beeping away to itself. While
argument is always the name of the terServiceCtrlHandler will be in its process loop, the service
service being started. This allows a unique for the service. This needs checks two fields: FTerminated, to
single entry point to be common to to be stored away, as it must be see if it should stop processing,
multiple services (more on this used when informing the SCM of and the contents of dwCurrentState
later). Any optional parameters the status of the service. to see if the service has changed its
which follow are the start-up pa- After registering the Handler status to paused.
rameters typed on the Control procedure, the ServiceMain proce- These states are set by the code
Panel Services applet by the user. dure needs to inform the SCM of its in the ServiceHandler. If you re-
This information can be used by current status. This is done via a member, this is called by the SCM
the service in any way you wish. call to SetServiceStatus. This when it needs to query or change
DemoSv1 uses the last parameter to function accepts the service han- the state of the service. If it re-
specify the delay between beeps. dle (returned from RegisterServ- quests that the service be stopped,
In the DemoServiceMain proce- iceCtrlHandler) and a pointer to a paused or resumed the code sim-
dure the first thing that needs to be TServiceStatus structure. Listing 2 ply updates dwCurrentState to indi-
done is to call the RegisterServ- shows the format of this structure cate this. It does not suspend or
iceCtrlHandler function. This and Table 1 shows the meaning of resume the service thread! If you
expects two parameters: a pointer the fields. did this you may pause the service
to the service name and the entry At this point we would start do- in the middle of processing a re-
point of the Handler procedure ing processing specific to our serv- quest. In the examples it is up to
described earlier. This procedure ice (eg waiting on a TCP port, setup the main service to respond to
is called DemoControlHandler in timers for scheduling etc). these requests. For example, if a
➤ Listing 8
➤ Listing 1, concluded
should have any sort of user inter- Once the file is open, GetSigOff-
face. It doesn’t prompt for files, it set is called to find the location of
called is TZipFile.SetZipName. This doesn’t put up dialogs to indicate the tail record within the ZIP file.
calls UnloadDirectory to dispose of errors, it is completely faceless. The tail can be identified because
any previous directory context The user interface is the sole re- it contains a special four byte sig-
and then tries to open the file, gen- sponsibility of the calling applica- nature in the first four bytes; more
erating an exception if the file tion. Instead, TZipFile responds to on this in a moment. If no tail can
couldn’t be found. As a philosophi- error conditions by generating ex- be found an exception is raised to
cal aside, let me just say that I don’t ceptions, which can be intercepted indicate that it’s not a valid ZIP file.
believe a low-level ‘file format in- and handled appropriately by the If the tail is found, the complete tail
terface class’ such as TZipFile application itself. record is read into memory and
var
TClassTrap In Use AnObj: TMyObject;
As one example, we can have a ...
if AnObj = nil then
solution to the problem of finding { we know here for sure that AnObj doesn’t point to a TMyObject }
else begin { it’s not nil: let’s assume AnObj points to a TMyObject }
the instantiation order of controls AnObj.Free;
AnObj := nil; { since we plan to test safely against nil later }
created by “foreign” forms (ie end;
where no source code is available).
Recommended Reading
➤ Object-Oriented Software Construction, Bertrand Meyer,
Prentice-Hall, 1988 (French version by InterEditions, Paris,
1990).
➤ Eiffel — The Language, Bertrand Meyer, Prentice-Hall, 1991
(French version by InterEditions, Paris).
➤ Delphi 2 — Programmation Avancée, Dick Lantim, Eyrolles,
1996 (great on Win32’s IPC, the OpenTools API and more).
➤ Delphi 2 Developer’s Guide, Xavier Pacheco and Steve
Teixeira, SAMS, 1996.
➤ The Revolutionary Guide To Delphi 2, various authors, Wrox
Press, 1996.
➤ Secrets of Delphi 2, Ray Lischner, Waite Group Press, 1996
(Valuable insights on the VMT, RTTI, etc and confirms what
we can learn by ourselves from long journeys deep into the
RTL/VCL source, simply a “must have” book!).
➤ Listing 5
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls;
type
TForm1 = class(TForm) Memo1: TMemo;
private
public
end;
var Form1: TForm1;
implementation
uses ObjTraps;
{$R *.DFM}
procedure MemoTrap(const trap: TClassTrap;
const obj: TObject; op: TObjectOperation);
begin
if op = ooCreate then
MessageBox(0, ‘TMemo created’, ‘’, MB_OK)
else
MessageBox(0, ‘TMemo freed’, ‘’, MB_OK);
end;
initialization
MakeTraps([TMemo], MemoTrap);
end.
EVERY YEAR, Borland organ- of the hotel? A speaker later re- The first real business of the day
ise a Conference somewhere in marked “It’s like living in a terrar- was registering for the conference,
the USA, with lots of technical ium, I keep expecting to see a giant which went very smoothly with no
sessions in a variety of tracks, an eye peering through the glass queue (I was almost disappointed
exhibition of third-party tools, roof.” having got so used to queuing for
books and the like, and usually By the time I had booked into the everything). I was given the usual
a bit of fun too. Your Editor is hotel, found my room and re- Borland bag and retired to a quiet
(as usual!) too busy working on moved the travel dust, it was too corner to explore its contents.
the next magazine to go hop- late to register for the conference First there was a name badge to
ping off around the world on and the rest of the evening was hang around your neck, with a
such jollies, so he asked me to spent in a steak house with Mike name label (coloured blue for
report back on my experiences and John together with another UK Delphi) which followed the time-
of this year’s conference in visitor, Mark Smith, who we honoured tradition of being just
Nashville, Tennessee... collected from the bar next door. too small to read without invading
the other person’s personal space.
Next was a small exhibits guide
Making A 256 Colour Bitmap Delphi 3 has rather more palette one of the button OnClick handlers
support built into the VCL and so from the Capture.Dpr project on
➤ RTREG32
The RT Registration Control is a li-
brary unit (DCU for Delphi, other-
wise DLL) containing functions to
protect shareware and other soft-
ware against unauthorised use:
files are unlocked with a unique
registration key. You can save en-
crypted information about users
somewhere in the system and a
count and/or date lock in order to
make an evaluation copy. This
means shareware can be marketed
electronically through the internet
because the same shareware ver-
sion can be turned into a registered
version. Another highlight is a sup-
port for leased/rented software
through linking the registration
key with the next payment date.
➤ ORANET23
This contains two documents put
together by George Pujol as a guide
➤ Some of the options available
to BDE/Oracle connectivity. TCP/IP, and Named Pipes proto-
for the Animated Tray Icon
The ORA7316.DOC file describes cols in the Windows NT version. 16
all the necessary steps for connect- and 32-bit ODBC drivers have also
ing to an Oracle Workgroup Server been successfully tested for the
Version 7.1, 7.2, or 7.3 for NetWare Oracle 7.3 version. All of the the
or Windows NT using the Borland information is current as of July
Database Engine and Oracle 1st, 1997.
SQL*Net version 2.1, 2.2, or 2.3 us-
ing 16-bit drivers. ➤ PGTRAY3X
The ORA7332.DOC file contains The Animated TrayIcon VCL is a
similar information but using 32-bit component you can use in Delphi 1,
drivers. This configuration works 2, and 3 as well as C++ Builder 1 to
for the SPX and TCP/IP protocols in add icons to the Windows 95 or NT
the NetWare version and the SPX, 4 system tray.
➤ Important Note!
Always, but always make a backup
copy of your Delphi 1 or 2 compo-
nent library file before you take the
plunge and install any new compo-
nent into Delphi! Sometimes com-
ponent installation can trash your
component library and you will
then be left with an inoperative
Delphi will have to re-add all your
extra components.
➤ Some of AppBar’s properties, which make it easy to have exactly
➤ Send In Your Code...
the style you want!
If you have some carefully crafted
routines, why not send them in for
➤ Z_PROF ➤ APPBAR11 evaluation by mail or (zipped up)
ZProfiler is a utility component The TAppBar class is a TForm derived by email to our Disk Editor, Mike
that enables the assessment of exe- class for Delphi 3 that lets your Orriss, at [email protected].
cution times of code fragments form to behave like an Application We do consider all submissions for
with a 0.01 microsecond resolu- Desktop Toolbar(appbar short), use on future disks.
tion. It is based on the CPU clock of which is a window that attaches it-
Pentium computers. self to an edge of your screen. The
The source code for the articles in this issue can be downloaded from our
website at www.itecuk.com. The extra bonus files described here are available
on the disk for this issue when you subscribe.
Delph
7
k at
offer
by cach w
around Revie
Dave
Je
w: As
compo well takes
nents th
ing rare to speed up
ync Pr
ly-upd
from Tu is suite of se
rboPow
ofessi
rial co
sl
ated d uggish
ata
onal
ListBo er out mm
for a te unications
Brian
Lo
x e s Have st drive
ListBox ng reveals Powe
➤ Develop better r!
contro the hid
l den dep
th s of th
e hum
ble
INCLU Abo
DED O Mike O ve: with the
applications more
N THIS rr TB
DISK
ARE R MONTH create iss on this m ag compone
power
EGISTR 'S ful Regi onth's disk yo nts from
COMP
ONEN
TS, A
Y EDIT
ING Beatin stry m
anipul u too can
BUILD
ER, M
N SQL
QUER
Dave g The ation to
EYES
OUSE
, PLU
S MO
-CHASI
N G
Y
Je
active well shows
System ols
RE... button h
s to in ow to create
material available
ps
Written by Steve
by Steve Troxell
Service Not Good Enough Combo Woes OnClick handler with a new D elphi incorporates some very
useful database components
make sure you’ve selected Local
Server, enter the path and filename
databases. A database is a
collection of tables; in Paradox
Edited by author,
OnClick
T&ipsTricks
DDE components make use of a
component called DDEMgr, of the un-
documented component type
stays behind the stay-on-top form.
Although the list box part of this
fake combo does have an OnClick shows
tables
That’s
orproblem
latesup
A by scanning
exactly through
Close method
thewith
is, and
what the
accordingly.
tablesfunctions
the array, calling the Open
it usually This method encapsu-
access, providing
that access to any unit
UPDATE and DELETE. These are the
workhorses of SQL and by the end
of this article you’ll be able to
window. If you want to run it again
(and perhaps make small changes
to it), you can retrieve any
ally requires a semi-colon at the
end of each statement, but in
certain tools (such as ISQL) it’s
TDDEMgr, which has a property event handler, it is only used to which
return uses the
floating Table
point unit and
values. Forallowing easy access to effectively use SQL to accomplish a previous SQL statement by clicking optional.
called AppName, used to define the
DDE service. Fortunately, DDEMgr is
declared in the interface section of
the DDEMan unit, so something like:
determine when to hide the
list box.
We can improve the situation by
extending the functionality of this point
the tables.
example,
will of
havescanning
So, there’s
in a Delphi
perform
The
a Visual finalapplication
Basic
troublethrough
DLL tonoreturn
part of Listing 1 shows an example
need for
table.
getting a function
actions on referred
value (hereafter
long table names and your can
a floating
all your tables
to with relative ease.
the Clinic answers Topics have included
wide variety of tasks. We’ll
continue to expand our knowledge
of SQL in the next issue.
All of the examples in this article
the Previous button.
SQL Preliminaries
Before we get started, let’s look at
Third, you can break an SQL
statement across multiple lines by
pressing RETURN anywhere you can
legally place a space in the
listbox’s OnClick event and causing as a float for brevity), as will an use the sample InterBase database a few of the ground rules for work- statement.
DDEMgr.AppName :=
’NewDDEServiceName’;Control Arrays
using Delphi
OnCreate
In Delphi
Click in a new component. Listing
few features
1 shows I miss
how. The
is the ability
TNewDBLookup
Arrays. The following techniquelist
own component
from Visualfor
constructor
to handle
searches throughControl
is until
a simple
its
solution
it finds a
Excel or Microsoft C application.
Basic options
Contributed
Regardless
(CompuServe
256
floats onColour
of by
the NDP
whatMark
are used,100627,422)
Mamone of Newcastle, UK
compiler
Borland prod-
ucts cause functions to return
Bitmaps
(Numeric Data
readers' “How do an introduction to
EMPLOYEE.GDB that ships with
Delphi. You may find it helpful to
connect to this database through
the Windows Interactive SQL
(ISQL) program that ships with
ing with SQL. First, three new
terms: the familiar structures of
file, record, and field are called
table, row, and column in relational
Finally, you can enclose literal
strings with single quotes or
double quotes. We’ll use single
quotes here.
every month.
Now, weTObject);
procedure NewGridClick(Sender: define a procedure to set up the pointers, memory stream and then loads the contents of the
if Assigned(FOldGridClick) then a copy of the EMPLOYEE.GDB file the waters of Client/Server for the first time.
public pointing to the table controls on the FOldGridClick(Self);
form – see the stream into the bitmap. The only clever part is noticing and work with the copy only. Steve is involved in developing a variety of Client/Server systems in
constructor Create(AOwner: TComponent); override; FOnClick := OnClick;
end; procedure TfrmTables.InitialiseTables in Listing 1. that a bitmap resource is the same as a bitmap file, but his work at TurboPower Software, using different server databases, and
if Assigned(FOnClick) then
procedure Register; FOnClick(Self); without a TBitmapFileHeader record at the front. To Using ISQL we are looking forward to learning from his experience over the months.
implementation end; allow the stream read to work, we need to put a fake To use Windows ISQL, start the As well as SQL – an essential part of the Client/Server developer’s skill
➤ Listing 1 TComponent);
constructor TNewDBLookup.Create(AOwner: procedure Register;
var Loop: Word;
TBitmapFileHeader record at the front of the stream. ISQL program from the Delphi set – Steve plans to cover a variety of other topics and also provide lots
begin
begin
const
RegisterComponents(’Samples’, [TNewDBLookup]); program group. From the File of hints and helps along the way. If there are things which you need
inherited Create(AOwner); end;
MAX_TABLES = do
for Loop := 0 to Pred(ComponentCount) 4; {Number of Tables} menu, select Connect to Database. some help with, why not drop us a line and let us know!
end.
{Constants for the array of tables} Contributed by Brian Long (CompuServe 76004,3437) In the Database Connect dialog box,
TABLE_BACKUP = 1;
TABLE_RECOVERY = 2;
TABLE_REUSE = 3;
56 TABLE_SUMMARY = 4; The Delphi Magazine Issue 6 12 The Delphi Magazine Issue 3
type ➤ Listing 2
{for handling tables without having controls
on-screen}
TableData = Array[1..MAX_TABLES] of TTable; type
var TResBitmap = class(TBitmap)
Data : TableData; public
procedure TfrmTables.InitialiseTables; constructor Create(ID: PChar);
var end;
ptr : Integer; constructor TResBitmap.Create(ID: PChar);
begin var
{Setup the Table Pointers ready for use} HResInfo: THandle;
for ptr := 1 to MAX_TABLES do begin
{Point to the component on the form}
case ptr of
TABLE_BACKUP : Data[ptr] := tblBACKUP;
BMF: TBitmapFileHeader;
MemHandle: THandle;
Stream: TMemoryStream;
ResPtr: PByte;
Under Construction:
TABLE_RECOVERY : Data[ptr] := tblRECOVERY;
Property Editors
ResSize: Longint;
TABLE_REUSE : Data[ptr] := tblREUSE;
Under Construction
TABLE_SUMMARY : Data[ptr] := tblSUMMARY; begin
end; inherited Create;
end; BMF.bfType := $4D42;
end; HResInfo := FindResource(HInstance, ID, RT_Bitmap); by Bob Swart
{ ...add code to open/close tables as required... } ResSize := SizeofResource(HInstance, HResInfo);
MemHandle := LoadResource(HInstance, HResInfo);
{ scanning through a table... } ResPtr := LockResource(MemHandle);
D elphi offers a Tools API, There’s actually much more to property editors already exist in
Internet Explorer
button
own home-grown terminology for make this control respond as much colour one. Similarly, when a but-
the way in which Microsofts re- like the Microsoft equivalent as ton is disabled, the glyph is drawn
greyed-out
in a three-dimensional,
manner.
back to
immediate
novice users,
visual feed-
showing
bar bands containing a TPanel com-
ponent. Inside this panel are four of
caption only, or you can just have
will respond to mouse clicks. As with Microsofts buttons, glyph, but it doesnt look terribly
TExplorerButton
convert VCL components into in one of four different ways: active The Explorer button supports a
ActiveX controls, and because of (when the mouse is over the but- number of different event types,
Visual Basic 5.0 CCE (Control Crea- idle state), disabled, or pressed event handler in the normal Delphi
you can create custom ActiveX clicked over the button). In Figure such as OnClick and OnMouseMove,
controls more easily than ever 1, the fourth button is pressed there are a couple of custom events
OnMouseEnter On-
new controls over the next twelve menu. MouseExit) which allow you to do
fore critical to make your new con- button, it automatically toggles mouse starts moving over a button
trol as easy to use and intuitive as from the inactive to active state. or leaves a button. These events
long way towards achieving this. At raised border around the button when the button flips from its inac-
make your new controls consistent (Borlands term for small bitmaps By utilising these events, you might
with industry leaders such as displayed inside button controls) (for example) change some aspect
FA
XN
Yes! Please enter my subscription to The Delphi Magazine OW
Please complete and fax or post to: The Delphi Magazine, 9a London Road, BROMLEY !
Kent BR1 1BY. Tel: +44 (0)181 249 0354. Fax: +44 (0)181 249 0376. Email: [email protected]
Name (Mr/Ms)
Position Company
Address
Town
County/State Post/Zip code Country
Telephone Fax Email
ddg
Subscription: 12 ISSUES INCLUDING FREE COMPANION DISKS, please tick one:
United Kingdom £75 Europe £80 USA/Canada £90 Rest of the World £95
Please tick here if you do NOT wish to receive information on relevant products and services from other companies
I enclose a check for US$140 payable to ‘The Delphi Magazine (USA)’ Note: please send
Sorry, we can’t accept payment by bank transfer payment only in
US dollars
We will start your subscription with the next issue
Please tick here if you do not wish to receive information on relevant products and services from other companies.
*Note: for subscriptions to other countries please contact the publishers direct:
iTec, 9a London Road, BROMLEY, Kent BR1 1BY, United Kingdom
Tel: +44 (0)181 249 0354 Fax: +44 (0)181 249 0376 Email: [email protected]