home *** CD-ROM | disk | FTP | other *** search
-
- ΓòÉΓòÉΓòÉ 1. April 1994's Title Page ΓòÉΓòÉΓòÉ
-
- Welcome to EDM/2 - The Electronic OS/2 Developer's Magazine!
- Portions copyright (c) by Larry Salomon Jr.
- Volume 2, issue 4
-
- Copyright Notice and Other Stuff
-
- The editor 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
-
- Leftovers
-
- Last month seemed to be the month of corrections. I have finally - thanks
- David Singer - updated the information about obtaining EDM/2 from within and
- without IBM on their gopher and WWW servers. Many other corrections have been
- made, and thanks go to all who sent me email with bug fixes to INSTALL.CMD,
- etc.
-
- I mentioned last issue that I would hopefully be attending the Technical
- Interchange in San Fransisco at the end of April. Unfortunately, that is no
- longer true because I have changed jobs; as of April 4, I am an employee of
- Cheyenne Software, Inc. As such, I have lost the approval from my management
- at my last job to go to San Fransisco. :)
-
- Speaking of New Employment
-
- Our collective net-friend Timothy Sipples has finally been swept into the Blue
- Family. Congratulations go to Timothy; hopefully, he will be able to continue
- his perpetual fight for truth, justice, and OS/2-for-the-masses from within
- IBM.
-
- More Recognition?
-
- Just a quick note here: I have started receiving mail at my house as the
- editor of this magazine. While I still wonder how my mailing address got out -
- maybe I am the victim of a smart mailing list merging program :) - I am happy
- that the magazine is getting recognized more and more as a real magazine.
-
- Rumor Central/2
-
- Rumor has it that OS/2 2.2 has slipped to November of this year. I don't know
- what that portends, nor what ramifications it holds, but it sure is
- interesting. :)
-
- Another rumor is that the volunteer authors are spending a lot of time on
- Spring Break and mid-terms, so this issue is a bit lean. I would have written
- some more myself, but I already have two columns and just recently contracted
- this virus called 'Internet Relay Chat'. :) My apologies, therefore, for the
- lack of quantity this month.
-
- Rexx Symposium
-
- Cathie Dager sent this to me and I thought the readers would find it
- interesting.
-
- The Rexx Symposium is the Rexx event of the year! It is a participtory
- conference for technical exchange, so bring your ideas, programs, diskettes,
- announcements, and questions to share. Author Mike Cowlishaw will attend and
- speak, along with implementers and developers for REXX on OS/2 and other
- platforms, including several for Unix. Also Timothy Sipples, the OS/2 FAQ
- author, will speak as well as developers for Object REXX for OS/2 and for
- several visual versions: VX-REXX, VisPro REXX and GPF REXX.
-
- This is your opportunity to share information and interact personally with
- implementers and others interested in using and enjoying programming in REXX.
-
- Registration is $200, $75 for students. To register contact Village Travel at
- 1-800-245-3260, 1-415-326-0510, fax 1-415-326-0245.
-
- In addition, the kick-off meeting of the REXX Language Association (RexxLA)
- will be held Monday, May 2, at 7:30 PM also at the Omni Parker House.
-
-
- ΓòÉΓòÉΓòÉ 2. Features for April 1994 ΓòÉΓòÉΓòÉ
-
- The following articles constitute this issue's features:
-
- o Debugging Classes in Borland C++
-
-
- ΓòÉΓòÉΓòÉ 2.1. Debugging Classes in Borland C++ ΓòÉΓòÉΓòÉ
-
-
- ΓòÉΓòÉΓòÉ 2.1.1. Introduction ΓòÉΓòÉΓòÉ
-
- Written by Timm Steinbeck
-
- Introduction
-
- When using Borland C++ for OS/2 I quickly found out that there are certain
- problems involved when debugging programs. Several of these were related to my
- programs, several were of a nature general to debugging and some were and are
- very specific problems due to Borland's debugger. The second type of problems
- manifested themself in a context of Murphy's law: Everything goes wrong when
- you expect it the least, meaning your program has a fault especially when you
- are not debugging it. The third category meant that when debugging rather
- often, not only my program would crash but also the debugger.
-
-
- ΓòÉΓòÉΓòÉ 2.1.2. The Base Protocol Class ΓòÉΓòÉΓòÉ
-
- The Base Protocol Class
-
- To avoid these types of problems I decided to write a class that would enable
- me easily to put statements in the code to write some sort of comment in a file
- for later analysis. I decided to write it so that there would be one globally
- accessible instance of this class in every program that uses it. That way I
- would not have to worry about initialization and deinitialization in the
- programs. I could put this code in the constructor and destructor and forget
- about it. I also made it it so that the constructor and destructor also wrote
- the time and date of the beginning and ending of the session.
-
- After some time I realized that it would be quite useful having routines for
- writing a complete PM message or a number without having to manually convert
- them to strings. So together with the function for writing text to the file I
- then had a class declaration that looked like this:
-
- class OProtocol {
- protected:
- char* PathName; // Pointer for the name of the file
- // were comments are to be stored
- int IO; // Indicator whether file can be
- // opened or not
- public:
- OProtocol(char* Name); // Filename is passed to class
- ~OProtocol();
- virtual void Text(char* Text);
- virtual void Msg(HWND hWnd, UINT Msg, MPARAM P1, MPARAM P2);
- virtual void Long(char *c, long l);
- };
-
-
- ΓòÉΓòÉΓòÉ 2.1.3. The Procedure Protocol Class ΓòÉΓòÉΓòÉ
-
- The Procedure Protocol Class
-
- After some time I even became too lazy to put statements at the beginning and
- end of each procedure. While nothing could be done about the beginning I
- decided to write another class for procedure-comments, using the OProtocol
- class for writing the comments to the file. For this class I only needed to
- write a constructor and a destructor. When an instance of the class is
- declared at the beginning of a procedure the constructor writes a comment about
- the procedure being started. The destructor is then called automatically when
- the procedure ends, so this is a good place for writing a comment about the end
- of the procedure. This left me with the following class declaration:
-
- class OProcedure {
- protected:
- char *ProcName;
- public:
- OProcedure(char * Name);
- ~OProcedure();
- };
-
- I wrote the constructor so, that it wrote something like "Function <name>
- started" in the protocol file. The destructor then writes "Function <name>
- ended". So when creating an instance of this class in a function passing the
- name of the function I had a list of when this function was called and when it
- was ended.
-
-
- ΓòÉΓòÉΓòÉ 2.1.4. The Method Protocol Class ΓòÉΓòÉΓòÉ
-
- The Method Protocol Class
-
- But even this capability did not satisfy me, since whenever working with
- several instances of a class I only knew that a member function was called, but
- not to which instance it did belong. Of course I could call
- OProtocol::Long(this) but being lazy, I sought a better - or rather easier -
- way to do this. The solution was to write a new class that was similar to the
- OProcedure class but whose constructor accepted a PVOID as an argument and
- could then write this pointer to the protocol file as well.
-
- class OMethod {
- protected:
- char *ProcName;
- void *that;
- public:
- OMethod(void *That, char *Name);
- ~OMethod();
- };
-
- This class is of course not much different from OProcedure, but it has the
- additional advantage of providing a standardized format in the file for method
- calls. I did not derive the OMethod class from the OProcedure class on purpose
- because I wanted to have the whole comment in one line, so that I had no use
- for the OProcedure constructor.
-
-
- ΓòÉΓòÉΓòÉ 2.1.5. Some Helping Hands ΓòÉΓòÉΓòÉ
-
- Some Helping Hands
-
- What I described so far are just the classes. But until now when I used them
- during a debugging cycle and then finished the program I would have to delete
- everything by hand. As I am sure you will have guessed by now, this did not
- satisfy me and so I went ahead and wrote a couple of macros for calling the
- functions. The first macro actually is for creating and initializing an
- instance of the OProtocol class.
-
- #define PROT_NEW(ClasS, FilE) ClasS Protocol(FilE);ProtP=3D&Protocol
-
- ProtP is a global pointer to OProtocol. So for using a protocol file in a
- program I would then write PROT_NEW(OProtocol, "Foo.Prt");. This approach also
- enables other users to derive classes from OProtocol and then use these for
- writing the messages. The other macros I defined just went about and called
- ProtP methods or created instances of OProcedure or OMethod respectively. And
- not to forget the reason for this operation I used preprocessor directives for
- empty versions of all these macros.
-
- The actual implementation of all this is rather straightforward and will
- therefore not be elaborated further; there are, of course, comments in the
- source file.
-
-
- ΓòÉΓòÉΓòÉ 2.1.6. Usage ΓòÉΓòÉΓòÉ
-
- Usage
-
- For the classes to be of some use, you must know how to use them. For this
- purpose I will put some exemplary statements here.
-
- PROT_NEW(OProtocol, "C:\\FOO\\BAR.PRT");
-
- This will initialize the protocol session in a file C:\FOO\BAR.PTR. A
- statement like that has to occur before any other protocoling attempts take
- place. And there should only be one of them as well.
-
- PROT_TEXT("Sample debugging text");
-
- This writes
-
- Sample debugging text
- in the previously initialized file, in this case C:\FOO\BAR.PRT. If you want a
- line feed here you have to pass it yourself, but it is not much work rewriting
- the code, so that it is done automatically.
-
- PROT_LONG("A sample long", ASampleLong);
-
- The Result of this will be
-
- A sample long: 0x1234\n
- or with whatever value ASampleLong happens to have.
-
- PROT_MSG(AnHWND, WM_CREATE, 0, 0);
-
- After this call you will be able to read
-
- Message: 0x1234 0x1 0x0 0x0\n
- in your protocol file.
-
- PROT_METHOD("SampleMethod");
-
- This statement in a method will result in two lines:
-
- Object 0x1234\tMethod --> SampleMethod\n
- Object 0x1234\tMethod <-- SampleMethod\n
- The this pointer of the object need not be given specifically
-
- PROT_PROCEDURE can be used similarly to PROT_METHOD. But whereas you can use
- PROT_PROCEDURE in methods as well, you can't use PROT_METHOD in a simple
- function, since it it assumes that this is properly defined.
-
- To determine what you want to include and what you don't want when compiling
- there are several #defines. These are:
-
- o DBG_PROT_TEXT
-
- o DBG_PROT_MSG
-
- o DBG_PROT_LONG
-
- o DBG_PROT_PROC
-
- o DBG_PROT_ALL
-
- All of those defines will result in the including of the OProtocol class and
- DBG_PROT_PROC will also include OProcedure and OMethod. They will also control
- the expansation of the PROT_* macros to something useful or just empty macros.
-
- DBG_PROT_TEXT This will expand the PROT_TEXT macro for text into a call to
- OProtocol::Text().
-
- DBG_PROT_MSG This will expand the PROT_MSG macro into a call to
- OProtocol::Msg().
-
- DBG_PROT_LONG This will enable the use of OProtocol::Long() via PROT_LONG.
-
- DBG_PROT_PROC This results in the expansion of the PROT_PROCEDURE and
- PROT_METHOD for access to the OProcedure and OMethod classes.
-
- Finally, to use it you need to link PROT.OBJ to your executable when you are
- debugging it. When you haven't defined any of the DBG_PROT_* defines there is
- no need to do so.
-
- I will also add one word or warning: be careful not to put too many
- protocoling statements in a program, especially be wary with protocolin
- messages. You can quickly end up having a protocol file of more than half a
- megabyte. Try to reduce the usage to the finished parts.
-
-
- ΓòÉΓòÉΓòÉ 3. Columns ΓòÉΓòÉΓòÉ
-
- The following columns can be found in this issue:
-
- o /dev/EDM/BookReview
- o C++ Corner
- o Introduction to PM Programming
- o Scratch Patch
-
-
- ΓòÉΓòÉΓòÉ 3.1. /dev/EDM/BookReview ΓòÉΓòÉΓòÉ
-
-
- ΓòÉΓòÉΓòÉ 3.1.1. Introduction ΓòÉΓòÉΓòÉ
-
- /dev/EDM2/BookReview
-
- Written by Carsten Whimster
-
- /dev/EDM2/BookReview is a monthly column which focuses on development oriented
- books and materials. This will mostly consist of programming books, such as
- this month's Learning to Program OS/2 2.0 Presentation Manager by Example, but
- could also cover books like The Design of OS/2. The column is from a beginning
- PM programmer's eyes (because that's what I am), and hopefully that is most
- useful to the community in general. As I get on with the column, however, I
- expect to get better, and so within a year or so, I will presumably :) qualify
- as an intermediate programmer, or perhaps even somewhat of an expert.
- Hopefully you, the readers, will move with me in that respect. When reading
- this column, try to pick up whichever book strikes your fancy, and join the
- growing group of people following our introductory PM programming columns. I
- will try to review books aimed at beginners to start with, and then move on
- from there.
-
- The column will largely be demand-oriented (after I get my own books out of the
- way early on), so if you have a book you would like reviewed, send me e-mail
- and tell me about it, or even better, send me the book. Finally, please send
- me your comments and thoughts so that I can make this column as effective as
- possible. After all, this is our magazine, and it will be most effective with
- lots of reader feedback.
-
- This month's selection was chosen because I own a copy :), and because it has a
- number of good chapters in it. It was purchased through IBM. It is obviously
- for the previous version of OS/2, and so does not have any 2.1 features in it.
- However, most of the API is unchanged so there is still lots of useful material
- in it.
-
-
- ΓòÉΓòÉΓòÉ 3.1.2. Errata ΓòÉΓòÉΓòÉ
-
- Errata
-
- After the March review I was contacted by someone who told me that the Watcom
- makefile wasn't on the disk that came with Real World Programming for OS/2 2.1.
- I took a quick look, and at first glance he appeared to be right. I looked a
- little closer, however, and found the file in a:\brief\backup\watcom.mak.
- Fairly well hidden, but there nonetheless. Why it was two levels deep remains a
- mystery, as the other makefiles were in the root directory. It does look like
- it is a Watcom C386 makefile, though. I don't know enough about their product
- to say whether it will work with Watcom C/C++, but I imagine it probably will.
-
- Some people have commented on Borland problems as well, so here is how to make
- RWPOS2 work with Borland:
-
- 1. edit BORLAND.MAK to say OS2 instead of OS2386 in both TLINK lines.
-
- OR
-
- if you have the Toolkit, make sure that BC can find OS2386.LIB . This lets
- you recompile the programs (link, to be accurate).
- 2. set an environment variable called LIB to point to your BCOS2\LIB
- directory. This fixes the command-line MAKE command.
- 3. if you don't have the Toolkit (see above), then you will have to edit the
- definition file from chapter 3 to include these lines to be able to
- recompile that particular program:
-
- IMPORTS
- Win32StretchPointer = PMWIN.968
-
-
- ΓòÉΓòÉΓòÉ 3.1.3. Learning to Program OS/2 2.0 Presentation Manager by Example ΓòÉΓòÉΓòÉ
-
- Learning to Program OS/2 2.0 Presentation Manager by Example
-
- This book has been an eye-opener for me. When I first bought it, I was a
- little disappointed with the fairly dry presentation, and the only 230 pages.
- As I started reviewing it in earnest, however, I realized that its small size
- is misleading. Before I go any further, let me list the chapter headings:
-
- 1. Overview
- 2. Working With Messages
- 3. Drawing in the Client Area
- 4. Working With Resources
- 5. Message and Dialog Boxes
- 6. Animation
- 7. Implementing a Help Interface
- 8. Working With Time
- 9. Notable OS/2 2.0 Enhancements
-
- This doesn't look like much on the face of it, but several of these chapters
- are very well written, and give a very good introduction to their material.
- Unfortunately, the installation "program" for the sample code (on a 3.5" disk)
- consists of a series of copy statements, so there is no great learning material
- in that area.
-
- First, I should note that I didn't really get a chance to read very much in
- chapters 3, 6, and 8, so, sorry Q, I don't know if the animation you are
- looking for is in chapter 6 :). It looks like it is only the imaginative
- application of GpiBitBlt and DosSleep, however, with GpiSetPattern thrown in
- for the fade effect demonstrated. No sprites. Chapter 3 looks like a fairly
- good introduction to GPI functions, working with fonts, kerning and so on.
- Chapter 8 contains a brief introduction to using WM_TIMER messages, DosSleep(),
- and threads.
-
- The chapters I did read in depth (chapters 1, 2, 4, 5, and 7) are very good,
- though. "Overview" is perhaps a bit brief, but I think that most programmers
- prefer getting their feet wet quickly, so no great loss there.
-
- "Working With Messages" introduces the first snippets of code. By the way,
- this book has only one sample program! It is a puzzle-type application, in
- which you cut the screen up into a grid, scramble the rectangles, and try to
- put it back together again. This program eventually grows to be fairly large,
- and serves to introduce a number of important basic areas, but if you are
- looking for a series of diverse applications and lots of sample code, look
- elsewhere. Having said that, let me explain why this is a good beginner's book
- after all. The introduction to why PM programs are as strangely laid out as
- they are is quite good, and the code is well documented and explained. This
- chapter lays out the obligatory skeleton program, on which the rest of the
- features are hung along the way.
-
- Each chapter adds its own components to the basic program, until at the end of
- the book, the full source code listing is presented in an appendix. In this
- manner, "Working With Resources" explains how the various pointers, bitmaps,
- the application icon, the menus, and the accelerator keys are added to the
- application. This chapter is probably the best written in the book, and goes a
- long way towards explaining why I appreciate this book. This doesn't mean that
- it goes into incredible depth, merely that each of the relevant resource
- statements is well explained, and the proper usage demonstrated.
-
- "Message and Dialog Boxes" explains how these types of windows are created and
- manipulated, and how they can be used most effectively, but again, there isn't
- great depth here, just very careful explanations.
-
- And so it goes: "Implementing a Help Interface" explains briefly how to use the
- tagging language to make HLP and INF files, and how to interface your
- application to them. It skips some of the more advanced features of IPFC, but
- covers the basics pretty well.
-
- Finally, "Notable OS/2 2.0 Enhancements" discusses the theoretical value of the
- file dialog, the font dialog, the value set control, the slider control, the
- container control, and the notebook control, but gives no code. This, for me,
- was disappointing, since I am trying to add a notebook to my application.
-
- In summary, for the rank novice, this book has some very good explanations,
- including good discussions of the various data structures, but it does not go
- into great depth anywhere. You will not become an expert in any one field by
- reading this book, but you will have a solid foundation on which to build.
- There aren't very many explanations of calls other than the ones used by the
- author, though. The language is a little dry, with less humour than I prefer,
- but it is also very competent. I feel that the description on the back of the
- book is a little ambitious given its size and content. If this book was
- rewritten with maybe another application or two to explain other techniques,
- more pages, more professional animation techniques, some 2.1 additions, and
- more depth (lotsa code!), especially in chapter 9, I would buy it (again).
- Especially if some chuckles were added.
-
-
- ΓòÉΓòÉΓòÉ 3.1.4. Summary and Ratings ΓòÉΓòÉΓòÉ
-
- Summary and Ratings
-
- This book is a bit of a mixed bag. It completely skips such areas as profile
- management, compatibility with 16 bit code, device drivers, WPS, SOM, and
- numerous others. It also brushes very lightly over DLLs, common dialogs,
- notebooks, etc. But, and it is a big "but", it has very good introductory
- chapters on messages, resources (including bitmaps, icons, pointers, menus, and
- accelerator keys), message boxes, dialog boxes, and implementing a help
- interface. If you are just getting into PM C programming (which I am), these
- chapters explain their material very well, and I went from knowing next to zip
- about resources to writing very nice dialogs, menus, and so on. It is slim,
- and expensive for its size, but in my case, it is what the doctor prescribed.
- In my humble opinion it needs rewriting for OS/2 2.1, and should have more
- depth in most areas, but it is still a good book for beginners. Intermediate
- and expert programmer's won't find much in here, though.
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- ΓöéBOOK ΓöéAUDIENCE ΓöéMARKΓöéCOMMENTS Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- ΓöéReal World Programming for OS/2 2.1,ΓöéIntermediateΓöéB+ ΓöéLots of good code examples, but sometimes it is Γöé
- ΓöéBlain, Delimon, and English, SAMS Γöéto Advanced Γöé Γöétoo complex for novices. Accurate. Well Γöé
- ΓöéPublishing. ISBN 0-672-30300-0. ΓöéPM C Γöé Γöéorganized. The index needs a little beefing up. Γöé
- ΓöéUS$40, CAN$50. Γöéprogrammers Γöé Γöé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 very Γöé
- ΓöéPresentation Manager by Example, ΓöéC Γöé Γöérewarding. It is not very large, and a bit Γöé
- ΓöéKnight, Van Nostrand Reinhold. ISBN ΓöéProgrammers Γöé Γöépricey, but has some excellent chapters on Γöé
- Γöé0-442-01292-6. US$40, CAN$50. Γöé Γöé Γöébeginning topics, such as messages, resources, Γöé
- Γöé Γöé Γöé ΓöéIPF, and dialog boxes. Strictly for beginners. Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
- This table contains all books I have reviewed, so that you can find what you
- are looking for at a glance. I will be very careful to rate books fairly
- relative to each other, but I will rate conservatively until I get a better
- feel for what's out there. 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, for example, a new book came out which was so good that there wasn't
- enough room at the top of the scale to properly convey this. :) Please note
- that books aimed at different audiences should only be compared with great
- care, if at all. I may revise, expand, or add categories in the future. By
- the way, if you are expecting a Siskel and Ebert type dicing and slicing show,
- you will be disappointed. I intend to concentrate on the strong points of the
- books I review, since I don't think too many people really deserve being cut up
- for a piece of work they have laboured over. Having said that, I will point
- out any weaknesses, but in a constructive manner. Read the reviews carefully
- for what you are looking for.
-
- BOOK: The name of the book, author(s), publishing company, ISBN, and price
- (approximate.)
-
- 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. I don't expect to see any
- book score less than C, but the scale is there if necessary.
-
- ΓöîΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé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 repairing Γöé
- Γö£ΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé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 summary of the review proper, although in a very brief
- format.
-
-
- ΓòÉΓòÉΓòÉ 3.1.5. Coming Up ΓòÉΓòÉΓòÉ
-
- Coming Up
-
- Next month I will be looking at The Art of OS/2 C Programming, Panov, Salomon,
- and Panov, if it gets here in time. Otherwise I will review Writing OS/2 2.1
- Device Drivers in C, 2nd Edition, Mastrianni. The books I currently intend to
- review are (not necessarily in this order):
-
- o The Art of OS/2 C Programming, Panov, Salomon, and Panov
- o Writing OS/2 2.1 Device Drivers in C, 2nd Edition, Mastrianni
- o OS/2 Presentation Manager GPI, Winn
- o OS/2 Presentation Manager Programming, Petzold - 1994 - not yet published, I
- am told :(
- o The Design of OS/2, 2nd Edititon, Kogan and Deitel - 1994 - maybe not
- published yet? I will review the old version if someone sends me one, but if
- I have to buy it I will wait for the new edition.
-
- This list is not set in stone, but they are books I am interested in. I am
- considering reviewing the IBM OS/2 Redbooks, since they are readily and cheaply
- available, and look like good introductory reference. I am also considering
- reviewing OS/2 Unleashed, but it is not strictly speaking a development book,
- so I'm going to wait until the list of real development books has diminished a
- bit. By the way, does anyone know why the special edition of OS/2 Unleashed
- has completely different authors? And what is different about the Special
- Edition?
-
- I would also like to review a REXX book, as I have VX-REXX 2.0, but I don't
- really know what books are supposed to be good, so if anyone has ideas here,
- please write.
-
- 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, the request could be satisfied a lot
- quicker if accompanied by a book. :)
-
-
- ΓòÉΓòÉΓòÉ 3.2. C++ Corner ΓòÉΓòÉΓòÉ
-
-
- ΓòÉΓòÉΓòÉ 3.2.1. Queues Continued ΓòÉΓòÉΓòÉ
-
- Written by Gordon Zeglinski
-
- Queues Continued
-
- We start by looking at what we have accomplished last time. In the last issue,
- OS/2 queues were encapsulated and a very simple shared memory management scheme
- was developed to manage the memory used by the queues. It was found that this
- scheme was next to useless for real applications. In the last issue, we
- concluded that in order to have a more usable queue object, we need better
- memory management. So now the goal is to develop a new method for using the
- shared memory. In this issue we start by looking for a new memory management
- scheme. Fortunately, OS/2 already provides a mechanism that fits our needs -
- suballocation! Yeah that's the ticket.
-
- The Saga Begins
-
- After a day of frustration, a short email is sent. Following is a paraphrased
- transcript:
-
- "Hey Lar, U ever use DosSubSetMem with shared Memory?"
-
- "No, but try a simple example and work from there ..."
-
- "Sounds like a good idea to me..."
-
-
- ΓòÉΓòÉΓòÉ 3.2.2. Off to the Races ΓòÉΓòÉΓòÉ
-
- Off to the Races
-
- Something simple...hmmm...Okay, lets try this:
-
- #define INCL_DOSMEMMGR
- #include <os2.h>
-
- #include <iostream.h>
- #include <conio.h>
-
-
- void main() {
- int ret;
- void *BaseAddr,*SubAdr;
- char *MemoryName="\\SHAREMEM\\Mem.Mem";
-
- //Allocate some shared memory
- ret=DosAllocSharedMem(&BaseAddr,MemoryName,1024*30,
- PAG_EXECUTE|PAG_READ|PAG_WRITE);
- cout<<"Alloc Return : "<<ret<<endl;
- cout<<"Base Adr : "<<BaseAddr<<endl;
-
- //Prepare shared Memory for sub allocation
- ret=DosSubSetMem(BaseAddr,DOSSUB_SPARSE_OBJ|DOSSUB_SERIALIZE|DOSSUB_INIT,
- 1024*30);
- cout<<"SubSet Return : "<<ret<<endl;
-
- cout<<"Press Return"<<endl;
- getch();
-
- //suballocate a bit of memory
- ret=DosSubAllocMem(BaseAddr,&SubAdr,1024);
- cout<<"SubAlloc Return : "<<ret<<endl;
- cout<<"SubAlloc Adr : "<<SubAdr<<endl;
-
- cout<<"Press Return"<<endl;
- getch();
-
- //free the suballocated ram
- ret=DosSubFreeMem(BaseAddr,SubAdr,1024);
- cout<<"SubFree Return : "<<ret<<endl;
-
- cout<<"Press Return"<<endl;
- getch();
-
- //Uninitialze suballocation struvtures
- ret=DosSubUnsetMem(BaseAddr);
- cout<<"SubUnSet Return : "<<ret<<endl;
-
- //Free up the main memory block
- ret=DosFreeMem(BaseAddr);
- cout<<"FreeBase Return : "<<ret<<endl;
- }
-
- The above program creates a heap in shared memory, prepares it for
- suballocation, suballocates a chunk of the heap, and frees everything up.
- That's simple enough, and it even works!
-
- Time to make it a bit more interesting. The following program is to be
- executed after the program above. The reason the program above has the "Press
- Return" messages in it is so that it can be paused long enough for this
- following program to be run.
-
- #define INCL_DOSMEMMGR
- #include <os2.h>
-
- #include <iostream.h>
- #include <conio.h>
-
-
- void main() {
- int ret;
- void *BaseAddr,*SubAdr;
- char *MemoryName="\\SHAREMEM\\Mem.Mem";
-
- ret=DosGetNamedSharedMem(&BaseAddr,MemoryName,
- PAG_READ|PAG_WRITE|PAG_EXECUTE);
- cout<<"Open Return : "<<ret<<endl;
- cout<<"Base Adr : "<<BaseAddr<<endl;
-
- //Get access to the named shared memory
- ret=DosSubSetMem(BaseAddr,DOSSUB_SPARSE_OBJ|DOSSUB_SERIALIZE,
- 1024*30);
- cout<<"SubSet Return : "<<ret<<endl;
-
- cout<<"Press Return"<<endl;
- getch();
-
- ret=DosSubAllocMem(BaseAddr,&SubAdr,1024);
- cout<<"SubAlloc Return : "<<ret<<endl;
- cout<<"SubAlloc Adr : "<<SubAdr<<endl;
-
- cout<<"Press Return"<<endl;
- getch();
-
- ret=DosSubFreeMem(BaseAddr,SubAdr,1024);
- cout<<"SubFree Return : "<<ret<<endl;
-
- cout<<"Press Return"<<endl;
- getch();
-
- ret=DosSubUnsetMem(BaseAddr);
- cout<<"SubUnSet Return : "<<ret<<endl;
-
- ret=DosFreeMem(BaseAddr);
- cout<<"FreeBase Return : "<<ret<<endl;
- }
-
- This one works too! So what was the big deal? As it turns out, the size
- parameter in the call to DosSubSetMem() must be the same in both processes.
- This doesn't really make sense to me, as one would think that the second
- process would be able to know the size used by the first process. After all,
- the memory block is already initialized by the first process. The thing that
- bothered me the most about the DosSubSetMem() call, is that it returns error
- codes which aren't even documented as being returned by this function! This
- certainly didn't make life any easier the first time.
-
- Included Files
-
- Compiled versions of the above code are included as MEMCREATE and MEMOPEN.
- When executing these programs, MEMCREATE must be executed first and be paused
- at one of the "Press Enter" requests before MEMOPEN can be started. For fun,
- try running these programs while stopping them at different "Press Enter"
- requests. What you will notice, is that the allocated pointers offset will
- vary depending on where the other program is stopped. This indicates that the
- memory block is being properly shared by the two processes.
-
- The Memory API
-
- We've used many of the memory management function found in the Dos* API. A
- quick overview follows :
-
-
- API Call Function
-
- DosAllocSharedMem Allocate a block of named or
- unnamed shared memory.
-
- DosGetNamedSharedMem Get access to a named block of
- shared memory.
-
- DosSubSetMem Initialize memory for
- suballocation if DOSSUB_INIT
- is used; otherwise, it
- attaches to an existing block
- of memory (provided
- DOSSUB_GROW is not used)
-
- DosSubAllocMem Allocate a chunk of ram from
- the heap created by
- DosSubSetMem.
-
- DosSubFreeMem Return memory to the heap.
-
- DosSubUnsetMem Undo the effects of
- DosSubSetMem.
-
- DosFreeMem Free the memory allocated by
- DosAllocSharedMem.
-
- More details on these functions can be found in Control Program Guide and
- Reference.
-
- To emphasize an important detail, when DosSubSetMem() is used with shared
- memory, the length parameter must be the same in all processes using the shared
- memory block.
-
-
- ΓòÉΓòÉΓòÉ 3.2.3. Back to OOP ΓòÉΓòÉΓòÉ
-
- Back to OOP
-
- Memory Objects
-
- The key to our new and improved Queue objects is better use of shared memory.
- Shared memory uses the same API as private memory. This gives us an
- opportunity to flex our OOP muscles a bit by creating a hierarchy that has the
- potential to encapsulate both shared and non-shared memory.
-
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- ΓöéMemoryObjΓöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
- Γöé Γöé
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- ΓöéSharedMemoryObjΓöé ΓöéPrivateMemoryObjΓöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
-
- Memory Object Hierarchy
-
- Although we won't develop the PrivateMemoryObj here, it's prototype is included
- in the header file for the memory objects. The difference between the shared
- and private memory objects, is that the private memory object would use
- DosAllocMem() instead of DosAllocSharedMem() to allocate memory for the heap.
-
- MemoryObj
-
- As the base of this hierarchy, this class provides methods and data members
- which encapsulate properties which are common to both private and shared
- memory. These properties are: a base address, methods for suballocation, and a
- method to free the base memory.
-
- SharedMemoryObj and PrivateMemoryObj
-
- These classes provide the methods necessary to create or gain access to the
- base memory block. In the case of shared memory, the name of the memory block
- is also stored.
-
- Included Files
-
- The files MEMOBJ.H and MEMOBJ.CPP contain all the source code necessary to
- compile the MemoryObj and SharedMemoryObj objects.
-
- New and Improved Queues
-
- One of the nice things about OOP is that even though the internals of an object
- are changed, code external to the object can use it without modification
- providing the objects interface remains the same. This is almost the case
- here. The queue client remains the same. However, because memory is now
- "officially allocated" in the client, the queue server now has to deallocate
- the memory the queue client allocates. The new version of the server code
- follows.
-
- int main() {
-
- int loop;
- QueueMessage *Mesg;
- EventSemaphore Sem((char*)NULL,Semaphore::SemCreate,DC_SEM_SHARED);
-
- ServerQueueObj InQueue(SMemName,NemSize,QName,0,&Sem);
-
-
- loop=1;
-
- Sem.Reset();
-
- cout<<"Queue Server Active !"<<endl;
-
- while(loop){
-
- Mesg=(QueueMessage *) InQueue.Read(0,1);
- while(InQueue.GetError() ){
- Sem.Wait();
- Mesg=(QueueMessage *) InQueue.Read(0,1);
- }
-
- if(Mesg->Number == -1){
- loop=0;
- cout<<"Terminating"<<endl;
- }
- else{
- cout<<"Number= "<<Mesg->Number<<endl;
- }
- InQueue.FreeLastReadMem();
- }
-
- return 0;
- }
-
- We now have queue objects which are not limited by the way they use shared
- memory. Our goal has been accomplished.
-
- Included Files
-
- Only the files QUEUEOBJ.CPP, QUEUEOBJ.H, and QSERVE.CPP are different than
- those included in part one of this column. However, for convenience, the
- complete set of files will be included.
-
-
- ΓòÉΓòÉΓòÉ 3.2.4. Summary ΓòÉΓòÉΓòÉ
-
- Summary
-
- Building upon our experience with shared memory from last issue, we developed a
- new memory hierarchy. The memory hierarchy was developed only far enough as to
- be useful to manipulate the shared memory pool used by the queue objects.
- Extending it further is left as an exercise to the reader. The new queue
- objects are not limited by the shared memory allocation scheme as were the ones
- developed last time.
-
-
- ΓòÉΓòÉΓòÉ 3.3. Introduction to PM Programming ΓòÉΓòÉΓòÉ
-
-
- ΓòÉΓòÉΓòÉ 3.3.1. Introduction ΓòÉΓòÉΓòÉ
-
- 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.
-
-
- ΓòÉΓòÉΓòÉ 3.3.2. Last Month ΓòÉΓòÉΓòÉ
-
- Last Month
-
- Last month, we began looking at dialog boxes and their components. This month,
- we'll continue by delving into the source code to HELLO which was presented
- last month. We'll examine the messages in our dialog procedure, and will begin
- looking at how controls are used within dialogs.
-
-
- ΓòÉΓòÉΓòÉ 3.3.3. nameDlgProc() ΓòÉΓòÉΓòÉ
-
- nameDlgProc()
-
- Below is the dialog procedure from HELLO.C condensed a bit:
-
- MRESULT EXPENTRY nameDlgProc(HWND hwndWnd,
- ULONG ulMsg,
- MPARAM mpParm1,
- MPARAM mpParm2)
- {
- switch (ulMsg) {
- case WM_INITDLG:
- :
- break;
- case WM_CONTROL:
- :
- break;
- case WM_COMMAND:
- :
- break;
- default:
- return WinDefDlgProc(hwndWnd,ulMsg,mpParm1,mpParm2);
- } /* endswitch */
-
- return MRFROMSHORT(FALSE);
- }
-
- We looked at the WM_INITDLG message last issue; let's take a look at the other
- two.
-
- WM_COMMAND
-
- This message occurs when a command is to be performed, or when a key
- combination is translated to a WM_COMMAND accelerator message.
-
- Parameters
-
- param1
-
- usId (USHORT)
-
- Identifier of the command or accelerator key.
-
- usSource (USHORT)
-
- A CMDSRC_* constant describing the source of the message
-
- param2
-
- bPointer (BOOL)
-
- Pointer indicator
-
- TRUE The message is the result of a pointer action.
- FALSE The message is the result of a keyboard action.
-
- Returns
-
- reply
-
- ulReserved (BIT32)
-
- Reserved, and must be zero.
-
- WM_CONTROL
-
- This message occurs when a control has a significant event to report to its
- owner.
-
- Parameters
-
- param1
-
- usId (USHORT)
-
- Identifier of the control sending the notification.
-
- usNotify (USHORT)
-
- The notification code. This is specific to the window class of the
- control.
-
- param2
-
- pvData (PVOID)
-
- Control data. This is specific to the notification code being sent.
-
- Returns
-
- reply
-
- ulReserved (BIT32)
-
- Reserved, and must be zero.
-
- Okay, "big deal," you say. Just add two more entries to your list of messages
- that you now know about? Well, these messages are a bit more important than
- that...
-
-
- ΓòÉΓòÉΓòÉ 3.3.4. The WM_COMMAND Message ΓòÉΓòÉΓòÉ
-
- The WM_COMMAND Message
-
- The WM_COMMAND message is important because it is the focal point through which
- your application will get notified that something needs to get done. Among
- other things...
-
- o menu items send this message when they are selected
- o pushbuttons send this message when they are selected
- o the frame window sends this message whenever the user presses a key
- combination that is defined in the accelerator table
- o dialogs automatically receive this whenever Enter or Escape are pressed.
-
- It doesn't look like much, but as you travel the PM developer's journey, you'll
- find that this message is frequently sent. It becomes your central interface
- to the user, since most actions are requested by the user through menus on
- client windows and through pushbuttons on dialogs.
-
- Let's take a look at how this message is treated in HELLO.C.
-
- case WM_COMMAND:
- switch (SHORT1FROMMP(mpParm1)) {
- case DID_OK:
- WinDismissDlg(hwndWnd,TRUE);
- break;
- case DID_CANCEL:
- WinDismissDlg(hwndWnd,FALSE);
- break;
- default:
- return WinDefDlgProc(hwndWnd,ulMsg,mpParm1,mpParm2);
- } /* endswitch */
- break;
-
- It isn't obvious in the documentation, if I remember correctly, so don't feel
- ashamed if you don't understand the constants DID_OK and DID_CANCEL.
-
- DID_OK Sent whenever the user presses Enter
- DID_CANCEL Sent whenever the user presses Escape
-
- It is imperative that you understand that these messages are not sent by
- pushbuttons. Thus, even though your dialog might not have pushbuttons, it is
- possible to receive these messages. (If you don't believe me, comment out the
- DEFPUSHBUTTON and PUSHBUTTON lines in HELLO.RC, recompile and try.)
-
- Dismissal Revisited
-
- When reading last month's column, I realized that I was talking about the
- dismissal of dialogs like we were all old pro's at it; if we were, I thought,
- this column wouldn't have a reason for existance.
-
- BOOL WinDismissDlg(HWND hwndDlg,ULONG ulResult);
-
- This function is used to dismiss a dialog. As was mentioned last time, this
- does not destroy the dialog by default; it only hides the dialog. What does
- this have to do with the WM_COMMAND message? Well, the typical action for
- DID_OK and DID_CANCEL is to dismiss the dialog (for DID_OK, data is usually
- read from the dialog also and verified), so you can see that this function is
- used frequently.
-
- In the above, no data is read from the dialog. How does the program know what
- name to display?...
-
-
- ΓòÉΓòÉΓòÉ 3.3.5. The WM_CONTROL Message ΓòÉΓòÉΓòÉ
-
- The WM_CONTROL Message
-
- What happens whenever an item in a listbox is selected? Or whenever the text
- in an entryfield changes? Or when a checkbox is clicked on by the user? For
- all of these, and many other events, the owner of the control is sent a
- WM_CONTROL message, meaning that something occurred that could have an effect
- on the behavior of the application.
-
- This is a broad message, which has a specific set of parameters based on two
- criteria:
-
- 1. the class of the control sending the message
- 2. the event that generate the message
-
- Thus, for the first scenario, the usNotify is LN_SELECT, and pvData is the
- handle of the listbox. For the second, usNotify is EN_CHANGE and pvData is the
- handle of the entryfield. And so on...
-
- case WM_CONTROL:
- switch (SHORT1FROMMP(mpParm1)) {
- case DNAME_LB_NAMELIST:
- switch (SHORT2FROMMP(mpParm1)) {
- case LN_SELECT:
- {
- HWND hwndLb;
- SHORT sIndex;
-
- hwndLb=WinWindowFromID(hwndWnd,DNAME_LB_NAMELIST);
-
- sIndex=WinQueryLboxSelectedItem(hwndLb);
- WinQueryLboxItemText(hwndLb,
- sIndex,
- pndiInfo->achName,
- sizeof(pndiInfo->achName));
-
- WinSetDlgItemText(hwndWnd,
- DNAME_EF_NAME,
- pndiInfo->achName);
- }
- break;
- case LN_ENTER:
- WinPostMsg(hwndWnd,WM_COMMAND,MPFROMSHORT(DID_OK),0);
- break;
- default:
- return WinDefDlgProc(hwndWnd,ulMsg,mpParm1,mpParm2);
- } /* endswitch */
- break;
- default:
- return WinDefDlgProc(hwndWnd,ulMsg,mpParm1,mpParm2);
- } /* endswitch */
- break;
-
- You probably don't understand the specific functions, but you can see for
- yourself by running the application that, whenever an item is selected in the
- listbox, the name selected is placed in the entryfield.
-
- .And the Point is...
-
- The point of introducing the WM_COMMAND and WM_CONTROL messages is to
- demonstrate the usefulness of them. As we begin to look at the controls, we
- will examine how they interact with the application through these messages;
- careful exploitation will (eventually) allow you to control the execution of
- your application.
-
-
- ΓòÉΓòÉΓòÉ 3.3.6. New Functions ΓòÉΓòÉΓòÉ
-
- New Functions
-
- In addition to the WinDismissDlg() function, we will look at three additional
- PM APIs.
-
- BOOL WinSetWindowText(HWND hwndWnd,PSZ pszText);
-
- LONG WinQueryWindowText(HWND hwndWnd,LONG lSzBuf,PSZ pszBuffer);
-
- LONG WinQueryWindowTextLength(HWND hwndWnd);
-
- WinSetWindowText sets the text of the specified window to the specified value.
- It returns a success flag.
-
- WinQueryWindowText queries the text of the specified window and copies up to
- either the end of the text or lSzBuf characters into the buffer pointed to by
- pszBuffer. It returns the number of characters copied.
-
- WinQueryWindowTextLength returns the length of the text for the specified
- window.
-
- It is important to note that how the window text is actually used differs from
- control to control. For example, the window text of an entryfield is what is
- displayed in the entryfield itself. This is also true for a titlebar. However,
- a listbox has many text entries, which cannot be described by a single text
- item so it ignores the window text. Some controls use their window text in
- other ways. A frame, for example, notices when its window text changes and
- updates the titlebar's window text, if a titlebar exists.
-
- In other words, your mileage may vary. :)
-
-
- ΓòÉΓòÉΓòÉ 3.3.7. Summary ΓòÉΓòÉΓòÉ
-
- Summary
-
- This month we introduced two very important messages - WM_COMMAND and
- WM_CONTROL - and described their purpose in a window or dialog procedure. We
- also looked at four new PM APIs and looked at window text for the first time
- since they were mentioned in volume 2, issue 1.
-
- Next month, we will continue with HELLO by begining to examine the controls
- within it individually.
-
-
- ΓòÉΓòÉΓòÉ 3.4. Scratch Patch ΓòÉΓòÉΓòÉ
-
- Written by Larry Salomon, Jr.
-
- Welcome to this month's "Scratch Patch"! Each month, I collect various items
- that fit into this column sent to me via email. The ones that I feel contribute
- the most to developers, whether in terms of information or as a nifty trick to
- tuck into your cap, get published in this column.
-
- To submit an item, send it via email to my address - os2man@panix.com - and be
- sure to grant permission to publish it (those that forget will not be
- considered for publication). This month, we have the following:
-
- o Questions and Answers
- o Snippet(s) of the Month
- o Want Ads
-
-
- ΓòÉΓòÉΓòÉ 3.4.1. Questions and Answers ΓòÉΓòÉΓòÉ
-
- Questions and Answers
-
- Ed Blackman (ebb7683@venus.tamu.edu) writes:
-
- Here's the question:
-
- Where does OS/2 store its default icons/bitmaps, and how can I access them in
- my programs? Say, for instance, I wanted to have a container that looks just
- like the default folder. I could just get a copy of the icon of a default
- folder (by invoking the Icon Editor from the General page of the Settings
- notebook), but it seems wasteful to make a copy when the original has to be
- around somewhere.
-
- The answer to this is tricky, since OS/2 stores them in many places. A long
- time ago, it was really easy since PMWIN.DLL was the only PM DLL per se. Now,
- we also have a mess of auxilliary DLLs and also the WPS DLL (PMWP.DLL) to
- consider.
-
- The bottom line, however, is that - unless you can get at the icon or bitmap
- through the PM APIs - you're going to have to copy them into your own resource
- file anyway. The APIs I am alluding to are WinGetSysBitmap and
- WinQuerySysPointer.
-
- ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇ
-
- Semir Patel (spatel@cs.utexas.edu) writes:
-
- Is it possible to change the priorities of processes/threads of processes that
- are not direct descendants of the current process? I haven't found a documented
- API that will do such a thing, but maybe someone knows of some undocumented
- API's that will handle the above. Thanks.
-
- Unfortunately, there is no API that I know of that will do what you are asking.
- The issue here is one of security; an OS designer cannot implement something
- like this and hope to have any semblence of security. For example, you could -
- if such a function existed - bring the system to a crawl by setting the
- priority of the WPS to idle time, -30. That wouldn't be a good thing, I am
- sure. :)
-
-
- ΓòÉΓòÉΓòÉ 3.4.2. Snippet(s) of the Month ΓòÉΓòÉΓòÉ
-
- Snippet(s) of the Month
-
- Yet another month with no submissions from the readers, so I have pulled out
- another (after doing some searching this time...I'm running out of these)
- function that I have found quite useful in the past.
-
- BOOL sizeMajorTabs(HWND hwndNb)
- //-------------------------------------------------------------------------
- // This function sizes the major tabs of a notebook according to the
- // largest text.
- //
- // Input: hwndNb - handle of the notebook
- // Returns: TRUE if successful, FALSE otherwise
- //-------------------------------------------------------------------------
- {
- HPS hpsTemp;
- SIZEL szlMax;
- ULONG ulMajor;
- ULONG ulPage;
- CHAR achText[256];
- BOOKTEXT btText;
- POINTL aptlBox[TXTBOX_COUNT];
- ULONG ulStyle;
-
- hpsTemp=WinGetPS(hwndNb);
-
- szlMax.cx=0;
- szlMax.cy=0;
-
- ulMajor=LONGFROMMR(WinSendMsg(hwndNb,
- BKM_QUERYPAGEID,
- MPFROMLONG(0),
- MPFROM2SHORT(BKA_FIRST,BKA_MAJOR)));
- while (ulMajor!=0) {
- ulPage=ulMajor;
-
- while (ulPage!=0) {
- btText.pString=achText;
- btText.textLen=sizeof(achText);
-
- WinSendMsg(hwndNb,
- BKM_QUERYTABTEXT,
- MPFROMLONG(ulPage),
- MPFROMP(&btText));
-
- GpiQueryTextBox(hpsTemp,
- strlen(btText.pString),
- btText.pString,
- TXTBOX_COUNT,
- aptlBox);
-
- aptlBox[TXTBOX_TOPRIGHT].x-=aptlBox[TXTBOX_BOTTOMLEFT].x;
- aptlBox[TXTBOX_TOPRIGHT].y-=aptlBox[TXTBOX_BOTTOMLEFT].y;
-
- szlMax.cx=max(szlMax.cx,aptlBox[TXTBOX_TOPRIGHT].x);
- szlMax.cy=max(szlMax.cy,aptlBox[TXTBOX_TOPRIGHT].y);
-
- ulPage=LONGFROMMR(WinSendMsg(hwndNb,
- BKM_QUERYPAGEID,
- MPFROMLONG(ulPage),
- MPFROM2SHORT(BKA_NEXT,0)));
- if (ulPage!=0) {
- ulStyle=LONGFROMMR(WinSendMsg(hwndNb,
- BKM_QUERYPAGESTYLE,
- MPFROMLONG(ulPage),
- 0));
- if ((ulStyle & BKA_MAJOR)!=0) {
- ulPage=0;
- } /* endif */
- } /* endif */
- } /* endwhile */
-
- ulMajor=LONGFROMMR(WinSendMsg(hwndNb,
- BKM_QUERYPAGEID,
- MPFROMLONG(ulMajor),
- MPFROM2SHORT(BKA_NEXT,BKA_MAJOR)));
- } /* endwhile */
-
- WinReleasePS(hpsTemp);
-
- WinSendMsg(hwndNb,
- BKM_SETDIMENSIONS,
- MPFROM2SHORT(szlMax.cx*4/3,szlMax.cy*3/2),
- MPFROMSHORT(BKA_MAJORTAB));
-
- return TRUE;
- }
-
-
- ΓòÉΓòÉΓòÉ 3.4.3. Want Ads ΓòÉΓòÉΓòÉ
-
- Want Ads
-
- Below are the hot topics as of this issue's writing. Feel free to write on any
- of these.
-
- Workplace Shell Programming (hot) - lately, I have noticed two things: 1) lots
- of people want to learn how to write new Workplace Shell classes and 2) no one
- who knows anything about it is telling the rest of us how to do it.
-
- Client/Server (hot) - using either named pipes (with or without a network) or
- sockets, client/server programming is all the rage these days. On a related
- note, some people have also expressed an interest in learning about interfacing
- with the various protocol drivers (e.g. NDIS, IPX/SPX, etc.). Any articles in
- this area are most welcome.
-
- Multimedia (warm) - last month we had two articles on this topic. However,
- they both dealt with sound, which we all know is not the only alternative media
- type. Articles on anything else - MIDI, video, etc. - are needed.
-
- Animation (warm) - a few readers expressed an interest in the various animation
- techniques that can be applied to PM applications. The ultimate article, in my
- opinion, would be one that develops a sprite library a la the Commodore 64's
- (and Amiga's?) built-in routines, since this is probably the hardest component
- of any good animation sequence. Call this a "personal request"...
-
-
- ΓòÉΓòÉΓòÉ 4. 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 ftp.cdrom.com in the
- /pub/os2/2_x/program/newsltr directory.
- o The EDM/2 mailing list. Send an empty message to edm2-info@knex.via.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.
-
-
- ΓòÉΓòÉΓòÉ 5. 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).
-
- The following people contributed to this issue in one form or another (in
- alphabetical order):
-
- o Larry Salomon, Jr.
- o Timm Steinbeck
- o Carsten Whimster
- o Gordon Zeglinski
- o Network distributors
-
-
- ΓòÉΓòÉΓòÉ 5.1. Larry Salomon, Jr. ΓòÉΓòÉΓòÉ
-
- Larry Salomon
-
- Larry Salomon 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 International Masters Publishers in Stamford,
- Connecticut and resides in Bellerose, New York with his wife Lisa.
-
- Larry can be reached electronically via the Internet at os2man@panix.com.
-
-
- ΓòÉΓòÉΓòÉ 5.2. Timm Steinbeck ΓòÉΓòÉΓòÉ
-
- Timm Steinbeck can be reached at Timm_Steinbeck@ac3.maus.de.
-
-
- ΓòÉΓòÉΓòÉ 5.3. Carsten Whimster ΓòÉΓòÉΓòÉ
-
- Carsten Whimster
-
- I am an undergraduate computer science student at the University of Waterloo,
- and an OS/2 enthusiast as of OS/2 2.0. I am currently in my third year, taking
- mainly operating system, language, compiler, and graphics courses, as much as
- possible. :)
-
- This summer I will be working at the University as a tutor in CS241, an
- introductory course to compilers.
-
- I am a beginning OS/2 PM programmer with a few projects on the go, and many
- more in my head. I try to buy as many books as I can afford on the subject,
- but if you work for a publisher, I would certainly not turn down any donations,
- and if the books are interesting and development-oriented, I will try to review
- them as time permits.
-
- I am a TEAM-OS/2 member, and stay busy trying to keep up with several OS/2
- groups on the Internet.
-
- I am also an original member of the Kitchener-Waterloo OS/2 Users' Group, and
- have recently volunteered to help out organizing the events.
-
- It's a miracle my girl-friend puts up with my doing all these things :)
-
- You may reach me...
-
- ...via email:
-
- bcrwhims@undergrad.math.uwaterloo.ca - Internet
-
- gopher://descartes.math.uwaterloo.ca:70/h0/mathSOC/.csc/.www/.bcrwhimster/homepage.html
- - Mosaic homepage
-
- ...via snail mail:
-
- Carsten Whimster
- 319 Erb Street West, 3rd floor
- Waterloo, Ontario
- Canada
- N2L 1W4
-
-
- ΓòÉΓòÉΓòÉ 5.4. 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.
-
-
- ΓòÉΓòÉΓòÉ 5.5. 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 Hethman (hethman@cs.utk.edu) - Compuserve
- o Gess Shankar (gess@knex.via.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!