home *** CD-ROM | disk | FTP | other *** search
-
- ΓòÉΓòÉΓòÉ 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