home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 32 Periodic
/
32-Periodic.zip
/
edm38.zip
/
EDMI3-8.INF
(
.txt
)
Wrap
OS/2 Help File
|
1995-09-10
|
308KB
|
4,133 lines
ΓòÉΓòÉΓòÉ 1. Sept 1995 Title Page ΓòÉΓòÉΓòÉ
The Electronic Developer's Magazine for OS/2
Portions copyright (c) by IQPac Inc.
Volume 3, issue 8
The New York Times Fiasco
If you haven't been in this dimension in the past month, you probably don't
know about the two articles printed by the New York Times and the ensuing
fallout. In a nutshell, the Times printed one article about the annual meeting
that IBM has with market analysts in which they severely misinterpreted Lou
Gerstner's statements. While IBM claims that he was simply reiterating the
strategy that IBM has had for the past five or so years (although with a
stronger emphasis), the `Times inferred that he was conceding the desktop to
Microsoft.
The following week, Peter Lewis - in his Science Times column - quoted David
Barnes as saying that he'll run Windows 95 at home instead of OS/2. It hurt so
much to read that one week after the first article that I and many others
immediately started shouting conspiracy and went witch- hunting. In
retrospect, it really shouldn't matter what David Barnes runs at home; he still
is the best OS/2 spokesman IBM has. However, I can't help but feel like I just
found out that Michael Jordan really wears ProKeds.
For more information, there are many places on the Web that you can visit; one
of these is http://www.inetnw.com/~os2man. Enjoy.
More About the Web Site
If you haven't dropped by the EDM/2 Web site
(http://os2man.netsysdev.telerate.com), you are missing some interesting
things. The Gotcha section is growing very slowly, but growing nonetheless.
Additionally, a new section has been added which allows you to do conferencing,
a la Netnews. This section, powered by the FORAWEB software that I wrote in
REXX for GoServe, has the advantages that it is easy to setup, doesn't require
a newsfeed to run, and is relatively instantaneous. The main disadvantage,
however, is that each server is self-contained; there is no shadowing
capability (although this is definitely something that needs looking into).
To read the articles posted, you simply need a Web browser. (Lynx will work
too if you use http://os2man.netsysdev.telerate.com/FLIST.CMD?FORA as the URL.)
To submit an article to a conference, your Web browser must have HTML forms
capability.
One of the existing conferences is for the discussion of EDM/2. Please drop by
and contribute your thoughts, comments, etc.!
Transparent Windows and Such
This month, I vowed to write the article on the transparency that I have
claimed to achieved. Before the transparency must come the samples, though. I
had no trouble getting the desired effect, but when I went to write another
sample to demonstrate how PM `normally' operates, two (bad) things happened:
1. The `non-transparent' application had the sample look.
2. When I removed the CS_SIZEREDRAW class style from the parent of the
window (the client), the window disappeared.
The second came about from my attempt to coerce the second sample to not look
like the first. I think that, if I painted the client window in something
other than a solid color, it would make a difference. However, more
investigation is needed before I can write about this topic and I offer my
apologies for this. In the meantime, I would guess that avoiding any calls to
WinFillRect() or GpiErase() may be used to reach the same goal.
EDM/2 A La Postscript
I fully intend, as I sit here to type in this section, to produce a Postscript
version of this issue. Whether or not this becomes a reality will be
discovered shortly. This will be a bit more time-consuming because normally I
send to Carsten (my proofreader) an .INF file and make the corrections
indicated by him to the .IPF source directly. However, I must now send him a
.RTF file and hope that it shows up properly on his side. Additionally, he
will no longer be able to check things such as the icons and such. The result
of all of this is that we might be a bit shaky in the quality of the issues
while we adjust our procedures. Please bear with us.
"How Will I Read the Issues?"
When the magazine eventually switches to Postscript as the file format,
instead of .INF, how will you read it? Some time ago, IQPac reached an
agreement with Magus Software to allow IQPac to distribute a customized
version of their PageTurner software (sans documentation, unfortunately),
which is a Postscript viewer. This version will only allow you to view
Postscript files that I produce using an encrypted password mechanism that is
imbedded in the file. The problem has always been that of distribution; since
IQPac is currently a no-income company, I am trying to keep my costs down. The
ideal distribution mechanism is through diskette mailers, but the miracle of
the Web makes that more expensive than necessary.
The idea `du jour' is that those who are Web capable will be able to fill out
an HTML form on the EDM/2 site. Completion of the form will assign you a
userid and password - valid for that day only - which you can use to obtain
access to a protected section of the site. There you will be able to download
the software. For those of you who are not Web capable, I will provide a form
for you to fill out and send to me along with a money order (drawable on US
funds) to cover shipping costs.
I apologize for my insistence that you fill out the form, but this information
is vital to obtaining (somewhat) accurate statistics on the number of readers
that EDM/2 has. With this information, a press kit can be constructed and
delivered to ISVs and advertising space sold. This income will be used to
offer some amount of compensation to the future contributors of articles,
columns, and (of course) me. It doesn't take a rocket-science degree to
figure this out on your own, but I am revealing it to you in order to keep a
clean conscience. We have all given much time and effort to insure a good
magazine filled with good information; please support us in this by
cooperating instead of trying to circumvent the measures I will have
established to achieve this goal. Please keep in mind that EDM/2 will still
be distributed free-of-charge to the readers.
I am interested in any thoughts you have on this matter - feel free to send
them to os2man@panix.com.
OOPS Corner Will Be Absent
Because Gordon has devoted a lot of time to doing the excellent reviews on the
C++ compilers, he has not had enough time to write this month's OOPS Corner.
We think that it is a fair trade.
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 2. Copyright Notice ΓòÉΓòÉΓòÉ
Copyright Notice
EDM/2 is published by IQPac Inc. IQPac Inc. can be reached via U.S. Mail at
the following address:
IQPac Inc.
7 East Broadway, Box 804
New York, NY 10038
U.S.A.
Editor-in-chief Larry Salomon Jr.
Associate editor Carsten Whimster
Contributing editor Gordon Zeglinski
CEO/President Larry Salomon Jr.
All material is copyrighted by its original author. No part of this magazine
may be reproduced without permission from the original author.
This publication may be freely distributed in electronic form provided that
all parts are present in their original unmodified form. A reasonable fee may
be charged for the physical act of distribution; no fee may be charged for the
publication itself.
Neither IQPac Inc. nor this publication are affiliated with International
Business Machines Corporation.
OS/2 is a registered trademark of International Business Machines Corporation.
Other trademarks are property of their respective owners. Any mention of a
product in this publication does not constitute an endorsement or affiliation
unless specifically stated in the text.
The OS/2 Accredited Logo is a trademark of International Business Machines
Corporation and is used by IQPac Inc. under license. This On-line
Publication is independently produced by IQPac Inc. and IBM is not
responsible in any way for its contents.
IQPac Inc. is an accredited member of the IBM Independent Vendor League.
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 3. Announcements ΓòÉΓòÉΓòÉ
Announcements
Rock Solid Software Announces IOPRO/VX
Rock Solid Software announces IOPRO/VX, a toolkit designed to support the rapid
development of data acquisition, analysis, and control applications under OS/2.
Thank you for allowing us to describe our line of technical productivity tools
for the OS/2 environment. Our mission is to support our customers in creating
in a wide variety of data acquisition, data analysis, process monitoring and
control, and data visualization applications. IOPRO/VX is simply the first
product in our plan to get the most out of this superior operating system.
Coming soon:
Notebook data acquisition (PCMCIA).
Imaging and image analysis.
DSP coprocessing.
Embedded applications.
Simply put, we are convinced OS/2 is the best operating system in the world
for affordable technical computing, data acquisition and analysis, and process
monitoring and control. We are committed to realizing that potential.
The following information will describe our initial offering, IOPRO/VX. This
toolset allows VX-Rexx developers to rapidly build a software program,
complete with graphical user interface, which can control the acquisition,
processing, display, and saving of data. This data can come from a variety of
sources such as disk files or local A/D- D/A and digital I/O adapter cards.
Extensions to the basic package allow accessing data from sources via network
connection, or from instrumentation accessed via serial or IEEE-488
interfaces.
The IOPRO/VX basic pak consists of the following:
The basic pak includes one driver for supported plug in adapter cards. While
we are trying to target the most capable and/or popular cards for driver
development, we are very willing to discuss how to expedite development for
your particular application. Please call for driver availability and/or to
discuss development schedules.
The main programming toolset comprising the IOPRO/VX package consists of a set
of objects which are added to the VX-Rexx toolbar. These objects are placed
into the application being developed using standard VX-Rexx techniques. These
objects provide the following functionality:
1. Disk Input: import data (in a variety of formats) from disk files.
2. Disk Output: export data: (again, a choice of formats) to disk or to
another program on the host machine. This is also used to move data to
the Integrated Data Display utility (see below) for realtime viewing.
3. Processing: this class of objects allows analysis or transform
operations on data. There are two basic types. The first simply allows
the developer to write a series of REXX statements which can operate on
the data. The second type acts as a link to some function residing in an
external function (C,C++,etc.) library.
4. I/O Channel Interface: this class presents a standard interface to
analog to digital converters, digital inputs, digital outputs, counters,
etc. The basic pak supports data originating locally, as from an I/O
adapter card plugged into the host machine. Optional extensions allow
access to data originating on other machines and accessed via a network,
or from instrumentation via RS-232 or IEEE-488.
5. Data Display Utility: this facility is used to display graphical plots
of data exported from the IOPRO/VX environment. It is implemented as a
process which runs independent from the VX-Rexx session. The DDU has
it's own set of PM based controls which are used to control plotting
behavior such as graph scaling, axis labels, etc.
6. System Control and Sequencing: this object acts as the 'main control
loop' found in so many applications of this type. It is basically a set
of event handling routines, where upon receipt of an event 'x', a user
definable set of REXX statements is executed. These statements can
invoke methods on the other objects to cause I/O channels to be read or
written, processing to occur on some buffer of data, etc. The SCS can
react to events from user activity, timer input, receipt of data from one
of the remote connections, or from an interrupt generated by a local I/O
adapter card.
This product is about to enter beta testing and should be available by Fall
95.
Look for our survey in the following locations:
Internet: comp.os.os2.programmer.tools
Compuserve: OS2USER OPEN FORUM
Please direct inquiries to the following:
Rock Solid Software
8460 Plank Rd.
Montville OH 44064
(216)-390-0590
76016.370@compuserve.com
____________________________________________________________
Secant Technologies Announces ObjectPM Control Pack
Additional info: http://www.secant.com
Questions to: info@secant.com
For more information: John Pompeii (216) 595-3830
CLEVELAND, OH -- Secant Technologies, Inc. announces the release of the
ObjectPM Control Pack library for OS/2. This package offers over a dozen
control types that extend the set of controls supplied by OS/2 Presentation
Manager. It is also the first control package to support the PMCX control
window specification allowing these controls to be used with products such as
the IBM Universal Resource Editor and Prominare Designer. The PMCX
specification is the latest control extension similar in concept to the VBX
specification in Windows.
"These controls will be a welcome addition to any OS/2 programmer's tool set"
according to senior architect Michael Flis. "Many badly needed features such
as multi-column list- boxes and edit masks are missing from OS/2. This
product fills those gaps."
This list of controls included with the package include:
Spreadsheet - A "grid" control allowing data to be presented in rows and
columns. The rows and columns can be sized hidden, inserted and deleted.
Cells can directly edited, and support character formatting.
Cellbox - A new list-box that adds multi-columns, images, "hot buttons",
and in-line character formatting.
Data Field - An edit control extension that supports edit masks, and a
host of data types.
RTF Viewer - Displays and prints Rich-Text-Format (RTF) documents. This
is a great tool to add prining capabilities to your apps!
Calendars - Displays a calendar, one month at a time, allowing a user to
click on a day to select it or flip between months and years.
DateComboBox - Combines a combo-box with the calendar control which
implements a visual drop-down date field.
CellComboBox - Combines a combo-box with the cellbox to add extended
combo features such as multi-selects and list-box columns.
Splitbars - Horizontal and vertical split bar controls for dragging.
ControlList - Contains a list of other controls that can be scrolled up
and down. This allows a large number of controls to fit in an area than
otherwise would be possible.
Gauges - A set of various indicators such as dials, thermometers, and LED
bars.
All controls in ObjectPM Control Pack conform to the PMCX architecture. This
allows the components to be used by virtually any OS/2 programming tool. To
support the various C++ programming environments, the Control Pack adds a set
of class libraries that integrate the controls natively into the OpenClass
(IBM), ObjectWindows (Borland), and ObjectPM (Secant) application framework
environments.
The ObjectPM Control Pack is available in binary form at an introductory price
of $99. Source code is also available. Programs that use the controls can be
distributed along with the run-time libraries without royalties or additional
purchases. To order, contact Secant Technologies, 23811 Chagrin Blvd. Suite
344, Beachwood, OH, (216) 595-3830. Additional information and samples are
available from the Secant World Wide Web home page at http://www.secant.com,
or email at info@secant.com.
ObjectPM is a trademark of Secant Technologies, Inc. OS/2 and Presentation
Manager are registered trademarks of International Business Machines
Corporation Microsoft Windows is a registered trademark of Microsoft
Corporation
____________________________________________________________
REXX/SQL - A REXX interface to SQL databases
General
REXX/SQL provides a simple interface for REXX programs to access SQL databases
through a number of external functions. REXX/SQL is intended to provide a
consistant interface to all SQL databases.
REXX/SQL is distributed under the GNU General Public License. See the file
COPYING for more details. The anon ftp site for REXX/SQL is:
ftp.qut.edu.au/src/REXXSQL.
The source code for each database interface code is in a separate archive
file. The general format of the archive files is: rxsql???nn.ext
where:
??? is the TLA for the database port, nn is the version number and ext is the
archive file type. e.g. the REXX/SQL Oracle port for Version 1.2 in
compressed tar file format is rxsqlora12.tar.Z.
Documentation, in Postscript and HTML, is available in rxsqldocnn.ext and
sample programs are in rxsqlsamnn.ext.
The documentation is intended as both a user's guide and a reference guide for
implementors of REXX/SQL on other database and operating system platforms.
All text files are stored in Unix text file format. ie LF only.
Current Release
The current release of REXX/SQL is 1.2. This version contains ports of
REXX/SQL for Oracle (ora) and mSQL (min).
Files in Release
The following packages are available in Info-Zip 2.0 format:
rxsqldoc12.zip - Documentation - Postscript and HTML
rxsqlsam12.zip - Sample REXX/SQL programs
rxsqlora12.zip - Oracle source and OS/2 EXE and DLL
rxsqlmin12.zip - mSQL source
and in compressed tar files
rxsqldoc12.tar.Z - Documentation - Postscript and HTML
rxsqlsam12.tar.Z - Sample REXX/SQL programs
rxsqlora12.tar.Z - Oracle source and OS/2 EXE and DLL
rxsqlmin12.tar.Z - mSQL source
Please forward any comments, suggestions, enhancements or other
implementations to be included in the official distribution.
The above files are currently in the /incoming directory and will be moved to
/src/REXXSQL shortly.
____________________________________________________________
Functional Software Announces LXOPT version 1.1
14 August 1995
Functional Software announces V1.1 of the code optimiser for 32-bit OS/2
executables and dynamic link libraries.
LXOPT (Linear eXecutable OPTimiser) is a unique OS/2 development tool, a code
optimiser which improves the layout of 32 bit OS/2 applications by direct
manipulation of EXE and DLL files. Processor instruction sequences are
reorganised to minimise page faults and ensure maximum CPU cache efficiency.
LXOPT V1.1 introduces:
Improved arrangement algorithms
CPU optimisations
OS/2 WARP compressed page (exepack:2) support
Support for CSet++ V2.x C++ template users
Improved support for Borland and Watcom C++ users
Recording file size reductions of > 80%.
In addition LXOPT is now supplied with program utilities to time application
execution, simulate low memory conditions, compress V2.x executables to WARP
(exepack:2) format and decompress exepack:2 executables for use with OS/2
V2.x.
LXOPT V1.1 has a RRP of USD 195, additional users may be added to an existing
license for USD 95. There are no restrictions or royalties on the
distribution of LXOPT V1.1 processed applications. Registered users receive
free maintenance releases and priority technical support.
A demonstration version of LXOPT V1.1 is available as LXOPT111.ZIP on
Compuserve (OS2DF1-Development Tools). This file is also being distributed to
various ftp sites and is now in the incoming directories on ftp.cdrom.com and
hobbes.nmsu.edu. The demo will be added to other sites during the next few
days.
The retail version of LXOPT is available from:
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
ΓöéCountry ΓöéDistributoΓöéVoice ΓöéFax Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéGermany ΓöéKessler Γöé+49 551 50762-0 Γöé+49 551 50762-22 Γöé
Γöé ΓöéSoftware Γöé Γöé Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéUK ΓöéGrey Γöé+44 1364 653499 Γöé+44 1364 653071 Γöé
Γöé ΓöéMatter Γöé Γöé Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé ΓöéOneStop Γöé+44 117 985 3370 Γöé+44 117 985 3373 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé ΓöéOS/2 Soln.Γöé+44 1285 641175 Γöé+44 1285 641661 Γöé
Γöé ΓöéCntr. Γöé Γöé Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéUSA ΓöéBMT Micro Γöé+1 800 414 4268 Γöé+1 910 350 2937 Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
LXOPT V1.0 Users
All registered LXOPT 1.0 users will be upgraded to V1.1 free of charge. Please
allow up to 14 days for delivery. If you have purchased but not registered
your copy of V1.0 with Functional Software please do so as soon as possible.
____________________________________________________________
Developer Connection Volume 8 Is Available
August 11, 1995
Today the Developer Connection Volume 8, 2nd Year Anniversary Issue has been
completed, and sent to Manufacturing. This means that our U.S. Developer
Connection Subscribers should start receiving it in the next couple weeks, and
our International customers soon after.
The Power of the Future Delivered to Your Door
The Developer Connection for OS/2 - continuing proof of IBM's commitment to
OS/2 developers - can greatly increase your productivity by providing you with
the latest tools, pre-release software, product demos, and information you
need on today's most convenient medium--a CD. And, because we live in
changing times, an annual subscription to the Developer Connection for OS/2
keeps your tools and information from becoming obsolete. Each year you'll
receive 4 volumes including CDs and The Developer Connection News, each packed
with the tools and information you need for your OS/2 development efforts.
When accessed from your CD drive, The Developer Connection for OS/2 becomes a
part of your Workplace Shell environment. Click on The Developer Connection
icon, and all the wealth of the Developer Connection for OS/2 is instantly
attainable. Use the powerful Developer Connection Browser to locate any piece
of information. And because the intuitive graphical user interface is a part
of the Workplace Shell environment, each task is familiar and simple. Try the
products, install them, or simply retrieve product information. There is also
an available option for creating diskettes for many of the products on the CD.
The Developer Connection program will continue to grow to support emerging
technologies. Subscribers also receive The Developer Connection for LAN
Systems, a cross-platform offering that supports the installation of products
and information to OS/2, Windows, DOS, and AIX workstations. It provides a
programming environment for client/server and distributed computing
application development. Device driver developers can now subscribe to The
IBM Developer Connection Device Driver Kit for OS/2 (Developer Connection
DDK). The Developer Connection DDK is an annual membership program, that
enables rapid development of device drivers for your personal computer
hardware using the 32-bit OS/2 operating platform. Members receive the
updated information, test tools and utilities, and many complete device driver
sources.
Put The Developer Connection for OS/2 to work for you...now
Receive product level versions of OS/2 developer toolkits (for OS/2 2.1,
OS/2 Warp Version 3, OS/2 SMP, Pen for OS/2, Mustimedia Presentation
Manager, LAN Systems)
Receive new versions of operating system technologies as soon as they are
developed.
Try new OS/2 products before you buy them.
Use the sample source code to start on the path of more productive
programming.
Access pre-release versions of IBM's 32-bit tools to prepare for
tomorrow's technology.
Receive updates to SMART, One Up Corporation's powerful tool that helps
migrate your 16-Bit and 32-Bit Windows code as well as 16-Bit OS/2 code
to 32-Bit OS/2 code.
Read The Developer Connection News for timely OS/2 information.
Access electronic support through the Internet, OS/2 BBS, and CompuServe.
In the US, you can subscribe to The Developer Connection for OS/2 by calling
1-800-6-DEVCON (1-800-633-8266), 303-330- 7655(fax).
In Canada, call 1-800-561-5293. 1-905-821-1187 (fax)
In Brazil, call 0800-111205(phone), (011)886-3222(fax)
In Mexico, call:
Toll Free: 91-800-00316
Phone: (525)- 627-1111 in Mexico City.
In other countries, please refer to the table below:
Country Telephone
Argentina 313-0014
Bolivia 35-1840
Chile 633-4400
Colombia 257-0111
Costa Rica 223-6222
Ecuador 56-5100
El Salvador 98-5011
Guatemala 31-5859
Honduras 32-2319
Panama 639-977
Paraguay 444-094
Peru 36-6345
Dom.Rep. 566-5161
Uruguay 923-617
Venezuela 908-8901
To order in Europe, call IBM ISMS Direct Services in Denmark. Please ensure
that you dial the international access code applicable to your country before
dialing the appropriate phone number. Operators speaking the following
languages are available. Note that 45 is the country code for Denmark.
TeleFax: Denmark=45 +48142207
In Asia/Pacific, call: 61-2-354-7684(phone), 61-2-354- 7766(fax). Note that
61 is the country code for Australia.
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
ΓöéLanguage ΓöéDial code ΓöéNumber Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéDutch ΓöéDenmark=45 Γöé+48101400 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéEnglish ΓöéDenmark=45 Γöé+48101500 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéFrench ΓöéDenmark=45 Γöé+48101200 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéGerman ΓöéDenmark=45 Γöé+48101000 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéItalian ΓöéDenmark=45 Γöé+48101600 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéSpanish ΓöéDenmark=45 Γöé+48101100 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéDanish ΓöéDenmark=45 Γöé+48101300 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéSweden ΓöéDenmark=45 Γöé+48101150 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéNorway ΓöéDenmark=45 Γöé+48101250 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéFinnish ΓöéDenmark=45 Γöé+48101650 Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
Prices vary by country. In the US, an Annual Subscription is $199.00, and an
Additional License is $75.00. These prices do not include shipping and
handling.
____________________________________________________________
DB Technologies' VX-CALENDAR for VX-REXX
August 14, 1995
DB Technologies, Inc. released a calendar object add-on for WATCOM VX-REXX.
The "VX-CALENDAR" provides developers with an easy-to-use, intuitive means of
viewing date information. Dates can be moved between the calendar and other
objects with drag-and-drop operations. It also includes support for different
colors, fonts, leap years, date navigation through properties and methods, and
selection of individual dates.
The VX-CALENDAR object was written in the C-Language, is SOM- based, and is
available from the VX-REXX object toolbar. The package includes
non-exclusive, royalty-free distribution rights. It is priced at $99.00.
Contact DB Technologies, Inc.
Sales: 800-830-8703
Tech Support: 941-378-3760
CompuServe: 72123,3661
Internet: dbtech@ibm.net
____________________________________________________________
IBM Announces Commonpoint For OS/2 Beta Program
Advanced object-oriented frameworks from Taligent speed application
development
OBJECT WORLD, SAN FRANCISCO, August 15, 1995...Now OS/2* developers have an
important resource for designing, building, and deploying collaborative
applications: IBM CommonPoint** for OS/2*. This powerful new application
system, developed by Taligent, Inc., provides the structural foundation for
developers to use object-oriented technology to create and customize
distributed business applications, such as client/server, customer support,
multimedia, and executive information systems.
At Object World West '95, IBM announced a "JumpStart" beta program for OS/2
developers, which will broaden the reach and accelerate the adoption of
cutting-edge CommonPoint technology. CommonPoint is a rich set of
approximately 100 object-oriented frameworks designed to increase programmer
productivity through the reuse of application code and design. CommonPoint's
application and system service frameworks, for example, can speed the
development and integration of facilities for data translation, data access,
collaboration, and other business needs.
Included in the IBM "JumpStart" program are the CommonPoint Application
Development Toolkit for OS/2, a comprehensive set of productivity and resource
tools that enable developers to build portable CommonPoint applications; the
CommonPoint Application System for OS/2, which enables the deployment of
robust CommonPoint applications on the OS/2 platform; and C Set++ for OS/2*,
Version 3.0, a fully integrated development environment. IBM CommonPoint for
OS/2 is based on the full-function CommonPoint 1.0 reference release, which
was announced by Taligent earlier this year.
IBM also announced that it has begun delivering IBM CommonPoint on AIX*
Version 4, which supports development of portable applications for the
leading-edge IBM RISC System/6000 (RS/6000)* platform.
The CommonPoint for OS/2 announcement expands an extensive portfolio of IBM
object-oriented offerings for the enterprise. IBM's object technology
solutions are suited to a variety of skill levels and application types,
allowing developers to select the most suitable point of entry into object
technology based on their experience, existing systems and tools, and the
needs of their customers. Advanced object-oriented developers, for example,
will find CommonPoint useful in developing new C++ applications that are easy
to prototype, customize, and maintain.
"We are excited about starting the early support program for OS/2 shortly
after delivering this advanced technology on AIX," said John Slitz, vice
president, Object Technologies Marketing, IBM. "IBM has been at the forefront
of helping customers apply object technology to solve business problems.
Today's announcement expands this initiative through service and support for
the early adoption of CommonPoint's superior object functionality across
multiple platforms."
IBM CommonPoint for OS/2 "JumpStart" Program
Beta code of the CommonPoint Application System for OS/2 and the CommonPoint
Application Development Toolkit for OS/2 will be delivered to corporate
developers and independent software vendors participating in the "JumpStart"
program, beginning in September 1995. Product availability is targeted for
year-end 1995.
Comprehensive technical support, education, and consulting services are
available to help "JumpStart" customers master developing applications with
CommonPoint.
"IBM now offers cross-platform object technology solutions for everybody, from
the neophyte just starting to use class libraries to the experienced object
developer who can move up to frameworks with CommonPoint," said Adrian Bowles,
managing director, Atelier Research. "This commitment to object technology --
backed up with real products -- positions IBM as a software development
leader."
During a separate announcement today, Taligent announced it plans to market
IBM's CommonPoint for AIX with Taligent services and education under the name
CommonPoint ProjectPak -- an integrated set of products and services for
corporate developers building their first CommonPoint application.
For additional information on the "JumpStart" program, contact
objtech@vnet.ibm.com via the Internet or access IBM's home page on the World
Wide Web at http://www.ibm.com, the IBM software page at
http://www.software.ibm.com, or the IBM object technologies page at
http://www.software.ibm.com/objects/.
The IBM CommonPoint application system is based on Taligent Inc.'s CommonPoint
application system built using advanced object-oriented frameworks. Taligent
is an independent software company jointly owned by Apple Computer, Inc.,
Hewlett-Packard Co., and IBM.
IBM, the world's largest software provider, creates, develops and manufactures
the industry's most advanced information technologies, including computer
systems, software, networking systems, storage devices and microelectronics.
IBM's Software Solutions Division, which has the object technology mission
within IBM, provides data management, application development and workgroup
solutions for mission-critical applications on PCs, workstations, LANs and
host systems.
* Indicates trademark or registered trademark of International Business
Machines Corporation.
** Products or companies mentioned are trademarks or registered trademarks of
their respective holder.
____________________________________________________________
TWAIN SDK and DDK For OS/2
Twain, an industry standard specification for any Twain enabled application to
use any Twain supported scanner was acknowleged by IBM as an important
workstation standard at the recent May 1995 New Orleans Technical Interchange.
A 32 bit, fully Twain compliant implementation is now available for OS/2
through Solution Technology, Inc.
Twain allows any application to use any supported imaging device (camera,
scanner, etc). A special advantage of Twain for OS/2 is its support for
almost any resolution image in simple black and white up through 24 bit color
without image size restrictions.
Another advantage of STI's multi-threaded OS/2 implementations of Twain
scanner drivers are their ability to scan documents at the full 35-45 pages
per minute speed of popular mid range document imaging scanners. Future
versions should push the speed even higher.
Attached you will find information on Twain for OS/2, Twain for OS/2 SDK and
the Twain for OS/2 DDK. Our two Twain enabled retail applications, Applause
and ReView, are available through distribution. All products are currently
available from stock.
The SDK will allow you to write the interface between your application and the
TWAIN.DLL for OS/2. The SDK comes with all the required and optional DLL's,
samples, and one scanner driver of your choice (normally Hewlett-Packard).
TWAIN enabling an existing imaging application should take less than a day and
and only about two pages of C code. The cost for the SDK is $695.00 USD.
The DDK allows a scanner manufacturer or third party developer to create fully
reentrant, multitasking, multi- threaded Twain for OS/2 scanner drivers. The
DDK contains carefully written and compilable base source code to which the
DDK user writes only the specific interface code to his actual hardware
device. The DDK, priced at $4,995.00 USD, comes with a full years telephone
support directly into Solution Technology's TWAIN engineering staff.
The optional annual software maintenance includes extended telephone support
and kit updates for both the SDK and DDK are available at $105 USD/year (SDK)
and $750 USD/year (DDK). Each kit has a distribution license for the
TWAIN.DLL. Distribution licenses are available for the TWAININT.DLL,
individual scanner drivers, or scanner driver packs at attractive rates.
TWAIN for OS/2 Scanner Drivers are being continually added to our inventory
(see attached current scanner support list) and may be purchased individually
or in packages of multiple scanner drivers. Integrators and Developers can
take advantage of our "Create-a-pak" licensing agreement to "roll- their-own"
driver packages without incurring the costs of distributing scanner drivers
they don't need. Run-time licenses are based on volume and the type of
scanner drivers required.
Please feel free to call if there are any questions.
TWAIN for OS/2 SDK
The Twain for OS/2 SDK is a developer's kit for TWAIN enabling any OS/2
imagingapplication. Our Twain package allows images to be efficiently
captured in bi-level, gray scale, pallet color, or full 24 bit color without
restrictionson image size. In addition, Twain for OS/2 production scanners
easily achieve scanning at or near their rated full speeds. Compliance with
the TWAIN standard ensures that any OS/2 Twain enabled application will
operate with anyOS/2 Twain enabled scanner to acquire images.
SDK Features:
Full 32-bit multithreaded, multiprocess implementation
Fully Twain Release 1.5 compliant
Requires less than one page of user C code in existing imaging
applications for Twain enablement
OS/2 compliant applications will run with any OS/2 Twain compliant
scanner or imaging device
SDK Extended Support and SDK maintenance options available
Includes distribution license for TWAIN.DLL
Scanner driver runtime licenses available individually or in packages of
multiple devices
Nominal licensing fee to distribute the TWAININT.DLL (fast Twain enabler
DLL)
Each SDK Includes:
TWAININT.DLL - Interface DLL to Twain Source Manager
TWAIN.DLL - Twain Source Manager DLL
One OS/2 Twain binary scanner driver of your choice (Hewlett-Packard SCSI
driver default)
OS/2 SDK Supplement to Twain Release 1.5 manual
Sample OS/2 SDK source code for simple Twain enabled viewer
Requires:
OS/2 2.1, 2.11, Warp, or Warp Connect
OS/2 Compatible supported scanner devices
CSET/2 or CSET/2++ or equivalent tools
STI Supported Scanners:
Hewlett-Packard IIP, IIC, IICX, 3P, 3C, 3CX
Logitech Scanman 256
Bell & Howell 3338
Epson 1200C, GT-9000 Series
Fujitsu 3096, 3097, and ScanPartner 10
Under Development at STI:
Microtek IISP
Mustek MFS-6000CX
Others Please Call
TWAIN for OS/2 DDK
The Twain for OS/2 DDK is a developer's kit for imaging device manufacturers
to develop a Twain for OS/2 device driver. Our Twain DDK package allows the
developer to create device drivers which efficiently capture images in
bi-level, gray scale, pallet color, or full 24 bit color without restrictions
on image size. In addition, the DDK contains code which permits the developer
to implement drivers which support high performance production scanners. The
structure of the DDK helps assure compliance with the TWAIN standard which
ensures that your device driver will operate with any OS/2 Twain enabled
application. If you would rather have OS/2 experts develop your device
driver, you can contract Solution Technology to develop it for you.
DDK Features:
Full 32-bit multi-threaded, multi-process implementation
Fully Twain Release 1.5 compliant
Typically takes two to four weeks to implement a Twain scanner device
driver
Manufacturer adds typically from 15 to 25 percent more code
Multi-thread code for high-speed scanner management included
All normal Twain messages already handled in supplied toolkit code
OS/2 compliant applications will run with any OS/2 Twain compliant
scanner or imaging device
DDK Extended Support and DDK maintenance options available
Distribute your scanner device driver royalty free
Each DDK Includes:
Twain for OS/2 SDK which includes:
- TWAIN.DLL - Twain Source Manager DLL
- TWAININT.DLL - Interface to Twain Source Manager
- OS2 SDK Supplement to Twain Release 1.5 manual
- Sample OS/2 SDK source code for simple Twain enabled viewer
- One OS/2 Twain binary scanner driver of your choice (Hewlett-Packard
SCSI driver default)
- One OS/2 Twain source of a sample scanner driver; only need to
implement manufacturer specific codes
OS/2 DDK Supplement to Twain Release 1.5 manual
OS/2 ASPI adapter driver example kit for SCSI scanners
One year telephone support directly into Solution Technology's TWAIN
engineering staff
Requires:
OS/2 2.1, 2.11, Warp, or Warp Connect
OS/2 Kernel debugger strongly recommended
OS/2 Compatible supported scanner devices
CSET/2 or CSET/2++ or equivalent tools
Add your scanner to this growing Twain for OS/2 support list:
Hewlett-Packard IIP, IIC, IICX, 3P, 3C, 3CX
Logitech Scanman 256
Bell & Howell 3338
Epson 1200C, GT-9000 Series
Fujitsu 3096, 3097, and ScanPartner 10
Under Development at STI:
Microtek IISP
Mustek MFS-6000CX
Others Please Call
Solution Technology, Inc. - "We provide solutions..."
1101 South Rogers Circle, Suite 14
Boca Raton, FL 33487
Phone: (407) 241-3210
Fax: (407) x997-6518
E-mail: solution@gate.net
Twain for OS/2, Twain Source Manager, all libraries and DLLs are proprietary
products of Solution Technology, Inc.
Twain for OS/2 is a trademark of Solution Technology, Inc.
OS/2 is a trademark of IBM Corporation
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 4. How Do I Get EDM/2? ΓòÉΓòÉΓòÉ
How Do I Get EDM/2?
EDM/2 can be obtained in any of the following ways:
On the Internet
All back issues are available via anonymous FTP from the following sites:
- hobbes.nmsu.edu in the /os2/newsltr directory.
- ftp.luth.se in the /pub/os2/programming/newsletter directory.
- generalhq.pc.cc.cmu.edu in the /pub/newsletters/edm2 directory.
The EDM/2 mailing list. Send an empty message to edm2-
info@knex.mind.org to receive a file containing (among other things)
instructions for subscribing to EDM/2. This is a UUCP connection, so be
patient please.
IBM's external gopher/WWW server in Almaden. The address is
index.almaden.ibm.com and it is in the "Non-IBM- Originated" submenu of
the "OS/2 Information" menu; the URL is
"gopher://index.almaden.ibm.com/1nonibm/os2nonib.70".
On Compuserve
All back issues are available in the OS/2 Developers Forum 2.
IBM Internal
IBM's internal gopher/WWW server in Almaden. The address is
n6tfx.almaden.ibm.com and it is in the "Non-IBM- Originated Files" menu;
the URL is "gopher://n6tfx.almaden.ibm.com/1!!nonibm/nonibm.70".
On BBS's
From BBS's in Denmark, send email to Jesper Nielsen at
afdata@pop02.ny.us.ibm.net for a location near you.
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 5. C++ Compiler Review (Part 2) ΓòÉΓòÉΓòÉ
C++ Compiler Review (Part 2)
Written by Gordon Zeglinski
Introduction
The second installment to our compiler review appears in this issue. We will
look at Borland C++ version 2.0 for OS/2 and Metaware High C/C++ version 3.32.
In addition to featuring these two compilers, the results of a series of
benchmarks will be presented. The benchmarks were cut down from the set listed
in the last issue due to time constraints.
These two compilers are at opposite ends of the user spectrum. Borland C++ is
a low cost quick compiler, with a good IDE. Metaware is at the high end of the
cost spectrum, supports numerous target environments, and is really designed
for those seeking the ultimate performance.
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 5.1. Borland C++ version 2.0 ΓòÉΓòÉΓòÉ
Borland C++ version 2.0
The Borland package requires about 60 megs of HD space to install. The package
includes PM and text mode compilers and debuggers. The OS/2 2.1 toolkit is
also included. The PM mode compiler is part of the IDE. In addition to tools
to help convert Windows resources to OS/2 resources, there is an OS/2 version
of TASM. (Personally, TASM is my favorite assembler.) Only OS/2 is supported
by this package, however; to do DOS and Windows applications the Windows
version must be purchased. A nice feature is that OWL (Object Window Library)
is now supported under both PM and Windows.
Compiler
This is the fastest compiler evaluated. It is significantly faster than Watcom
10a, which is the second fastest compiler evaluated. On the flip side the code
produced by Borland is slower than that of all the the compilers. As far as
RAM requirements go, this system was easily able to handle them. It supports
C++ exceptions, templates, run time type identification, and the new style
casts. As can be expected, moving from the DOS/Windows version is fairly easy
especially if you use OWL, although the BGI functions are not included in the
OS/2 version. The CRTL is designed to work around the problem of OS/2 not
unloading and loading DLLs in a guaranteed order (which does cause problems in
CSet 2.1 under certain circumstances). While on the topic of the CRTL,
complete source code to the CRTL, OWL and class libraries is included on the CD
version.
Like VAC++, Borland had problems compiling one of the C++ test objects.
Development Environment
The PM IDE has a built in debugger and compiler. It follows the same design as
the Windows and DOS IDEs. The built-in editor is one of the best I've used.
Although the IDE is not as open or flexible as Workframe/2, it is very capable
of handling complex projects. One bug I noticed is that in the IDEs project
"memory", it does not store the fully qualified path to the project file.
Thus, unless the current working directory happens to be the same as the
project file, the memory feature is useless.
The IDE also contains a code browser. With the browser, one can examine both C
and C++ code. Function chains can be followed. In the case of C++, object
hierarchies and objects can be explored. The browser could use some threading
on startup and there should be an easy way to "Backup". Each time you open a
new more detailed browser view, the previous view disappears. It would be
useful to be able to "backup" to the less detailed view.
Borland is the only compiler package that ships with a decent resource editor.
Borland's dialog editor is the best part of the resource package. The resource
workshop is less featured than their windows counter part. The editor may have
problems on some systems working with icons, and bitmaps. If the resource
editor was as good as their Windows resource workshop, it alone would nearly
justify buying this package. Unfortunately it is almost identical to the
version shipped in version 1.0.
Debugger
The most noticeable change from version 1.0 is the improved stability. The
debugger doesn't offer any PM-specific debugging aids. However, the debugger
has an appealing design and is easy to use. Its a lot easier to view a pointer
as an array in Borland's debugger than in C-Set++'s debugger. It has no
scripting capability, unfortunately.
Documentation
In keeping with Borland tradition, there's a lot of documentation. The
documentation is well written and useful to new and experienced programmers.
The manuals themselves seem to be made of low grade paper and bindings. The
quality of the material is below that of the Metaware or Watcom manuals, but
the ease of use exceeds that of the Watcom manuals. The following manuals are
included:
Borland C++ Library Reference
Borland C++ User's Guide
Borland C++ Programmer's Guide
Turbo Assembler Quick Reference Guide
Turbo Assembler User's Guide
Turbo Debugger User's Guide
Turbo Debugger GX User's Guide
Tools & Utilities Guide
Resource Workshop User's Guide
ObjectWindows Reference Guide
ObjectWindows Programmer's Guide
ObjectWindows Tutorial
Summary
Overall, the package shows great improvements in some areas and little
improvement in others. In particular the lack of improvement to the resource
workshop is most annoying. The compiler supports more C++ features than
either C-Set++ or Watcom and is extremely fast. This makes it an ideal
compiler for new programmers. At the same time, the PM version of OWL allows
programmers to create code that runs under both Windows (using the Windows
version of the product) and OS/2.
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 5.2. Metaware High C/C++ version 3.32 ΓòÉΓòÉΓòÉ
Metaware High C/C++ version 3.32
The Metaware package requires about 13 megs of HD space to install. The
package includes text mode debugger, the OS/2 2.1 toolkit, and Tools.h++ by
Rogue Wave. Installation was pretty simple. Although the package only
includes support for OS/2, Metaware has versions of the compiler available for
DOS, Windows, and various flavors of unix.
Compiler
The compiler is slow but generates fast code. The error messages generated by
the compiler are very precise and make fixing compile time errors fairly easy.
High C/C++ has the most complete C++ implementation of any of the reviewed
compilers. It supports templates, C++ exceptions, run time type
identification, name spaces, new type casting methods, and C++ iterators. In
addition to having the most complete C++ implementation, Metaware was a pioneer
in Direct To Som (DTS) technology and High C/C++ was the first OS/2 compiler to
support DTS.
High C/C++ has tighter C syntax rules than the other C compilers but it
supports many nice extensions. For instance, you can compile C code in
"Incremental C++ mode". This allows you to use C++ features in a C program
without all the syntax rules of C++ being enforced. Case statements can
support ranges like, "case 'A'..'C':". There are many more extensions.
Virtually every aspect of the optimizer can be individually toggled on and off.
The compiler has switches and #pragmas to configure just about everything.
This is both good and bad. It's good because it allows you to remove an
optimization that may be causing a bug or affecting performance adversely or
cause some other strange side effect. It's bad because you can play with
switches and pragmas for a long time if you get into it.
Development Environment
Support for IBM's Workframe/2 version 1.x is included. No native IDE is
provided.
Debugger
The debugger is useable although awkward in interactive mode. It's essentially
a command line debugger wrapped loosely with a menu system. For instance, a
local variable display can be accessed through a menu option. However, when the
local variable view window is open, it's not possible to step the debugger.
The powerful scripting language allows one to create a batch file for debugging
an application. Combine the powerful script support with the poor interactive
support, one ends up with a debugger that is best suited for batch debugging.
Documentation
The documentation covers covers the various operating systems supported by the
compiler. This allows one to plan for cross platform support. Even though
multiple operating systems are included in the same manuals, they do not suffer
a reduction in readability. The indexes are organized well, making it easy to
find information. I find these manuals to be among the best I've ever used.
The following manuals are included:
High C/C++ Language Reference
High C Library Reference
High C/C++ I/O Streams Library Reference
High C/C++ Programmer's Guide
High C/C++ DirectToSOM Developer's Guide
High C/C++ Debugger User's Guide and Reference
High C/C++ New Information
High C/C++ Installation Guide
High C/C++ Language Quick Reference Notes
High C/C++ I/O Streams Library Quick Reference Notes
Tools.h++ Introduction and Reference Manual
Summary
Although the compiler is slow, it produces fast code and good diagnostic
messages. When it comes to C++ and DTS support, this compiler is the leader.
If you need an interactive debugger, though, you will probably have to find
one that supports Metaware. In addition, you will have to get PM specific
debugging aids from a DevCon CD or someplace else.
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 5.3. Benchmarks ΓòÉΓòÉΓòÉ
Benchmarks
We finally get to the benchmarks. As I mentioned previously, the benchmarks
were scaled down a bit. The following table shows the results of the C
benchmarks:
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
ΓöéCompiler ΓöéBsort ΓöéSieve ΓöéDhrystone 21 ΓöéWhetstone (S) ΓöéWhetstone (D) Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéMetaware Γöé2.468 Γöé4.218 Γöé62500.0 Γöé142857 Γöé111111 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéVAC++ Γöé2.219 Γöé3.750 Γöé58139.5 Γöé34482 Γöé34482 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéWatcom Γöé1.970 Γöé1.090 Γöé65789.5 Γöé111111 Γöé76923 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéBorland Γöé2.406 Γöé6.062 Γöé32467.5 Γöé17241 Γöé17241 Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
ΓöéCompiler ΓöéRolled Linpack (S) ΓöéRolled Linpack (D) ΓöéUnrolled Linpack (S) ΓöéUnrolled Linpack (D) Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéMetaware Γöé3135 Γöé2194 Γöé3135 Γöé2312 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéVAC++ Γöé2928 Γöé1996 Γöé2928 Γöé2090 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéWatcom Γöé2922 Γöé1990 Γöé3121 Γöé2328 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéBorland Γöé2444 Γöé1758 Γöé2586 Γöé1829 Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
The units for the C benchmarks are as follows. Bsort and Sieve are in seconds
(the smaller the number the better). Dryhstone 21 is in Dhrystones/sec. The
two whetstone tests are in KWhets/sec. All the Linpack tests are in Kflops.
With the exception of the first two benchmarks, larger numbers are better.
The following table show the results of the C++ benchmark.
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
ΓöéCompiler ΓöéTest 1 ΓöéTest 2 ΓöéTest 3 ΓöéTest 4 ΓöéTest 5 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéMetaware Γöé3.187 Γöé8.531 Γöé2.938 Γöé33.406 Γöé10.344 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéVAC++ Γöé2.187 ΓöéNA Γöé2.282 Γöé460.156 ΓöéNA Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéWatcom Γöé3.090 Γöé18.720 Γöé4.910 Γöé93.400 Γöé20.970 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéBorland Γöé3.406 ΓöéNA Γöé3.032 Γöé825.344 ΓöéNA Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
Test 1 simply tests the construction and destruction of an object including a
call to its virtual function.
Test 2 is like test 1 except a more complex object is used.
Test 3 is similar to test 1 except that the object is created/destroyed from
within a try/catch block.
Test 4 is like test 3 except that an exception is actually thrown and caught.
Test 5 assigns the complex object to another object. The same complex object
that was used in test 2 is used here.
Test 3 uses 1 less function calls than test 1. In theory, it should use up less
time than test 1 unless the amount of time used to setup the try/catch block
exceeds that of a function call. In both the Metaware and Borland test
results, test 3 was faster than test 1. The following table shows the
compilation time and executable size for the C++ bench mark program.
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
ΓöéCompiler ΓöéCompile+Link Times ΓöéExecutable Speeds ΓöéEXE size (bytes) Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéMetaware Γöé629.47 Γöé2.37 Γöé128579 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéVAC++ Γöé189.10 Γöé2.50 Γöé136755 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéWatcom Γöé232.22 Γöé2.07 Γöé96027 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéBorland Γöé168.53 Γöé2.40 Γöé140339 Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
The unzip test compares the compilation time, executable speed, and executable
size for Info unzip version 5.12. The following table shows the results of the
unzip test.
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
ΓöéCompiler ΓöéCompile+Link Times ΓöéEXE Size (bytes) Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéMetaware Γöé59.19 Γöé80400 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéVAC++ Γöé35.35 Γöé39936 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéWatcom Γöé84.63 Γöé65898 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéBorland Γöé14.22 Γöé41489 Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
Notes
The command line used to test executable speed was unzip -t unzip512.zip >NUL.
Although VAC++ compiled unzip faster than Watcom, this is usually not the case.
VAC++ takes twice as long to compile the AdeptXBBS source code. Automatic
function inlining had to be turned off in VAC++ because the resulting EXE
falsely reported error in a good zip file. Metaware had inlining turned on.
Included Files
The source code to the C and C++ benchmark programs is included, along with the
.cmd files used to compile the executables. The raw output from the benchmarks
is also included. The executables are not included to keep the size of the
distribution down.
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 5.4. Summary ΓòÉΓòÉΓòÉ
Summary
So you're probably wondering which compiler is the best compiler for OS/2
programming. When I started this series, I thought I'd be able to say
definitively that compiler XXX is the best without a doubt. Unfortunately it's
not that easy because no single compiler is the best. Below I'll try to give
some guidelines on what I think each compiler is best suited for.
The Metaware compiler has the best OOP support around. It was the first
compiler to support direct to SOM and has the most complete C++ implementation
of the reviewed compilers. Its code optimizer is one of the best so if code
speed is important then this compiler is worth considering. It's definitely
not for the hobbyist, however.
The Watcom compiler can generate executable for almost every PC operating
system. This makes it the choice for cross platform development. In addition,
Watcom usually makes the smallest executables. Unfortunately the compatibility
problems with Warp make version 10a less than perfect, though version 10.5
should fix these problems. Watcom is a great "mid level" package - it
generates fast code with the smallest executable size. Watcom is such a
versatile package it's great for the novice programmer as well as the
professional.
Visual Age C++ has the highest system requirements. Although at present it
needs a few CSDs, once these are released, it should be the ideal compiler for
people needing to make large cross platform projects. Although the package
only supports OS/2, it is available on several other hardware platforms and
operating systems. The "Open Class" library abstracts windowing, threading and
more from the application. This allows a high degree of code reusability when
moving the application to another environment supported by VAC++. This package
is definitely not designed for the hobbyist. Professional programmers with
some serious hardware that want to do visual programming should consider this
package.
Borland C++ is the quickest compiler of the ones we have looked at. In
general, its optimizer isn't as good as the other 3 compilers. Through OWL,
one can create PM and Windows programs from the same source without too much
difficulty. (Of course to do Windows programming, you have to purchase the
Windows version of the compiler.) The Windows version has a lot more polish
than the OS/2 version. Borland is a good choice for a beginner programmer and
those who are familiar with OWL.
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 6. Easy Buttonbars ΓòÉΓòÉΓòÉ
Easy Buttonbars
Written by Eric Slaats
Introduction
When I started programming PM applications I was really amazed that simple,
common things that most application feature like buttonbars, multi windowing
(tile, cascade etc.) weren't standard features. On my first attempt to build
an application, I wanted to include a buttonbar so I started looking for an API
call that would place all the buttons for me in the right place. There isn't
such a call! The lack of this call made me construct a method like Marc and I
described in "Building Custom Controls" (see EDM/2 3-4). The method described
in that article is complete and does everything it should do. However, I wasn't
satisfied with the amount of code it took when writing another (very small)
application. So I started to experiment with the menu styles and found a very
simple way to implement a buttonbar.
In this (short) article I'll describe this very simple approach to build a
buttonbar. It functions very well, but it also has some drawbacks (see the
section Concluding Notes). If you're willing to accept this, you'll be
rewarded with a toolbar which is very very easy to implement.
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 6.1. Bitmap Buttons In A Menu ΓòÉΓòÉΓòÉ
Bitmap Buttons In A Menu
In the introduction I stated that there isn't a API call to build a buttonbar.
In fact this isn't true. We can build a menu filled completely with buttons
containing a bitmap. So, in fact, OS/2 has a method to build a buttonbar!
(This approach is already been handled in "Building Custom Controls" in EDM/2
3-4.)
To use bitmaps in a menu, the bitmaps should be known in the .RC file. To
accomplish this we need to do two things. First we need to create identifiers
for all the the bitmaps we want to use. These are usually kept in the header
file.
// Bitmap identifiers
#define ONE 101
#define TWO 102
#define THREE 103
#define FOUR 104
#define FIVE 105
Figure 1) Bitmap identifiers
These declarations are used in the RC file to associate the bitmaps with an
identifier.
// Bitmap declaration
BITMAP ONE "ONE.BMP"
BITMAP TWO "TWO.BMP"
BITMAP THREE "THREE.BMP"
BITMAP FOUR "FOUR.BMP"
BITMAP FIVE "FIVE.BMP"
Figure 2) Bitmap filename declaration
The next step in creating a menu with bitmaps is building the actual menu. The
following lines in the .RC file describe the buttonbar menu.
// Menu declaration
MENU TOOLMENU
BEGIN
MENUITEM "#101", IDM_ONE, MIS_BITMAP MENUITEM "#102",
IDM_TWO, MIS_BITMAP MENUITEM "#103", IDM_THREE, MIS_BITMAP
MENUITEM "#104", IDM_FOUR, MIS_BITMAP MENUITEM "",
MIS_SEPARATOR
MENUITEM "#105", IDM_FIVE, MIS_BITMAP END
Figure 3) Menu template
The menustyle for each of the buttons is MIS_BITMAP. This means the menuitem
will display as a bitmap and the RC compiler expects the identifiers of the
bitmaps in the textarea of the menuitems. We'll put the identifier of the
bitmap preceded by a `#' in the text area.
Besides the declaration of the menuitems a MIS_SEPARATOR is included. This
line in the RC file will put a blank between the buttons FOUR and FIVE. This
way we have a method to separate groups of buttons.
If a window is built using the menu described above, we'll get a window which
will look like this:
Figure 4) Window with a simple buttonbar
In this example button 32X32 bitmaps are used. These bitmaps are shaped as a
button. Of course any bitmap can be used. The bitmaps used in this example
can be found in the toolbar2.zip file. [Editor's note - Eric forgot to send
this file with the article. It will be placed on the EDM/2 ftp site as soon as
possible.]
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 6.2. Adding 'Normal' Menu Items ΓòÉΓòÉΓòÉ
Adding 'Normal' Menu Items
Well I promised a simple buttonbar. The 'trick' is indeed very simple. We add
the normal menuitems to the menu defined in the previous section. The thing to
do is to give the 'normal' menu items the same identifier as the corresponding
button. (It isn't forbidden to have more than one item with the same
identifier in one menu!) This way we're sure the button and the menuitem
trigger the same case item in the window procedure.
If we leave the menu like this, the buttons and the menuitems are displayed in
one row (given a large enough window). If we want a buttonbar, we want it to
be displayed underneath the normal menu items. This effect can be accomplished
to ad the MIS_BREAK stye to the first menuitem that has to be displayed on the
second row. The menu code in the RC file should look something like this:
// Menu declaration
MENU TOOLMENU
BEGIN
MENUITEM "~One", IDM_ONE
MENUITEM "~Two", IDM_TWO
MENUITEM "Th~ree", IDM_THREE MENUITEM "~Four", IDM_FOUR
MENUITEM "F~ive", IDM_FIVE
MENUITEM "#101", IDM_ONE, MIS_BITMAP | MIS_BREAK
MENUITEM "#102", IDM_TWO, MIS_BITMAP
MENUITEM "#103", IDM_THREE, MIS_BITMAP MENUITEM "#104",
IDM_FOUR, MIS_BITMAP MENUITEM "", MIS_SEPARATOR
MENUITEM "#105", IDM_FIVE, MIS_BITMAP
END
Figure 5) New menu template
The MIS_BREAK style is normally used to build a submenu with two or more
columns. Using it like this we create a menu with two rows, thus separating
the menu items from the button items. Used in a window this should look
something like this:
Figure 6) New buttonbar appearance
A complete working example can be found in the toolbar2.zip file.
Note: The menu control also has a style called MIS_BREAKSEPARATOR. Using this
style, the rows or columns separated by this style should be separated by a
line. I found that this worked perfectly with columns, but it didn't work with
rows! Maybe this is a bug, maybe my RC compiler is buggy? Who knows?
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 6.3. Concluding Notes ΓòÉΓòÉΓòÉ
Concluding Notes
That was simple enough, but what are the drawbacks?
There isn't a line drawn between the buttonbar and the menubar. Of
course this is a cosmetic effect, but I think it should be there.
MIS_BREAKSEPARATOR should work, but it doesn't. I haven't fixed this
yet, but it should be possible with an owner drawn menuitem
(MIS_OWNERDRAWN).
This is just one menu. That means it can't be split (buttons at the
bottom or side of the frame window, normal menu on top).
This also means the buttonbar and the normal menu can't be given
different colors.
Adding two toolbars, one on top, one at the bottom or side of the window
is impossible
Of course, this method hasn't the flexibility of a toolbar as it was described
in `Building Custom Controls,' let alone the flexibility of a (great) package
like UCMENU (see OS/2 Developer in the January/February 1995 issue). But if
you can live with these drawbacks there are a number of pro's.
It's very simple
No extra programming needed, everything can be done with a resource
editor.
No subclassing required
A working example of a buttonbar created with this method is found in the file
toolbar2.zip. This example is created and compiled with Borland C++ 2.0.
Feel free to use the code any way you like and send me your comments.
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 7. Gearing Up For Games (Part 3) ΓòÉΓòÉΓòÉ
Gearing Up For Games (Part 3)
Written by Michael T Duffy
Introduction
Welcome to the third installment of Gearing Up For Games. The past couple of
months have been really busy for me, and in August I took a two week trip to
Japan that took me completely away from the computer. Add to this the fact
that I'm trying desperately to get my own game out before the end of the year,
and you begin to see why I didn't get a chance to finish this article.
I had planned on covering threads and semaphores, and basic sprites in this
article. It turns out that I have only had time to write about threads and
semaphores. However I wrote the code for the article before I started the
text, so I finished all of the basic sprite code. Rather than pull the sprite
code out, I have left it in. For those of you already familiar with sprites,
you should be able to follow the code fairly easily. The next to last section
of this article briefly describes how I approached sprites, though it is not
meant to be an in-depth explanation. It will have to suffice for now.
Also, I should point out that my discussion of threads and semaphores is
oriented towards games, and does not cover all aspects of threads or
semaphores. A complete discussion is beyond the scope of this article, and I
would suggest that you look into the reference documentation in the OS/2
toolkit (namely Control Program Guide and Reference) as well as a good book or
two on OS/2 programming. I have found both Petzold's OS/2 Presentation Manager
Programming (pub. Ziff- Davis Press) and Real World Programming for OS/2 2.11
from SAMS Publishing to be useful references. Each book covers some material
that the other doesn't, so it may be a good idea to look at more than one
explanation. The material presented in this article should be enough to give
you a basic understanding of threads and along with the accompanying sample
code, you should be able to use threads and semaphores in your own game
programs.
Enough for excuses...time to get to the meat of the matter!
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 7.1. Threads ΓòÉΓòÉΓòÉ
Threads
One of the advantages of an operating system like OS/2 is that the programmer
has available to him or her a multitasking environment. This not only means
that more than one program can be running concurrently, but also that different
parts of the same program can execute concurrenly. In DOS, programmers did not
have multitasking and instead relied on interrupt handlers and reprogramming
the internal timer chip in order to achieve this, e.g. reading the keyboard or
joystick while blitting to the screen. This is no longer necessary in OS/2,
and part of the reason is because of threads.
What is a thread? A thread is a separate unit of execution within a program.
Each thread has its own set of CPU register variables and its own stack. For
the beginner, register variables are the variables used inside of the CPU to
perform calculations and keep track of where the program is currently
executing. The stack is where local variables are allocated and deallocated
from when a new routine is entered. Threads are owned by a process, where a
process is usually the program that you are running.
Multitasking is handled by the CPU, with the operating system telling the CPU
how much time to give each thread. It basically works like this: the CPU
executes a thread for a given amount of time, stopping the thread after that
time has elapsed. The CPU stops the thread dead in its tracks, even if it is
in the middle of executing a single line of C code, like usVariable1 =
usVariable2. All of the variables in the CPU registers are stored. The OS
then instructs the CPU which thread to run next, and the CPU loads its
registers with the saved registers of the next thread, then executes that
thread for a given amount of time, and so on. An operating system like OS/2
can determine how much CPU time a thread needs, and adjust the amount of time
it gives a thread for its next execution. The OS can also suspend a thread if
the CPU is needed elsewhere, such as reading keyboard, COM port, or disk drive
data. This is equal to the interrupts of the days of DOS.
As a result, you never know when control will be given to or taken from your
thread. You can indirectly affect how much time your thread is given by
setting the priority level of the thread. A priority level basically tells the
CPU how important your thread is compared to other threads. Threads that have
a more important priority level are serviced before threads of lower priority.
Threads of the same priority level are serviced in a round-robin fashion. For
example, let's say you have two threads of the priority, A and B, and one
thread of a lower priority, C. Depending on the load level of the machine and
other settings, these three threads might gain control in the order: A B A B C
A B A B A B A B C A B C A B C. Since A and B are of the same priority, they
will be serviced equally. Thread C will be serviced when A and B have been
handled, and there is CPU time left over.
As mentioned before OS/2 can adjust on the fly how much time each thread gets
before the CPU stops it. How does OS/2 determine how much time a thread uses?
A thread can signal that it has used enough CPU time for now in two ways. One,
if you have a message queue then OS/2 knows when you're done processing because
your message handling routine returns to the operating system once it has
handled the message. The second way is that threads can be suspended, resumed,
or paused (with DosSleep()). This will be discussed shortly.
How are threads useful, and when do you use one?
Threads are needed when you must do two or more things at the same time. An
important thing to remember about threads however, is that on Intel based
machines, two threads don't really execute at the same time. The CPU runs one
thread for a short time, switches to other threads, switches back to the first
thread and so on. Even on machines with SMP (Symmetrical Multi-Processors)
often all of the threads of a given process are run on a single CPU. A CPU can
only execute a certain number of instructions per second, and all threads take
up a share of those instructions. It also takes time to switch from one thread
to another, even though this amount of time is very, very short overall.
Threads are therefore useful when you need to to several tasks at basically the
same time, and you don't want to have to worry about giving each task its share
of the CPU. Instead, OS/2 will handle the thread management. Good examples of
threads are the thread that handles the main message queue, a thread that blits
images to the screen, a thread that loads/saves/sends/receives data in the
background, a thread that mixes sound, and perhaps a thread that handles the
artificial intelligence (AI) of the other opponents in a game. In your games
you will always want to have at least two threads: one to handle the main
message queue, and one to handle the game mechanics. The reason for this is
that you should always spend a little time as possible in the message queue
routine, otherwise you risk slowing down overall system performance. One of
the flaws of OS/2 is that it has a single system message queue. Since the OS
can't send out other messages until the message it just sent is processed, a
greedy program that uses a lot of time between when it is sent a message and
when it returns to the OS holds up other messages meant both for itself and for
other programs. If the processing of a message will take a long time, it is
better to instruct a second thread to handle the processing and then return to
the OS. This way the second thread can perform the processing while the OS
continues to send out other messages.
Threads are not very useful when you have a certain number of things that must
be done in a certain order. For example, in an action game you may have
several tasks to complete in a certain time frame, and one must follow the
other. Every frame of a shooting game, you must read the joystick or keyboard,
update the player's position, call the enemy AI routines and update their
positions, move all missiles and bullets, and then draw the new graphics with
the new positions to the display. Even though you could theoretically
calculate player movement and enemy AI at the same time, the player only sees
the finished screen and everything else must be completed before that screen is
rendered. No matter how you arrange the above tasks, together all of the above
tasks will require the same amount of CPU time before the screen can be
blitted. Placing each task in a separate thread would not speed things up, and
in fact things would slow down because you will have to synchronize the
threads' access to variables, and the overhead of switching threads itself will
slow things down some. The solution to the above problem is to place all of
the tasks in the same thread.
Other games can have different tasks running at the same time. Consider a
simulation or an adventure game. These kind of games can have complex AI for
the computer opponents, and the calculations for the AI take a long time.
However, the player is not continually giving input and the opponents are not
continually moving like in a fast paced action game. The player might be
studying graphics or maps, or even reading text while not inputting requests
for new actions. Rather than having the computer wait for the player to make a
move before deciding how the computer opponents would move (as a DOS game would
do), the computer can decide it's next move while the player is involved with
non-intensive CPU activities. If the computer does not finish a task before
the player makes a move, then it can continue to process until it does make a
decision. Depending on the type of game, this would mean either stopping the
game until the decision were made, or continuing with the previous action this
turn until a new action is decided upon.
Types of Threads
There are two basic types of threads: message queue and non- message queue.
The type is determined obviously enough based upon whether or not that thread
has created a message queue. The type of thread you use will depend on your
purpose. Aside from having a message queue and a message queue handle, message
queue threads differ from non-message queue threads in a few significant ways.
Non-message queue threads cannot do the following: create windows, contain
window procedures, send messages to window procedures with WinSendMsg()
(although they can call WinPostMsg()), or call functions that cause messages to
be sent to window procedures. On the other hand, message queue threads cannot
be suspended or blocked, or else they will hold up the rest of the operating
system. Also, it is important to note that you cannot use the message queue
handle of another thread to call windowing procedures. The strengths and
weaknesses of each type should be weighed carefully when organizing your
program.
Using Threads
Threads can be created either through the functions in a standard library, such
as C/C++'s _beginthread() function, or through the OS/2 API. We will be using
the latter approach since the OS/2 API allows more control over threads than
the former approach. I suggest that you obtain a copy of IBM's Control Program
Guide and Reference for a complete reference to the thread and semaphore API.
Note that when you use threads, you must compile with the switch that tells the
compiler that you are working with a multithreaded program. This switch tells
the compiler to use a special version of the standard libraries that are
"multithread-safe". If two theads call the same or related functions in the
standard C or C++ library at the same time, then there could be problems if
this flag is not specified. With the Watcom C/C++ compiler, the flag is -bm.
To create a thread we call DosCreateThread(). We tell this function what
routine the thread is to run and give a single parameter to be passed to that
routine, tell it what the stack size of the new thread is to be and whether or
not to commit the pages of the stack, and whether the thread it to be executed
immediately or created in a suspended state.
Once a thread is created, you should set its priority status with
DosSetPriority(). You will have to experiment to find out what priority levels
to use for each of your threads. It is a good idea to have your message queue
to be at a higher priority than your other threads so that the entire system
will stay responsive.
A thread ends itself by either by returning from initial thread function, or
calling DosExit(). A thread may kill another thread by calling
DosKillThread(), though it is often a good idea to signal a thread that it
should kill itself so that it may shut down what it is doing before it
terminates.
Threads can also be temporarily stopped and restarted with the functions
DosSuspendThread() and DosResumeThread(). While a thread is suspended, it does
not take up any CPU time; it is simply not called. When a message queue thread
returns to the OS/2 kernel and there are no messages for it, the OS/2 suspends
the thread until new messages are available. Note that threads obviously
cannot resume themselves since they are not running, though they can suspend
themselves and other threads. If a thread is created in a suspended state, you
must call DosResumeThread() to begin its execution.
Another way to temporarily suspend a thread is to call DosSleep(). This
function takes a single parameter that tells the system how many milliseconds
the thread should be suspended before it is resumed. Note that this can not be
used for exact timing purposes. As soon as the time runs out, the thread that
called DosSleep() will be considered again for CPU time slices, but other
threads may execute before the recently resumed thread gets it's turn,
especially if the other threads have a higher priority. Calling DosSleep(0)
causes the thread to release the remainder of it's CPU time for the current
time slice back to OS/2 so that it can be used elsewhere. This should be used
in non-message queue threads where you don't want to hog CPU time and you don't
have anything special to do. It is especially useful at the bottom of a loop
where you have just finished a task and you don't need to start the next task
immediately. This is not needed if you suspend the thread through other means.
Finally, a thread can suspend itself until another thread has finished
executing. When DosWaitThread() is called, a flag is passed that specifies
whether the function should wait for end of execution or not. If DCWW_NOWAIT
is specified, the function returns immediately and the error status tells
whether or not the specified thread is still running. If DCWW_WAIT is
specified, then the function does not return until the specified thread
terminates. DosWaitThread() is useful when thread A wants to terminate thread
B. Thread A signals thread B that it should terminate. Thread A then calls
DosWaitThread() with the wait flag specified. Thread B receives the shutdown
signal, cleans up what it needs to, and the exits gracefully. As soon as
thread B exits, DosWaitThread() returns and thread A can continue about its
business.
As far as the creating, executing, suspending, and resuming the execution of
threads, that's all there is too it. To communicate amongst different threads
and to coordinate their use of global variables and memory, you will have to
rely on semaphores.
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 7.2. Semaphores ΓòÉΓòÉΓòÉ
Semaphores
A semaphore is like a traffic cop that keeps threads from crashing into each
other. They are needed because when the CPU switches from one thread to
another, it may interrupt it anywhere. For example, Thread A might be in the
middle of updating a structure. It gets halfway through the update, and then
it is interrupted by the CPU and thread B gets control. Thread B tries to use
the information in the structure, but only half of it is correct. Imagine if
the structure contained a forward and backward linked list, and only one of the
two pointers were updated. Behavior of the program would be unpredictable and
buggy. It gets even worse. Actions we consider atomic in C may actually be
compiled down into several assembly language instructions. Consider the
expression ++usVar1; The compiler might break it down like:
mov eax, [usVar1] ;eax = 0, usVar1 == 0
inc eax ;eax = 1, usVar1 == 0
mov [usVar1], eax ;eax == 1, usVar1 = 1
Figure 1) Assembler for ++usVar1
What happens if Thread A is interrupted by Thread B during the middle of the
command, and thread B tries something simple like incrementing usVar1. Remember
that each thread has it's own set of CPU register variables.
A - mov eax, [usVar1] ;eax = 0, usVar1 == 0
A - inc eax ;eax = 1, usVar1 == 0
---- switch threads ----
B - mov eax, [usVar1] ;eax = 0, usVar1 == 0
B - inc eax ;eax = 1, usVar1 == 0
B - mov [usVar1],eax ;eax == 1, usVar1 = 1
---- other processing ----
---- switch threads ----
A - mov [usVar1],eax ;eax == 1, usVar1 = 1
Figure 2) Accessing usVar1 by multiple threads
Although at the end of two ++usVar1 instructions it should go from 0 to 2, the
final value comes out to be 1. This is obviously not good.
What you would want to do to solve this problem is to make sure your thread
were not interrupted in the middle of using a variable, structure, or other
piece of data. This can be accomplished in two ways. One way is to call
DosEnterCritSec() before the calculation, and call DosExitCritSec() afterwards.
This causes all thread switching to stop between the two function calls. All
threads. The threads that control OS/2, other threads in your program, all
threads in other programs, and all threads that handle interrupt processing.
Use of these two functions may be fine for simple operations such as a single
increment or decrement of a variable, but should never be used for processing
that takes longer than just a few assembly language instructions. If you
suspend system threads for too long you risk losing data coming in from the
keyboard or serial ports, and you will prevent other updates that need to be
done on a regular basis. Besides, you are only really worried about threads A
and B accessing a given piece of data.
A much better solution is to use semaphores. Semaphores come in three
varieties: mutually-exclusive (mutex), event, and multiple-wait. Mutex
semaphores are like a hall pass; only one thread may have the hall pass at any
one time, and the others must wait until the pass is returned. Event
semaphores are like traffic lights where you can have a stop and a go status.
Multiple wait semaphores are like a collection of the other two types; you have
several hall passes or traffic lights to consider at the same time.
Semaphores may also be private or shared, and named or unnamed. Private
semaphores may only be used by a single process; shared semaphores may be used
by several processes. Other processes may obtain the handle of a semaphore in
a couple of ways. The handle of the thread can be passed in a message. If the
semaphore is named, then the other process may use a known name to request the
handle from the operating system.
The programming samples in Gearing Up For Games will use only private, unnamed
semaphores, so only they will be covered. Also, we will not be using multiple
wait semaphores. For information on named and unnamed, private and shared, and
multiple wait semaphores check out the OS/2 Toolkit documentation, or a good
third party book on OS/2 programming.
Mutex Semaphores
Mutex semaphores allow two or more threads to take turns in accessing
information. First, the mutex semaphore must be created with
DosCreateMutexSem(). Often it is convenient to do this in the main thread
during initialization before any threads are even created. When the semaphore
is no longer needed, DosCloseMutexSem() is called. This can also be done in
the main thread during cleanup.
When a thread wants to access a piece of information that two or more threads
use, it calls DosRequestMutexSem(). If this function returns without error,
then the thread "owns" the semaphore. When this function is called, a timeout
value is also specified. The timeout value is the number of milliseconds that
DosRequestMutexSem() will wait for the semaphore to become available. If this
time runs out, the function returns with a timeout error. The timeout value may
also be given the values of SEM_IMMEDIATE_RETURN and SEM_INDEFINITE_WAIT. An
immediate return request means that the function will not wait for the
semaphore at all. An indefinite wait request means DosRequestMutexSem() will
not return until it has gained ownership of the semaphore, and this is the
setting we will use.
When the thread is finished accessing the shared data, it calls
DosReleaseMutexSem(). This allows another thread to have access to the data.
If two or more threads are waiting for a semaphore when it is released, the
thread with the highest priority gains control. Note that an internal counter
is kept for each semaphore that is incremented upon a request and decremented
upon a release. Therefore you must call DosReleaseMutexSem() for each time
that you called DosRequestMutexSem().
Let's consider two threads, A and B, trying to use the variable ulVar1. During
setup DosCreateMutexSem() is called and the handle is stored in hmtxSem1.
Threads A and B run. Thread A comes to a place where it needs ulVar1, so it
calls DosRequestMutexSem() with the semaphore handle stored in hmtxSem1. No
other thread owns this semaphore, so A gains ownership. It can now safely
access ulVar1. While thread A is using ulVar1, thread B comes to a place where
it needs to access the same variable. Thread B calls DosRequestMutexSem() with
hmtxSem1 and an indefinate wait specified. However since A already owns the
semaphore, thread B blocks. When thread A finishes accessing ulVar1, it calls
DosReleaseMutexSem(). Now thread B's call to DosRequestMutexSem() returns and
thread B can safely access ulVar1. Thread B must release the semaphore when it
is done accessing ulVar1.
Mutex semaphores can also be used when one thread wants to stop another thread,
but wants to let the second thread finish what it is doing. An example of this
is pausing a game. The main loop of the game thread looks something like this:
while (! bEndGameThread)
{
DosRequestMutexSem (hmtxPause, SEM_INDEFINITE_WAIT);
DosReleaseMutexSem (hmtxPause);
// regulate the speed of the game
// move player
// move enemies
// move bullets, etc.
// compose graphics screen.
// blit screen.
};
Figure 3) Processing loop for a game thread
Now the player presses a button that pauses the game. The button press is
intercepted by the message processing routine in the main thread. It requests
ownership of hmtxPause, and chances are that it will get it. The game thread
will finish blitting the frame that it is working on, and before it starts the
next frame, it will request hmtxPause. Since this semaphore is already owned
by the main thread, the main game thread will block and the game will be
paused; new positions will not be calculated, and new screens will not be
blitted. Note that this means that if the game is in a window and the window
needs to be updated, then you will have to blit the last completed frame
elsewhere. Most likely this will be in the handling of the WM_PAINT message.
When the player presses the button to unpause the game, the message handler in
the main thread receives the request. If the game is paused, then the main
thread releases hmtxPause, and the game thread may continue. Be certain to
check to see if a game is paused or unpaused before requesting or releasing the
semaphore, because you only want to have one request active at a time.
Finally, you can use the function DosQueryMutexSem() to find out what (if any)
process and thread owns the semaphore, as well as find out how many outstanding
requests for the semaphore exist (including the request made by the thread that
currently owns the semaphore).
Event Semaphores
Event semaphores are useful for one thread to let another know that something
has happened. They are also useful because they can be hooked up to timers,
and the timer can use the semaphore to let a thread know when a certain time
period has passed.
Like mutex semaphores, event semaphores can be private or shared, named or
unnamed. You create an event semaphore with DosCreateEventSem(), and destroy
it when you are finished with DosCloseEventSem(). This is usually done in the
main thread during setup and cleanup respectively. If you wish to hook a timer
up to the semaphore, this can be done right after it is created with a call to
DosStartTimer().
Event semaphores have two states: posted and reset. You post to an event
semaphore when an event occurs, and you reset it when you want to clear it and
wait for the next event. The number of times an event semaphore is posted to
is recorded and given upon request.
You post an event semaphore with a call to DosPostEventSem(). If you have
hooked the event semaphore up to a timer, then the timer will automatically
post the semaphore after the requested period of time. You clear the semaphore
with DosResetEventSem(), and this call will return the number of times the
semaphore was posted since the last reset.
Although you can use DosQueryEventSem() to find out how many times it has been
posted, most often you will check an event semaphore with DosWaitEventSem().
DosWaitEventSem() blocks a thread like DosRequestMutexSem(), and it acts much
the same way. You provide a timeout value, SEM_INDEFINITE_WAIT, or
SEM_IMMEDIATE_RETURN. If you specify an indefinite wait, the function will
return immediately if the semaphore has already been posted, or it will block
the calling thread until the semaphore is posted to by another thread or a
timer. After DosWaitEventSem() returns, you will probably want to immediately
reset it so that you know if any new posts have been made between this and the
next call to DosWaitEventSem(). DosResetEventSem() clears the number of posts
to 0.
Often you will use event semaphores and timers together. There are only a
limited number of timers available in OS/2. These timers are hooked up not to
the Programmable Interrupt Timer (PIT) that is usually reprogrammed in DOS
games, but rather to a different hardware timer that I believe is also used for
managing multitasking. Although you request the time between timer posts in
milliseconds, time is actually handled in units of clock ticks, which varies
depending on the computer system. For Intel based systems, the resolution of
this timer is about 32 milliseconds, and this gives a rate of about 31 or 32
posts per second.
Before requesting a timer, you will want to make sure there are still some
available. The number of available timers can be found with a call to
WinQuerySysValue() to find the value of SV_CTIMERS. If no timers are
available, you should exit the game with an error message. You request a timer
with a call to DosStartTimer() after you have created the event semaphore. You
pass the handle of the event timer to this function, along with a millisecond
count. Now the event semaphore will be posted every x milliseconds, with x
being the value you specified in the call to DosStartTimer(). When you are
done with the timer, you call DosStopTimer() to stop it and release it for
another program to use.
You can use event semaphores and timers to regulate the speed of your game.
Let's consider an action game. You want the game to run at a constant frame
rate regardless of the speed of the computer it is running on. Since the timer
runs at around 32 posts per second, we will target our frame rate to this
speed. For faster frame rates we need a higher resolution timer. I believe
that at least two such timers currently exist; one is available on the DevCon
Device Driver Kit and is designed for use by device drivers, and the other
timer is accessed through the two DosTmr* functions. The DosTmr* functions
require 128-bit division and multiplication to use. I have not used either of
these timers yet however, so I will not cover them.
To achieve a constant frame rate at the top of your main game loop, you check
your timer. If the timer interval has passed, you reset the timer and continue
on. Otherwise you wait until the required interval has passed. With a timer
and an event semaphore, you know the correct interval has passed when the
semaphore is posted. With a timer that only allows you to read it's value and
doesn't generate interrupts, post messages, or post semaphores (such as the
DosTmr* functions), you will need to check the elapsed time yourself. If
enough time has passed, update your timer variables and continue. If not, you
will have to continue to poll the timer since you don't have a function that
blocks the current thread. In order to keep the polling loop from burning up
CPU time when it doesn't need to, call DosSleep (0) after every unsuccessful
check.
With the standard timer and event semaphore, our main game loop for an action
game looks something like this:
DosResetEventSem (hevTimerSem);
while (! bEndGameThread)
{
// check for paused game
// regulate the speed of the game
DosWaitEventSet (hevTimerSem, SEM_INDEFINITE_WAIT);
DosResetEventSem (hevTimerSem);
// move player
// move enemies
// move bullets, etc.
// compose graphics screen.
// blit screen.
};
Figure 4) Processing loop revisited
One final note about blocking the game thread with either an event or a mutex
semaphore. When you request that the game ends (by setting bEndGameThread to
true), then you must make sure the game thread is not blocked by either a pause
or a speed regulating semaphore. You must therefore release any mutex
semaphores that the main thread owns, and post any event semaphores that the
game thread is waiting on.
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 7.3. Basic Sprites ΓòÉΓòÉΓòÉ
Basic Sprites
I have not had time to write the Basic Sprite explanation for this article, but
I have included the code. I implemented sprite drawing in a very simple way.
All sprites are stored in a PCX file. This file is read into a canvas, and the
canvas is passed to the sprite class. Each sprite is defined as a rectangular
region of the canvas. When the sprite is drawn, the sprite is copied pixel by
pixel from the sprite canvas over to the destination canvas. If the pixel's
value is greater or equal to 248, then the pixel is not written, thus making
those pixels clear since the background remains. This makes the top 8 colors
clear.
The background is stored in it's own PCX file and read into it's own canvas.
To erase the sprites, I just copy part of the background canvas over to the
display canvas. This covers everything that was written last time, and then
the new sprites are written directly to the display canvas. This display
canvas is then blitted to the screen.
Sprites are referenced with a book number and a sprite number. A book is a
collection of several sprites, up to 65,535 sprites per book. There can be up
to 255 books of sprites. You would probably want to have a book of sprites for
the player, a book for each of the enemies, and a book for missiles and
explosions. Each book will contain all of the frames of animation for that
object.
When we get into more advanced sprites, we will actually encode them from a
canvas and store the encoded data. Then we can discard the canvas the sprites
were encoded from, thus saving memory. Furthermore, encoded sprites will
display much, much faster than the current method. Also we will store the
books of encoded sprites to disk in library files. I will be explaining
library files in the future when I cover organizing game data.
The sprite class has a number of routines which are really just place holders
for more advanced features. If a function doesn't seem to have a use now then
just ignore it; we will come back to it in the future.
The Canvas Class
One small addition has been made to the canvas class as well. I have added the
routine CopyDirtyRec(), and this copies a rectangle from one canvas to another.
This routine is used to copy part of the background canvas to the display
canvas when the display canvas needs to be erased. The code of this routine is
a good demonstration of how to move canvas data around, and some of the
speedups that canvases allow.
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 7.4. Those Silly Bugs ΓòÉΓòÉΓòÉ
Those Silly Bugs
The MAKEFILE that accompanied my last article appears to have had a slight bug
in it. In calling the linker, I neglected to put the full path name before the
"mmpm2.lib" file. Therefore "libr mmpm2.lib" should read "libr
c:\toolkit\lib\mmpm2.lib" or add whatever path you have to the lib directory of
the OS/2 toolkit.
Aside from that, I don't think there were any other bugs in the article for
EDM/2 3-7. Am I mistaken?
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 7.5. News and other Nonsense ΓòÉΓòÉΓòÉ
News and other Nonsense
By the time you read this, the Entertainment Toolkit for OS/2 may already be
out on DevCon 8. It was not yet available at press time, so I am unable to
cover anything on it with any certainty. I will be writing about it in the
near future.
If you haven't visited it yet, I'd like to suggest that you drop by IBM's Games
Home Page. The URL is http://www.austin.ibm.com/os2games and you will need a
Web browser to look at it. IBM seems to be using this as their main
notification to the public (that's us) of game related information, so it makes
good sense to check it out every week or so for new stuff. Recently the beta
documentation for the Entertainment Toolkit has been placed on this site, as
well as the joystick drivers and documentation and other stuff.
While we're on the topic of Web pages, I have finally put one up of my own. I
hope to eventually have online versions of my EDM/2 articles up there, and I
may even be placing code and text on the web page before it sees print in
EDM/2. The page is really, really sparse right now, but it should grow as I
find time to work on it. I also have a number of OS/2 game related links on my
page already that you may want to check out.
This month I also did things a little bit differently in that I didn't
distribute duplicates of code from previous articles when the code didn't
change at all. The README.1ST file in the code archive will tell you which
files you need from the last article. Simply place those files in the
directory with the new code, and run the makefile (if of course you are using
the Watcom compiler, otherwise the makefile will not work).
Next month I hope to cover sprites in depth, including how to construct, store,
and display Run Length Encoded (RLE) sprites, and how to clip sprites. If I
have time, I may show how dirty rectangles can be used in some cases to speed
up sprite updating, though with a full scrolling background dirty rectangles
don't do us much good. Also I should be able to cover DIVE's fullscreen
abilities in the 320x200x256 color mode, since they are a breeze to implement.
As always, I welcome comments. You can reach me at mduffy@ionet.net, or find
me lurking on comp.os.os2.games among other places. Until next time...
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 8. Inside INF ΓòÉΓòÉΓòÉ
Inside INF
Written by Peter Childs
Introduction
The Problem
As I sat debating the approach I would adopt for this article it became
distressingly obvious that there would be only a small audience of fanatics
that would share my enthusiasm for the intricate details of the INF file
format.
I also had to painfully admit that others would not even know that INF/HLP
files are the backbone of OS/2's online help system, and that most of those
that did would be quite happy to consider the issue finished at that point.
The Solution
In this article I will attempt to present a overview of the OS/2 INF/HLP file
format in such a manner that a cursory read will leave the reader with a
general idea of the file format. I will also explain some of the compression
ideas used in the INF files and provide additional information for those
wishing to investigate deeper.
As my talents as a programmer are fairly limited I will not include large
chunks of source. I am, however, working on developing some C++ classes to
allow easy access to the information in INF files. If there is sufficient
demand I may do an article showing the possible use of these classes.
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 8.1. What does it mean? ΓòÉΓòÉΓòÉ
What does it mean?
Some Basic Terms
In this document we will be discussing the INF/HLP file format.
INF files and HLP files are basically identical with the exception that INF
files are generally designed to be viewed with the view.exe program, like this
magazine, and HLP files are developed to provide online help for applications.
To the best of my knowledge the file format is identical except for a single
flag bit. From here on, when I refer to INF files I mean both INF and HLP
files.
INF files are compiled with the IPFC (Information Presentation Facility
Compiler) available with most OS/2 compilers, and the OS/2 Tool kits. The
source used is a form of fairly simple markup, with the power to do just about
anything you could want.
The IPF Online Reference (1st Ed 1994) describes IPF:
The Information Presentation Facility (IPF) is a tool that enables you to
create online information, to specify how it will appear on the screen, to
connect various parts of the information, and to provide help information that
can be requested by the user.
It is important to realize the difference between IPF source markup, and INF
files. The INF files are the compiled versions, and the difference is as
marked as the difference between C source and an executable. The IPF source
markup is well documented, whereas the INF file format is not officially
documented.
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 8.2. In the beginning ΓòÉΓòÉΓòÉ
In the beginning
The Header
The header is described here as a structure. When I began playing with INF
files I just defined this structure and then read 155 bytes into it starting at
offset 0. Although this worked fine for Borland C++ I had to muck with things
with gcc to force the structure to be packed.
Most compilers offer a method of packing structures but if your code has to be
portable then you will also have to consider the big-endian / small-endian
stuff (ie. the bytes are stored differently in memory on Sparcs than PCs).
Although probably obvious to most programmers, this had me stumped!
Starting at file offset 0 the following structure resembles the header
(packed):
struct os2infheader
{
int_16 ID; // ID magic word (5348h = "HS")
int_8 unknown1; // unknown purpose, could be third letter of ID
int_8 flags; // probably a flag word...
// bit 0: set if INF style file
// bit 4: set if HLP style file
// patching this byte allows reading HLP files
// using the VIEW command, while help files
// seem to work with INF settings here as well.
int_16 hdrsize; // total size of header
int_16 unknown2; // unknown purpose
int_16 ntoc; // 16 bit number of entries in the tocarray
int_32 tocstrtablestart; // 32 bit file offset of the start of the
// strings for the table-ofcontents
int_32 tocstrlen; // number of bytes in file occupied by the
// table-of-contents strings int_32 tocstart;
// 32 bit file offset of the start of tocarray
int_16 nres; // number of panels with resource numbers
int_32 resstart; // 32 bit file offset of resource number table
int_16 nname; // number of panels with textual name
int_32 namestart; // 32 bit file offset to panel name table
int_16 nindex; // number of index entries
int_32 indexstart; // 32 bit file offset to index table
int_32 indexlen; // size of index table
int_8 unknown3[10]; // unknown purpose
int_32 searchstart; // 32 bit file offset of full text search table
int_32 searchlen; // size of full text search table
int_16 nslots; // number of "slots"
int_32 slotsstart; // file offset of the slots array
int_32 dictlen; // number of bytes occupied by the "dictionary"
int_16 ndict; // number of entries in the dictionary
int_32 dictstart; // file offset of the start of the dictionary
int_32 imgstart; // file offset of image data
int_8 unknown4; // unknown purpose
int_32 nlsstart; // 32 bit file offset of NLS table
int_32 nlslen; // size of NLS table
int_32 extstart; // 32 bit file offset of extended data block
int_8 unknown5[12]; // unknown purpose
char8 title[48]; // ASCII title of database
}
Figure 1) INF header structure
Most of these values come in handy.
Our Sample File
Below is a simple IPF (source) file which I have compiled into a INF for use in
examples.
:userdoc.
:title. Sample INF file...
:h1.Header One
:p.This is a test. Os/2, lies, and Windows 95.
:p.1234.5
:artwork name='in_inf.bmp'.
Hello
:p.
:artwork name='tocarray.bmp'.
:i1. This is a index entry
:euserdoc.
Figure 2) Sample IPF file
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 8.3. Master Dictionary ΓòÉΓòÉΓòÉ
Master Dictionary
Each INF file has a master dictionary which holds all of the words and symbols
used in the articles that make up the INF file. The dictionary starts at
offset dictstart, has a length dictlen, and comprises of ndict words.
Figure 3) Master dictionary layout (in the file)
In the example case above the dictionary is like this:
[0] : (,)
[1] : (.)
[2] : (/)
[3] : (1234)
[4] : (2)
[5] : (5)
[6] : (95)
[7] : (a)
[8] : (and)
[9] : (Hello)
[10] : (is)
[11] : (lies)
[12] : (Os)
[13] : (test)
[14] : (This)
[15] : (Windows)
Figure 4) Master dictionary for the IPF sample
Some things to note are that the source contains the word Os/2, whereas the
dictionary contains the words '/', '2', and 'Os'.
One way of loading the dictionary is detailed below (C++ code snippet).
dict = new char*[ infHeader.ndict ]; // our array of pointers
// change all length bytes to '\0' and set pointers
// to start of each word
while( i < infHeader.dictlen && j < infHeader.ndict )
{
add = dictstore[i];
dict[j++] = &( dictstore[i+1] );
dictstore[i] = '\0';
i += add;
}
Figure 5) C++ code for loading the dictionary
The method used is irrelevant but you need some way of mapping i to the i'th
element of the dictionary. Also don't forget to delete the allocated memory if
you use the above sample with:
delete[] dictstore;
delete[] dict;
Figure 6) C++ to delete the dictionary
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 8.4. Articles ΓòÉΓòÉΓòÉ
Articles
Each article in an INF file is comprised of one or more slots. There are
several structures that deal with slots. One is a array of offsets mapping i
to the i'th slot's position in the file. Another is also the structure of the
slot itself. Each slot also has a local dictionary that maps items in the slot
to words in the master dictionary.
The Slots Array
Beginning at file offset slotsstart (from the header) there is an array of
int32's. These are offsets in the INF file in which the i'th slot can be
found.
int_32 slots[nslots]
Figure 7) Slots area declaration
The Slots Themselves
Beginning at the file offset slots[i] the following structure can overlay the
file:
{
int_8 stuff; // ?? [always seen 0]
int_32 localdictpos; // file offset of the local dictionary
int_8 nlocaldict; // number of entries in the local dictionary
int_16 ntext; // number of bytes in the text
int_8 text[ntext]; // encoded text of the article
}
Figure 8) Slots structure
The Local Dictionary
The local dictionary is used to map items in the encoded text of the slot to
words in the master dictionary. Take note that the nlocaldict variable in a
slot's structure is a byte in size, hence a single slot can only have a maximum
of 255 (really 250 - we'll discuss that later) different words from the master
dictionary in it.
Beginning at file offset localdictpos (for each article) there is an array:
int_16 localdict[nlocaldict]
Figure 9) Local dictionary declaration
The Text Itself
The encoded text is decoded somewhat like the following:
bool space = TRUE;
while( i++ < ntext )
switch( text[i] )
{
case 0xfa: // end of paragraph, sets space to TRUE
break;
case 0xfb: // [unknown]
break;
case 0xfc: // spacing = !spacing
break;
case 0xfd: // line break, set space to TRUE if not monospaced
// example
break;
case 0xfe: // space
break;
case 0xff: // escape code
break;
default: // output dict[localwords[text[i]]] and, if
// space==TRUE a space.
break;
}
Figure 10) Sample code for decoding text
It is pretty obvious that this doesn't leave a lot of space for formatting
commands. This is where the escape codes come in. The general format for an
escape code is:
{
int_8 FF; // always equals 0xFF
int_8 esclen; // length of sequence
// (including esclen, excluding 0xFF)
int_8 escCode; // which escape code
}
Figure 11) Escape codes structure
These escape codes define things like setting margins, inter document links,
and the like. We will ignore them here for the moment. There are described in
the inf03.txt.
So Show Me Something That Works!
Ok, here's a snippet that shows the basic idea behind decoding slots. For the
sake of simplicity we ignore most of the nasty stuff. You should also note
that although each slot contains some text - the way these slots fit together
is described next in Table of Contents.
Included with this issue of EDM/2 is the source for a small program, called
exttext.cc, that extracts all the textual information from an INF file. Also
included is a simple INF header class.
A few quick notes I've noticed about decoding articles that isn't mentioned in
the inf02a.doc. When you decode multi- slots articles, the state of SPACE (ie
true or false) is retained between the article and the next. Basically,
although the local dictionary changes, pretend that each document is merge onto
the next -- with regard to settings like the left and right margins, fonts,
colours, font styles, and space.
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 8.5. Table of Contents ΓòÉΓòÉΓòÉ
Table of Contents
The Table of contents is created by loading in an array of [ntoc] 32-bit
offsets, starting at offset tocstart.
At the offset ( tocentrystart[i] ) a toc entry structure is located that
contains information including the title, the items level in the table of
contents, if it is hidden or not, and, most importantly, how many and which
slots make up the item. There is also a 'has_children' flag which if true
means the following entry has a higher level.
Figure 12) TOC (Table of Contents) entries
Index
The index is pretty simple and relies on table of contents a fair bit.
Beginning at file offset indexstart there is nindex structures like the
following stored.
{
int_8 nword; // size of name
int_8 level; // indent level
int_8 stuff;
int_16 toc; // toc entry number of panel
char8 word[nword]; // index word [not zero-terminated]
}
Figure 13) Index structure
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 8.6. Bitmaps ΓòÉΓòÉΓòÉ
Bitmaps
I am only going to cover this at a superficial level. I am only going to
describe the compression used in newer INF files. The older (ie. v1.3 etc)
INF files use a proprietary compression scheme.
The newer INF files use a LZW based compression scheme. This scheme is
basically the same as the one covered in 'LZW Revisited' (Dr.Dobbs June 1990).
You must alter the decompression code to use MAX_BITS 12 or you will spend a
long time figuring out that after that last input byte 512 your output is all
wrong [grin].
Getting Started
There seems to be no array of bitmap offsets in the file anywhere but there is
a general start for the image information - imgstart.
Here's the basic rundown on decompression:
When during the decompression of a slot you come across a sequence something
like 0xff + 0x07 + 0x0E + 0x01 + 0x00 + 0x00 + 0x00 + 0x00
you know is an escape code (0xff) of length 7 bytes (0x07); that code is for a
bitmap/metafile (0x0E). The next byte is the flags byte and it breaks down
like this:
if( items[i] & 0x01 ) printf ("Left "); // 00000001
if( items[i] & 0x02 ) printf ("Right "); // 00000010
if( items[i] & 0x04 ) printf ("Center "); // 00000100
if( items[i] & 0x08 ) printf ("Fit "); // 00001000
if( items[i] & 0x10 ) printf ("Runin "); // 00010000
Figure 14) Alignment for bitmaps
The next four bytes are a 32-bit offset from imgstart to the bitmap/metafile.
(i.e. you do a is.seekg( imgstart + offset ) Also remember again here that if
you are writting for cross platform support you'll have to deal with the big-
endian, little-endian issue.)
The Bitmap Header and Colour table
If you do the seek and read in the next two bytes you'll be able to know what
sort of image comes next. mf means a metafile (I think - I haven't seen one!).
BM means the old bitmap compression, and bM is the one that we are happy to
see.
So, if everything is OK (ie 'bM') then read in a basic OS2BITMAP_FILEHEADER and
OS2BITMAP_INFOHEADER. Something like this:
{ // BITMAP FILE HEADER
char8 usType[2]; // = 'bM';
int_32 cbSize;
int_16 xHotSpot;
int_16 yHotSpot;
int_32 offBits; // =size(hdr)+size(colortbl)
// BITMAP INFO HEADER
int_32 cbFix; // =size(info_hdr) (usually = 12?)
int_16 cx; // x size
int_16 cy; // y size
int_16 cPlanes; // color planes
int_16 cBitCount;
}
Figure 15) Bitmap information structure
A quick note that if you are going to use this structure "as is" to dump to a
bitmap then you'll have to change the offBits like:
offBits = 14 + 12 + ( 3 * ( 1 << cBitCount ) );
Figure 16) Code change to use structure in figure 15
Next up after the header comes the colour table which is basically an array of
( 1 << cBitCount ) RGB entries (well actually 1 byte Blue, 1 byte Green, 1 byte
Red)
Data Blocks
Next up (after all that) comes the Master Data Block, and one (or more) minor
data blocks - each with their own compression type.
{ // Master Data Block
int_32 num_to_follow; // total number of bytes to follow
int_16 uncompressed_bytes; // uncompressed bytes in each block
}
{ // Minor Data Block
int_16 x_bytes_to_follow; // number of bytes in this block (to follow)
int_8 comp_type; // compression type 0=uncompressed, 2=lzw-based
}
Figure 17) Data block structures
To help with your understanding here is the output from a program I wrote while
working out the decompression routine.
[Editor's note - my word processor completely destroyed the alignment that was
present in the output, so I feel forced to delete it. My apologies.]
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 8.7. Parting words ΓòÉΓòÉΓòÉ
Parting words
All my knowledge of the INF file format stemmed from the work of others. I
hopefully have added some small bits of useful information and my motivation
for writing this article is to make that information available to others.
The document that encouraged me into investigating the INF file format is
available at ftp://hobbes.nmsu.edu/os2/dev32/inf02a.doc and was authored by
Carl Hauser, and updated by Marcus Groeber. I lifted lots of stuff out of it
for this article and have included inf03.txt as a slightly updated version.
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 9. OS/2 Warp Game Developer's Seminar ΓòÉΓòÉΓòÉ
OS/2 Warp Game Developer's Seminar
Written by Dave Briccetti
Introduction
On August 16th, 1995, I attended the OS/2 Warp Game Developer's Seminar,
presented by the IBM Solution Partnership Center with speakers from the IBM
Personal Software Products Boca Raton lab. The Seminar was held in San Mateo,
near San Francisco. This is a brief report about my experiences at that event.
I have no association with any of the products or companies mentioned herein,
except that I'm a member of several IBM vendor support programs.
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 9.1. Presentations ΓòÉΓòÉΓòÉ
Presentations
After a continental breakfast I took a seat with about 80 other developers in
the classroom at the Solution Partnership Center. Like the airlines, IBM had
overbooked the event, but they weren't offering free future classes to people
who would go away. (Their classes are free anyway.)
Welcome & Introduction
E. Lloyd Webber, Worldwide Games Brand Manager from Boca Raton, Florida,
started the presentations. Lloyd announced the OS/2 Warp Entertainment Toolkit
Beta 1, which is part of the now shipping Developers Connection 8. He made it
very clear that IBM wants to help game developers, and told us that they want
to hear from us about how they can help us.
Video Performance
Next up was one of the Entertainment Toolkit developers, Luis Rodriguez, on
video performance with Direct Interface Video Extensions (DIVE). Luis showed
an animated jet fighter in a window (some of you have seen this before), and it
was running so fast it was just a blur. It was running at around 135 frames
per second. Maximized on the 640 x 480 desktop it was about 36 frames per
second.
Luis took us through the steps involved in using DIVE from a program. I won't
go into the details since they are documented very well elsewhere. Take a look
at the IBM OS/2 Games Home Page for more information. See the last section of
this report for the URL.
One interesting feature of the toolkit allows a PM game developer to switch to
full-screen modes such as 320 x 200, which is typical for games, and get the
same performance as DOS games while still using the PM architecture.
3D Graphics (BRender)
After a break we had a fascinating and awesome demonstration of BRender, a 3D
real-time, high performance rendering program, an evaluation copy of which is
included with the toolkit. BRender stands for `Blazing Render,' and it truly
blazes. Rich Seidner of Argonaut Technologies (formerly with IBM and then
Kaleida) showed the product, along with several games such as FX Fighter which
use BRender.
Here the topic drifted far from OS/2 as people asked esoteric questions about
other platforms, and most of the stuff Rich showed was under DOS. Nonetheless,
the technology is fascinating, and running under OS/2.
Rich announced a special offer: For a limited time, developers may license
BRender for unlimited, royalty-free use under OS/2 for a onetime fee of $2,000.
For multi- platform use, the fee is $10,000.
Lunch and Technology Demos
IBM fed us sandwiches and cookies and we wandered around to various rooms where
we could meet the toolkit developers and other IBMers from Boca and Austin.
One of those developers was Mike Brown, the author of PMMPEG, a program to
display MPEG movies. Several months ago Mike added DIVE support to PMMPEG, and
he showed me the difference. The color and speed improvements are quite
impressive.
I also saw programs with the new network games APIs demonstrated. There were
some glitches but the concept is pretty cool: OS/2 APIs to connect players up
to a game over the internet.
Presentations, Continued
Audio
Next up was Larry Kyrala who talked about Direct Audio and real-time MIDI.
These features allow more precise control over audio in the dynamic game
environment. One buzzword I heard was `score richening.' I think this means
that when you're getting your butt kicked in a game the music gets louder and
busier.
Input Devices
Herman Rodriguez was the next speaker. Herman leads the toolkit development
team. He struck me as being very knowledgeable and capable. In this segment
he talked about device driver support for generic input devices, and joysticks
specifically. He has developed an API which not only supports current analog
joysticks, but which will support new digital joysticks being developed. He
said his goal was to generalize the interface to support devices such as data
gloves.
Multi-player Network
The toolkit includes warpnet.dll, which provides an API to support multi-player
games over a network. The API currently supports TCP/IP. There are functions
such as WarpNetInitialize, Open, Broadcast, PackSend, PackRecv, and Close.
Herman Rodriguez made this presentation.
Technology Demos
After the presentations we were invited to wander around and meet the
developers and look at their demonstrations. I saw an early version of
Avarice, from Stardock Systems. It has stunning graphics, but the guy running
it (an attendee like myself) didn't know how to run it and we just didn't get
it. It was very soothing and mellow, but I'm a Dark Forces kind of guy, I
guess. Psygnosis' Lemmings for OS/2 was cute. SimTown was there but I didn't
see it. I think I saw Star Emperor, which I believe is the follow-on to the
highly successful Galactive Civilizations. It looked good. Conclusion
I very much enjoyed taking a day and immersing myself in this new entertainment
development technology. I remain convinced that IBM is committed to supporting
OS/2 developers. IBM's developers of this new technology appear quite
knowledgeable, and they obviously enjoy what they're doing. Now let's see if I
can satisfy my own creative needs and develop something fun!
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 9.2. More Information ΓòÉΓòÉΓòÉ
More Information
I can be reached at daveb@netcom.com, and 74475,1072 on CompuServe, or by phone
at 510 945-7565, Ext. 210. My WWW home page is http://www.best.com/~daveb.
The location of the HTML version of this document is
http://www.best.com/~daveb/Programming/gamedev.html.
The IBM OS/2 Games Home Page is http://www.austin.ibm.com/os2games.
Herman Rodrigues, Toolkit Manager: hermanr@vnet.ibm.com.
Rich Seidner, Argonaut: rich@argonaut.com.
Bradley Wardell, Stardock Systems: wardell@ibm.net.
IBM Solution Partnership Center -- West
2929 Campus Drive, Suite 275
San Mateo CA 94403
1-800-678-4249 or 1-415-312-0240
fax 1-415-312-0254
IBM Solution Partnership Center, OS/2 Program Manager, Keith
Lew, kflew@sfovmic1.vnet.ibm.com.
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 10. Plugging into OS/2 Socket Programming ΓòÉΓòÉΓòÉ
Plugging into OS/2 Socket Programming
Written by Edward D. Boykin
Introduction
Heya! I would like to welcome you folks to a new series of EDM/2 articles on
Client/Server programming with OS/2 Warp. Client/Server programming
encompasses a whole slew of different forms; so, for now, this series will
focus entirely on the peer-to-peer LAN protocol referred to as "sockets".
I am guessing that there will be three or four articles in this series but
there might be more or less depending on how well I feel I am covering the
topics. This is my first shot at writing anything even remotely like this so
if I stumble some please bear with me. Thanks!
If anybody notices some errors or better ways of doing some of the things I am
doing please feel free to e-mail me. The same goes if you have any questions
on any of the subjects discussed here.
I must also make another apology. The code I use here is based on the IBM
TCP/IP Development Toolkit which is a commercial product. I am therefore
unable to distribute the header files needed to compile the source code. I
have included copies of the executables so that you may see the results of the
code. The executables are compiled with full debugging on so you can step
through it if you have the IPMD debugger. I would make the code portable
between EMX and C- Set++ but I don't have the time.
Path of Study
Over the next few months I will cover everything necessary for you to get
started in socket programming. The articles will start with a very simple
client and server program which I will then develop into a basic message system
allowing multiple client connections to a single server. It will allow the
people on the client end to connect to the server and chat with anyone else
connected to the same server in near real-time.
However, we have to walk before we can run. This month I will start with an
introduction to the basic functions in the socket API. These are the minimal
functions that are necessary to create the most basic client and server
programs. I have included just such a set of programs and encourage you to
examine them while you read through this article.
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 10.1. What is a Socket? ΓòÉΓòÉΓòÉ
What is a Socket?
History
Back in 1981, sockets were first introduced as the UNIX BSD 4.2 generic
interface that would provide point to point communications for TCP/IP networks.
After a couple of revisions and some stiff competition from other similar
protocols, the socket API has become a very prevalent peer to peer protocol.
This is good because it means my articles are not wasted electrons.
Anyway, since then support for sockets has migrated to just about every
operating environment including MS-DOS, OS/2, UNIX, MacOS etc. In the BSD UNIX
system, sockets are integrated in the system kernel while in the non-BSD
systems, like OS/2, the socket services are provided in the form of libraries.
This wide range of availability makes sockets one of the best portable network
communication protocols.
Description
A socket is a peer to peer communications construct. This construct basically
consists of a name, or descriptor, and a network address. There are a few
different protocol families in which a socket can operate. These include
AF_INET, AF_UNIX, AF_PUP and AF_APPLETALK. OS/2 currently only supports
AF_INET. This family designation is mainly used to define the addressing
scheme which the socket will use.
There are three types of sockets which OS/2 can use. These are stream,
datagram, and raw sockets. Stream sockets interface with TCP, datagram sockets
interface with UDP, and raw sockets interface with ICMP and IP. The most
commonly used socket type is the stream socket and this is what we will use in
our sample programs.
The stream socket is the most commonly used because of its reliability. Packets
sent over a stream socket are guaranteed to be sent without error or
duplication and they will be received in the same order they are sent in. There
are no boundaries imposed on the data. Think of the data as a simple stream of
bytes flowing from one computer to another. The only real bummer with stream
sockets is that they are slower and require some extra programming overhead.
NOTE: Because there are no data boundaries, TCP does not know where a message
ends or begins. This means that if you send two packets to someplace you must
have some way of letting they receiving end know how to delimit the two
different packets. Don't worry; it's a piece of cake.
TCP/IP Internet Addressing
The basic socket address consists of an internet address and a port address.
The internet address is a 32 bit number that many of us are used to seeing as a
series of four three digit numbers that are separated by decimals. This number
is unique for every network interface within a domain. For instance, I have
two internet addresses on my computer at home. One of the addresses is for my
PPP connection and the other is for my Ethernet card.
A port address is a 16 bit integer representing where the entry point for a
particular service is on a server machine. If you have TCP/IP installed, you
can look in the \TCPIP\ETC\SERVICES file and see a long list of the most
commonly used ports. These are reserved and you should not set up any servers
which use the ports for anything other than what the SERVICES file specifies.
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 10.2. The Socket API ΓòÉΓòÉΓòÉ
The Socket API
The complete socket API consists of 58 different functions which can be broken
down into 21 core functions and 37 utility functions. Since there are so many
I will only explain 10 of the core functions and then only the utility
functions I need for this months programs. As the series continues, I will use
more functions and I'll be sure to explain them at that time.
Socket Setup Functions
These are the functions which are used by the client and server to set up the
sockets on their respective ends.
int sock_init()
Figure 1) sock_init() function
The sock_init() call is used to initialize the socket data structures and check
to see if INET.SYS is running. Every program which uses sockets must use this
call before doing any socket related activities. The return values for this
call are: 0 - Failure 1 - Success
int socket(
int domain, // This is the address type. It must always be AF_INET
int type, // This is the type of socket created. SOCK_STREAM,
// SOCK_DGRAM, and SOCK_RAW are the possible choices
int protocol // The protocol requested. Most commonly 0. Others are
// available.
)
Figure 2) socket() function
The purpose of the socket() function is to create a socket and return it
descriptor. It will return a non-negative integer if the function succeeds and
will return -1 if an error occurs.
int bind(
int s, // This is the socket to which an address is
// bound
struct sockaddr *name, // Pointer to the sockaddr structure containing
// the name to bind to socket s
int namelen // Size of the buffer which name points to in
// bytes
)
Figure 3) bind() function
bind() is used to bind a unique port number to a socket. This is how a server
uses a specific port for it's service. The system can assign a port for you
automatically but there is no way for clients wanting to connect to your server
to know what that port is. bind() will return 0 on success and -1 on failure.
A Brief Aside.....The sockaddr structure
The sockaddr structure, defined in <sys/socket.h>, is what it used to define a
socket address. It is defined as follows:
struct sockaddr {
ushort sa_family, // The address family which is always AF_INET for OS/2
char sa_data[14], // 14 bytes of direct access data which is different
// for each family type
}
Figure 4) sockaddr structure
Because OS/2 only uses the AF_INET family, the sockaddr structure may be
substituted with the sockaddr_in structure. This is just a structure with the
14 data bytes defined for the internet addressing scheme. It is defined in
<netinet/in.h> header and looks like this:
struct sockaddr_in {
short sin_family; // AF_INET always for OS/2
ushort sin_port; // Port to be used in network byte order
struct in_addr sin_addr; // The internet address to be used. It is also in
// network byte order
char sin_zero[8]; // Extra junk. Set it to all zeros
}
Figure 5) sockadd_in structure
Host and Network Byte Orders - Yet Another Brief Aside
Machines on a network can have different ways of storing integers. Intel
machines, such as the PC we run OS/2 on, use "little endian", while Motorola
and SPARC machines use "big endian". Sockets require that all data coming in
and going out be in network byte order, which is most significant byte first or
"big endian". There are a couple of socket utility functions used to convert
integers from little to big endian and vise-versa. The naming scheme for most
of these functions makes it very easy to remember them so rather than listing
all of the functions I will only explain the scheme.
The function names are composed of 4 parts. First is the byte order to
translate from. This is either n or h for network or host respectively. Second
is just "to". Third is the byte order to translate to. This is also either n
or h. Last is the type of integer being translated. It will be l or s for a
long or short integer. The functions all return the same integer type as what
they are converting. For instance:
To convert a port number to network byte order, which must be done for the port
in the sockaddr_in structure, you would use the function htons().
There are also two functions which can be used to swap the bytes in an integer.
These are bswap() and lswap() for short and long integer respectively. All of
these functions are defined in <utils.h>.
Back to the socket API
int soclose(
int s // Descriptor of the socket to be closed
)
Figure 6) soclose() function
The soclose() function is used to shut a socket down, free its resources, and
close the TCP connection if one is open. It will return 0 if successful and -1
if it failed.
Connection Management
These functions are used by clients and server to initiate and manage socket
connections from one another.
int connect(
int s, // The socket descriptor for your connection
struct sockaddr *name, // The socket address structure for the socket
// you wish to connect to
int namelen // Size, in bytes, of the socket address pointer to name
)
Figure 7) connect() function
connect() is one of the mainstay functions in a socket program. You use it
with a clients to connect between two machines on a network. Connect will
actually perform two tasks when it is called. The first is to complete any
binding necessary for a stream socket (in case you haven't already used bind()
for this socket). Second, It attempts to make the connection to the host
supplied in the sockaddr structure.
In order for connect() to succeed, the point to which it is attempting to
connect must have a passive open socket pending. In other words, the server
had better be listening after calling bind() and listen(). If this is not the
case, connect() will return a -1.
Depending on how the socket you supply in s is configured, connect() will
either block or not block. Using our unmodified sockets for now, we will
assume that connect() is always in blocking mode. This means that while
connect() is trying to connect the program or thread will not continue until a
connection is established or an error is received. I will cover the
non-blocking situation in a future article.
int listen(
int s, // Socket descriptor
int backlog // Number of pending connections allowed
)
Figure 8) listen() function
The listen() call applies only to stream sockets and performs two tasks. It
will complete any binding if necessary (i.e. you forgot to do it) and then it
will create a connection request queue of length backlog. After this queue is
full, no further connections will be accepted.
listen() is called when your server is ready to begin accepting connections
from clients. You must first allocate a stream socket using the socket()
function then bind that socket to the socket address structure (or name) of the
server. Listen must be called before you can accept any connections.
Backlog can be any number between 0 and SOMAXCONN. SOMAXCONN is defined in
<sys/socket.h>.
int accept(
int s, // The socket for accepting new connections
struct sockaddr *name, // Pointer to a buffer which will hold the name
// information for the connecting client
int *namelen // Initially points to an integer which contains the size
// of the buffer name points to. On return, it contains
// the size of the struct name now points to
)
Figure 9) accept() function
accept() is what is used by a server to accept the incoming connection requests
from a client. The first connection request in the queue set up by listen() is
the connection which is accepted. A new socket will be created by accept()
with the same properties as socket s. It is this socket which accept() will
return. If there are no pending connection requests then accept() will block
until a request is made. Non-blocking will be covered in a later article. The
new socket which is returned cannot be used to accept new connections; however,
s is still available to accept more requests.
The sockaddr structure in the parameter list is used to store the socket
address structure of the connection requester. This parameter can be NULL if
you have no need for this information. I find it handy to have this
information so I advise you to go ahead and grab it even if you don't plan on
using it. If you do get lazy and set the name to NULL then you don't have to
worry about the namelen parameter either.
int shutdown(
int s, // Socket to be shutdown
int how // Method of shutdown
)
Figure 10) shutdown() function
shutdown() is used to shutdown all or part of a duplex connection. In English,
you can shutdown communication from socket s, to socket s, or both to and from
socket s depending on the value of how. Those values are 0, 1, and 2
respectively.
Connected Data Exchanges
These functions are for transferring data to and from connected sockets. There
are two more functions for receiving and sending data which I will cover later.
They are a bit harder to handle than the two I have included here.
int recv(
int s, // Socket to receive data from
char *buf, // Pointer to a buffer to receive the data into
int len, // Length of buffer pointed to by buf in bytes
int flags // Flags for receiving the data
)
Figure 11) recv() function
recv() is used to receive data from a connected socket. If successful it will
return the length, in bytes, of the message packet. A value of 0 indicates the
connection is closed and -1 indicates an error.
recv() will block, if the socket is in blocking mode, until a message arrives
and then places the incoming data into the buffer and returns its length. If
the incoming data is too large to fit into the buffer than the socket will read
up to the parameter specified in len. There is a method to check and see the
amount of data waiting to be read but it is part an advanced topic I don't want
to sling at you right now.
There are two parameters you can ''OR" together to modify how recv() reads the
incoming data. The first, MSG_OOB, is for datagram socket and will not be
covered. The other is MSG_PEEK. This flag allows you 'peek' at the data
without consuming it. This means the data is still waiting to be fully read in
from the socket. Normally, NULL is used in this parameter.
int send(
int s, // Socket to send data on
char *msg, // Pointer to a buffer containing data to be sent
int len, // Size, in bytes, of data which msg points to
int flags // Flags for sending data
)
Figure 12) send() function
send() is recv()'s counterpart. It operates in the same manner as recv()
except it sends the data through the socket. send() will send all of the data
in msg as long as it doesn't exceed the total socket buffer space. If is
exceeds this buffer size then send will block until all of the data can be
sent. This will only occur if you send a large amount of data rapidly through
the socket.
Both of the flags which can be set for send() are not normally used; therefore,
I will skip them. Use a 0 in the flag parameter when using this function call.
This wraps up the discussion on what I feel are the minimal functions needed to
set up a very basic client and server. At this point you should have a basic
understanding of how to program a sockets based application.
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 10.3. Finish Up and Next Month ΓòÉΓòÉΓòÉ
Finish Up and Next Month
I hope this article will help you to get started in programming with sockets.
It may seem like there is a lot of information needed to program with sockets;
however, once this slightly steep learning curve is past it becomes second
nature to program sockets quickly and easily.
Next month I will be adding more features to the simple client/server program
and discuss more of the socket utility API. Until then I urge you to read over
my sample code and play with the two programs to get a good feel of how they
are working. Thanks for reading.. See you next month!
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 11. /dev/EDM/BookReview ΓòÉΓòÉΓòÉ
/dev/EDM/BookReview
Written by Carsten Whimster
Introduction
In /dev/EDM2/BookReview, I focus on development books and materials. The
column is written from the point of view of an intermediate PM C programmer and
intermediate REXX programmer. Pick up whichever book strikes your fancy, and
join the growing group of people following our PM programming columns. I have
already reviewed a number of beginner's books, and will try to concentrate a
bit more on intermediate techniques and special topics from now on.
Please send me your comments and thoughts so that I can make this column as
good as possible. I read and respond to all mail.
Designing High-Powered OS/2 Warp Applications is an updated version of David
Reich's earlier Designing OS/2 Applications, and contains some expanded
sections, and new PowerPC consideration sections.
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 11.1. Errata ΓòÉΓòÉΓòÉ
Errata
My Web page is continually growing, and has become quite large and popular. It
has recently had over 1500 hits, forcing me to expand my counter to 5 digits.
It should be ok there for a while [grin]. It includes, among other things, a
short list of developer-oriented links. Check it out at
http://www.undergrad.math.uwaterloo.ca/~bcrwhims/os2.html.
This summer has seen me incorporating a number of useful changes into my
POV-Panel/2, culminating in a 1.1 beta release available on my Web page. It
also saw me getting my first few registrations, so I must be finally doing
something right [grin]. I had a lot of learning to do during this, however,
both with respect to REXX, VX-REXX, OS/2, and supporting paying customers. It
seems that if you pass a commandline to REXX with a quoted long filename in it,
it isn't parsed correctly, but rather on a word-by-word basis. In some ways
this is not too strange, but it is rather awkward, and has caused me to create
a known-bugs section in my README file for the program.
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 11.2. Designing High-Powered OS/2 Warp Applications ΓòÉΓòÉΓòÉ
Designing High-Powered OS/2 Warp Applications
Designing High-Powered OS/2 Warp Applications is a unique type of book. It
does not attempt to teach you how to program, but rather how to design
programs, or how to think about programming. These are the chapter titles:
Section I. Why OS/2?
1. OS/2 as an End-User Platform
2. Why Program for OS/2?
3. OS/2 as a Development Platform
Section II. Overall Application Design
4. Good Programs Have Good Up-Front Design
5. OS/2 Kernel Architecture
6. Presentation Manager, Graphics, and the User Interface
7. OS/2 Warp for the PowerPC
8. Features for Your Application
9. Application Structure
Section III. Use Building Blocks or Your App Will Crumble
10. Block Design and Architecture
11. Designing the User Interface
12. Where's the Beef?
Section IV. Making It Happen
13. The Development Environment
14. Prototyping the User Interface
15. Building the Core Functions
16. Using Advanced Functions
17. Non-English-Language Support
Section V. Performance
18. Base Tuning
19. Visual Tuning
Section VI. Testing and Code Changes
20. Testing Methodology
21. Code Change
Section VII. Installation Programs
22. Designing the Installation Program
23. Appendix A: Summary and Conclusions
24. Appendix B: Bibliography
I will concentrate on the sections, rather than the chapters, since the
divisions between the chapters are much fuzzier than in actual programming
books.
If any of the above sounds familiar, that is because it is. I didn't realize
until I started reading (and after getting a heavy dose of deja-vu all over
again [grin]) that this book is an update of Reich's previous Designing OS/2
Applications. It has one new chapter, a few new sections, and some updated
text here and there. For this reason (after much internal debating), I have
decided to just concentrate on the new or changed sections, and a few problem
areas in the older book (to see if they have been fixed), rather than copying
the old review, or pretending that it never happened, and reviewing it as if
it was totally or even mostly new. I will use some of the text from the
previous review, and just brush quickly through a lot of the book, but really
concentrate on the new stuff. For a complete review of the previous book, I
refer the reader to Volume 3 Issue 1 of EDM/2, available at fine FTP sites
near you. Here goes...
Section I explains the advantages of OS/2 over other platforms. This is
explained both from an end-user's point of view, as well as from the
programmer's point of view, and includes discussion of such issues as
pre-emptive multitasking, multi-threading, virtual memory, and so on. There
are new sub-sections on symmetric multiprocessing and portability to the
PowerPC. The importance of the proper use of threads to benefit from SMP is
stressed. The PowerPC sub- section has a small quote which re-raises an old
point of discussion between followers of the PowerPC: "Object code compiled
for Intel chips will not run on most PowerPC RISC chips." The key word here
is, of course, "most". IBM has repeatedly denied (until I last heard) that
there is a PowerPC chip being designed which has hardware emulation of the
80x86 instruction set to speed up running Intel-compiled programs, and to
speed up the acceptance of the PowerPC chip. Considering Reich's insider
position (he does not work for IBM any more, but was on the OS/2 development
team, and has very strong ties in IBM), I would take this as further evidence
that such a chip is actually being designed. Interesting.
Reich also has a small dig against Microsoft in the following sentence, which
is quite amusing: "In contrast to others, with sets and subsets of APIs, this
gives your user the consistency without you having to rewrite code to exploit
the set or subset of function depending on which version of the operating
system you may be on." Apart from the obvious value in advocacy USENET
forums, this is quite interesting from a programmer's point of view too, in
that we have it so much easier over here than they do over there with their
ever-changing APIs. The basic message here is that only a recompile is
necessary to move to the PowerPC, except for device-driver writers.
The next new sub-section is on "OS/2 Development: The Next Generation". Huh,
Star Trek? Nope, just a brief paragraph extolling the virtues of objects,
code and object reuse, and development environments. Curiously enough, IBM's
latest CSet++ (Now Visual Age C++) is much more of an "environment" than it
ever was, so Reich is obviously in tune with the developments at IBM [grin].
Section II is a large section, which outlines the overall application design
theory and procedures. The importance of good, solid, up-front design are
stressed over and over again, not quite ad nauseam. Again, there is a new
sub- section on SMP, which discusses scheduling on SMP machines. It is
obviously (but not obviously enough!) very important not to make assumptions
based on the fact that on the vast majority of machines, only one thread can
run at a time. This does happen, though, and it is a very subtle thing, so
making sure that your design is correct up-front really pays off here.
Timing-related bugs are a beast to debug, as I found out in CS342 (concurrent
programming), but that is another story. He also emphasizes that just adding
more threads to make a program SMP-able is not a good idea; rather, add
threads where appropriate on non-SMP machines, and SMP will enhance the
running of your program.
Chapter 7 is a completely new chapter on Warp for the PowerPC. As such, I
will go into more detail here. The Workplace OS is explained, and the fact
that OS/2 Warp for the PowerPC is merely the first implementation of this is
stated. The personalities of Workplace OS are explained. Basically they are
just an API layer between the program and the IBM Microkernel, which is a
Mach-derivative. This API layer can be almost anything, including OS/2 PM,
DOS (an INT13 etc. API layer? Yuck), AIX, and at some point in the not too
distant past, Windows NT and System 7. Understandably, both Apple and
Microsoft got cold feet about having their OSes run under an IBM OS, and
canned the idea. Anyway, the main (and startling) difference between
Workplace OS and Intel OS/2 is that the device drivers, OS/2 API, and other
sub-personalities run as user programs, not as privileged programs! This
makes no difference to most of us, with the glaring exception of device-driver
writers. It does mean, though, that once the microkernel is stable and
mature, this baby will be solid as a rock, and re-booting will become very
rare. As a worst-case scenario, you will have to restart the interface. This
we can already do now, but not in quite the same way. Device driver writers
can look forward to much more portable drivers, since they are not, to any
large extent, hardware dependent, but rather send messages to and from the
microkernel. At least, this is the way it is explained, although it seems a
little hard to believe; only a recompile should be necessary. I don't quite
see where the new code goes every time a new sound card or video card is
written; in the microkernel? A new microkernel every time a new "thing" is
released? Inconceivable. To some extent then, these device drivers must be
hardware dependent, but only dependent on the "thing", not the machine. Weird
science. Same device driver works for all the personalities too. This is
easier to see. Basically, each personality is comprised of a server, and a
client-library (the API). The server has the major chunks of ideology
specific to the O/S it emulates, and the client-library actually services the
API calls from programs, sometimes without calling the server, other times by
calling the server. All calls take the form of messages, which are more or
less the same old thing for PM writers, except on a below- the-surface scale.
Section III discusses modularization in much greater detail. Reich presents
his idea of design (which is tempered by years of writing for OS/2, so listen
up), starting with the overall design accomplished by taking a black-box
approach to your app. There is a new sub-section on Application Development
Tools for OS/2 (actually this used to be a CASE tools section, but CASE tools
are frequently way too expensive for individual developers, so I imagine that
is why the section now has a more generic flavour) which discusses the various
types of tools that are available to help design and write applications,
including RAD environments, CASE tools, and so on. This is followed by a
sub-section on Object Technologies. SOM, CORBA, and OpenDoc are discussed
here, along with explanations of how it all hangs together. Finally, there is
a new sub-section on Interprocess Objects and Agents, which discusses
communication with WPS objects. DSOM is also briefly mentioned.
Making it Happen is the title of section IV. Practical decisions are the main
focus here, such as the choice of development environment, tools, source code
revision systems, and so on. The sub-section Handling Long Jobs has been
restructured a little to make the flow more logical, and this has affected the
layout of the next couple of sections. In the next chapter, there is a new
sub-section named Guard Pages and Exceptions which discusses, well, I won't
spoil the surprise [grin].
Note: the example on semaphores and deadlock is strictly speaking inaccurate.
I quote: "You can see there are three threads. Threads 1 and 2 make use of
semaphore A. Threads 2 and 3 make use of semaphore B, and threads 1 and 3 make
use of semaphore C. No two threads make use of the same resources, but you can
see that if thread 1 has semaphore A, thread 2 has semaphore B, and thread 3
has semaphore C, any semaphore request by any of the three will cause a
deadlock." In fact, if, say, thread 1 requests semaphore C, it is still
possible for the three threads to complete as follows: thread 1 requests
semaphore C, and locks. Thread 2 requests semaphore A, and locks. Thread 3
finishes with semaphore C, releases it, requests semaphore B, and locks.
Thread 1 can now get semaphore C, and run to completion, releasing semaphore A
and C. Now thread 2 can get semaphore A, and run to completion, releasing
semaphore A and B. Finally, thread 3 gets semaphore B, and runs to completion.
In fact, any sequence of events will complete, which has one thread giving up
a semaphore before requesting another. If all three threads needed two
semaphores at the same time, and each acquired one, then any further requests
causes deadlock. This is slightly different than the statement of the
problem, but it is significant. I imagine this is what was meant. This
section needed rewording in the first book too, so I guess Reich doesn't read
my column. (Sigh)
There is a small new sub-section (which isolates material covered elsewhere in
the previous book, I think) which discusses resources in DLLs.
Section V deals with performance tuning. Many little neat performance tricks
are presented, such as minimizing fix-up costs, accessing DLLs intelligently,
thread priorities, EXE packing, and DLL placement. User interface speed is
also discussed in some detail. There is a new sub-section called Code Size
versus Path, which should be called Code Size versus Path Length, I think.
Basically, Reich advises that, since CPU power is getting cheaper much faster
than RAM and hard drives, and since the CPU is faster than either, it is
advisable to pack code and data as much as possible, and to unpack it using
extra CPU cycles. There is a limitation to this, of course, but in general I
would agree. One extreme example of the benefits of this is given by Stacker
and similar programs: occasionally, having the data compressed on the
hard-drive, and decompressing it on-the-fly actually yields an increase in
speed, due to the reduced wait for the hard-drive to transfer the data! This
is not in all cases, of course, but more often that you would think.
The penultimate section deals with testing and changing code. These two
chapters are short, sweet, use common sense, and haven't changed, so I will
leave them out here.
The final section is on installation programs, and this happens to be a pet
peeve of mine. Frequently, you pick up some really neat program, but get
frustrated trying to install it correctly. In my opinion, a decent
installation procedure should include instructions on how to install manually,
in case the installation program fails. This is obviously difficult to do in
the case of something as complex as OS/2 itself. With the types of programs
that most of us write, however, it should be a breeze. In addition,
reinstalling and uninstalling are mentioned, but too briefly. Uninstallation
programs really should be given more emphasis, especially in this day and age
where programs like Uninstaller for Windows are perpetually at or near the top
of the best-seller list, and Windows 95's logo program requires an
uninstallation program.
There is a brief summary following this last section, which concludes the
book.
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 11.3. Summary ΓòÉΓòÉΓòÉ
Summary
Not surprisingly, this book is very much like its predecessor. In fact, so
little has changed that it is more of an update than a new book. A few areas
have been improved, and a few need improvement, but overall this book has
retained the strengths of the previous book, and still should have a spot in
most OS/2 programmers' libraries.
The book is now pretty up to date, which is a plus, but the semaphore example
still needs rewording, and the book still drags slightly in the early chapters.
The book still has a slight C bias, which I suppose is in order, despite going
a little against the self-imposed language-neutrality of the text.
If you already have the previous book, then take a long hard look at the new
sections, and see if you really need it. If you don't, get it; 'nuff said. It
is a very good book for showing you what features OS/2 offers a programmer, and
how to go about the up-front design of applications. For large projects, this
kind of book is essential. It gets a solid A on the report card.
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 11.4. Book Reviewed ΓòÉΓòÉΓòÉ
Book Reviewed
Designing High-Powered OS/2 Warp Applications, Reich
- John Wiley and Sons. ISBN 0-471-11586-X. US$34.95, CAN$50.
- OS/2 Programmers
- A
This book is a rewrite of Reich's earlier Designing OS/2 Applications,
and has been updated to include PowerPC and SMP information. A very
thorough book on the how-tos of designing applications, rather than
actually writing them. Recommended strongly for anyone starting large
projects.
NOTES
Please note that books aimed at different audiences should only be compared
with great care, if at all. I intend to concentrate on the strong points of
the books I review, but I will point out any weaknesses in a constructive
manner.
LEGEND
BOOK: The name of the book, and the author(s)
PUBLISHING INFORMATION: Publishing company, ISBN, and approximate price.
AUDIENCE: This is a description of the audience I think the book targets
best. This is not intended as gospel, just a guideline for people not
familiar with the book.
MARK: My opinion of the success of the book's presentation, and how well it
targets its audience. Technical content, accuracy, organization, readability,
and quality of index all weigh heavily here, but the single most important
item is how well the book covers what it says it covers. Many books try to
cover too much, and get a lower mark as a result.
A+ Ground-breaking, all-around outstanding book
A Excellent book. This is what I want to see happen a lot
A- Excellent book with minor flaws
B+ Very good book with minor flaws or omissions
B Good book with some flaws and omissions
B- Good book, but in need of improvement
C+ Mediocre book with some potential, but in need of some updating
C Mediocre book with some good sections, but badly in need of fixing
C- Mediocre book, little good material, desperately in need of an overhaul
D Don't buy this book unless you need it, and nothing else exists
F Don't buy this book. Period
COMMENTS: This is a very brief summary of the review proper.
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 11.5. Index ΓòÉΓòÉΓòÉ
Index
This Content Index is designed to let you find the book that covers the topics
you need to learn about. It will eventually have a lot of categories, with
each book being rated along each row. These tables will be quite large, and
will continually grow, so please give me your feedback regarding what
categories you would like to see, and which you don't. It may take me a while
to flesh them out, so have a little patience.
Book Legend
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
ΓöéCode ΓöéIssue ΓöéTitle Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéRWP Γöé2-3 ΓöéReal World Programming for OS/2 2.1 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéLPE Γöé2-4 ΓöéLearning to Program OS/2 2.0 Presentation Manager by Example Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéODD Γöé2-5 ΓöéWriting OS/2 2.1 Device Drivers in C Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéGPI Γöé2-6 ΓöéOS/2 Presentation Manager GPI Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéTAO Γöé2-7 ΓöéThe Art of OS/2 2.1 C Programming Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéMOR Γöé2-8 ΓöéMastering OS/2 REXX Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéRSH Γöé2-9 ΓöéREXX Reference Summary Handbook Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéADO Γöé2-10 ΓöéApplication Development Using OS/2 REXX Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéPMP Γöé2-11 ΓöéOS/2 Presentation Manager Programming Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéDOA Γöé3-1 ΓöéDesigning OS/2 Applications Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéOSP Γöé3-2 ΓöéOS/2 Programming Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéTGO Γöé3-4 ΓöéThe GUI-OOUI War Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéOU Γöé3-5 ΓöéOS/2 Warp Unleashed, Deluxe Edition Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéQR1 Γöé3-6 ΓöéWIN Functions, OS/2 Quick Reference Library Volume 1 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéPWG Γöé3-7 ΓöéProgramming the OS/2 Warp Version 3 GPI Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéDHP Γöé3-8 ΓöéDesigning High-Powered OS/2 Warp Applications Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
NOTE: Books which cover the same material can look similar in this table, but
be different in real life. The style of a book, for example, can not be seen
from a quick table, so make sure that you follow up by reading the reviews of
the books you find here. Finally, be sure that the books you are comparing are
aimed at the same audiences.
PM C Books
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
ΓöéBOOK ΓöéMARK ΓöéKernel ΓöéDevice ΓöéVIO andΓöéPM ΓöéGPI ΓöéFonts ΓöéPrint Γöé
Γöé Γöé ΓöéBasics ΓöéDriversΓöéAVIO Γöé Γöé Γöé Γöé Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéRWP ΓöéB+ Γöé2 Γöé0 Γöé0 Γöé4 Γöé4 Γöé4 Γöé3 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéPME ΓöéB- Γöé1 Γöé0 Γöé0 Γöé2 Γöé2 Γöé2 Γöé0 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéODD ΓöéA Γöé0 Γöé5 Γöé0 Γöé0 Γöé1 Γöé0 Γöé1 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéGPI ΓöéC+ Γöé0 Γöé0 Γöé0 Γöé0 Γöé5 Γöé2 Γöé3 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéTAO ΓöéB+ Γöé3 Γöé2 Γöé1 Γöé4 Γöé1 Γöé2 Γöé0 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéPMP ΓöéA- Γöé1 Γöé0 Γöé1 Γöé5 Γöé3 Γöé4 Γöé2 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéOSP ΓöéB+ Γöé2 Γöé0 Γöé0 Γöé3 Γöé2 Γöé1 Γöé0 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéQR1 ΓöéA Γöé0 Γöé0 Γöé0 Γöé5 (WIN)Γöé0 Γöé0 Γöé0 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéPWG ΓöéA- Γöé0 Γöé0 Γöé0 Γöé1 Γöé5 Γöé5 Γöé5 Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
REXX Books
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
ΓöéBOOK ΓöéMARK ΓöéREXX ΓöéWPS ΓöéReferenceΓöé
Γöé Γöé ΓöéIntro Γöé Γöé Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéMOR ΓöéB Γöé4 Γöé0 Γöé2 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéRSH ΓöéA Γöé1 Γöé2 Γöé5 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéADO ΓöéA- Γöé3 Γöé2 Γöé4 Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
System and Non-Programming Books
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
ΓöéBOOK ΓöéMARK ΓöéKernel ΓöéDevice ΓöéVIO andΓöéPM ΓöéThreadsΓöéGPI ΓöéFonts ΓöéPrint ΓöéWPS Γöé
Γöé Γöé ΓöéBasics ΓöéDriversΓöéAVIO Γöé Γöé Γöé Γöé Γöé Γöé Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéDOA ΓöéA Γöé4 Γöé4 Γöé2 Γöé4 Γöé5 Γöé3 Γöé2 Γöé3 Γöé1 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéTGO ΓöéB Γöé0 Γöé0 Γöé0 Γöé2 Γöé1 Γöé0 Γöé2 Γöé1 Γöé5 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéOU ΓöéA+ Γöé1 Γöé4 Γöé4 Γöé5 Γöé2 Γöé5 Γöé5 Γöé5 Γöé5 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéDHP ΓöéA Γöé4 Γöé4 Γöé2 Γöé4 Γöé5 Γöé3 Γöé2 Γöé3 Γöé1 Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
Ratings Legend
Rating Description
0 No coverage
1 Very light coverage
2 Introductory coverage
3 Good Coverage
4 In-depth coverage
5 Authoritative
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 11.6. Coming Up ΓòÉΓòÉΓòÉ
Coming Up
I have here a trilogy of Warp API reference manuals, which I will review for
next month. Other books I would like to review are:
OS/2 Warp (Control Program/Workplace Shell/Presentation Manager) API,
Stock, Pollack, Barnum
OS/2 Presentation Manager GPI, 2nd edition, Winn
The Design of OS/2, 2nd Edititon, Kogan and Deitel
I am also toying with the idea of reviewing OS/2 Certification Handbook. While
it is not a programmer's book, it can be very relevant to programmers who are
faced with having to support their programs in the real world, and in fact,
this very situation was a large factor in making me purchase this book.
If anyone has a book they want to see reviewed, I will be happy to oblige.
Just mail me and tell me. Publishers can send me books at the address on my
personal page at the end of the magazine, and I will review all OS/2
development- related and advanced user books I receive.
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 12. Introduction to PM Programming ΓòÉΓòÉΓòÉ
Introduction to PM Programming
Written by Larry Salomon Jr.
Introduction
The purpose of this column is to provide the readers out there who are not
familiar with PM application development the information necessary to satisfy
their curiosity, educate themselves, and give them an advantage over the
documentation supplied by IBM. Of course, much of this stuff could probably be
found in one of the many books out there, but the problem with books in general
is that they don't answer the questions you have after you read the book the
first time through.
I will gladly entertain feedback from the readers about what was `glossed over'
or what was detailed well, what tangential topics need to be covered and what
superfluous crap should have been removed. This feedback is essential in
guaranteeing that you get what you pay for. <grin>
It should be said that you must not depend solely on this column to teach you
how to develop PM applications; instead, this should be viewed as a supplement
to your other information storehouses (books, the network conferences, etc.).
Because this column must take a general approach, there will be some topics
that you would like to see discussed that really do not belong here. Specific
questions can be directed to me via email and I will do my best to answer them
in a timely fashion.
This month
This month, we will finish up our tour of the menu window class by looking at
how popup menus are implemented, more of the messages that are used for
interacting with the menu control, and one or two other neat things that can be
done with menus.
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 12.1. Popup Menus ΓòÉΓòÉΓòÉ
Popup Menus
I can remember when my colleague at IBM, Thierry Samama, wrote a program called
UBU, which sported a popup menu to avoid using real estate which was quite
precious. These behaved much like their modern counterparts and I wouldn't be
surprised to find that IBM's CUA group lifted the concept from this program
which was developed when OS/2 1.2 was the current product level.
Figure 1) Simple popup menu
From a user's perspective, popup menus are requested by pressing some
combination of mouse buttons or (since CUA requires that all functions are
accessible by mouse and keyboard) keystrokes. The user likes popup menus
because they do not take up screen space that could be used for the workarea(s)
and because they can be made context-sensitive (which is a fancy word to mean
that only menuitems that are valid for the object(s) under the location of the
mouse are displayed).
From a developer's perspective, popup menu requests are sent as a single
message to the control under the mouse. It is the task of the window procedure
associated with the control to determine what to do - if anything - with the
request. The programmer hates popup menus because they create more work for
them. However, the results are very nice, so the extra effort is worth it (in
my opinion).
With the exception of the container control (WC_CONTAINER), the standard window
classes ignore the popup menu request. Thus, you will have to subclass the
controls where you want to receive this message. Once you receive the message,
the remainder of the processing is trivial - there is only one function call to
be added and the WM_COMMAND message processing remains unchanged.
The popup menu request message is WM_CONTEXTMENU. The system fortunately
handles both the mouse and keyboard combinations for you and also uses the
current settings in the `Mappings' tab of the Mouse settings notebook.
WM_CONTEXTMENU
SHORT1FROMMP(mpParm1) - x position of the mouse in window coordinates
SHORT2FROMMP(mpParm2) - y position of the mouse in window coordinates
SHORT1FROMMP(mpParm1) - reserved
SHORT2FROMMP(mpParm2) - TRUE if the keyboard was used, FALSE otherwise
SHORT1FROMMR(mrResult) - TRUE if the message was processed
Remember, window coordinates are relative to the lower left corner of the
window to which they are associated. This isn't what we want, as we'll see
below.
Once you receive the message and have decided to display a popup menu, you
will call the function WinPopupMenu() to perform all of the work. It will
convert the menu from horizontal to vertical format and will display the menu
at the specified location.
BOOL WinPopupMenu(hwndParent,
hwndOwner,
hwndMenu,
ulX,
ulY,
ulItem,
ulFlags);
Figure 2) WinPopupMenu() function
hwndParent and hwndOwner are the parent and owner windows of the menu.
hwndMenu is the handle of the menu to be displayed (see below). ulX and ulY
are the desktop coordinates at which the menu is to be displayed. ulItem is
the initial item to be under the mouse and is ignored unless PU_POSITIONONITEM
or PU_SELECTITEM is specified in ulFlags. ulFlags is a combination of flags
the controls how the function behaves.
Flag Description
PU_POSITIONONITEM Specifies the initial item under the mouse
PU_HCONSTRAIN Insures that the menu is within the left and
right boundaries of the display
PU_VCONSTRAIN Insures that the menu is within the top and
bottom boundaries of the display
PU_NONE Specifies that the keyboard was used to invoke
the menu
PU_MOUSEBUTTON1DOWN Specifies that mouse button 1 was used to invoke
the menu
PU_MOUSEBUTTON2DOWN Specifies that mouse button 2 was used to invoke
the menu
PU_MOUSEBUTTON3DOWN Specifies that mouse button 3 was used to invoke
the menu
PU_SELECTITEM Specifies that ulItem is to be selected
PU_MOUSEBUTTON1 Specifies that mouse button 1 can be used to
select a menuitem
PU_MOUSEBUTTON2 Specifies that mouse button 2 can be used to
select a menuitem
PU_MOUSEBUTTON3 Specifies that mouse button 3 can be used to
select a menuitem
PU_KEYBOARD Specifies that the keyboard can be used to
select a menuitem
Since WM_CONTEXTMENU gives you window coordinates and WinPopupMenu() expects
desktop coordinates, you will either have to call WinMapWindowPoints() to
convert from one to the other or call WinQueryPointerPos() to simply retrieve
the desktop coordinates of the mouse.
From where do you get the value for hwndMenu? You have two options: you can
load it just prior to calling WinPopupMenu() or you can load it during the
WM_CREATE processing and save the value in a structure pointed to by your
window words. Using the latter is acceptable; however, popup menus are
usually a frequently used resource, so performance might suffer slightly if
you load and destroy the menu everytime it is requested. This is especially
evident if you are running the application from a network- mapped drive. If
you still decide to do this, you can destroy the menu using the
WinDestroyWindow() function when you receive the WM_MENUEND message.
WM_MENUEND
This message is sent when a menu or one of its pull-downs has finished the
selection process.
SHORT1FROMMP(mpParm1) - specifies the identifier of the menu who is
finished the selection process.
HWNDFROMMP(mpParm2) - specifies the handle of the menu.
Regardless of when you decide to load the menu, you will have to use
WinLoadMenu() to load the menu template.
WinLoadMenu(hwndFrame,hmodDll,ulResourceId);
Figure 3) WinLoadMenu() function
hwndFrame is the handle of the frame to which the menu is to be attached. In
the `old' days, when menus were simply action bars, you would indeed specify
the frame window handle here, and the function would automatically assign the
window identifier FID_MENU to the loaded menu, attach it to the frame, and
`reflow' the frame window. Since we have a popup menu - which we don't want
to be displayed - we will use HWND_OBJECT here. hmodDll is the module handle
containing the menu template. ulResourceId is the menu template identifier.
Menu Messages
We now need to look at more of the messages that we need to interact with the
control. The MM_QUERYITEM and MM_SETITEM messages are used to query
information about and set information for a node in the menu tree, whether it
is a branch or leaf node. Both messages have the same parameters:
SHORT1FROMMP(mpParm1) specifies the identifier of the node to search for
SHORT2FROMMP(mpParm1) specifies whether or not submenus should be
searched also
PVOIDFROMMP(mpParm2) points to a MENUITEM structure.
typedef struct {
SHORT iPosition;
USHORT afStyle;
USHORT afAttribute;
USHORT id;
HWND hwndSubMenu;
ULONG hItem;
} MENUITEM,*PMENUITEM;
Figure 4) MENUITEM structure
iPosition is the 0-based position of the item within its parent. afStyle and
afAttribute are the MIS_ and MIA_ flags associated with the item. id is the
numeric identifier of the item. hwndSubMenu is the handle of the submenu
associated with this item if the MIS_SUBMENU flag is specified in the afStyle
field. hItem is a 4-byte application-usable area that is associated with the
item.
As I stated in issue 3-6, a few people had asked about the buttons that are to
the right of certain menuitems. The submenus associated with these are said
to be a conditionally cascading submenu - the word `conditionally' comes from
the behavior of the submenu, which is conditional on how the user interacts
with it. If the user simply clicks on the text that contains the submenu, the
default item is sent to the application via the WM_COMMAND message.
Although an MIS_CONDITIONALCASCADE style exists, the resource compiler (when I
last checked) did not recognize this as a valid flag. So, this is added to
the list of things that needs to be done to implement this user interface
feature.
Set the style of the submenu to include MIS_CONDITIONALCASCADE
Set the default menuitem
Check the default menuitem for user-feedback
The first item can only be done using the MM_QUERYITEM and MM_SETITEM messags.
Since this is a fairly frequently needed function, I created the
setCascadeDefault() function, which is included in cascade.zip.
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 12.2. From CUA 89 to CUA 91 Style Menus ΓòÉΓòÉΓòÉ
From CUA 89 to CUA 91 Style Menus
I have included with this month's column the MENU sample, which has been
`ported' to use popup menus instead of the old-style menus. In doing so, I
kept track of the changes that were necessary to give you an idea of the things
that need to be done to convert your application to the `new look.'
Remove FCF_MENU from the frame creation flags passed to
WinCreateStdWindow().
Add hwndMenu to instance data structure.
Load the menu in WM_CREATE and store the handle in the instance data.
Add processing for WM_CONTEXTMENU (#define INCL_WININPUT for the message
and #define INCL_WINPOINTERS for pointer stuff).
Change references of WinWindowFromID(pidData->hwndFrame,FID_MENU) to
pidData->hwndMenu.
This list is by-no-means conclusive, but it shows you what I had to do so that
you have a rough idea of what you will also need to do.
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 12.3. Conclusion ΓòÉΓòÉΓòÉ
Conclusion
This concludes our look at the menu control. As always, questions and comments
are welcome via my email address. Next month, we'll continue our journey, but
I have no idea where it will take us at this time. Keep reading!
EDM/2 - Sept 1995 - Volume 3, Issue 8
ΓòÉΓòÉΓòÉ 13. Contributors to this Issue ΓòÉΓòÉΓòÉ
Contributors to this Issue
Are You a Potential Author?
We are always looking for authors. If you have a topic about which you would
like to write, send a brief description of the topic electronically to any of
the editors, whose addresses are listed below, by the 15th of the month before
the month in which your article will appear. This alerts us that you will be
sending an article so that we can plan the issue layout accordingly. After you
have done this, get the latest copy of the Article Submission Guidelines from
hobbes.nmsu.edu in the /os2/newsltr directory. (The file is edmsub.zip.) The
completed text of your article should be sent to us no later than five days
prior to the last day of the month; any articles received after that time may
be pushed to the next issue.
The editors can be reached at the following email addresses:
Larry Salomon - os2man@panix.com (Internet).
Carsten Whimster - bcrwhims@undergrad.math.uwaterloo.ca (Internet).
____________________________________________________________
Edward Boykin
Ed Boykin will be graduated this winter from Georgia Institute of Technology
with a Bachelor Degree in Aerospace Engineering. He has been studying
programming on his own for about three years and will probably be continuing
at Tech to get a Master's degree in Computer Science or Engineering. His
current OS/2 projects include a POP and SMTP e-mail program for OS/2 and other
network client/server projects. He is currently working as an intern for
Racetrac Petroleum Corp, doing client/server programming using Microsoft
Windows NT and Oracle.
He can be reached at gt5584e@acme.gatech.edu.
____________________________________________________________
Dave Briccetti
For those of you who don't know me, I'll tell you a little about myself. I
have been developing applications for OS/2 since 1987, as an independent
developer and consultant. I am a cofounder and the president of the OS/2 Bay
Area User Group, a large, independent organization of OS/2 users and
developers. Most of the development work I have done has been with C and C++
and PM, in the areas of business and scientific programming.
Recently I have felt compelled to do something flashy and fun; either games or
edutainment software development for OS/2. I bought several great books on
graphics and game programming, and now IBM has released Beta 1 of its OS/2
Warp Entertainment Toolkit. I'm ready!
____________________________________________________________
Peter Childs
Peter is an undergraduate Computer Science student at the Flinders University
in South Australia. Last year he studied Mechanical Engineering at the
Adelaide University, and the year before he was a Missile Number serving with
111 Air Defense Bty (Lt) of the Australian Army.
Peter is a member of the South Australian Os/2 User Group and the author of
the POPWatch mailbox watching program (OS/2), and the Inf-HTML suite, which
allows batch or runtime conversion of OS/2 INF files to HTML (platform
independent).
You may reach Peter
...via email:
pjchilds@apanix.apana.org.au - Internet
...World Wide Web homepage
http://www.apanix.apana.org.au/~pjchilds/ - WWW
...via phone
61-8-2787381
____________________________________________________________
Michael T. Duffy
Michael is a recent graduate of the University of Southern California and has
degrees in Cinema Production and East Asian Languages and Cultures. His
computer skills are self- taught, and he has been programming for OS/2 since
about December of 1994. Michael is working on breaking into the game
development industry, and has been working towards that goal for a number of
months. He expects to release his first game, an OS/2 shooter, later this
year.
Michael can be reached on the internet at mduffy@ionet.net.
____________________________________________________________
Larry Salomon Jr.
Larry Salomon Jr. has been developing OS/2 applications since version 1.1 in
1989. He has written numerous applications, including the Scramble applet
that was included in OS/2 versions 2.0-2.11, and the I-Brow, Magnify, and
Screen Capture trio that has been distributed on numerous CD-ROMs.
Larry is also the coauthor of the successful book, The Art of OS/2 2.1 C
Programming (Wiley-QED). Finally, he is the CEO/President of IQPac Inc. which
is responsible for the publication of EDM/2 and he is a frequent contributor
to the publication.
Larry can be reached electronically via the Internet at os2man@panix.com.
____________________________________________________________
Eric Slaats
Eric Slaats teaches information technology at the Hogeschool Eindhoven,
Faculty of Economics Sr. Business Informatics. Besides teaching, he has
written a number of books. Currently, he is researching the behavior of
neural networks in a financial environment. He started programming OS/2 PM to
build an interface for a Neural network problem in september 1994.
Eric can be reached electronically via the internet at e.slaats@fe.hse.nl.
____________________________________________________________
Carsten Whimster
Carsten is an undergraduate Computer Science student at the University of
Waterloo. He is currently in fourth year, and enjoying it immensely. He uses
Watcom C/C++ 10.0a and Watcom VX-REXX 2.0b. Carsten is the author of some
commandline utilities, and POV-Panel/2. He is currently trying to learn
enough GPI programming to do a remake of the old video game Qix. He is also a
TEAM-OS/2 member, and has adopted a little computer store called The Data
Store in Waterloo, Ontario, which promptly hired him part-time.
You may reach Carsten...
...via email:
bcrwhims@undergrad.math.uwaterloo.ca - Internet
...World Wide Web homepage (incomplete; aren't they all):
http://www.undergrad.math.uwaterloo.ca/~bcrwhims - WWW
...via snail mail: Carsten Whimster 318A Spruce Street Waterloo, Ontario
Canada N2L 3M7
...via phone
(519) 886-2439
____________________________________________________________
Gordon Zeglinski
Gordon Zeglinski is a freelance programmer/consultant who received his
Master's degree in Mechanical Engineering with a thesis on C++ sparse matrix
objects. He has been programming in C++ for 6 years and also has a strong
background in FORTRAN. He started developing OS/2 applications with version
2.0 .
His current projects include a client/server communications program that
utilitizes OS/2's features which has entered beta testing. Additionally, he
is involved in the development of a "real-time" automated vehicle based on
OS/2 and using C++ in which he does device driver development and designs the
applications that comprise the control logic and user interface.
He can be reached via the Internet at zeglins@cc.umanitoba.ca.
____________________________________________________________
Network Distributors
These people are part of our distribution system to provide EDM/2 on networks
other than the Internet. Their help to provide access to this magazine for
others is voluntary and we appreciate them a lot! ┬╖ Paul Hethmon
(phethmon@utk.edu) - Compuserve ┬╖ Gess Shankar (gess@knex.mind.org) -
Internet ┬╖ Jason B. Tiller (PeerGynt@aol.com) - America On-line ┬╖ David
Singer (singer@almaden.ibm.com) - IBM Internal ┬╖ Jesper Nielsen
(afdata@pop02.ny.us.ibm.net) - Denmark BBS's
If you would like to become a "network distributor", be sure to contact the
editors so that we can give you the credit you deserve!
EDM/2 - Sept 1995 - Volume 3, Issue 8