home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 32 Periodic
/
32-Periodic.zip
/
edmi2-10.zip
/
EDMI2-10.INF
(
.txt
)
< prev
next >
Wrap
OS/2 Help File
|
1994-11-08
|
145KB
|
1,760 lines
ΓòÉΓòÉΓòÉ 1. Nov 1994 Title Page ΓòÉΓòÉΓòÉ
EDM/2
The Electronic Developer's Magazine for OS/2
Portions copyright (c) by Larry Salomon Jr.
Volume 2, issue 10
Copyright Notice and Other Stuff
The Editor-in-Chief of this electronic magazine is Larry Salomon, Jr.
Portions of EDM/2 are copyrighted by the editors. 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.
All articles are copyrighted by their authors. No part of any article may be
reproduced without permission from the original author.
Neither this publication nor the editors 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.
Administrivia
What a month it has been! By the time you read this, OS/2 3.0 Warp will be
available in (hopefully) stores everywhere and you may be reading this issue
using Warp on your computer. I had the pleasure of finding a shrink-wrapped
copy sent by IBM on my doorstep in mid-October, which I installed the next day.
After almost a month of use, I must say that IBM has a winner here...
If they can market it effectively, that is. IBM is as notorious for poor
marketing as Microsoft is for missing deadlines. Will they be able to change?
Who can say? IBM has two things going for them, however: a new advertising
agency and a new budget. The possibilities are there; now it is up to IBM to
realize this new-found potential.
Support Your Favorite Operating System
Fortunately, we can aid IBM in its struggle against the behemoth. Team-OS/2 is
an excellent organization that coordinates the world-wide battle to evangelize
OS/2 and its advantages versus Windows. A number of well-known IBMers are
affiliated, though not officially, with this organization. Check with your
local IBM office to see how you can be put in touch in order to help out in
your neck-of-the-woods.
Like I Said...
"By the time you read this..." During the development of the sample for the
Introduction to PM Programming column, all-of-a-sudden the Resource Compiler
stopped working. After two days of unsuccessfully beating on my machine, I
thought that maybe it was an environment inconsistency that occurred when I
installed Warp and forgot to save my CONFIG.SYS (and thus had to rebuild the
development-related sections manually). So, I uninstalled the Toolkit and
C-Set++ and reinstalled them.
Nothing different. RC still hung apparently somewhere in the middle of
including <os2.h>.
After two more reinstalls of both products, I decided - on a whim - to try
running RC against another source file and, to my chagrin, it worked. "It must
be," I thought, "a problem with the BUTTON.RC file." So I pulled up my editor
to find a hex x'02' character at the end of one of the lines. Ironically, this
is a smiley face; I suppose someone was laughing during both days while I was
going nuts trying to get this to work (so that I could finish the magazine).
Now, my qualm with the whole situation is with the (lack of) error recovery in
RC. This has happened to me once before but (obviously) I didn't bother
jotting down what the cause of the error was. I claim, though, that I
shouldn't have to if RC would simply report errors when it sees them. Remember
this one?
BUTTON.RES(0): I/O error. Attempting to continue...
For those of you who haven't seen this error before, it happens most frequently
when the RES file was not generated because the user pressed Ctrl-Break in the
middle of the compilation. Has anyone in the Toolkit Department in Boca Raton
ever heard of the remove() function? No, I suppose not, or this message would
have been removed a long time ago when IBM received the code from Microsoft for
the Toolkit utilities.
Looking to Steal a Good Idea
In the "Quest of the Month" department, I am trying to steal; yes, I want to
steal a good idea from another great electronic magazine, OS/2 Personal. In
order to make it easier for people to write, I want to change our source format
from OS/2's Information Presentation Facility (IPF) format to Rich Text Format
(RTF). This would allow future authors to write their articles in any one of
the many word processors that support this format on export.
The problem which I am trying to solve is in the translation from RTF to INF
for viewing by our many readers. If you have a solution to this interesting
problem (perhaps an RTF to IPF compiler?), please contact me via email; I'd
love to hear what information you can provide.
Washing Up Gets Rids of Dirt
I was conversing with someone through email and he mentioned something called
Clean, so the obvious question in my mind was, "What is it?" It is apparently
a functional programming language, which means that all programs written in the
language are comprised solely of functions. To use the example given to me,
consider the function to calculate the factorial of a number:
Fac:: Int -> Int
Fac 1 = 1;
Fac n = n * Fac (n - 1);
That should be enough to whet your attetite. Clean is available for the OS/2,
Mac, Sun, and Linux platforms and the latest version (0.8) can be obtained via
anonymous FTP from ftp.cs.kun.nl.
Washing Up Gets Rid of Bugs
And while the latest CSD from IBM would also appear to do this, according to
David Charlap, it could have done a better job. "Fixpacks" XR_A056 and XR_A058
are available for OS/2 2.11 which fix, among other things, some interesting Gpi
bugs. However, David mentioned that, after installing both of these CSD's,
IPMD started behaving weirdly and that a bug report was sent to the C-Set++
group. We will keep you posted as he sends us new information. Thanks, David,
for your note.
Reader's Choice Awards
This is your friendly reminder that, next month, we will conduct our Reader's
Choice Awards for the year 1994. I sincerely hope to receive more than 14
votes for the best articles of the year. <grin>
Title Page - EDM/2 - Nov 1994 - Volume 2, Issue 10
ΓòÉΓòÉΓòÉ 2. The Design and Implementation of VIOWIN - Part 3 ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 2.1. Introduction ΓòÉΓòÉΓòÉ
The Design and Implementation of VIOWIN - Part 3
Written by Larry Salomon, Jr.
Introduction
For my job, I once had to write an application that ran only when OS/2 booted
from the floppy diskettes. Because I had no access to the functionality PM
provides, I resorted to a line-oriented interface, where messages were
displayed on the screen and scrolled up when necessary. It was a good
interface, I thought; it was fully NLS enabled and had intelligent defaults so
the user basically only had to type in the name of the application.
Unfortunately, the Quality Assurance team didn't concur with my opinion. "We
want a nice interface!" one exclaimed. "Yeah, one with different windows and
such!" another shouted.
I was backed into a corner that I could only get out of one way.
This series describes the design and implementation of VIOWIN, a library that
implements a subset of the Win APIs provided by PM for fullscreen sessions.
The reasoning behind writing this series is that it provided me and will
hopefully provide you with some unique insights into how a windowing system is
developed; and since it is based on PM, your familiarity with the already
defined interface will increase your capability to fully understand what is
being described.
Obviously, this series assumes you have PM application development experience,
but it isn't required.
Last Month
Last month, we looked at the design of the keyboard monitor which provides the
WM_CHAR messages to the system and how the design lent itself to a more
difficult implementation. This month, we will continue by looking at the
remaining functions that are called from within the main() function.
The Design and Implementation of VIOWIN (Part 3) - EDM/2 - Nov 1994 - Volume 2,
Issue 10
ΓòÉΓòÉΓòÉ 2.2. Errata ΓòÉΓòÉΓòÉ
Errata
Before we do anything, however, a correction needs to be made. In postKeyMsg()
there was the following code:
case 0x37:
usFlags|=KC_VIRTUALKEY;
usVkey=VK_PRINTSCRN;
break;
This code was written with the intent of allowing me to press the PrintScrn key
and get a screen dump in a held printer queue using the IBMNULL printer driver.
After you finish laughing at the stupidity of my assumption that this will do
the trick, you will realize that 0x37 is the scan code of the "7" key and that
it will not work if this code is left in. Thus, it was removed.
The Design and Implementation of VIOWIN (Part 3) - EDM/2 - Nov 1994 - Volume 2,
Issue 10
ΓòÉΓòÉΓòÉ 2.3. Classes ΓòÉΓòÉΓòÉ
Classes
Since the first thing a PM application typically does after initialization is
register a private window class or two, let's look at this code first.
SHORT EXPENTRY _findClass(PVWCLASSINFO pciInfo,PCHAR pchClass)
//-------------------------------------------------------------------------
// This function compares the name of the specified class to see if it
// matches the specified name. It is called by CmnLstSearchRecord().
//
// Input: pciInfo - points to a VWCLASSINFO structure
// pchClass - points to the class name to compare with
// Returns: 0 if match, non-0 otherwise
//-------------------------------------------------------------------------
{
return (strcmp(pciInfo->achName,pchClass)!=0);
}
BOOL EXPENTRY vwRegisterClass(PCHAR pchClass,PFNVWWP pfnWndProc)
//-------------------------------------------------------------------------
// This function registers the class with the name specified.
//
// Input: pchClass - points to the name of the class
// pfnWndProc - points to the window procedure for the class
// Returns: TRUE if successful, FALSE otherwise
//-------------------------------------------------------------------------
{
VWCLASSINFO ciInfo;
if (hmqQueue==NULL) {
return FALSE;
} /* endif */
if (CmnLstSearchRecord(CmnLstQueryRecord(habAnchor->hclClasses,0),
pchClass,
(PFNRECCOMP)_findClass)!=NULL) {
return FALSE;
} /* endif */
strcpy(ciInfo.achName,pchClass);
ciInfo.pfnWndProc=pfnWndProc;
return CmnLstAddRecord(habAnchor->hclClasses,&ciInfo,LAR_TAIL,NULL);
}
This function is fairly trivial - it checks to see if vwInitialize() has been
called by checking the value of hmqQueue. It then searches the class list to
see if the class name is already used. See the documentation for the Common/2
library for more information about the linked-list routines. If the class was
not found, it is added to the class list via CmnLstAddRecord().
Note!
You should note the deviations from PM: there are no class styles and there is
no way to get more than the 8 bytes of window words as provided by the VWWND
structure (see volume 2, issue 8).
There are two other trivial functions dealing with classes - vwQueryClassName()
and vwQueryClassInfo() - which we will not discuss here, but are included in
the sample source provided with this article.
The Design and Implementation of VIOWIN (Part 3) - EDM/2 - Nov 1994 - Volume 2,
Issue 10
ΓòÉΓòÉΓòÉ 2.4. Windows ΓòÉΓòÉΓòÉ
Windows
The next thing that is done is to create a window, so let's look at
vwCreateWindow() and vwDestroyWindow().
HVWWND EXPENTRY vwCreateWindow(PCHAR pchClass,
USHORT usId,
ULONG ulStyle,
PCHAR pchText,
LONG lX,
LONG lY,
ULONG ulCx,
ULONG ulCy,
LONG lForeClr,
LONG lBackClr)
//-------------------------------------------------------------------------
// This function creates a window.
//
// Input: pchClass - points to the name of the class of the window
// usId - specifies the window id. If -1 is specified, the check
// for other windows with the same id is not performed.
// ulStyle - specifies the style of the window
// pchText - points to the text of the window
// lX, lY - specifies the lower left corner of the window, relative
// to the desktop
// ulCx, ulCy - specifies the width and height of the window
// lForeClr - specifies the VWCLR_* constant for the foreground color
// lBackClr - specifies the VWCLR_* constant for the background color
// Returns: window handle if successful, NULLHANDLE otherwise
//-------------------------------------------------------------------------
{
PVWCLASSINFO pciClass;
VWWND vwWnd;
HVWWND hwndNew;
BOOL bDesktop;
if (hmqQueue==NULL) {
return NULL;
} /* endif */
//----------------------------------------------------------------------
// Make sure the class was registered
//----------------------------------------------------------------------
pciClass=(PVWCLASSINFO)CmnLstQueryRecord(habAnchor->hclClasses,0);
pciClass=(PVWCLASSINFO)CmnLstSearchRecord(pciClass,
pchClass,
(PFNRECCOMP)_findClass);
if (pciClass==NULL) {
return NULL;
} /* endif */
memset(&vwWnd,0,sizeof(VWWND));
vwWnd.ulSzStruct=sizeof(VWWND);
vwWnd.pciClass=pciClass;
//----------------------------------------------------------------------
// If the window id is not -1, check for another window with this id.
//----------------------------------------------------------------------
if ((usId!=-1) && (vwWindowFromID(usId)!=NULL)) {
return NULL;
} /* endif */
//----------------------------------------------------------------------
// If there are no other windows, then this window's id *must* be
// VWWID_DESKTOP.
//----------------------------------------------------------------------
if ((CmnLstQueryRecordCount(habAnchor->hclWindows)==0) &&
(usId!=VWWID_DESKTOP)) {
return NULL;
} /* endif */
vwWnd.usId=usId;
vwWnd.ulStyle=ulStyle;
vwWnd.swpSwp.lX=lX;
vwWnd.swpSwp.lY=lY;
vwWnd.swpSwp.ulCx=ulCx;
vwWnd.swpSwp.ulCy=ulCy;
vwWnd.lForeClr=lForeClr;
vwWnd.lBackClr=lBackClr;
if (!CmnLstAddRecord(habAnchor->hclWindows,
&vwWnd,
LAR_TAIL,
(PPVOID)&hwndNew)) {
return NULL;
} /* endif */
//----------------------------------------------------------------------
// If this is the desktop, set a flag so that we post it a WM_PAINT
// instead of sending it the message.
//----------------------------------------------------------------------
bDesktop=(usId==VWWID_DESKTOP);
if (bDesktop) {
habAnchor->ulStatus|=VW_HABST_CREATINGDESK;
} /* endif */
//----------------------------------------------------------------------
// Check for valid initialization
//----------------------------------------------------------------------
if (LONGFROMMR(vwSendMsg(hwndNew,WM_CREATE,0,0))==TRUE) {
CmnLstDeleteRecord(habAnchor->hclWindows,hwndNew);
habAnchor->ulStatus&=~VW_HABST_CREATINGDESK;
return NULL;
} /* endif */
if (bDesktop) {
habAnchor->ulStatus&=~VW_HABST_CREATINGDESK;
} /* endif */
vwWnd.pchText=NULL;
vwSetWindowText(hwndNew,pchText);
//----------------------------------------------------------------------
// Paint
//----------------------------------------------------------------------
if ((habAnchor->ulStatus & VW_HABST_CREATINGDESK)==0) {
vwSendMsg(hwndNew,WM_PAINT,0,0);
} else {
vwPostMsg(hwndNew,WM_PAINT,0,0);
} /* endif */
return hwndNew;
}
BOOL EXPENTRY vwDestroyWindow(HVWWND hwndWnd)
//-------------------------------------------------------------------------
// This function destroys a window
//
// Input: hwndWnd - handle to the window
// Returns: TRUE if successful, FALSE otherwise
//-------------------------------------------------------------------------
{
if (hwndWnd==VWHWND_DESKTOP) {
hwndWnd=vwWindowFromID(VWWID_DESKTOP);
} /* endif */
if (!vwIsWindow(hwndWnd)) {
return FALSE;
} /* endif */
//----------------------------------------------------------------------
// If this is the desktop window, traverse the window list and destroy
// all of the children first.
//----------------------------------------------------------------------
if (vwQueryWindowUShort(hwndWnd,QWS_ID)==VWWID_DESKTOP) {
CmnLstTraverseList(habAnchor->hclWindows,(PFNRECFUNC)destroyWindow);
destroyWindow(hwndWnd);
} else {
destroyWindow(hwndWnd);
} /* endif */
return TRUE;
}
Note!
Note the deviations again from PM. In PM, the desktop is created when the
system initializes itself. Since VIOWIN doesn't support parent-child
relationships unless the parent is the desktop, I decided to let the
application create the desktop of a class it chooses. The desktop is
identified by a special id - VWWID_DESKTOP.
Note!
Since the desktop will usually create a number of child windows, the WM_PAINT
message is posted and not sent to any children it creates, but is sent to
itself, through the use of the VW_HABST_CREATINGDESK flag in
habAnchor->ulStatus. The intent is to prevent the desktop from painting over
its children because, if the message were posted, the desktop would receive it
last.
The Design and Implementation of VIOWIN (Part 3) - EDM/2 - Nov 1994 - Volume 2,
Issue 10
ΓòÉΓòÉΓòÉ 2.5. Messages ΓòÉΓòÉΓòÉ
Messages
The final thing that is done, inside the main() function at least, is to enter
the message loop.
BOOL EXPENTRY vwGetMsg(PVWQMSG pqmMsg)
//-------------------------------------------------------------------------
// This function gets the next message from the circular queue.
//
// Input: pqmMsg - points to the VWQMSG structure
// Output: pqmMsg - points to the initialized VWQMSG structure
// Returns: TRUE if successful, FALSE otherwise
//-------------------------------------------------------------------------
{
if (hmqQueue==NULL) {
return FALSE;
} /* endif */
while (hmqQueue->ulTail==hmqQueue->ulHead) {
DosSleep(0);
} /* endwhile */
hmqQueue->ulHead++;
if (hmqQueue->ulHead==VW_SIZEQUEUE) {
hmqQueue->ulHead=0;
} /* endif */
*pqmMsg=hmqQueue->aqmMsgs[hmqQueue->ulHead];
return (pqmMsg->ulMsg!=WM_QUIT);
}
BOOL EXPENTRY vwDispatchMsg(PVWQMSG pqmMsg)
//-------------------------------------------------------------------------
// This function calls the appropriate window procedure with the appropriate
// parameters.
//
// Input: pqmMsg - points to the initialized VWQMSG structure
// Returns: TRUE if successful, FALSE otherwise
//-------------------------------------------------------------------------
{
if (hmqQueue==NULL) {
return FALSE;
} /* endif */
(*pqmMsg->hwndWnd->pciClass->pfnWndProc)(pqmMsg->hwndWnd,
pqmMsg->ulMsg,
pqmMsg->mpParm1,
pqmMsg->mpParm2);
return TRUE;
}
The Design and Implementation of VIOWIN (Part 3) - EDM/2 - Nov 1994 - Volume 2,
Issue 10
ΓòÉΓòÉΓòÉ 2.6. This Is Too Easy ΓòÉΓòÉΓòÉ
This Is Too Easy
By now, you're probably thinking, "Wake me up when we get to something that
requires more intelligence than that of a second grade child." You are right;
everything we've seen is quite easily done. However, I must stress that the
linked-list routines, which I said before were used heavily, are not shown here
and they would take up a good sized portion of the code (but that's why there
are DLL's, correct?). Also, these are the base routines, so they should be
simplistic; the hard stuff comes later with the timers and such.
In other words, be patient but (by the same token) don't expect too much.
You should be aware that we have seen the code for all of the functions that
are used in a typical main() function in a PM application. Next month, we will
look at more of the window management functions as well as vwPostMsg() and
vwSendMsg() and other stuff.
The Design and Implementation of VIOWIN (Part 3) - EDM/2 - Nov 1994 - Volume 2,
Issue 10
ΓòÉΓòÉΓòÉ 3. /dev/EDM/BookReview ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 3.1. Introduction ΓòÉΓòÉΓòÉ
/dev/EDM2/BookReview
Written by Carsten Whimster
Introduction
/dev/EDM2/BookReview is a monthly column which focuses on development oriented
books and materials. The column is from a beginning PM programmer, but
intermediate REXX programmer's eyes. Pick up whichever book strikes your
fancy, and join the growing group of people following our PM programming
columns. I will review books aimed at beginners for a while, and then move on
from there.
Please send me your comments and thoughts so that I can make this column as
good as possible. All mail gets read and responded to.
Application Development Using OS/2 REXX is a fairly fast-paced REXX book. It
covers some unusual and rare material in some depth.
/dev/EDM2/BookReview - EDM/2 - Nov 1994 - Volume 2, Issue 10
ΓòÉΓòÉΓòÉ 3.2. Errata ΓòÉΓòÉΓòÉ
Errata
Well, my WWW homepage is up and running again. Hopefully I'll catch up with my
work at school soon, so that I can start expanding it, complete the index and
so on. I still have to get it installed onto our school's system, so it is not
accesible yet.
I tried to get in touch with Charles Petzold regarding his new book OS/2
Presentation Manager Programming, but he never responded, so maybe I have the
wrong address. In any case, I went out and bought the book. Look for the
review next month.
With the imminent release of OS/2 Warp 3.0, I have decided to delay the
purchase of OS/2 Unleashed, until the new version is released. I picked up a
list of all the new books planned specifically for Warp, and I was quite
surprised. This list looks larger than the complete list of books for OS/2 2.0
(well, maybe not quite)! There are some really decent books on it too, among
others a new (and much needed) version of OS/2 Presentation Manager GPI, Winn.
I reviewed the old version recently, and basically thought it was a decent book
badly in need of updating (it was written for OS/2 1.3!); it should be popular
too, judging from the number of people who have requested a good GPI book over
the last few months.
/dev/EDM2/BookReview - EDM/2 - Nov 1994 - Volume 2, Issue 10
ΓòÉΓòÉΓòÉ 3.3. Application Development Using OS/2 REXX ΓòÉΓòÉΓòÉ
Application Development Using OS/2
Application Development Using OS/2 REXX starts out on a funny note...let me
explain. The following is an excerpt from the introduction:
The title of this book Mastering OS/2 REXX: The Practical Usage
of OS/2 REXX reveals the purpose I had in writing it: a
concise, but complete, source of information necessary to master the REXX
language for applications in the OS/2 environment.
I spent a few moments verifying that I was indeed reading Application
Development Using OS/2 REXX, and then I wondered about this error. I suppose
that since Mastering OS/2 REXX (Gargiulo) was released by the same publisher,
the editors probably suggested the name change, but one would think that they
would have looked through the book and fixed the relevant parts? That doesn't
inspire confidence, that's for sure. In any case, I read on, and what Rudd
said is not just idle talk. Here are the chapter headings:
1. Introduction
2. REXX Concepts
3. REXX Program Elements
4. Parsing
5. Arithmetic
6. Input/Output
7. Debugging
8. Programming Practices
9. REXX Instructions
10. REXX Built-In Functions (SAA)
11. REXX Built-In Functions (Non-SAA)
12. Utility Routines
13. Worked Example
14. REXXUTIL Utility Functions
15. Host Commands
16. Application Programming Interface
17. Service Routines
18. Worked Example (Programmed Implementation)
19. Database Manager Interface
20. Personal REXX
21. Other Products
22. Appendix A: REXX Instruction Syntax
23. Appendix B: Syntax Notation
24. Appendix C: Bibliography
25. Appendix D: Glossary
26. Appendix E: Compatibility (Various Implementations)
27. Appendix F: REXX Data Types
28. Appendix G: Useful Control Program Services
29. Appendix H: RXSTRING Processing Routines
30. Appendix I: Function Migration
31. Appendix J: Program Preparation
The first few chapters form the obligatory REXX introduction, and since I have
done a few of those recently, I'll skip over it lightly. Basically, you learn
the answer to the following questions:
o What is REXX?
o Where did REXX come from?
o What does REXX do?
o Where can I use REXX?
o What is in the future for REXX?
o What is the OS/2 version of REXX like?
o What does a REXX program look like?
o What do REXX statements look like?
o How do I write REXX statements?
o What are REXX variables like?
o How does REXX interpret statements?
o How do I run a REXX program?
o What flow control constructs does REXX have?
o What are REXX queues?
Parsing is explained next, and although the chapter is not long, it is quite
good. Arithmetic follows, and REXX's arbitrary precision is demonstrated along
with numeric formats and sequence of operators. Input/output streams are
explained, with sections on buffering, files, terminals, characters, and
various other topics following. A chapter is devoted to debugging, but since
this is not a topic which is frequently found in this type of book, I would
have liked to see a more thorough treatment. Nevertheless, there are no glaring
omissions, just a few vague points.
Chapter 8 is a rare piece on programming practices. I would love to see more
information like this in programming books, but it is unfortunately frequently
skipped over. This chapter helps the novice/intermediate programmer to learn
about good programming habits, and maintenance/performance issues. The chapter
is good, but a bit short.
Chapters 9 to 12 combine to make an oddly placed, but well-written reference
section. The syntax and parameters of REXX instructions, built-in functions
(SAA), built-in functions (non-SAA), and utility functions are all presented
rigorously.
Chapter 13 confirms the unusual direction this book has been given, which we
had a glimpse of in chapter 8. The chapter consists of a 49 line program which
implements the DISKW operation of the EXECIO command found in MVS and VM/CMS
environments. The syntax is presented, followed by the program, and finally a
line-by-line explanation of the program. This type of real-world program can
teach REXX far more effectively than a million small programs can. The reader
gets a chance to see how a REXX programmer solves a real problem. The chapter
is short, but other writers should take notice. This is a great idea. Of
course, this program is probably too complicated for a novice, but it is
refreshing to see a program which actually does something useful, rather than
the "Hello World" variety (which does have its place, however).
After the sample program, the book launches into an "advanced" section. This
section consists of discussions of such topics as REXXUTIL (REXXUTIL is a DLL
with OS/2 specific commands) with an example of how to do full-screen
input/output, and host commands (starting DOS and OS/2 sessions and so on).
Chapter 16 introduces the topic of interfacing with other programming languages
and programs. Specifically, it shows how to include REXX functions or programs
from C code, and gives some decent examples of how to do this. It even gives a
brief example of how to call REXX from PL/I. The inclusion of this chapter,
which is one of the longer ones in the book, goes a long way towards
demonstrating the intent of this book. It may sound like a REXX how-to book
for beginning and intermediate REXX programmers, but when you look a little
closer, there is some serious information here for the advanced programmer who
already knows REXX, and needs a book which covers the unusual, and acts like a
reference manual as well. Chapter 17 then adds to this by explaining how to
register external functions for use within REXX.
Chapter 18 is another "worked example"; this time it expands on the example in
chapter 13, and the result is FEXECIO, a routine which can process a whole file
in one call. The surprise is that it is written in C, and calls REXX routines
to do the dirty work.
The third part of the book is about "applications". The emphasis here is on
how to use REXX for real-world productivity solutions, such as interfacing with
DB2/2. As in previous examples, some real SQL calls are demonstrated, and
decent code snippets are given. Personal REXX from Quercus Systems, and some
other REXX products are given a brief treatment, among which is VX-REXX. The
appendices are all very brief and their titles pretty well explain what they
are all about, so I'll skip them here.
/dev/EDM2/BookReview - EDM/2 - Nov 1994 - Volume 2, Issue 10
ΓòÉΓòÉΓòÉ 3.4. Summary ΓòÉΓòÉΓòÉ
Summary
Application Development Using OS/2 REXX is a unique kind of book. It has
enough reference material in it to serve as a decent reference manual, but it
also has good sections on programming and debugging techniques, and interfacing
with C and DB2/2. It covers far more than a book this size has a right to, but
sacrifices a little depth in places. As a consequence, beginners should
probably stay away from this book until they are reasonably fluent with REXX.
If your needs are unusual, however, and all you need is a pointer in the right
direction, then this book is for you.
/dev/EDM2/BookReview - EDM/2 - Nov 1994 - Volume 2, Issue 10
ΓòÉΓòÉΓòÉ 3.5. Books Reviewed ΓòÉΓòÉΓòÉ
Books Reviewed
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
ΓöéBOOK ΓöéAUDIENCE ΓöéMARKΓöéCOMMENTS Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéReal-World Programming for OS/2 ΓöéIntermediateΓöéB+ ΓöéLots of good code examples, but Γöé
Γöé2.1, Blain, Delimon, and English, Γöéto Advanced Γöé Γöésometimes it is too complex for Γöé
ΓöéSAMS Publishing. ISBN ΓöéPM C Γöé Γöénovices. Accurate. Well organized. Γöé
Γöé0-672-30300-0. US$40, CAN$50. Γöéprogrammers Γöé ΓöéThe index needs a little beefing up. Γöé
Γöé Γöé Γöé ΓöéGood, but not entirely complete how-to Γöé
Γöé Γöé Γöé Γöéreference. Good purchase. Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéLearning to Program OS/2 2.0 ΓöéBeginning PMΓöéB- ΓöéThis book can be both frustrating and Γöé
ΓöéPresentation Manager by Example, ΓöéC Γöé Γöévery rewarding. It is not very large, Γöé
ΓöéKnight, Van Nostrand Reinhold. ΓöéProgrammers Γöé Γöéand a bit pricey, but has some Γöé
ΓöéISBN 0-442-01292-6. US$40, Γöé Γöé Γöéexcellent chapters on certain beginningΓöé
ΓöéCAN$50. Γöé Γöé Γöétopics, such as messages, resources, Γöé
Γöé Γöé Γöé ΓöéIPF, and dialog boxes. Strictly for Γöé
Γöé Γöé Γöé Γöébeginners. This book has only one Γöé
Γöé Γöé Γöé Γöé(large) sample program! Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéWriting OS/2 2.1 Device Drivers inΓöéAdvanced C ΓöéA- ΓöéThe only thing a device driver Γöé
ΓöéC, 2nd Edition, Mastrianni, Van ΓöéProgrammers,Γöé Γöéprogrammer would not find in here is Γöé
ΓöéNostrand Reinhold. ISBN Γöéfamiliar Γöé Γöéhow to write SCSI, ADD, and IFS Γöé
Γöé0-442-01729-4. US$35, CAN$45. Γöéwith Γöé Γöédrivers. Most everything else is in Γöé
Γöé Γöéhardware Γöé Γöéhere, along with skeleton examples. AnΓöé
Γöé Γöéprogramming Γöé Γöéoptional DevHlp library of C-callable Γöé
Γöé Γöé Γöé Γöéfunctions can be purchased by those whoΓöé
Γöé Γöé Γöé Γöédon't have time to write their own. Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéOS/2 Presentation Manager GPI, ΓöéIntermediateΓöéC+ ΓöéThis book needs updating for OS/2 2.x. Γöé
ΓöéWinn, Van Nostrand Reinhold. ISBN Γöéto advanced Γöé ΓöéIt is a well-written in-depth coverage Γöé
Γöé0-442-00739-6. US$35, CAN$45. ΓöéPM C Γöé Γöéof the OS/2 way of programming for Γöé
Γöé Γöéprogrammers Γöé Γöégraphics. It is not an introductory PMΓöé
Γöé Γöé Γöé Γöéor graphics programming book. You Γöé
Γöé Γöé Γöé Γöéshould know the basics of PM Γöé
Γöé Γöé Γöé Γöéprogramming already. Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéThe Art of OS/2 2.1 C Programming,ΓöéBeginning ΓöéB+ ΓöéThis is a great introductory PM Γöé
ΓöéPanov, Salomon, and Panov, ΓöéOS/2 and PM Γöé Γöéprogramming book. It covers basic OS/2Γöé
ΓöéWiley-QED. ISBN 0-471-58802-4. Γöéprogrammers Γöé Γöéissues like threads before it jumps Γöé
ΓöéUS$40, CAN$50. Γöé Γöé Γöéinto PM programming. The coverage is Γöé
Γöé Γöé Γöé Γöéquite thorough, with just enough Γöé
Γöé Γöé Γöé Γöéreference material to make it useful Γöé
Γöé Γöé Γöé Γöéafter you read it through the first Γöé
Γöé Γöé Γöé Γöétime. The upcoming revised edition Γöé
Γöé Γöé Γöé Γöéshould be a killer. Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéMastering OS/2 REXX, Gargiulo, ΓöéIntermediateΓöéB ΓöéThis book is very easy to understand. Γöé
ΓöéWiley-QED. ISBN 0-471-51901-4. ΓöéOS/2 users Γöé ΓöéIf you program with any regularity, Γöé
ΓöéUS$40, CAN$50. Γöéand Γöé Γöélook elsewhere, but if you need an Γöé
Γöé Γöébeginning Γöé Γöéeasily read, well-explained beginner's Γöé
Γöé Γöéprogrammers Γöé Γöébook, look no further. Some more Γöé
Γöé Γöé Γöé Γöédetailed, and complex real-world Γöé
Γöé Γöé Γöé Γöéexamples might be useful as you learn Γöé
Γöé Γöé Γöé Γöéthe material. Good coverage of REXX's Γöé
Γöé Γöé Γöé Γöécapabilities. Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéREXX Reference Summary Handbook, ΓöéBeginning toΓöéA ΓöéThis little handbook is packed full of Γöé
ΓöéGoran, C F S Nevada. ISBN Γöéadvanced Γöé Γöéuseful information. Includes chapters Γöé
Γöé0-9639854-1-8. US$20, CAN$25 ΓöéREXX Γöé Γöéon both built-in and some popular Γöé
Γöé Γöéprogrammers Γöé Γöécommercial libraries. Well-written andΓöé
Γöé Γöé Γöé Γöécomprehensively indexed. A must for Γöé
Γöé Γöé Γöé ΓöéREXX programmers. Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéApplication Development Using OS/2ΓöéIntermediateΓöéA- ΓöéExcellent coverage of everything REXX, Γöé
ΓöéREXX, Rudd, Wiley-QED. ISBN Γöéto advanced Γöé Γöéwith the occasional sparse section. It Γöé
Γöé0-471-60691-X. US$40, CAN$50 ΓöéREXX Γöé Γöéis a decent reference book, and has Γöé
Γöé Γöéprogrammers Γöé Γöéenough unusual material that it will Γöé
Γöé Γöé Γöé Γöéprobably find its way into many REXX Γöé
Γöé Γöé Γöé Γöéprogrammers' libraries. Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
This table contains all books I have reviewed, so that you can find what you
are looking for at a glance. I will be careful to rate books fairly. If I
feel a need to adjust ratings, I will adjust all of them at the same time, and
write a note explaining why I felt this necessary. 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, author(s), 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 - Nov 1994 - Volume 2, Issue 10
ΓòÉΓòÉΓòÉ 3.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. This table 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 fill it, so
have a little patience.
Note: Books which cover the same material can look similar in this table, but
be different in real life. Be sure that the books you are comparing are aimed
at the same audiences.
PM BOOKS:
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
ΓöéBOOK ΓöéMARK ΓöéPM ΓöéGPI ΓöéFonts ΓöéDevice ΓöéPrint Γöé
Γöé Γöé ΓöéIntro Γöé Γöé ΓöéDriver Γöé Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéRWP ΓöéB+ Γöé4 Γöé4 Γöé4 Γöé0 Γöé3 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéPME ΓöéB- Γöé2 Γöé2 Γöé2 Γöé0 Γöé0 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéODD ΓöéA Γöé0 Γöé1 Γöé0 Γöé5 Γöé1 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéGPI ΓöéC+ Γöé0 Γöé5 Γöé2 Γöé0 Γöé3 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéTAO ΓöéB+ Γöé4 Γöé1 Γöé2 Γöé0 Γöé2 Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
REXX BOOKS:
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
ΓöéBOOK ΓöéMARK ΓöéREXX ΓöéWPS ΓöéReferenceΓöé
Γöé Γöé ΓöéIntro Γöé Γöé Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéMOR ΓöéB Γöé4 Γöé0 Γöé2 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéRSH ΓöéA Γöé1 Γöé2 Γöé5 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéADO ΓöéA- Γöé3 Γöé0 Γöé4 Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
BOOK LEGEND:
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
ΓöéReal-World Programming for OS/2 2.1 ΓöéRWP Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéLearning to Program OS/2 2.0 Presentation Manager by Example ΓöéPME Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéWriting OS/2 2.1 Device Drivers in C, 2nd Edition ΓöéODD Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéOS/2 Presentation Manager GPI ΓöéGPI Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéThe Art of OS/2 2.1 C Programming ΓöéTAO Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéMastering OS/2 REXX ΓöéMOR Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéREXX Reference Summary Handbook ΓöéRSH Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
ΓöéApplication Development Using OS/2 REXX ΓöéADO Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
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 - Nov 1994 - Volume 2, Issue 10
ΓòÉΓòÉΓòÉ 3.7. Coming Up ΓòÉΓòÉΓòÉ
Coming Up
Next month I will be looking at OS/2 Presentation Manager Programming, Petzold.
The books I intend to review are (not necessarily in this order):
o OS/2 Presentation Manager Programming, Petzold
o Designing OS/2 Applications, Reich
o OS/2 Unleashed, Moskowitz and Kerr
o The Design of OS/2, 2nd Edititon, Kogan and Deitel
I am considering reviewing the IBM OS/2 Redbooks, since they are readily and
cheaply available, and look like good reference.
If anyone has a book they want to see reviewed, I will be happy to oblige, as
long as I can afford it. Of course, requests can be satisfied quicker when
accompanied by a book :) Publishers can send me books at the address on my
personal page at the end of the magazine, and I will review all OS/2
development-related and advanced user books I receive.
/dev/EDM2/BookReview - EDM/2 - Nov 1994 - Volume 2, Issue 10
ΓòÉΓòÉΓòÉ 4. C++ Corner ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 4.1. Introduction ΓòÉΓòÉΓòÉ
C++ Corner
Written by Gordon Zeglinski
Introduction
So are we sick of SOM yet? I hope not! This issue last will be the last
column on SOM for a while. We will look at some benchmarks of SOM vs C++ based
objects. Hopefully you are a curious as I am about the overhead built into
SOM.
ΓòÉΓòÉΓòÉ 4.2. On with the Benchmark ΓòÉΓòÉΓòÉ
What we will try to do here is write a series of tests to determine the
overhead involved with calling a member function in SOM. Because we are
interested only in the function call overhead, the function will simply
increment a counter variable. This counter variable will be stored in the
object's instance data. For comparison, a C++ version of the SOM object will
be used to establish a base mark. The interface definition of the SOM object
follows.
interface SOMFoo : SOMObject
{
attribute long Count; // Stores the Count Data
void IncrementCount(); //procedure
void OffIncrementCount(); //offset
void LookIncrementCount(); //lookup
#ifdef __SOMIDL__
implementation
{
releaseorder: _get_Count,_set_Count,IncrementCount,\
OffIncrementCount,LookIncrementCount;
IncrementCount: procedure;
LookIncrementCount: namelookup;
callstyle=oidl;
filestem = sombench;
somInit: override; // initialize instance variables to 0
somUninit: override; // just for fun
};
#endif /* __SOMIDL__ */
};
Three functions are defined to test the various resolution methods.
IncrementCount is used to test the "procedure" resolution method. A procedure
doesn't use a resolution method per se; a procedure is similar to a non-virtual
C++ function because it is called by its address. OffIncrementCount is used to
test the offset resolution method. This is the default method used by SOM to
resolve a function call. This method is similar to virtual functions in C++.
LookIncrementCount is used to test the name lookup resolution method.
A function can be labeled a procedure as follows:
IncrementCount: procedure;
Because the default "type" for a function is method, one only has to list
functions that are to be procedures.
Note: only methods can be overridden.
Similarily, one can specify that a method is to lookup offset resolution by
using the following:
LookIncrementCount: namelookup;
Again, one only lists functions which deviate from the normal resolution
method. The normal method is offset.
Note: there seems to be a bug in the C++ emitters. This bug causes incorrect
code to be generated for the lookup resolution method.
For the C++ object, we use the following class definition :
class CPPfoo{
int Count; // Stores the Count Data
public:
CPPfoo();
~CPPfoo();
void IncrementCount(); //similar to SOM procedure
void InlineIncrementCount(){Count++;} //no equivalence in SOM procedure
virtual void OffIncrementCount(); //similar to SOM offset
void SetCount(int C){Count=C;}
int GetCount(){return Count;}
};
The C++ object duplicates the SOM object wherever possible. The two major
differences between tests on the C++ and SOM objects are that the C++ object
can't do "name lookup resolution" and the SOM object can't do inline code.
Now that we have seen the objects, we can look at how they will be used. Both
the C++ and SOM objects are structured similarly, thus, it follows that both of
the tests will be implemented similarly.
#define INCL_DOS
#include <os2.h>
#include "sombench.xh"
#include <stdio.h>
void main(){
ULONG StartTime, EndTime;
int i;
SOMFoo *sfoo=new SOMFoo;
DosQuerySysInfo(QSV_MS_COUNT,QSV_MS_COUNT,&StartTime,4); //Get Start time using the system timer
for(i=0;i<1000000;i++)
SOMFoo::IncrementCount(sfoo); //lets call the fnc a million times
DosQuerySysInfo(QSV_MS_COUNT,QSV_MS_COUNT,&EndTime,4); //Get End time we
printf("Time for Procedure calls %i ms count= %i\r\n",EndTime-StartTime,sfoo->_get_Count());
sfoo->_set_Count(0);
DosQuerySysInfo(QSV_MS_COUNT,QSV_MS_COUNT,&StartTime,4);
for(i=0;i<1000000;i++)
sfoo->OffIncrementCount();
DosQuerySysInfo(QSV_MS_COUNT,QSV_MS_COUNT,&EndTime,4);
printf("Time for Offset lookup calls %i ms count= %i\r\n",EndTime-StartTime,sfoo->_get_Count());
sfoo->_set_Count(0);
DosQuerySysInfo(QSV_MS_COUNT,QSV_MS_COUNT,&StartTime,4);
for(i=0;i<1000000;i++)
lookup_LookIncrementCount(sfoo);
// sfoo->LookIncrementCount();
DosQuerySysInfo(QSV_MS_COUNT,QSV_MS_COUNT,&EndTime,4);
printf("Time for Name lookup calls #1 %i ms count= %i\r\n",EndTime-StartTime,sfoo->_get_Count());
sfoo->_set_Count(0);
DosQuerySysInfo(QSV_MS_COUNT,QSV_MS_COUNT,&StartTime,4);
for(i=0;i<1000000;i++)
(somResolveByName(sfoo,"LookIncrementCount") )(sfoo);
DosQuerySysInfo(QSV_MS_COUNT,QSV_MS_COUNT,&EndTime,4);
printf("Time for Name lookup calls #2 %i ms count= %i\r\n",EndTime-StartTime,sfoo->_get_Count());
}
To determine the overhead in making the function call, we call the function 1
million times. The time it takes to call the function 1 million times along
with the value of the incremented variable is displayed after each iteration.
The results of the SOM test follow.
Time for Procedure calls 656 ms count= 1000000
Time for Offset lookup calls 719 ms count= 1000000
Time for Name lookup calls #1 22031 ms count= 1000000
Time for Name lookup calls #2 175031 ms count= 1000000
On a side note, The procedure IncrementCount is emitted as a static member
function in C++. This is strange because you still have to pass it a pointer
to the instance of the C++ object that wraps instance SOM object. This of
course is exactly what a C++ member function does (in an implicit manner).
Running the tests on the C++ object yields the following.
Time for Procedure calls 219 ms count= 1000000
Time for Offset lookup calls 281 ms count= 1000000
Time for inline calls 0 ms count= 1000000
Examining the Results
As usual to give a benchmark meaning, the system it is run on has to be listed.
The following list shows the syslevels of the various components involved in
the tests.
IBM OS/2 Base Operating System
Version 2.11 Component ID 562107701
Type 0
Current CSD level: XR06200
Prior CSD level: XR02110
IBM C/C++ Tools (compiler)
Version 2.00 Component ID 562201703
Current CSD level: CT00010
Prior CSD level: CT00009
SOMobjects Developer Toolkit
Version 2.00 Component ID 96F8647TK
Current CSD level: SM20004
Prior CSD level: SM00000
All of this was running on a 486 DX2-66 PC clone machine with 20 megs of RAM.
Let's start by looking at the C++ test. For 1 million calls to a member
function, only 219 milliseconds was used. Calling a virtual function took just
slightly more time. The inline case took no measurable amount of time. What
happened most probably in the inline case is that the optimizer completely
removed the loop and did a direct assignment instead. (I haven't checked the
compiled code to verify if this is the case or not. If you are curious feel
free to check it yourself.)
One of the arguments you see tossed around when arguing the merits of C++
versus C is that the additional amount of time it takes to call a virtual
function compared to a normal "C function" is negligible. This test confirms
those arguements. The overall amount of time used to call one a virtual
function for "real cases" is even less important.
The offset resolution case in the SOM test took about 2.5 times longer to
execute than did the virtual C++ function test. Recall that the offset
resolution case in SOM is equivalent to the virtual function case in C++. There
are several ways to call a function by it's name. In the first name lookup
test, we use the macro created by the SOM compiler called
lookup_LookIncrementCount. For the second test, we use somResolveByName. Note
that the difference in execution time between the two lookup tests.
Even though the second name lookup case took much longer than the other cases,
one should remember that this test does not necessarily represent a real world
use of the somResolveByName function. This function was called a million
times. If one were to write this in an efficient manner, only 1 call would be
made to determine the address of the function. Once this address has been
determined, it can be reused inside the loop. The time used by the revamped
lookup test should then approach that of the procedure test.
One of the reasons the SOM version is slower than the C++ version is because,
in SOM, the object's interface doesn't have to be fully disclosed. The base
pointer to the data is not the same as the pointer to the objects instance.
Thus, in SOM, one has to query the pointer for the instance data in order to
access it. Consider the following SOM function:
SOM_Scope void SOMLINK OffIncrementCount(SOMFoo *somSelf)
{
SOMFooData *somThis = SOMFooGetData(somSelf);
// SOMFooMethodDebug("SOMFoo","OffIncrementCount");
(somThis->Count)++;
}
Note: I commented out the debug call to increase performance.
Now compare the SOM function to the following C++ member function:
void CPPfoo::IncrementCount(){
Count++;
}
Notice that in the SOM function, we have to determine the value of somThis.
Finally a word of caution. OS/2's time slicing is far too coarse for high
degrees of accuracy with numbers this small. A variation of 32ms (or so) may
occur when running these tests, since that is the resolution of the clock used
to preempt tasks running within the system.
Included Files
CPPTEST.CPP C++ test
SOMBENCH.IDL SOM idl file
SOMBENCH.CPP C++ implementation for SOM object
SOMBENCH.XH SOM header
SOMBENCH.XIH SOM implementation header
SOMBTEST.CPP main routine for SOM tests
ΓòÉΓòÉΓòÉ 4.3. Wrapping Things Up ΓòÉΓòÉΓòÉ
That's it for another fun-filled look at SOM. It should be noted that there
probably will not be an installment of this column next month while I wrap up
the development of INTERcomm, a commercial communications package that I have
developed.
ΓòÉΓòÉΓòÉ 5. Introduction to PM Programming ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 5.1. Introduction ΓòÉΓòÉΓòÉ
Introduction to PM Programming
Written by Larry Salomon, Jr.
Introduction
The purpose of this column is to provide the readers out there who are not
familiar with PM application development the information necessary to satisfy
their curiousity, educate themselves, and give them an advantage over the
documentation supplied by IBM. Of course, much of this stuff could probably be
found in one of the many books out there, but the problem with books in general
is that they don't answer the questions you have after you read the book the
first time through.
I will gladly entertain feedback from the readers about what was "glossed over"
or what was detailed well, what tangential topics need to be covered and what
superfluous crap should have been removed. This feedback is essential in
guaranteeing that you get what you pay for. :)
It should be said that you must not depend solely on this column to teach you
how to develop PM applications; instead, this should be viewed as a supplement
to your other information storehouses (books, the network conferences, etc.).
Because this column must take a general approach, there will be some topics
that you would like to see discussed that really do not belong here. Specific
questions can be directed to the Scratch Patch, where an attempt to answer them
will be made.
Last Month
Last month, we looked at the WC_BUTTON class and the five different
"subclasses" contained therein. This month, we will look at a new application
- BUTTON - which creates types of all of these controls. We will also look at
the ownerdraw concept and how is specifically applies to button controls.
Introduction to PM Programming - EDM/2 - Nov 1994 - Volume 2, Issue 10
ΓòÉΓòÉΓòÉ 5.2. Good Guys Come Last ΓòÉΓòÉΓòÉ
Good Guys Come Last
And easier concepts come first. Before we delve into the application, we
should understand what ownerdraw controls are. The idea behind the ownerdraw
control is that the application garners the responsibility for painting the
control. This is useful in many situations; you might want to change the
appearance of the control (as in ownerdraw buttons), or you might want to add
functionality via usability enhancements (as in ownerdraw listboxes which
contain icons). As more controls are developed with ownerdraw capability, more
uses will be found for this newly created functionality (or is it the second
that drives the first...?).
The last sentence has a double-edged blade, unfortunately. Since there are
more than a few controls with this capability, there can be no standard way of
implementing ownerdrawing. The specifics are tightly bound to the type of the
control which is being "ownerdrawn." For buttons, the owner receives a
WM_CONTROL message with the notification BN_PAINT when the button needs to be
drawn, as an example.
Introduction to PM Programming - EDM/2 - Nov 1994 - Volume 2, Issue 10
ΓòÉΓòÉΓòÉ 5.3. Heeeeere's Johnny ΓòÉΓòÉΓòÉ
Heeeeere's Johnny
Now that we aren't complete idiots <grin> with regard to ownerdraw windows, we
can look at the sample code to see what secrets it holds. The application
isn't complicated - there is a main() function which displays a dialog box.
That's it. But the dialog box procedure is more complicated than what we have
seen up to this point in the column.
MRESULT EXPENTRY buttonDlgProc(HWND hwndWnd,
ULONG ulMsg,
MPARAM mpParm1,
MPARAM mpParm2)
{
PBTNDLGINFO pbdiInfo;
pbdiInfo=(PBTNDLGINFO)WinQueryWindowPtr(hwndWnd,0);
switch (ulMsg) {
case WM_INITDLG:
{
HPS hpsWnd;
//----------------------------------------------------------------
// Get the dialog's instance data and set it in the window words
//----------------------------------------------------------------
pbdiInfo=(PBTNDLGINFO)PVOIDFROMMP(mpParm2);
WinSetWindowPtr(hwndWnd,0,pbdiInfo);
//----------------------------------------------------------------
// Load the bitmaps
//----------------------------------------------------------------
hpsWnd=WinGetPS(hwndWnd);
pbdiInfo->hbmOkUp=GpiLoadBitmap(hpsWnd,
NULLHANDLE,
BMP_OKUP,
0,
0);
pbdiInfo->hbmOkDown=GpiLoadBitmap(hpsWnd,
NULLHANDLE,
BMP_OKDOWN,
0,
0);
pbdiInfo->hbmCancelUp=GpiLoadBitmap(hpsWnd,
NULLHANDLE,
BMP_CANCELUP,
0,
0);
pbdiInfo->hbmCancelDn=GpiLoadBitmap(hpsWnd,
NULLHANDLE,
BMP_CANCELDN,
0,
0);
WinReleasePS(hpsWnd);
//----------------------------------------------------------------
// Set the default state of the dialog
//----------------------------------------------------------------
/* @1 */ WinSendDlgItemMsg(hwndWnd,
DBT_CB_ENABLEGROUP,
BM_SETCHECK,
MPFROMSHORT(TRUE),
0);
}
break;
case WM_DESTROY:
//-------------------------------------------------------------------
// Cleanup
//-------------------------------------------------------------------
GpiDeleteBitmap(pbdiInfo->hbmOkUp);
GpiDeleteBitmap(pbdiInfo->hbmOkDown);
GpiDeleteBitmap(pbdiInfo->hbmCancelUp);
GpiDeleteBitmap(pbdiInfo->hbmCancelDn);
break;
case WM_CONTROL:
switch (SHORT1FROMMP(mpParm1)) {
case DBT_CB_ENABLEGROUP:
switch (SHORT2FROMMP(mpParm1)) {
case BN_CLICKED:
case BN_DBLCLICKED:
{
BOOL bChecked;
//----------------------------------------------------------
// Get the check state of the window and enable or disable
// the radio button group appropriately.
//----------------------------------------------------------
/* @2 */ bChecked=SHORT1FROMMP(WinSendDlgItemMsg(hwndWnd,
DBT_CB_ENABLEGROUP,
BM_QUERYCHECK,
0,
0));
WinEnableWindow(WinWindowFromID(hwndWnd,DBT_RB_CHOICE1),
bChecked);
WinEnableWindow(WinWindowFromID(hwndWnd,DBT_RB_CHOICE2),
bChecked);
}
break;
default:
return WinDefDlgProc(hwndWnd,ulMsg,mpParm1,mpParm2);
} /* endswitch */
break;
case DBT_UB_OK:
case DBT_UB_CANCEL:
switch (SHORT2FROMMP(mpParm1)) {
case BN_PAINT:
{
PUSERBUTTON pubButton;
HBITMAP hbmDraw;
RECTL rclWnd;
BITMAPINFOHEADER2 bmihInfo;
POINTL ptlPoint;
//----------------------------------------------------------
// Get the USERBUTTON structure so that we can paint
// ourselves properly.
//----------------------------------------------------------
/* @3 */ pubButton=(PUSERBUTTON)PVOIDFROMMP(mpParm2);
if (pubButton->fsState==BDS_HILITED) {
if (SHORT1FROMMP(mpParm1)==DBT_UB_OK) {
hbmDraw=pbdiInfo->hbmOkDown;
} else {
hbmDraw=pbdiInfo->hbmCancelDn;
} /* endif */
} else {
if (SHORT1FROMMP(mpParm1)==DBT_UB_OK) {
hbmDraw=pbdiInfo->hbmOkUp;
} else {
hbmDraw=pbdiInfo->hbmCancelUp;
} /* endif */
} /* endif */
//----------------------------------------------------------
// Center the bitmap within the window
//----------------------------------------------------------
/* @4 */ WinQueryWindowRect(pubButton->hwnd,&rclWnd);
bmihInfo.cbFix=16;
GpiQueryBitmapInfoHeader(hbmDraw,&bmihInfo);
ptlPoint.x=rclWnd.xRight/2-bmihInfo.cx/2;
ptlPoint.y=rclWnd.yTop/2-bmihInfo.cy/2;
//----------------------------------------------------------
// Draw the bitmap
//----------------------------------------------------------
WinDrawBitmap(pubButton->hps,
hbmDraw,
NULL,
&ptlPoint,
0,
0,
DBM_NORMAL);
}
break;
default:
return WinDefDlgProc(hwndWnd,ulMsg,mpParm1,mpParm2);
} /* endswitch */
break;
} /* endswitch */
break;
case WM_COMMAND:
switch (SHORT1FROMMP(mpParm1)) {
case DBT_UB_OK:
case DID_OK:
{
SHORT sChecked;
//-------------------------------------------------------------
// Query the tri-state checkbox to see if we should beep.
// If in "halftoned" state, assume that means "don't care"
// and beep anyway.
//-------------------------------------------------------------
/* @5 */ sChecked=SHORT1FROMMP(WinSendDlgItemMsg(hwndWnd,
DBT_3B_WANTBEEP,
BM_QUERYCHECK,
0,
0));
switch (sChecked) {
case 0:
break;
case 1:
WinAlarm(HWND_DESKTOP,WA_NOTE);
break;
case 2:
WinAlarm(HWND_DESKTOP,WA_ERROR);
break;
default:
break;
} /* endswitch */
WinDismissDlg(hwndWnd,TRUE);
}
break;
case DBT_UB_CANCEL:
case DID_CANCEL:
WinDismissDlg(hwndWnd,FALSE);
break;
case DBT_PB_BEEPNOW:
WinAlarm(HWND_DESKTOP,WA_NOTE);
break;
default:
return WinDefDlgProc(hwndWnd,ulMsg,mpParm1,mpParm2);
} /* endswitch */
break;
default:
return WinDefDlgProc(hwndWnd,ulMsg,mpParm1,mpParm2);
} /* endswitch */
return MRFROMSHORT(FALSE);
}
When you stop to look at it, there are only four messages that are processed:
WM_INITDLG and WM_DESTROY for initialization and termination of the dialog box,
WM_CONTROL to control the execution path of the dialog box, and WM_COMMAND to
process the final result of the dialog box.
Landmarks Again
Look at landmark @1; here, we manually set the check state of the button. Why?
If you try the application, you'll see that this checkbox controls whether or
not the radio buttons are enabled. If we do not send the BM_SETCHECK message,
the checkbox will not be checked (by default) but the radio buttons will be
enabled and this doesn't make sense semantically.
At landmark @2, you find that we have to query the button ourselves to see if
it is checked before we can proceed. This has always been one of my pet-peeves
since it should make sense to provide this information to the application in
this message.
Skip to landmark @5 where we find the same BM_QUERYCHECK message as in the
WM_CONTROL notification. The reason for pointing it out here is to demonstrate
that tri-state buttons return a 0, 1, or 2 to indicate unchecked, checked, or
half-toned state.
Back at landmark @3 we see the ownerdrawing code. Button controls pass a
pointer to a USERBUTTON structure in mpParm2 for the BN_PAINT notification.
typedef struct _USERBUTTON {
HWND hwnd;
HPS hps;
ULONG fsState;
ULONG fsStateOld;
} USERBUTTON, *PUSERBUTTON;
hwnd is the handle to the button, hps is the handle to the presentation space
in which you are to draw, fsState and fsStateOld describe the current and
previous state of the button as a BDS_* constant:
BDS_HILITED The button is depressed.
BDS_DEFAULT The button is the default pushbutton.
BDS_DISABLED The button is disabled.
Note that the explanation for BDS_DEFAULT implies that an ownerdraw button is
really a pushbutton incognito.
During the notification, we obtain the pointer to this structure, check the
value of fsState, and draw ourselves appropriately at landmark @4. This final
one, I will ask you to save for a later time.
Introduction to PM Programming - EDM/2 - Nov 1994 - Volume 2, Issue 10
ΓòÉΓòÉΓòÉ 5.4. Conclusion ΓòÉΓòÉΓòÉ
Conclusion
Our conclusion is simple: the button control isn't fooling anyone by looking
complex. In fact, it is a rather unintimidating control. We also looked at
what an ownerdraw control is and how is applies specifically to buttons. As we
dissect other controls with this capability, we will learn how the
functionality can be utilized.
Next month, we will begin looking at our next window class - the listbox.
Introduction to PM Programming - EDM/2 - Nov 1994 - Volume 2, Issue 10
ΓòÉΓòÉΓòÉ 6. Contributors to this Issue ΓòÉΓòÉΓòÉ
Are You a Potential Author?
We are always looking for (new) authors. If you have a topic about which you
would like to write, send a brief description of the topic electronically to
any of the editors, whose addresses are listed below, by the 15th of the month
before the month in which your article will appear. This alerts us that you
will be sending an article so that we can plan the issue layout accordingly.
After you have done this, get the latest copy of the Article Submission
Guidelines from ftp.cdrom.com in the /pub/os2/2_x/program/newsltr directory.
(The file is artsub.zip.) The completed text of your article should be sent to
us no later than five days prior to the last day of the month; any articles
received after that time may be pushed to the next issue.
The editors can be reached at the following email addresses:
o Larry Salomon - os2man@panix.com (Internet).
o Carsten Whimster - bcrwhims@undergrad.math.uwaterloo.ca (Internet).
The following people contributed to this issue in one form or another (in
alphabetical order):
o Larry Salomon, Jr.
o Carsten Whimster
o Gordon Zeglinski
o Network distributors
Contributors - EDM/2 - Nov 1994 - Volume 2, Issue 10
ΓòÉΓòÉΓòÉ 6.1. Larry Salomon, Jr. ΓòÉΓòÉΓòÉ
Larry Salomon, Jr.
Larry Salomon, Jr. wrote his first Presentation Manager application for OS/2
version 1.1 in 1989. Since that time, he has written numerous VIO and PM
applications, including the Scramble applet included with OS/2 and the
I-Brow/Magnify/Screen Capture trio being distributed by IBM with the
Professional Developers Kit CD-ROM. Currently, he works for Cheyenne Software
in Roslyn, New York and resides in Bellerose, New York with his wife Lisa.
Larry can be reached electronically via the Internet at os2man@panix.com.
Contributors - EDM/2 - Nov 1994 - Volume 2, Issue 10
ΓòÉΓòÉΓòÉ 6.2. Carsten Whimster ΓòÉΓòÉΓòÉ
Carsten Whimster
Carsten is an undergraduate Computer Science student at the University of
Waterloo. He is currently in third year, and enjoying it.
Carsten is a beginning OS/2 PM programmer with a few projects on the go. He
uses Watcom C/C++ 10.0 and Watcom VX-REXX 2.0b.
Carsten is the author of POV-Panel/2, a popular shareware dashboard-like
front-end for the POV-Ray 2.x compilers. It can be found on ftp-os2.cdrom.com
in pub/os2/32bit/graphics and some of the other major OS/2 ftp sites. He is
also a TEAM-OS/2 member, and has adopted a little store in Waterloo.
You may reach Carsten...
...via email:
bcrwhims@undergrad.math.uwaterloo.ca - Internet
...via snail mail (notice the changed address):
Carsten Whimster
318A Spruce Street
Waterloo, Ontario
Canada
N2L 3M7
Contributors - EDM/2 - Nov 1994 - Volume 2, Issue 10
ΓòÉΓòÉΓòÉ 6.3. 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 zeglins@cc.umanitoba.ca.
Contributors - EDM/2 - Nov 1994 - Volume 2, Issue 10
ΓòÉΓòÉΓòÉ 6.4. 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!
o Paul Hethmon (hethmon@apac.ag.utk.edu) - Compuserve
o Gess Shankar (gess@knex.mind.org) - Internet
o David Singer (singer@almaden.ibm.com) - IBM Internal
o Andre Asselin (ASSELIN AT RALVM12) - IBM Internal
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 - Nov 1994 - Volume 2, Issue 10
ΓòÉΓòÉΓòÉ 7. How Do I Get EDM/2? ΓòÉΓòÉΓòÉ
How Do I Get EDM/2?
EDM/2 can be obtained in any of the following ways:
On the Internet
o All back issues are available via anonymous FTP from the following sites:
- ftp.cdrom.com in the /pub/os2/2_x/program/newsltr directory.
- ftp.luth.se in the /pub/os2/programming/newsletter directory.
- generalhq.pc.cc.cmu.edu in the /pub/newsletters/edm2 directory.
o The EDM/2 mailing list. Send an empty message to edm2-info@knex.mind.org to
receive a file containing (among other things) instructions for subscribing
to EDM/2. This is a UUCP connection, so be patient please.
o IBM's external gopher/WWW server in Almaden. The address is
index.almaden.ibm.com and it is in the "Non-IBM-Originated" submenu of the
"OS/2 Information" menu; the URL is
"gopher://index.almaden.ibm.com/1nonibm/os2nonib.70".
On Compuserve
All back issues are available in the OS/2 Developers Forum 2.
IBM Internal
o IBM's internal gopher/WWW server in Almaden. The address is
n6tfx.almaden.ibm.com and it is in the "Non-IBM-Originated Files" menu; the
URL is "gopher://n6tfx.almaden.ibm.com/1!!nonibm/nonibm.70".
o IBM's REQUEST command on all internal VM systems. Enter the VM command
REQUEST LIST FROM ASSELIN AT RALVM12 and a list of the requestable packages
will be sent to you; in this list are the names of the packages containing
the EDM/2 issues.
How do I Get EDM/2? - EDM/2 - Nov 1994 - Volume 2, Issue 10