home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 32 Periodic
/
32-Periodic.zip
/
edmi4-1.zip
/
EDMI4-1.INF
(
.txt
)
< prev
next >
Wrap
OS/2 Help File
|
1996-01-16
|
234KB
|
2,096 lines
ΓòÉΓòÉΓòÉ 1. Jan 1996 Title Page ΓòÉΓòÉΓòÉ
The Electronic Developer's Magazine for OS/2
Portions copyright (c) by IQPac Inc.
Volume 4, issue 1
Administrivia
Well, here I am again, and I'm going to do what I did last month - concatenate
the "From the Editor" sections together, liberally sprinkle the <BACKSPACE>
key, and serve them up again as though fresh from the oven. However, you should
read this month's title page, if you didn't last month, because you might miss
some interesting things here that aren't anywhere else...
Gearing Up for Games Update
I received mail from Michael Duffy regarding the Gearing Up for Games series.
Because he now works for Stardock Systems, he is working quite a lot up to 18
hours a day, trying to meet Christmas deadlines and such. However, he said he
does have the code done for the next part of the series and simply needs to
finish the text. Look for this to appear in February or soon after.
Missing in Action
I still haven't located Johan Wikman, however. He was writing the RMX-OS2
series, which I personally found quite interesting. Mail to him bounces and I
have no other way of contacting him. If you do, please do and let me know how
to contact him also.
Best Wishes for a Speedy Recovery
I hope that our student readers did well on their finals, especially Carsten.
He has suffered from a lack of time lately, which is why all of the typos
slipped through the cracks on the December articles. I apologize for this, but
English was never my best subject.
Credit Where Credit is Due
Before I begin this week's spew of talk, I would like to publicly thank Rocco
Caputo for the immense and intense amount of help he provided to me last month
on the Perl script that processes the new Search facility on the web site.
comp.os.os2.announce , Etc.
Eh? New Search facility?
If you haven't been keeping in touch with the net over the holidays, EDM/2 has
announced (by the time you read this) a permanent home for the web version of
the publication. (Actually, the home belongs to IQPac Inc. but who's
counting?) The new URL of the magazine is http://www.iqpac.com. There are a
lot of things that are different there from what you were used to at the venus
site. You might check out the press release that was posted to the various
newsgroups.
If you've noticed, I've been trying harder to keep the community abreast of
things via the newsgroups comp.os.os2.announce and comp.os.os2.programmer.*.
My aim is to achieve the level of feedback that Trevor Smith (from OS/2
e-Zine!) provides in comp.os.os2.misc, but it will be difficult. In order to
continue taking EDM/2 (and, to an extent, IQPac, Inc.) to higher levels, it is
necessary to generate and maintain a high interest level for the magazine.
The point of this is that, although this is the preferred place for you to
watch, you can also keep an eye out in the OS/2 newsgroups for the same and
possibly additional information about EDM/2.
More Thanks to be Spread
This is where I would like to thank Rajv (as he is known in the #os/2 channel
on IRC) for allowing EDM/2 to spend so much time at venus on his hardware.
Without him, the web site would have "crashed and burned." Fortunately, there
are always people out there who want to help out when help is sorely needed.
Another Call for Writers
Unfailingly, I get a letter or two every month from people asking if topic
such-and-such would be interesting. Let me put this in a way everyone could
understand:
Yes!
(Eesh!)
Seriously, if you have a topic that is relevant to OS/2 development, we want
you to write about it! Read the Article Submission Guidelines first and then
start your keyboards!
Holiday Wishes
Although I am aware of the many religions that span our reader base, I would
like to wish everyone a happy holiday.
Ah, how I love the holidays. There isn't anything like lots of good music,
food, and fellowship to brighten the days during the end of December.
You can keep the messes and the dirty dishes.
Anyway, my family decided to brave the winter cold in New York by coming up
(from South Carolina!) to spend this week with my wife and I. It's been fun,
and has kept us busy.
Sockets
Speaking of busy, I've managed to talk to a couple of people despite the
arrival of my family. It seems that we all got the same idea and decided to
write a socket library to help us develop our TCP/IP applications. Of course,
I did not think to ask whether they were planning to release the library to the
general public. I would certainly hope so, however.
Myself, if my library ever matured to the point where it was generic enough to
be usable from a variety of applications, I would release it. Of course, the
ultimate goal for me is to fold the socket library into the Common/2
communications subsystem. The current implementation uses named pipes, but it
would be nice to allow the application to use the same interface for both named
pipes and sockets.
Managers and Such
Of course, such an approach is not without its design difficulties. Although
named pipes are supported natively by OS/2, sockets are not, and the DLL's
needed by TCP/IP may or may not be there. This immediately suggests either a
bunch of DosLoadModule() and DosQueryProcAddr() calls by Common/2 (referred to
as dynamic binding) or a set of statically bound DLL's which are called by
Common/2. However, now I have to add error checking to insure that the
application doesn't specify a protocol that isn't installed, etc.
As I said, this approach isn't without its difficulties.
No More PC Week, Infoworld, etc.
It's funny how I tout the web as the greatest thing since sliced bread, yet I
find that I am at a loss, now that I no longer will be able to browse the
printed versions of the weekly trade publications that I used to read. I guess
I will now have to make an extra effort to set aside time at home to keep
up-to-date on the goings-on in the world.
Does this mean the web will never entirely replace the printed publication?
Well, I don't think any of us were naive enough to believe this in the first
place. (Remember the "paperless office"?) However, I do think that industry
analysts overestimate the worth of the web, from the user's point of view. I
guess that, until ISDN and other forms of high speed, digital communication
capabilities become available and more popular, the status quo will rule.
Watch, though, for the day when it changes, because I believe it will change
quickly.
New Books
'Ever wanted to write a book? Although OS/2 seems to be catching up to Windows
in terms of the number of books it has available, it still has quite a long way
to go. If you think you have the ability and the time and the desire to stay
committed to completing a tome, then you should see what you can do to get a
publisher to sponsor you. This thought arose because it seems that I've
started receiving more and more notes that begin with: "since you have made
the rounds in book publishing..."
ΓòÉΓòÉΓòÉ 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. (larry_salomon@iqpac.com)
Associate editor Carsten Whimster (carsten_whimster@iqpac.com)
Contributing editor Gordon Zeglinski (gordon_zeglinski@iqpac.com)
CEO/President Larry Salomon Jr. (larry_salomon@iqpac.com)
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.
Copyright Notice - EDM/2 - Jan 1996 - Volume 4, Issue 1
ΓòÉΓòÉΓòÉ 3. How Do I Get EDM/2? ΓòÉΓòÉΓòÉ
How Do I Get EDM/2?
EDM/2 can be obtained in any of the following ways:
Anonymous FTP on the Internet
hobbes.nmsu.edu in the /os2/newsltr directory.
ftp.luth.se in the /pub/os2/programming/newsletter directory.
Elsewhere on the Internet
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.
On Compuserve
All back issues are available in the forum OS2DF2, section 15.
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.
How do I Get EDM/2? - EDM/2 - Jan 1996 - Volume 4, Issue 1
ΓòÉΓòÉΓòÉ 4. Plugging Into OS/2 Socket Programming (Part 3) ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 4.1. Introduction ΓòÉΓòÉΓòÉ
Plugging Into OS/2 Socket Programming (Part 3)
Written by Edward Boykin
Introduction
Welcome to my third article on OS/2 socket programming. We are finally going
to look at a more advanced client-server setup. This month, I will discuss
only the client part and treat the server only as a 'black box' so that you may
concentrate on one half of the set up. I have included only the client source
and executables, but in order to make the client usable I wrote it so it would
work with an internet "chat" type server (not IRC) that already exists. The
server to be connected with is hard-coded in the client source. Next month I
will update the client so you can connect to the server I am writing.
For some of you who have been unable to work with sockets because of the cost
of the IBM TCP/IP toolkit, I have some good news: it has come to my attention
that the Warp Connect CD-ROM contains all the headers, libraries and DLLs of
the toolkit; however, it does not contain documentation. If you own this CD
then do a search for the "toolkit" directory and you will find this zip file
there. (Those of you who do not have Warp Connect are still out of luck,
unfortunately.)
On to the show...
Plugging Into OS/2 Socket Programming (Part 3) - EDM/2 - Jan 1996 - Volume 4,
Issue 1
ΓòÉΓòÉΓòÉ 4.2. The Select() Function ΓòÉΓòÉΓòÉ
The Select() Function
In my study of socket programming, I found that only one function really ever
confused me and that was the select() function. There are two versions of
select() in the OS/2 socket SDK: one version is the same as the BSD socket
call which uses bitmasks and such to set up the function; the other is IBM's
version of the function with the same name. I found the former to be too
difficult to use so I opted to use the latter instead.
The select() function is used to check one or many socket descriptors for
readability, writability, and exceptions. The function looks like this:
int select ( int *socks,
int noreads,
int nowrites,
int noexcept,
int timeout );
Figure 1) IBM's version of the select() function.
The first parameter is an array which contains the socket descriptors you wish
to perform the select call on. When creating this array, place all of the
sockets you wish to check for readability first, then for writability, and
finally for exceptions. So, you could theoretically have an array of three
integers with the same integer, or socket descriptor, in all three places,
meaning that you want to see if you can read from and write to the socket and
check for any socket exceptions. The next three parameters tell select how
many sockets in that array are for reading, writing and exception checking. The
final parameter is a timeout value. This value is in seconds and determines
how long the select call will block if none of the sockets check out. If you
make this value 0 select will not block, and if you make it -1 select will not
timeout.
Plugging Into OS/2 Socket Programming (Part 3) - EDM/2 - Jan 1996 - Volume 4,
Issue 1
ΓòÉΓòÉΓòÉ 4.3. The Anatomy of a Client ΓòÉΓòÉΓòÉ
The Anatomy of a Client
The client I have provided for this article is a very simple, PM based TCP
packet client. In a nutshell, it connects to a server and sends and receives
packet to and from the server. The server allows multiple client connections
and when one client sends a message the server relays that message to all of
the other connected clients. This is what allows the network "chatting" to
take place.
A good client application should have at least the following capabilities. Of
course, it needs to be able to send and receive messages quickly with these
message being of some standardized protocol. It should also be able to connect
to any server which supports the particular chat protocol. (This ability will
be available in the next article.) The client should have an easy to use user
interface. And, finally, the client should be easily enhanced.
The User Interface
I mentioned before that the client was to be PM based. I did this to make it
easier to handle user input and server output. The interface for the sample
client is a simple one. It contains two buttons, a read-only multiple line
editor, and an entry field. One button is for connecting to the server and the
other for disconnecting while the MLE is for server output and the entry field
is for user input. It is a crude, but effective, interface for our needs.
A more advanced client interface might allow for drag-n-drop font changes or
dynamic font changing based on the dimensions of the main window, etc. These
things, however, are for the future.
The Packet Protocol
The packet protocol I have selected is one which is used by the "Internet
Citizens Band", or ICB, servers for years. A single packet to or from the
client contains three parts and has the form: "l p m", where l is a single
byte which specifies the total length of the packet including itself, p is the
packet type indicator, and m is the packet data. The current client only
supports the login packet, a, and the open message packet, b, for the packet
type.
Even though we have a limited number of packet types right now, by including
this byte of information we are not limited to just these packet types - the
"Internet Citizens Band" server actually supports many other packet types. I
have limited this client only for simplicity's sake. The single byte of the
length does pose one restriction, however, and that is that the total length of
message can only be 253 bytes since the length byte includes the protocol type
and itself in that length.
Sending Packets
Sending packets is very simple. I have defined a user message called SM_SEND
which, when sent to the send/receive thread, tells the thread that there is an
outgoing message. The message contains a pointer to the already prepared
packet in mp1.
Receiving Packets
Receiving packets is accomplished in almost the same way as sending them. When
the send/receive thread loop receives a packet, it is broken down by removing
the l (size) and p (packet type) from the string and then runs through a case
statement to determine the packet type. Since the client only supports the b
(open message) packet type, this is the only case we look for. We also define
a default which takes any of the other packets from the server and ignores
them. Once it is determined that a complete open message packet has been
received the thread then sends another user message, SM_RECV, to the user
interface thread. Once again mp1 contains a pointer to the message string.
Enhancing the Client
It should be obvious how the client is easily enhanced in the last few
sections. I have used a packet protocol which allows for a byte to specify a
different kind of packet. This could include private messages, specially
formatted open messages, or just about anything else you can think of. We
could create a broken up message which could be any packet type that was over
253 bytes. The packet could then be broken into 253 byte chunks and sent
separately. The possibilities are almost endless here. Imagination is the
only limit.
Plugging Into OS/2 Socket Programming (Part 3) - EDM/2 - Jan 1996 - Volume 4,
Issue 1
ΓòÉΓòÉΓòÉ 4.4. The Operation of CLIENT.EXE ΓòÉΓòÉΓòÉ
The Operation of CLIENT.EXE
Now that I have described what goes into the client program I will begin to put
it all together. As I said before, the client contains two threads. I will
call this the user interface thread and the send/receive thread. The user
interface thread handles the user input and server output and the connection of
the client to the server. The send/receive thread handles the sending and
receiving of message packets to and from the server. The two threads will talk
to each other via user defined messages.
Take a look at Figure 2. I have diagrammed the basic execution layout of the
client program there. I will start with the top of the diagram in the user
interface thread and work may way over.
Figure 2) Execution path of client.
Initializing the Client Application
Upon initial client startup the main window is displayed. You must supply a
nickname on the command line when you start CLIENT.EXE. At this point the user
should press the "Connect" button. The connect button send a WM_COMMAND
message with the button id, ID_CONNECT, as one of its parameters which the
window procedure handles by calling a function setupSockets(). SetupSockets()
will initialize the socket environment and create the socket that the client
will use to communicate with the server. If this all occurs normally then
setupSockets() will return the socket descriptor that was created. If all does
not go well then it will return 0 or a negative number. If it is a negative
number then this is the error code multiplied by -1.
Assuming we had a good socket returned then WinPostMsg() is used to send a
SM_SOCKETGO message. The basic structure is in the code to add some kind of
error notification to the user but for times sake I did not include anything to
that effect.
Connecting to the Server
The SM_SOCKETGO message is used to tell the client that the socket environment
is all set up ready to go and we need to connect to the server now. The
message will be handles by calling the connectToServer() function. We send to
this function our socket descriptor, the server name, and the server port. I
have defined, in client.h, the server to be icb.sjsu.edu and the port to be
7326. Leave these be until next month when I will have the server ready for
you.
ConnectToServer() does just that - it connects to the server. It sets up the
necessary hostent struct which is used by the socket function connect() to
determine the place we want to connect to. Notice we are using the
gethostbyname() function in order to determine icb.sjsu.edu's interment IP
address. Upon a successful connection the function loginToServer() is called.
The parameters to this function are the socket descriptor and your chosen
nickname.
LoginToServer() gives us our first look at sending and receiving a message
packet. This is the only time that message will be sent or received outside of
the send/receive thread. The comments at the beginning of the function
describe the format of the login packet. Notice that fields are separated by a
^A or \001 character. This is part of the standard message packet protocol so
if you were to create some new message packet type that used fields you would
want to use that character to separate them. If you follow through the first
couple lines of actual code you will see how I go about assembling the message
packet for our login.
The first communication activity that takes place is the reception of the
protocol packet from the server. This is the server saying "hi there". Using
a bit of string and pointer acrobatics, I take the two fields of this packet
and create the connect message to be displayed on the MLE. The last thing to
do is to send that login packet that was put together. If all goes well the
function will return TRUE; else it will return FALSE to the caller, the
connectToServer() function. A TRUE return code will cause a SM_CONNECTED
message to be posted; otherwise the message "Unable to Connect to Server" is
displayed on the MLE.
The SM_CONNECTED message tells the client that all is ready for normal
communications with the server. The message is handled by calling
_beginthread() to start up the send/receive thread.
The Send/Receive Thread Loop
We now come to the meat of the client application. It is here that all further
communication between the client and the server will take place. The thread
basically executes an continual loop until either we shut down or the server
shuts us down. This loop has two sections:
Check message loop for outgoing messages.
If there are some, then call select() to check for writeability of socket
Continue until all messages are sent or select() returns a not ready.
Check socket for readability by letting select() run for a few seconds
before returning.
Process any incoming messages and pass them on by using SM_RECV messages.
The fist part of the loop checks for incoming SM_SEND, or SM_KILL messages.
This is pretty self explanatory. If an SM_SEND message is received then the
first message parameter, mp1, is used as the pointer to the message to be
sent. Select() will be called to check the socket for writeability. If the
socket is ready to have data sent out then all that is needed is to call the
send() function. The packet is contained in a chunk of allocated memory
pointed to by the SM_SEND message's mp1 parameter. Some error checking should
be used here to insure that all the bytes were sent. The last step is to free
the allocated memory which contains the packet. This process will continue
until no more messages are in the queue.
The SM_KILL message can also be received. The user defined message is used to
tell the send/receive thread to shutdown the socket connection and end the
thread. To do this soclose() is called and the Connected variable is set to
FALSE.
If there are no messages to read or once all of the messages have been read
and processed and no SM_KILL messages were received then the socket will be
checked for incoming packets from the server. To do this, select() is called
again. I included a timeout value of 5 seconds just to give the receive
section a chance to get some data in if there is none at the moment.
If select() returns a ready socket then the first byte is read to determine
the length of the incoming packet. Another read is then done to read in just
that amount of data specified in the first byte. After checking to be sure we
got the correct amount of data in, the packet type is checked in a switch()
statement. If the packet type is b, open message, then the packet message is
sent to the user interface thread via the SM_RECV thread. If a packet type is
received which is not supported then the memory that contains it is freed.
This loop continues indefinitely until the SM_KILL is received or the program
is terminated.
The User Interface Thread
The user interface thread, as I said before, is responsible for handling the
user input and server output. The whole thread runs off of a standard client
window procedure.
The user input part is fairly simple. The message loop captured the WM_CHAR
message and looks for the enter or return key to have been pressed. It then
queries the text in the WND_INPUT window and if there is text in there it
processes the string.
To process the string, the string, open message packet type, and packet length
byte is inserted into a 256 byte character string. A null terminator is added
to specify the end of the created string. The message packet is then sent to
the send/receive thread via the SM_SEND message. The final thing done is to
show the user his own message on the output window.
The server output is handled a bit differently. Once the SM_RECV message is
received another series of string acrobatics is done to break the fields of
the packet up. When we receive an open message packet from the server it
contains 2 fields. The first field is the nickname of who sent the message
and the seconds is the message itself. Once the packet is broken up it is
then displayed on the output window.
Plugging Into OS/2 Socket Programming (Part 3) - EDM/2 - Jan 1996 - Volume 4,
Issue 1
ΓòÉΓòÉΓòÉ 4.5. Wrap Up and Next Time ΓòÉΓòÉΓòÉ
Wrap Up and Next Time
Well, we are almost finished. This month I have use a simple client
application which allows a chat over TCP/IP networks. Please examine the code
and try to understand how I have integrated the socket functions into a PM
program and how things like the select() call work. If you have any questions
I can always be reached at aviator@mindspring.com.
Next time I will include a server which you can set up yourself and allow
anyone on your network to chat. I will also change the client code so you can
specify what server you want to use. Thanks for you time. I hope you have
learned a lot.
Plugging Into OS/2 Socket Programming (Part 3) - EDM/2 - Jan 1996 - Volume 4,
Issue 1
ΓòÉΓòÉΓòÉ 5. /dev/EDM/BookReview ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 5.1. Introduction ΓòÉΓòÉΓòÉ
/dev/EDM2/BookReview
Written by Carsten Whimster
Introduction
In /dev/EDM2/BookReview, I focus on development books and materials. I have
written this column 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 what
you want it to be. I read and respond to all mail.
OS/2 Warp Presentation Manager API is a new reference book from Wiley which
covers the Presentation Manager API (surprise), both documented and
undocumented.
/dev/EDM2/BookReview - EDM/2 - Jan 1996 - Volume 4, Issue 1
ΓòÉΓòÉΓòÉ 5.2. Errata ΓòÉΓòÉΓòÉ
Errata
My Web page now has a new section on publishers, including a list of currently
available books from each publisher. If you have any comment, mail me. If you
have any additions or corrections, mail me. Note the change of URL too. Check
it out at http://www.undergrad.math.uwaterloo.ca/~bcrwhims/os2/index.html .
I have been using my new copy of VAC++ and the WorkFrame is slow, even with C
programs. I also don't seem to be able to turn off all the informational
messages that a compile brings up. I have them turned off for the compiler
itself, but the rest of them are as healthy as ever, completely cluttering up
even a routine compile. Oh well, it works well enough I guess. I did run into
some problems when I wanted a stand-alone program. I was using the math
library, but in spite of an include, the linker could not find the library, and
the compile would not consistently finish. Sometimes it would, but mostly it
wouldn't. Eventually I just created a table of cos and sin values in my header
file, but what a hazzle. Other than the speed, the message overdose, and the
math compilation problems, it is a great environment, and I am taking to LPEX
quicker than I thought I would. The speed, though, the speed. On a DX4-100
with 20Mb it really ought to fly, but no such luck. I hope they rewrite it in
VAC++ rather than Smalltalk next time. I should be releasing a small utility
soon, and perhaps write an article for EDM/2 on the problems I had to solve
while coding.
/dev/EDM2/BookReview - EDM/2 - Jan 1996 - Volume 4, Issue 1
ΓòÉΓòÉΓòÉ 5.3. OS/2 Warp Presentation Manager API ΓòÉΓòÉΓòÉ
OS/2 Warp Presentation Manager API
This month's book is second in a new series of three API references from John
Wiley and Sons, covering the Control Program, Presentation Manager, and
Workplace Shell APIs. This particular book also promises to cover more than
just what the Warp Toolkit online references cover, while presenting the
material in a well-structured, easy-to-use manner. Here are the chapters:
1. PM Application Setup and Cleanup
2. Registering and Creating Windows
3. Messaging
4. Keystrokes and Focus
5. Presentation Spaces and Device Contexts
6. Window Drawing Functions
7. Clipping and Invalid Regions
8. Menus
9. Dialogs
10. Standard Dialogs
11. Resources
12. Help
13. Window Information
14. System Information
15. Atoms
16. The Clipboard and Dynamic Data Exchange
17. Rectangles
18. Task List Functions
19. Workplace Shell Functions
20. National Language Support
Appendix A. WinLockVisRegions
Similar to last month's book, publishing deadlines did not allow the
development of a full complement of examples for each API, but there are a few
this time. The major difference between this book and last month's book is
that I find the chapter introductions a little more sketchy. Perhaps that was
necessary to keep the book a similar size, but I prefer slightly more detailed
descriptions, and the PM Win functions really require this unless you have
already used them.
Like the previous book, the organization of the book is as follows:
each major topic is given its own chapter (see above)
each chapter has a few introductory paragraphs, tutorial in nature
each function which comes under this chapter's heading is then given, as
follows:
- name and type of API (ie. chapter heading repeated)
- brief description
- syntax
- parameters, each with a brief explanation, and tables of possible
values, if appropriate
- returns, with value and description of error codes
- other info, including include file, define, ordinal, and DLL API
resides in
- see also, with related APIs, each with a page number
- notes, including warnings, restrictions and so on
This very simple layout makes it very simple to navigate, and powerful,
although having used this book for the better part of a month, I find that
this layout does compromise the quick-lookup ability for a single function,
which most other reference books have. I am undecided as to whether this
layout is better in the end, or whether a more traditional pure-alphabetical
layout is preferable. In writing my current program I think the alphabetical
approach has won so far, but perhaps in the long run, the new layout works
best? In any case, both work, and both have their strengths and weaknesses.
One thing is for sure, I like the OTHER INFO section, with its INCLUDE
information. Now my utility has only the necessary includes, and whether that
makes a difference or not to the size of the compiled program or the
compilation speed, I feel better about it. I have never liked the fact that
all functions in a library get brought in by C, whether you need them or not.
That is it, for the second time! I have been much busier this month, so I
didn't get all the way through this book like last month. With this type of
reference that really isn't necessary though. The functions are all there,
and the first appendix even has a late-breaking addition of the
WinLockVisRegions function. I am not sure why it is here, and not in the main
part, since it is documented in the pmwin.h file, but perhaps it wasn't in
previous versions and only just made it in time for publicat ion.
This review is a little short again, but this month I won't include a sample
function since it is so similar in layout to the original book in the series.
I will instead just add a example of the sample code that is in a very few
functions in this book. This one is for WinBeginPaint(), style unaltered:
case WM_PAINT:
{
HPS hps; // cached-micro PS handle
RECTL rcl; // bounding rectangle
hps = WinBeginPaint ( hWnd, NULLHANDLE, &rcl );
GpiErase ( hps );
WinEndPaint ( hps );
}
return 0;
Figure 1) Sample code from the book for the WM_PAINT message.
There you are, all done for this month. This book, due to the "not quite
enough for me" chapter introductions, and the struggle with alphabetized
versus sectionized layout, loses the A+ of the last book, but retains an A,
and is still a great reference book. Another must-have from this series.
/dev/EDM2/BookReview - EDM/2 - Jan 1996 - Volume 4, Issue 1
ΓòÉΓòÉΓòÉ 5.4. Summary ΓòÉΓòÉΓòÉ
Summary
This is now my favorite PM reference book, as well as one of my only two PM
reference books [grin]. I had a less successful time with the sectionized
layout than with the Control Program API book, perhaps because of the more
diverse nature of the mater ial, and I needed more of an explanation at the
start of each chapter, due to the more complicated nature of the material, but
got only the same level of explanation, so it gets an A instead. Still a great
book, and so far without much competition as a PM reference book in my library.
A must-have for serious PM programmers.
/dev/EDM2/BookReview - EDM/2 - Jan 1996 - Volume 4, Issue 1
ΓòÉΓòÉΓòÉ 5.5. Book Reviewed ΓòÉΓòÉΓòÉ
Book Reviewed
OS/2 Warp Presentation Manager API, Barnum
- John Wiley and Sons. ISBN 0-471-03887-3. US$29.99, CAN$40
- OS/2 C/C++ PM Programmers
- A
This is an excellent reference to the Presentation Manager API. It is
very complete, but the topical layout may throw you for a loop if you are
used to alphabetized books. It contains syntax, usage guides, data
structures, and sample cross-referencing. Highly recommended.
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.
/dev/EDM2/BookReview - EDM/2 - Jan 1996 - Volume 4, Issue 1
ΓòÉΓòÉΓòÉ 5.6. Content Index ΓòÉΓòÉΓòÉ
Content 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 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéOCH Γöé3-9 ΓöéOS/2 Certification Handbook Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéCPA Γöé3-10 ΓöéOS/2 Warp Control Program API Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéPMA Γöé4-1 ΓöéOS/2 Warp Presentation Manager API Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
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 ΓöéDriver ΓöéAVIO ΓöéIntro Γöé Γöé Γöé Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé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 Γöé(WIN) 5Γöé0 Γöé0 Γöé0 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéPWG ΓöéA- Γöé0 Γöé0 Γöé0 Γöé1 Γöé5 Γöé5 Γöé5 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéCPA ΓöéA+ Γöé5 Γöé0 Γöé0 Γöé0 Γöé0 Γöé0 Γöé0 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéPMA ΓöéA Γöé0 Γöé0 Γöé0 Γöé5 Γöé1 Γöé1 Γöé1 Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
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 ΓöéThread ΓöéGPI ΓöéFonts ΓöéPrint ΓöéWPS Γöé
Γöé Γöé ΓöéBasics ΓöéDriver ΓöéAVIO Γöé Γöé Γöé Γöé Γöé Γöé Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéDOA ΓöéA Γöé4 Γöé4 Γöé2 Γöé4 Γöé5 Γöé3 Γöé2 Γöé3 Γöé0 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé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 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéOCH ΓöéA Γöé? Γöé? Γöé? Γöé? Γöé? Γöé? Γöé? Γöé? Γöé? Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
RATINGS LEGEND:
ΓöîΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé0ΓöéNo coverage Γöé
Γö£ΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé1ΓöéVery light coverage Γöé
Γö£ΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé2ΓöéIntroductory coverage Γöé
Γö£ΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé3ΓöéGood Coverage Γöé
Γö£ΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé4ΓöéIn-depth coverage Γöé
Γö£ΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé5ΓöéAuthoritative Γöé
ΓööΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
/dev/EDM2/BookReview - EDM/2 - Jan 1996 - Volume 4, Issue 1
ΓòÉΓòÉΓòÉ 5.7. Coming Up ΓòÉΓòÉΓòÉ
Coming Up
I will now take a break from this API series, both because I have a few other
books lined up, and also because I have not done any WPS programming, and so
need to get going on that before I can do a proper review of it. I will likely
review Programming in REXX or The REXX Cookbook next month, or perhaps The OS/2
Warp Programmer's Sidekick, which I have found quite useful recently.
Books I have:
OS/2 Warp Workplace Shell API, Pollack
The OS/2 Warp Programmer's Sidekick, Diviney and Murray
Programming in REXX, Daney
The REXX Cookbook, Callaway
Other books I would like to review:
The Design of OS/2, 2nd Edition, Kogan and Deitel - I am having trouble
getting a copy of this, so if anyone can help, please do. A 1st edition would
do me fine too.
OS/2 C++ Class Library: Power GUI Programming with C-Set++, Law, Leong, Love
and Tsuji - This is on the way I am told.
OS/2 Presentation Manager GPI, 2nd edition, Winn - I really would like to
review this soon, as I am coming across some stuff that the old one doesn't
handle in an up-to-date manner, and want to see what the new one is all about.
Visual Age: Concepts and Features, ? - This sounds interesting.
If anyone has a book they want to see reviewed, I will be happy to oblige.
Just mail me and tell me which. 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 a nd advanced user books I receive.
/dev/EDM2/BookReview - EDM/2 - Jan 1996 - Volume 4, Issue 1
ΓòÉΓòÉΓòÉ 6. OOPS Avenue ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 6.1. Introduction ΓòÉΓòÉΓòÉ
OOPS Avenue
Written by Gordon Zeglinski
Introduction
So what happened to the rest of the screen saver DTS series? Seems life is
full of mini-disasters up here. Last month I injured my shoulder which made
typing impossible. This month I had to reinstall OS/2 and reformat the hard
disk. I have not yet reinstalled the SOM toolkit or Metaware's High C/C++.
Until I have time to do so, the DTS articles will have to wait. Instead, we
will talk this month about C++ exceptions.
C++ exceptions are a powerful method of handling special cases. Traditionally,
one might do something like:
switch( foo(MyArguement,&var) ){
case 0: //alls well
break;
case 1:
foo(0,&var); //myarguement is invalid..
break;
case 2; //out of memory or other serious error
exit(2);
break;
default:
fprintf(stderr,"Unknown Error returned from foo\r\n");
break;
}
Figure 1) Traditional method of error code handling.
Depending on the return value from foo(), an error condition may or may not
exist. Exceptions follow a similar concept but are far more powerful.
OOPS Avenue - EDM/2 - Jan 1996 - Volume 4, Issue 1
ΓòÉΓòÉΓòÉ 6.2. What is Exactly is a C++ Exception? ΓòÉΓòÉΓòÉ
What is Exactly is a C++ Exception?
An exception is an object designed by the programmer specifically to relay
error information. They can be organized in hierarchies, as in the following
example:
class ErrorBase{
public:
ErrorBase(char *F,int L);
ErrorBase(const ErrorBase &error);
virtual ~ErrorBase();
const char* GetFile() const {return File;}
int GetLine() const {return Line;}
protected:
char *File;
int Line;
};
class ErrorBadArg:public ErrorBase{
public:
ErrorBadArg(char *F,int L);
ErrorBadArg(const ErrorBadArg &error);
~ErrorBadArg();
};
class ErrorNoMem:public ErrorBase{
public:
ErrorNoMem(char *F,int L);
ErrorNoMem(const ErrorNoMem &error);
~ErrorNoMem();
};
Figure 2) Sample exception hierarchy.
An advantage of using heirarchies of error objects is that any error object
with a parent can be caught by blocks expecting the parent object. We'll look
at catching exceptions by the exception object's parent class later.
OOPS Avenue - EDM/2 - Jan 1996 - Volume 4, Issue 1
ΓòÉΓòÉΓòÉ 6.3. Try, Catch and Throw ΓòÉΓòÉΓòÉ
Try, Catch and Throw
"Try" blocks are used to "catch" exceptions that are thrown in functions called
within the block. We have already seen that an exception is nothing more than
an object designed to convey error information. Unlike the simple switch case,
however, try blocks can be nested within and across function calls. Also,
exceptions don't rely on the function returning a value. The following sample
code illustrates a nested exception.
void foo1(){
try{
foo2();
}
catch(ErrorBase error){
cerr<<"An exception was thrown from file "<<error.GetFile()<<" Line "<<error.GetLine()<<endl;
}
catch(...){ //some other error
cerr<<"Some other exception has been thrown"<<endl;
}
}
void foo2(){
try{
foo3(10);
}
catch(ErrorBadArg){
try{
foo3(0);
}
catch(ErrorBadArg){
cerr<<"I give up. 0 is not a valid arg to foo3"<<endl;
}
catch(ErrorNoMem){
cerr<<"We're Out of memory"<<endl;
throw; //I don't want to handle this let whoever called me get a kick at it
}
}
catch(ErrorNoMem){
cerr<<"We're Out of memory"<<endl;
throw;
}
}
void foo3(int arg){
if(arg==rand()%10)
throw ErrorBadArg(__FILE__,__LINE__);
if(arg==rand()%40)
throw ErrorNoMem(__FILE__,__LINE__);
}
Figure 3) Nested exception example.
Function foo1() calls function foo2(). Any exceptions rethrown by foo2() or
that are not handled by foo2() can be caught by foo1(). In fact, the statement
"catch (...)" in foo1() catches all exceptions that aren't explicitly handled.
In this case, any exception other than those in the ErrorBase() family are
caught by the catch (...) block. Function foo3() illustrates how to throw an
exception.
OOPS Avenue - EDM/2 - Jan 1996 - Volume 4, Issue 1
ΓòÉΓòÉΓòÉ 6.4. Formal Exception Declaration ΓòÉΓòÉΓòÉ
Formal Exception Declaration
In order to make sure that a function only throws certain exceptions, C++
allows a list of exceptions to be given with the function declaration.
Rewriting foo3() we have:
void foo3(int arg) throw(ErrorBadArg,ErrorNoMem){
if(arg==rand()%10)
throw ErrorBadArg(__FILE__,__LINE__);
if(arg==rand()%40)
throw ErrorNoMem(__FILE__,__LINE__);
}
Figure 4) Declaring a method to throw specific exception classes.
Now foo3() can only throw the exceptions ErrorBadArg and ErrorNoMem. An
attempt to throw any other exception will result in a runtime error. This
makes it easier for the programmer to use third party libraries. The program
will not encounter any surprise exceptions because the set of exceptions which
a routine may throw is guaranteed.
Note: foo3() must catch all exceptions in any routine it calls other than the
two it declares as those to be thrown by it.
OOPS Avenue - EDM/2 - Jan 1996 - Volume 4, Issue 1
ΓòÉΓòÉΓòÉ 6.5. Runtime Exception Errors ΓòÉΓòÉΓòÉ
Runtime Exception Errors
There's two runtime errors that can occur in the exception handling code.
First, the exception might not be caught by any try/catch block. Second, an
exception that wasn't in the declaration list for a function might not be
caught by the function or a programmer may try to throw an unlisted exception.
In the first case, the "terminate" function is called, in the second, the
"unexpected" function is called. The functions set_terminate() and
set_unexpected() can be used to replace the default function with application
specific ones. The following sample shows how to use set_terminate().
typedef void (*pVdFn)();
void My_Terminate(){
cerr<<"My Terminate Called"<<endl;
exit(1);
}
int main(){
pVdFn oldFn=set_terminate(My_Terminate); //replace the previous terminate fnc
foo3(11);
set_terminate(oldFn); //set the terminate fnc back to the original
/* do other stuff here */
return 0;
}
Figure 5) Using set_terminate().
In the above sample, if an exception occurs in foo3(), My_Terminate() should be
called because we didn't set up a catch/try block.
Note: set_unexpected() is used in the exact same way as set_terminate().
OOPS Avenue - EDM/2 - Jan 1996 - Volume 4, Issue 1
ΓòÉΓòÉΓòÉ 6.6. Gotchas ΓòÉΓòÉΓòÉ
Gotchas
There are two areas to watch out for. The first one is resource leaks. The
second one is an overreliance on exceptions to alter the programs flow. Let's
look at the following sample function.
void foobar(char *arg){
char *X=new char[300];
DosRequestMutexSem(hMux,-1);
if(arg==NULL)
throw ErrorBadArg;
DosReleaseMutexSem(hMux);
delete [] X;
}
Figure 6) Resource leaks with thrown exceptions.
There are 2 potential resource leaks in this function. Because the throw
alters the programs flow, when the throw statement is executed the mutex
semaphore will not be released and the allocated memory will not be returned to
the heap. There are several different ways of fixing this problem. The
easiest is to move the allocation and semaphore request to after then throw
statement.
void foobar(char *arg){
if(arg==NULL)
throw ErrorBadArg;
char *X=new char[300];
DosRequestMutexSem(hMux,-1);
DosReleaseMutexSem(hMux);
delete [] X;
}
Figure 7) Removing the leak by relocating the resource allocation.
Another approach would be to release the semaphore and free the memory before
throwing the exception.
void foobar(char *arg){
char *X=new char[300];
DosRequestMutexSem(hMux,-1);
if(arg==NULL){
DosReleaseMutexSem(hMux);
delete [] X;
throw ErrorBadArg;
}
DosReleaseMutexSem(hMux);
delete [] X;
}
Figure 8) Removing the leak by freeing the resource before throwing an
exception.
Finally, the most thorough way is to use objects to handle the memory and
semaphore.
template<class T> class MemBlock{
typedef T *pT;
public:
MemBlock(size_t len){Block=new T[len];}
~MemBlock(){if(Block!=NULL) delete [] MemBlock;}
operator pT(){return Block;}
protected:
pT Block;
};
class MutexRequest{
typedef unsigned long ULONG;
typedef unsigned long HMTX;
public:
MutexRequest(HMTX hand,ULONG time){hmtx=hand;DosRequestMutexSem(hmtx,time);}
~MutexRequest(){DosReleaseMutexSem(hmtx);}
protected:
HMTX hmtx;
};
void foobar(char *arg){
MemBlock<char> X(300);
MutexRequest sem(hMux,-1);
if(arg==NULL)
throw ErrorBadArg;
/* do other stuff here */
}
Figure 9) Removing the leak by performing resource management in the
constructor and destructor.
This last approach has a hidden advantage. Suppose we called some other
functions in foobar() and one of these functions threw an exception. What
would happen in either of our first 2 versions of foobar()? The answer is that
we would have the same resource leak that we fixed in the last 2 versions.
Unless we add a try/catch block in foobar() and then place calls to
DosReleaseMutexSem() and delete inside the catch block, we will leak resources.
Encapsulating the resources and using constructors/destructors to handle their
allocation and deallocation provides a safer alternative than manually
maintaining the deallocation of resources in several possible exit points.
The second pitfall is using exceptions too liberally. Suppose we have a
function that has a fixed set of valid results. Let's say that one result
happen most of the time, but it is possible in some cases for the others to
occur. Should we use exceptions? The answer is no. Exceptions should only be
used to indicate error conditions, not to indicate which action a function
performed. As we seen from the C++ compiler benchmarks several issues ago,
throwing exceptions is expensive. Not only is throwing the exception
expensive, but setting up a try block alone can have noticeable overhead. To
keep performance acceptable, exceptions should only be used to indicate an
error condition.
OOPS Avenue - EDM/2 - Jan 1996 - Volume 4, Issue 1
ΓòÉΓòÉΓòÉ 6.7. Wrapping Things Up ΓòÉΓòÉΓòÉ
Wrapping Things Up
This concludes our look at C++ exception handling. We covered how to define
exceptions, catching, and throwing exceptions. Also, we seen how to handle
unexpected results by using the set_terminate() and set_unexpected() functions.
Exceptions provide a formal method for handling and declaring error conditions.
They have significant run time cost and should only be used where necessary.
OOPS Avenue - EDM/2 - Jan 1996 - Volume 4, Issue 1
ΓòÉΓòÉΓòÉ 7. REXX Inside and Out ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 7.1. Introduction ΓòÉΓòÉΓòÉ
Rexx Inside and Out
Written by Joy Wyatt
Introduction
When Rexx was originally written for IBM's Virtual Machine operating system, it
was given no native file handling capabilities. VM has its own file handling
command, EXECIO, which has proven to be sufficient in that environment. There
is a down side to everything and the problem with EXECIO is that it is part of
VM and not an architected element of the Rexx language. When portability became
an issue, Mike Cowlishaw, author of Rexx, went back to the drawing board and
designed enhancements to the language that allow Rexx programs to read and
write to files in such a way as to be independent of the operating platform.
This article will take a look at each of Rexx's file handling functions to
perform the basics of file manipulation.
"So what, Uncle Bob, are the basics", you ask? Well, boys and girls, quit
calling me Uncle Bob and we'll get on with it. Rudimentary file function
includes opening a file, writing to it, reading from it, and closing it. There
is more than one way to do each of these and we will discuss all of the ones I
know about, their good points, and their bad. Before we get into the nitty
gritty we must get a definition behind us.
file pointer: A file pointer is a place holder the operating system uses to
keep track of where the program is reading or writing in a file. Let's use a
small file as an example to provide an illustrative definition. Imagine the
file as 512 characters typed onto a page. Take your finger and point to the
first character on the page. Read the character under your finger and move
your finger to the next character. Your finger on the page is like the file
pointer OS/2 uses. When you tell OS/2 to read a line or a character from a
file, OS/2 moves its "finger" to the next line or character to be read.
Although OS/2 doesn't really have any fingers it does have a better imagination
than you do.
Rexx Inside and Out - EDM/2 - Jan 1996 - Volume 4, Issue 1
ΓòÉΓòÉΓòÉ 7.2. Opening a file ΓòÉΓòÉΓòÉ
Opening a file
While Rexx does not contain a specific "open file" function, there are at least
five methods of opening a file on purpose (explicitly as opposed to
implicitly). The first four are easy to explain away.
Any attempt to write to an unopened file using the lineout or charout functions
will implicitly attempt to open the file for read/write processing. These
functions can also be used to explicitly open a file. The following
statements:
/* open file and place file pointer on line 1 */
rc = lineout( myFile, , 1 );
rc = charout( myFile, , 1);
Figure 1) Implicitly opening a file for read/write access.
will attempt to open the file whose name is contained in the variable myFile.
If the open process is successful the value of rc will be "0" and the file
pointer will be positioned at the beginning of the existing file. If, for some
reason, the file cannot be opened rc's value will be "1". While this is
functional, it generally leads to such descriptive error messages as, "Hey,
Hoser! Your file just ain't going to make it this time." This isn't a lot of
debug information to go on. The input functions are similar in that the first
use of them on an unopened file will implicitly attempt to open the file. They
also may be used for an explicit open as follows:
/* open file and read zero lines from line 1 */
rc = linein( myFile, 1, 0 );
/* open file and read zero chars from char 1 */
rc = charin( myFile, 1, 0);
Figure 2) Implicitly opening a file for read-only access.
When either of these functions, used in this manner, are successful the file
pointer is placed at the first character of the file. As far as diagnostic
information is concerned these input functions are worse than their output
siblings. These functions return data and no numeric code. If everything went
well there is no return data from the function because of the "0" in the
parameter list. If the file could not be opened then there is no return data
from the function. This leads to error messages similar to, "Hey, Hoser. If
you got this message then there were no syntax errors in the open call, but we
don't know if your file opened successfully."
"Alas!", you cry. "Are users of my Rexx code destined to be called 'Hosers'
for the rest of their days?"
Maybe. But you can at least give them some decent debugging information as
well by using the stream function to open your files.
The stream function is multipurpose and can handle the opening of files very
nicely. Stream has other uses, but this article will not delve into them. We
will limit ourselves to using stream to open and close files. The following
invocation of stream:
rc = stream( myFile, "c", "open" );
Figure 3) Explicitly opening a file.
will attempt to open the file for reading and writing and place something a bit
more usable in the return area if the attempt fails.
Should the file be opened successfully the string "READY:" is stored in your
result area. If there are problems, however, a string similar to "NOTREADY:nn"
is issued. The "nn" in this case is a return code that indicates the reason
the attempt to open the file failed. This code can be used with OS/2's help
facility to provide the user with some valuable information. See example code
Rexx_a.cmd for an illustration.
The stream function can also be used to open a file and designate its intended
use. This allows you to set the file pointer for the processing you desire.
The default open mode is "read" which will place the file pointer at the first
byte of the file. Changing the third parameter from "open" to "open write"
will cause the file pointer to be placed at the end of the file. "Open read"
as the third parameter will set the file pointer to the top of the file and
limit the function to read only.
Most of the Rexx programs that I have seen, though, do not use any of these
explicit methods for opening a file for processing. If the two terms "quick
and dirty" and "Rexx programming" seem synonymous to you then you may already
be aware that the first use of any of the input/output functions will
implicitly attempt to open the file. You still, of course, are limited to the
eloquent "1" or "0" diagnostics with this method.
Rexx Inside and Out - EDM/2 - Jan 1996 - Volume 4, Issue 1
ΓòÉΓòÉΓòÉ 7.3. Reading Data From a File ΓòÉΓòÉΓòÉ
Reading Data From a File
Unlike open, you cannot read (or write) data by accident. Two built-in methods
for reading data exist in the Rexx language. The "C" programmer in me was
fairly comfortable dealing with the "one character at a time" functionality of
the charin function, but the rich string handling functions in Rexx have caused
me to all but abandon charin.
Charin
Charin reads one or more characters at a time from a specified location and
returns the data to the result area. It is quite handy when there are no CR LF
defined records in the file to be read or when a specified block length is
needed, but that is usually a contrived situation on the PC platform. To test
the performance, I created a file with 1024 records of 1024 bytes each and read
them using both charin and linein. Detailed results are located in a table
after the linein discussion.
Syntax of the charin function:
text = charin(myFile, start, count);
Figure 4) Syntax of charin.
To make things interesting none of the parameters are required. If myFile is
not specified then the data is taken from the standard input device (usually
the keyboard). The second parameter, start, positions the file pointer before
the read takes place. The final parameter, count, specifies the number of
characters that are to be read. So to read eight characters starting at the
50th character, the function would be coded as follows:
text = charin(myFile, 50, 8);
Figure 5) Using charin to read a specific set of characters in a file.
That's about all there is to it. An example of the use of charin is included
as Rexx_b.cmd. This program does a hex dump of itself. Not very useful, I
agree, but you are welcome to customize the program for your own uses.
Linein
The Rexx language is a string manipulator's dream language (relative to C,
PL/1, FORTRAN, Pascal, or COBOL). Because of this it is quite nice to consider
an entire line at one time. This is achieved with the linein function.
Linein's syntax:
record = linein(myFile, start, count);
Figure 6) Syntax of linein.
It would follow that the parameters act just like those of charin. They don't.
MyFile still contains the name of the file to be read, and defaults to the
standard input if not specified. Start specifies the line you wish to place
the file pointer on before the read is done. OS/2 only allows a start value of
1, the beginning of the file. Count is still the number of lines to read, but
the only valid values are "1" and "0".
So which function is best to perform a read? It depends. If you are
performing random reads of files with constant record sizes then you might want
to use charin because of its ability to position the file pointer. If there
are variable length records in the file and the program considers a record at a
time during processing it makes sense to use linein. There is usually a design
consideration that makes one of these functions better than the other. It is a
good knowledge of how each one works that gives the programmer the power to
make that decision.
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé Γöélinein Γöécharin Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé1 byte/read Γöén/a Γöé705.94 secs Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé1K bytes/read Γöé3.7 secs Γöé1.65 secs Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé1M bytes/read Γöén/a Γöé2.6 secs Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
Table 1) Comparison of the performance of linein and charin by the number of
characters handled when reading file with 1024 records of 1024 bytes each.
Cache was cleared between each test.
Rexx Inside and Out - EDM/2 - Jan 1996 - Volume 4, Issue 1
ΓòÉΓòÉΓòÉ 7.4. Writing to a File ΓòÉΓòÉΓòÉ
Writing to a File
Each of the input functions described above, charin and linein, have twins for
writing data to a file. These functions are fairly consistent with their
sibling input functions, but there is a difference when these functions are
used to open the file implicitly. If charout or lineout are used the file is
opened for write, the file pointer is positioned at the end file, and the data
to be written is appended to the file.
Charout
Charout will place a string into a specified file starting at any location
within the file that the programmer desires. No carriage return/line feed
combination is inserted after the data.
count = charout(myFile, text, start);
Figure 7) Syntax of charout.
This function call looks much like charin with text, start, and count shifted.
Text is the string to be written to the file. String can contain non-printable
characters (including carriage returns and line feeds). Start, again, is the
position of the file pointer before the read. The desired value of count is 0.
Count does not indicate the number of bytes successfully written to the file,
but indicates the number of bytes not written to the file because of some type
of error.
Lineout
While charout could be used several times during the output of a single record,
lineout will always append the text with an end of record marker. This requires
the programmer to build all data for the record in a program variable. Lineout
looks quite similar to its cousin, charout.
count = lineout(myFile, text, start);
Figure 8) Syntax of lineout.
The parameters and return values are the same as charout except that they deal
with lines rather than characters. The only valid value of start is "1". This
will set the file pointer to the beginning of the file and existing text will
be overwritten. Omit the parameter to continue writing where the file pointer
currently resides.
Rexx Inside and Out - EDM/2 - Jan 1996 - Volume 4, Issue 1
ΓòÉΓòÉΓòÉ 7.5. Closing the File ΓòÉΓòÉΓòÉ
Closing the File
Either of the output functions may be used to close the file by supplying only
the file name as an argument.
lineout( myFile );
charout( myFile );
Figure 9) Implicitly closing a file.
Either of the two functions will suffice. However, and there is always a
however, if the close should fail there is no indication of this fact nor the
reasons for its occurrence. The stream function should be used for programs
other than personal utilities to close the file as well as open it.
rc = stream(myFile, "c", "close");
Figure 10) Explicitly closing a file.
The above invocation should look familiar. The diagnostics are not as
descriptive for close as they are for open, but at least there is an indication
of the success of the call. Should the close command fail, the stream function
will return a null string. The literal "READY:" is returned after a
successful close.
Rexx Inside and Out - EDM/2 - Jan 1996 - Volume 4, Issue 1
ΓòÉΓòÉΓòÉ 7.6. Other File Functions of Note ΓòÉΓòÉΓòÉ
Other File Functions of Note
Reading data from a file is fine and good, but it would be nice to know when to
stop reading. I'll quickly outline two functions that exist for this purpose.
Chars
Chars is a function that will return the number of characters from the current
location of a file pointer to the end of the file. This function can be used
with the character based input function, charin, to calculate the number of
times a loop needs to be iterated to read the entire file. It is suggested
that chars be called once before the loop to calculate a constant value for the
loop comparison rather than calling the function in the loop. Chars only
accepts one argument.
count = chars( myFile );
Figure 11) Syntax of chars.
The above invocation will return the number of bytes from the current location
of the file pointer to the end of myFile. Execution of this function against
any defined OS/2 device, such as LPT1:, will always return "1". Chars cousin is
lines.
Lines
You might think that the lines function would return the number of lines from
the file pointer to the end of the file. You might have caught on by now that
OS/2 has no idea how many lines there are from the current file pointer to the
end of the file. Since there is no constant record structure in an OS/2 file
the lines function simply returns a "1" if there are remaining lines to be
read. This means that you cannot use lines to calculate a constant number of
times to process a loop, but must use the function in the loop comparison.
do while( lines( myFile ) )
rec = linein( myFile )
end
Figure 12) Using lines in a loop.
This snippet of useless code will read all of the data in myFile and stop at
the end of file. The body of the loop should be customized to actually perform
some useful work.
Rexx Inside and Out - EDM/2 - Jan 1996 - Volume 4, Issue 1
ΓòÉΓòÉΓòÉ 7.7. That's the Basics ΓòÉΓòÉΓòÉ
That's the Basics
You can't get much more basic than open, close, read, and write. There is more
than one way to do each of these. The correct way depends on the context of
your program and its intended audience. The important point is that your
understanding of the available functions is key to your choosing the best
method to fit the program's circumstances.
More (and probably better) information can be obtained from OS/2's online Rexx
manual. If you would like to comment on or contest any of this information
please feel free to do so. My email address is in the "Contributors" section.
Rexx Inside and Out - EDM/2 - Jan 1996 - Volume 4, Issue 1
ΓòÉΓòÉΓòÉ 8. Under the Scope ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 8.1. Introduction ΓòÉΓòÉΓòÉ
Under the Scope
Written by Brad Scharf
Introduction
Welcome to the utility review column. This is a new column that will review
freeware, shareware and commercially available applications intended to aid the
development process and initially will be targeted towards beginner OS/2
programmers.
The column will feature one or two utilities each month. I will try and let
the reader know in advance which tools will be featured. Also, there will be
an index at the end of every column that will include program names and
descriptions, which issue of EDM/2 featured the program review and in future
issues I will try and let the reader know where the utilities can be found and
at what cost.
By the way, if you have any comments or suggestions regarding this column
please let me know. If the column is to be a success it will be through the
feedback of its readers. Likewise, if you know of a utility that would be
beneficial to other programmers please mention it and I'll do what I can to
ensure that readers are made aware of it. I may be reached via the internet at
schab@sasknet.sk.ca .
Under the Scope - EDM/2 - Jan 1996 - Volume 4, Issue 1
ΓòÉΓòÉΓòÉ 8.2. What's Reviewed ΓòÉΓòÉΓòÉ
What's Reviewed
In my own experience, and I imagine most of your own, I have found that despite
my best intentions my programs don't always behave as expected. (That must be
a first!) Usually this isn't a problem but occasionally I'll compile and run a
program which I then can't shutdown, even from the Window List.
In addition to the above, sometimes we will write applications that modify
system INI files. It's a sad fact of life that the modifications will not
always be as expected, or perhaps we just wish to remove them in order to leave
things as they were before testing our projects.
To help us deal with both of these issues, I review in this issue a process
monitor utility entitled PSPM/2, as well as an INI file editor called EDITINI.
So read on!
Under the Scope - EDM/2 - Jan 1996 - Volume 4, Issue 1
ΓòÉΓòÉΓòÉ 8.3. PSTAT PM/2 v5.10 ΓòÉΓòÉΓòÉ
PSTAT PM/2 v5.10
PSTAT PM/2 (PSPM/2) is a 32-bit PM utility that provides the user with a
graphical representation of running processes as well as information about
those processes, such as hierarchical relationships, number of threads and
thread info.
All of the information that can be obtained from this program is available from
the PSTAT program that ships with OS/2. In fact, PSTAT will actually provide
more information than PSPM/2. The usefulness of PSPM/2 lies in its ease of
use, simple visual representation of running processes, point-and-shoot
capabilities, continual refresh (if desired) and perhaps most of all, the
ability to terminate running processes. Unlike some other process killers,
PSPM/2 works independently from OS/2s PSTAT program.
The need for this type of utility first became apparent to me when, after
writing my first PM program, I could not stop it from running. The appearance
program icon indicated that it was running but nothing appeared on the screen,
nor did the program appear in the window list. The only method available to
shut down the application was to reboot my PC. Obviously this is not the
preferred method of shutting down applications!. As it turned out, I had
declared the window to include a menu item that I failed to provide in a
resource file. Everything compiled OK but the system didn't like it very much.
In comes PSPM/2...
In cases as I've mentioned PSPM/2 performs very well. It allows one to obtain
basic information about a running process and to shut the process down if
desired. Of the many times I've used it to do this I have never found any
problems. Shutting down an application is simply a matter of clicking on the
process name in the main window and selecting "Terminate Process" from the
resulting dialog. At this point you have one chance to change your mind when
the verification dialog appears. Selecting "Yes" will terminate the process.
Where PSPM/2 does not perform well is during cases of system lockup. Since the
program only responds to user requests, it relies on keyboard and/or mouse
input. This renders the program useless when user I/O is not possible. As a
result, if your new programs locks up the system you need to reboot or make use
of a different utility that allows you to recover from these situations if
repeated pressing of Ctrl-Esc doesn't work.
Another situation where PSPM/2 can cause problems occurs when it is used (at
least on my system) to shut down PMSHELL in an attempt to reboot the Workplace
Shell. This caused a blank desktop to appear with a loss of keyboard and mouse
response and required a reboot of my system. Its effect on other WPS
applications is unknown and would require further testing to determine its
suitability for closing misbehaved WPS programs that you may be writing. Since
OS/2 can behave quite differently with individual installations other users may
get different results and if so I would be interested in hearing about them.
Configuration of PSPM/2 is very simple. The user has one pull- down menu from
which settings such as default font, window position and size, colours and
refresh rate may be selected. The settings may be changed for a single session
only by declining to save the selected options. There is no online help but
everything is pretty straight-forward so the lack of built-in documentation
should not pose problems.
Overall, PSPM/2 is a nice little utility. The graphical, tree-like display
provides an easy and quick way to view which processes are running. Viewing
information about or termination of a process is simply a matter of clicking on
the process name. As a programming aid, it has saved me much time by allowing
me to close test applications by eliminating the need to reboot. While not the
only utility of this type, it is a simple and effective tool well worth the
storage space it takes up on your disk.
Under the Scope - EDM/2 - Jan 1996 - Volume 4, Issue 1
ΓòÉΓòÉΓòÉ 8.4. EditINI ΓòÉΓòÉΓòÉ
EditINI
EditINI is a simple tool that may be useful to those who create programs that
modify either the OS2.INI or OS2SYS.INI files. Being even less complex than
PSPM/2 this review will be short.
EditINI allows the user to view, add, modify or delete information from the OS2
and OS2SYS INI files. The PM interface makes it easy to use. You select which
of the INI files you wish use from one of two radio buttons, pick the
application (from a drop down list-box) whose entries you wish to act upon,
choose the "key name" (also from a list box) and view or modify the data under
that key name.
This isn't a bad little utility if your applications make few modifications to
the INI files, but for programs that make lots of additions to these files,
EditINI, while still useful, can be time-consuming. There can (and probably
will) be dozens of application entries and each application in turn can have
many more entries in the "key names" and data fields. This isn't a problem
when manually changing settings in the INI files, but can be time consuming
when deleting all references to a program because the list boxes are of the
style "single selection".
To make matters worse, after deleting an entry, the lists are reset to the top.
Applications can only be deleted by first removing all "key names" (one at a
time) and if an application has made many entries into the INI files it may
take a while to remove all references to it because you have to find (again)
the application name and then the key name from lists that can be fairly long.
If your program does make lots of entries, it may be best to create a separate
INI file for use during the testing phase of development and then, when
everything has been debugged, simply change the code to use the system INI
files instead of an application-specific one. This won't work in all cases, as
you may need to register new objects or data types etc., but placing as many
profile items as possible into a separate file during development can save a
lot of time. This way, if things don't go as they should, you can simply
delete the new INI file and try again. As you can probably tell from this
text, I'm a firm believer in the hit-and-miss approach!.
Where this program can be really convenient is when writing your first
applications that read and write to the INI files. Since we all know it's
safer to read from than to write to a file, you can use EditINI to make INI
file entries manually, perfect the code that reads the information first and
then worry about the code that writes information. For beginners this is ideal
because it allows one to get some experience with the profile functions without
the worry of destroying important system files. For the more advanced user,
any information contained in the OS2 and OS2SYS INI files can be viewed,
modified or deleted. Since there are too many to list, I'll assume you know
what INI entries you need to access but rest assured that if it exists in these
files, you can get at it with EditINI.
Despite having mentioned more dislikes than likes about this program, I do like
it and would have had more good things to say if it weren't so simplistic. As
a tool, especially for beginners, it is very useful and should be part of your
collection.
Under the Scope - EDM/2 - Jan 1996 - Volume 4, Issue 1
ΓòÉΓòÉΓòÉ 8.5. Index ΓòÉΓòÉΓòÉ
Index
This index is intended to give you an overview of the products reviewed and
will eventually contain other pertinent information such as an overall rating
and a brief summary of the product reviewed. Each table is assigned a category
and contains products which fall into that category; however, as more products
are reviewed, the category list will be expanded and some categories might be
renamed to more accurately reflect their contents.
System Information Utilities
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
ΓöéProgram ΓöéIssue Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéPSPM/2 Γöé4-1 Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
INI File Editors
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
ΓöéProgram ΓöéIssue Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéEditINI Γöé4-1 Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
Under the Scope - EDM/2 - Jan 1996 - Volume 4, Issue 1
ΓòÉΓòÉΓòÉ 9. 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 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, read the latest copy of the Article Submission
Guidelines on our web site or download them to your machine also from our web
site. These guidelines contain everything you need to know about writing an
article for EDM/2.
The editors can be reached at the following email addresses:
Larry Salomon - larry_salomon@iqpac.com (Internet).
Carsten Whimster - carsten_whimster@iqpac.com (Internet).
The following people contributed to this issue in one form or another (in
alphabetical order):
Edward Boykin
Larry Salomon, Jr.
Brad Scharf
Carsten Whimster
Joe Wyatt
Gordon Zeglinski
Network distributors
Contributors - EDM/2 - Jan 1996 - Volume 4, Issue 1
ΓòÉΓòÉΓòÉ 9.1. Edward Boykin ΓòÉΓòÉΓòÉ
Edward Boykin
Ed Boykin will graduate this winter from Georgia Institute of Technology with a
Bachelors' 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 aviator@mindspring.com or on the IRC #OS/2 channel as Av8|
Contributors - EDM/2 - Jan 1996 - Volume 4, Issue 1
ΓòÉΓòÉΓòÉ 9.2. Larry Salomon, Jr. ΓòÉΓòÉΓòÉ
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
larry_salomon@iqpac.com.
Contributors - EDM/2 - Jan 1996 - Volume 4, Issue 1
ΓòÉΓòÉΓòÉ 9.3. Brad Scharf ΓòÉΓòÉΓòÉ
Brad Scharf
Brad discovered computers while enrolled in a chemistry B.S. program and soon
after switched to computer science. He has been using OS/2 since the release
of version 2.0, has used OS/2 exclusively since version 2.1, and is now in the
process of teaching himself PM programming.
Brad can be reached via the internet at schab@sasknet.sk.ca
Contributors - EDM/2 - Jan 1996 - Volume 4, Issue 1
ΓòÉΓòÉΓòÉ 9.4. Carsten Whimster ΓòÉΓòÉΓòÉ
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
Visual Age C++, Watcom C/C++ 10.0a and Watcom VX-REXX 2.0c. Carsten is the
author of some commandline utilities, and POV-Panel/2. He is also a TEAM-OS/2
member, and has adopted a little computer store called The Data Store in
Waterloo, Ontario.
You may reach Carsten...
...via email (Internet):
carsten_whimster@iqpac.com
...via the World Wide Web:
http://www.undergrad.math.uwaterloo.ca/~bcrwhims/
...via snail mail:
(I am just about to move. Hang in there for a month)
...via voice:
(519)886-2439
Contributors - EDM/2 - Jan 1996 - Volume 4, Issue 1
ΓòÉΓòÉΓòÉ 9.5. Joe Wyatt ΓòÉΓòÉΓòÉ
Joe Wyatt
Joe has been working in OS/2 since 1.3 and has programmed in Rexx on four
different platforms. Rexx projects have included elegant, complex systems in
both VM and OS/2, operating system automation in MVS, and your basic "quick and
dirty" tools in DOS. He has recently mustered up the courage to jump into the
world of consulting and self-employment. (God help him.) He makes his home in
San Antonio, Texas with a wife and four children (along with 2 dogs, 1 cat, 1
turtle, varying numbers of fish, and a rabbit).
He can be reached via internet address jwyatt@txdirect.net for comments and
criticisms.
Contributors - EDM/2 - Jan 1996 - Volume 4, Issue 1
ΓòÉΓòÉΓòÉ 9.6. Gordon Zeglinski ΓòÉΓòÉΓòÉ
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 gordon_zeglinski@iqpac.com.
Contributors - EDM/2 - Jan 1996 - Volume 4, Issue 1
ΓòÉΓòÉΓòÉ 9.7. Network distributors ΓòÉΓòÉΓòÉ
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
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!
Contributors - EDM/2 - Jan 1996 - Volume 4, Issue 1