home *** CD-ROM | disk | FTP | other *** search
-
- ΓòÉΓòÉΓòÉ 1. May 1994 Title Page ΓòÉΓòÉΓòÉ
-
- Welcome to EDM/2 - The Electronic OS/2 Developer's Magazine!
- Portions copyright (c) by Larry Salomon Jr.
- Volume 2, issue 5
-
- 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
-
- Ah! I've been running around like a madman the past two weeks. So much has
- happened that needs to be told that I doubt I will remember to tell it all.
- First, the IBM PSP Technical Interchange in San Francisco (yes, I finally
- spelled it correctly) was amazing. I was fortunate enough to meet so many
- people, and many of the people I met told me they knew of, if not read
- themselves, EDM/2. Of the many I met, I have to say that the best meets were
- with Kathleen Panov (just because I coauthored a book with her doesn't mean
- I've met her!), Tim Sipples, and Dave Whittle.
-
- The sessions themselves were chocked full of useful information. Myself, I got
- the most from Sheila Harnett's WPS Programming, and I hope to apply that to my
- current work projects (and eventually write an article for EDM/2). There was a
- Meet the Editors session where the editors of OS/2 Developer, OS/2 Magazine,
- and OS/2 Professional talked a lot and answered questions; of course, yours
- truly jumped in the conversation whenever possible to plug the magazine.
- Throughout the week, I managed to distribute close to 100 flyers to people who
- asked for one about the magazine, so if any of you are out there, welcome
- aboard!
-
- New Conquest Achieved
-
- Also, I had the pleasure of meeting Janet Gobielle who graciously volunteered
- to distribute EDM/2 on FidoNet. Onward to plunder and burn! <grin>
-
- Things Desired
-
- Recently in the comp.os.os2.programmer.misc newsgroup, a few people griped
- about the need for sprite support. So, starting with this issue, there will be
- a multi-part series on a completely modular, multithread-enabled library that
- supports sprite of up to 128x128 pels in size. The library is already written
- and even incorporated into a new version of Common/2 - soon to be released on
- hobbes - so don't worry about this becoming an undoable project. <grin>
-
- Credit Deserved
-
- Since Carsten has been proofing the magazine since volume 2, issue 3 (although
- I lost his changes for the last issue), I've decided it's time to start giving
- him credit for his extra work beyond the call of duty; so, Carsten is now
- officially the/an Associate Editor of the magazine. Congratulations on a job
- well done!
-
- More From the Credit Department
-
- David Charlap, in his endless pursuit to open problem reports against OS/2
- <grin> has notified me that APAR number PJ13781 has been created for the
- problem of the Palette Manager samples (in volume 1, issue 1 of EDM/2) causing
- PM to become unstable. Thanks, David!
-
-
- ΓòÉΓòÉΓòÉ 2. Features for May 1994 ΓòÉΓòÉΓòÉ
-
- The following articles constitute this issue's features:
-
- o Sprites and Animation - Part 1
- o Using SYSLEVEL Files in Your Applications
-
-
- ΓòÉΓòÉΓòÉ 2.1. Sprites and Animation - Part 1 ΓòÉΓòÉΓòÉ
-
-
- ΓòÉΓòÉΓòÉ 2.1.1. Introduction ΓòÉΓòÉΓòÉ
-
- Written by Larry Salomon, Jr.
-
- Introduction
-
- Some time ago, I posted an article to comp.os.os2.programmer.misc describing
- how a friend and I wrote an animated demo application using home-grown sprite
- routines. As I stated then, the routines were very tightly integrated into the
- application; thus, they were not suitable for general availability. I received
- a few requests to "clean them up" and since animation had been in the Want Ads
- for some time, I decided to design and implement a sprite library. The result
- is presented in i495.zip. This is a demonstration program that uses the sprite
- library to simulate the Long Island Expressway on my trip to and from work. :)
-
- This multipart series will go through the design and implementation of the
- sprite library; additionally, its uses for animation will be briefly touched
- upon. The reader is expected to be competent in PM application development as
- well as have at least introductory knowledge to the Gpi subsystem. Any
- background knowledge on animation techniques will be very helpful also.
-
- A caveat: I intentionally left out the source code for the sprite library from
- part 1 so that no one who doesn't already know this stuff will make any
- incorrect assumptions about how the code works; the source will be included in
- later parts of this series. In the meantime, you can enjoy using the SPRITE.H
- and SPRITE.LIB files. :) The library was compiled using IBM C-Set++, so it is
- a 32-bit library. It was not compiled for multithreaded applications, nor was
- z-ordering implemented. By next month, I will have released a new version of
- Common/2 (available at your nearest hobbes shadow) containing the sprite
- subsystem and corresponding programming reference; unlike the remainder of the
- library, however, I will make the source for this component available so do not
- think that the usefulness of the series will be diminished.
-
- Another caveat: the library was developed on my SVGA system at work; when
- showing it to some fellow colleagues at the IBM PSP Technical Interchange on an
- XGA system, the transparancy was - shall we say - overdone. A quick chat with
- Kelvin Lawrence yielded nothing other than the SVGA drivers do not work
- properly all of the time. I guess I broke the library so that it would work on
- my SVGA screen. :)
-
-
- ΓòÉΓòÉΓòÉ 2.1.2. Background ΓòÉΓòÉΓòÉ
-
- Background
-
- What is a sprite? The term dates at least as far back as the VIC-20 and refers
- to a graphical object that is animated in some form or another; for performance
- reasons, these sprites were typically bitmapped graphics. Since animation
- often depicts everyday objects, and these objects have arbitrary (i.e.
- non-rectangular) shapes, bitmaps - in the Gpi sense - cannot be used alone to
- represent a sprite because they overpaint what is underneath. This wouldn't be
- a problem normally except that bitmaps must be rectangular in shape.
-
- Presentation Manager defines a resource called a pointer (for this discussion,
- we will lump icons in this category since the only difference between the two
- is the first two bytes in the file defining the pointer or icon), which has an
- color which is transparent, i.e. the areas painted by this "color" show what
- was underneath instead. Unfortunately for us, the size of the pointer is fixed
- (its size can be determined using the WinQuerySysValue() function), making it
- unsuitable for most animation (assuming we stick to documented functions for
- drawing the pointer). If we were able to create a transparent "color" for our
- bitmaps, we could have irregular shapes surrounded by transparency to make the
- shape "rectangular". This is, then, our immediate goal; there are other
- functions which will also be needed, but without the ability to draw a sprite
- the remainder of the library is rather useless.
-
- Let us begin by looking at the design of the library as well as the decisions
- that were made and how they affect the implementation. My original intent for
- the library was to have four functions:
-
- o Create a sprite from a bitmap
- o Destroy a sprite
- o Draw a sprite
- o Move a sprite
-
- We must first explain the third for - speaking in hindsight - the
- implementation of the drawing will affect the method of creation.
-
-
- ΓòÉΓòÉΓòÉ 2.1.3. Blast From the Past ΓòÉΓòÉΓòÉ
-
- Blast From the Past
-
- I must confess that I learned the technique for drawing a sprite from Charles
- Petzold's article series in the Microsoft Systems Journal where he developed a
- game of checkers for OS/2. The checker pieces are irregular so he described
- how to draw them and keep the underlying image intact where the piece was not
- drawn. How is it done? Well, if you'll think back to the days of boolean
- logic, you'll remember that the AND and OR functions have the following
- properties:
-
- x AND 1 = x
- x OR 0 = x
-
- If we require that all regions in the original bitmap that are to be
- transparent must have the color black, we can use the OR function with the
- target being x to implement the transparent portions. If we only do this,
- however, the non-transparent portions of the bitmap will get OR'd with whatever
- was underneath. Somehow, we need to insure that all portions on the target
- where the original bitmap is not transparent are turned to black, so the OR
- function will not alter the bitmap in any way.
-
- Phantom of the Opera
-
- To accomplish this, we need a second bitmap. Called a mask, it is a monochrome
- bitmap which we combine with the target to change the portions of the target to
- black as stated in the last paragraph. This is accomplished by making the
- portions of the mask corresponding to the transparent areas white, and the
- non-transparent areas black, and then AND'ing this mask with the target.
-
- I realize this is quite confusing, so let's present an example of what is being
- said. To the left is the original bitmap; to the right is the mask. Both are
- surrounded by a light gray rectangle only for illustrative purposes.
-
- We will paint the original bitmap on the following background, using black as
- the transparency color, as described above.
-
- First, we need to mask out the areas of the target where the image will be
- painted. This is done using GpiBitBlt() with the ROP_SRCAND operation, and it
- yields the following:
-
- Finally, we paint the original bitmap on top of this using the ROP_SRCPAINT
- operation (the equivalent of the OR function), yielding the following:
-
-
- ΓòÉΓòÉΓòÉ 2.1.4. The Four Revisited ΓòÉΓòÉΓòÉ
-
- The Four Revisited
-
- To implement the create sprite from bitmap function, we need to also create a
- mask which is associated with the bitmap. The application programmer should
- not have to manage this and insure the proper mask is used with the
- corresponding bitmap, etc., so the sprite data structure should keep track of
- both.
-
- When you look at the code, you'll think that it is rather trivial. However,
- actually developing the code to its present state was a bit of work. Of course,
- we have to have a memory device context and associated presentation space.
- And, since we stated that the mask is a monochrome bitmap, we can call
- GpiQueryBitmapInfoHeader() to get information about the original image, set
- cPlanes and cBitCount to 1 and call GpiCreateBitmap() to create the bitmap.
- This is then set into the presentation space.
-
- Now comes the tricky part. How do you tell the GpiBitBlt() function to make
- all black portions white and all non-black portions black? To quote an
- extremely old piece of IBM documentation, the Programming Guide (page 24-7)
- from the OS/2 1.2 Programmer's Toolkit:
-
- o If you are copying a color bit map to a monochrome bit map or device, those
- pels that have the same color as the current image-background color in the
- source presentation space adopt the image background color of the target
- presentation space. So, for example, if your current image background color
- in the source presentation space is blue, all blue pels in the bit map take
- on the color of the current image background in the target presentation
- space.
-
- All other pels in the color bit map adopt the current image-foreground color
- of the target presentation space.
-
- Unfortunately, I decided to use GpiWCBitBlt() instead of GpiBitBlt() for the
- mask creation. Since there is no source presentation space it is difficult to
- determine what will happen given the above text. I could not determine what
- the rule is for GpiWCBitBlt() (since what I observed makes no sense), so either
- the text is wrong, I am just being stupid, or we are seeing the broken SVGA
- drivers in action. :) By trial-and-error I figured out that, in order to
- create the mask, we call GpiSetColor(CLR_WHITE) and GpiSetBackColor(CLR_BLACK)
- and then call GpiWCBitBlt() to actually initialize the mask bitmap.
-
- ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇ
-
- Sprite destruction should be fairly trivial, and we have already discussed how
- the sprites are drawn, so let's look at how they are moved.
-
- The Quest to Avoid Flicker
-
- When a sprite is moved, there are two scenarios to consider:
-
- 1. The bounding rectangle of the sprite at the old and new positions do not
- overlap
- 2. The bounding rectangle of the sprite at the old and new positions overlap
-
- The first case is trivial to implement - you paint the background over the old
- position, and redraw in the new position. The second case, however, is not so
- simple; if we treated the second case as the first, there is a noticeable
- flicker in the regions that overlap. To avoid this, we need to insure that we
- call GpiBitBlt() only once. This is accomplished using a work-area which is
- another bitmap set in a presentation space associated with a memory device
- context. The strategy is thus:
-
- 1. Determine the rectangle that bounds the bounding rectangles of the sprite
- at the old and new positions.
- 2. Copy the background from the rectangle calculated in step 1 into the work
- area.
- 3. Draw the sprite at the new position, relative to the old position.
- 4. Copy the contents of the work area to the screen presentation space.
-
- Step 4 has the visible effect of both erasing the sprite at the old position
- and redrawing it in the new position. This is a hybrid form of
- double-buffering, which is defined to be the procedure by which the next
- "frame" in a sequence is prepared off-screen while the first screen is being
- displayed. The prepared screen is then displayed while the next frame is
- prepared, and so on. The effect produced is much smoother than if the frames
- were prepared on-screen, as you can imagine.
-
- Note that the algorithm we used is only good when the overlapping is present.
- Attempting to use this when there is no overlap could result is severely
- degraded performance when you consider that the distance between the old and
- new position could be quite a lot, making the area blit'd to the screen quite
- large and CPU intensive in execution.
-
-
- ΓòÉΓòÉΓòÉ 2.1.5. Summary ΓòÉΓòÉΓòÉ
-
- Summary
-
- In the last section, you probably noticed a few loose ends, namely the concept
- of a background and the management of the work area used when moving the sprite
- from one position to another. Next month, we'll tie up these loose ends with
- the introduction of the playground; we will also start to look at the
- implementation of i495.exe followed by the code for the library itself.
-
-
- ΓòÉΓòÉΓòÉ 2.2. Using SYSLEVEL Files in Your Applications ΓòÉΓòÉΓòÉ
-
-
- ΓòÉΓòÉΓòÉ 2.2.1. Introduction ΓòÉΓòÉΓòÉ
-
- Written by Martin Lafaix
-
- Introduction
-
- What's that?
-
- Determining a computer software configuration has always been a tricky process.
- It would be great to have a standard way for registering applications, so that
- we could easily query the system configuration. But wait a minute! OS/2
- provides the SYSLEVEL command, which does just that (it even tells us the
- various component versions)! If only we could use it for our own purposes...
-
- Why?
-
- This registering ability proves its usefulness when writing (relatively) large
- projects or components. For example, if you write a public toolkit or tools
- other programs may use, it would be a good idea to register them. (OS/2 already
- uses it this way: on my home system, the syslevel command tells me that MMPM/2
- and the Developer's toolkit are present - the same thing occurs if you have
- Communication Manager, etc.) When distributing such a tool, tell your users
- your component name and ID; it would then be easy for them to write an
- installation procedure which checks your component presence.
-
- Another interest is that it helps component writers in creating CSD or
- component updates. As each SYSLEVEL file maintains a current CSD level as well
- as a previous CSD level field, it's easy to check what to update, and what to
- leave alone.
-
- It's also useful while maintaining a computer network. It would provide the
- maintainer an up-to-date information database.
-
- Contents
-
- This article contains two parts. The first one describes the SYSLEVEL file
- format. The second part describes the two proposed APIs (one for C, and one
- for Rexx).
-
-
- ΓòÉΓòÉΓòÉ 2.2.2. A Voyage to Syslevel ΓòÉΓòÉΓòÉ
-
- A Voyage to Syslevel
-
- When you start SYSLEVEL.EXE, it scans all your drives for SYSLEVEL files.
- These files are named SYSLEVEL.xxx (where xxx is any three-letters extension),
- and have a specific header. When one such file is found, it is displayed, as
- shown in figure 1. So, to be able to use SYSLEVEL for our own purpose, we'll
- have to decrypt SYSLEVELs' file headers, and find out how (and where) to store
- our own data.
-
- C:\MMOS2\INSTALL\SYSLEVEL.MPM
- Multimedia Presentation Manager 2
- Extensions systКme 1.10 ID de composant 562137400
- Type MMPM\2
- Niveau de modifications en cours : UN00000
- Niveau de modifications antВrieur : UN00000
-
- Figure 1. Syslevel output sample (French version, sorry :-) )
-
- On the File Header
-
- A SYSLEVEL file header looks like the following:
-
- typedef struct _SYSLEVELHEADER {
- unsigned char h_magic[2];
- unsigned char h_name[9];
- unsigned char h_reserved1[4];
- unsigned char h_updated;
- unsigned char h_reserved2[17];
- ULONG h_data;
- } SYSLEVELHEADER;
-
- Figure 2. The SYSLEVELHEADER structure.
-
- h_magic is the magic cookie. Its value is 0xFFFF.
-
- h_name is the string "SYSLEVEL", in uppercase and null-terminated.
-
- h_reserved1 meaning unknown. Set to zero.
-
- h_updated was 1 for OS2, GRE and MPM, and 0 for TLK. My guess: set
- it to zero.
-
- h_reserved2 meaning unknown. Set to zero.
-
- h_data points to the beginning of the file's data structure
- (offset from the beginning of the file), which is described
- below.
-
- While I realize there's still many holes in there, it appears to fulfill our
- needs; namely, we are now able to create files recognized by SYSLEVEL.EXE.
- Isn't that great?
-
- But it's time to learn more...
-
- The SYSLEVEL Data Structure
-
- In the previous section, we have seen that the file's data structure starts at
- offset h_data. This structure (aka. the SYSLEVEL data structure) looks like
- the following:
-
- typedef struct _SYSLEVELDATA {
- unsigned char d_reserved1[2];
- unsigned char d_kind;
- unsigned char d_version[2];
- unsigned char d_reserved2[2];
- unsigned char d_clevel[7];
- unsigned char d_reserved3;
- unsigned char d_plevel[7];
- unsigned char d_reserved4;
- unsigned char d_title[80];
- unsigned char d_cid[9];
- unsigned char d_revision;
- unsigned char d_type[1];
- } SYSLEVELDATA;
-
- Figure 3. The SYSLEVELDATA structure.
-
- d_reserved1 set to zero...
-
- d_kind specifies the component "kind". It can be any of the
- following:
-
- SLK_BASE (0) "Base version"
- SLK_EXTENSION (2) "System extension"
- SLK_STANDARD (15) Neither "Base version" nor "System extension"...
- :-)
-
- Any other value is equivalent to SLK_STANDARD (except 1, which is equivalent
- to SLK_EXTENSION).
-
- d_version specifies the component version. Its format is a bit
- strange: the four high-order bits of d_version[0] contains
- the major version number, the four low-order bits contains
- the first minor version digit, and d_version[1] contains
- the second minor version digit.
-
- For example, if d_version[0] is 0x21 and d_version[1] is
- 0x02, you will get "2.12".
-
- [You can have a revision level, as in "2.12.a". See
- d_revision below.]
-
- d_reserved2 oh no, not again. Set to zero.
-
- d_clevel specifies the current CSD level. It's a seven-byte string,
- usually in the form "AAC####", where AA is a two-byte
- string, C a country-dependent code, and #### a number. For
- example, on my home computer, I get "XRF2010" for the base
- operating system (It's the French version), and "XR02100"
- for the developer's toolkit (US version, this time).
-
- It's just a suggested usage and is not enforced in any way.
- As long as you use seven printable characters, it should
- work.
-
- d_reserved3 guess what? You lose! Set to 0x5F this time.
-
- d_plevel specifies the previous CSD level. If there was no previous
- level; set it equal to the current level, d_clevel.
-
- d_reserved4 is just like d_reserved3; set to 0x5F
-
- d_title specifies the component name. It's a null-terminated
- string.
-
- d_cid specifies the component ID. It's not null-terminated.
-
- d_revision specifies the component revision. It does not appear in
- the version field if sets to zero. If it's not null, it
- will be concatenated with major and minor version number,
- as in "1.2.3" (where 1 is the major version, 2 the minor
- and 3 the revision). If you prefer a letter in place of a
- digit, just increment the revision number by 0x10 for an
- upper-case letter, or by 0x30 for a lower-case. That is,
- if d_revision is 0x11, you will get an "A", and so on.
-
- d_type specifies the component type. It's an optional,
- null-terminated string. This field allows you to store
- additional informations for your component. For example,
- this field is used to differentiate the blue and salmon
- distribution of OS/2 (a type of '0-2' indicates the
- 'salmon' one).
-
- Well, enough said on this exploration. It's time to go back to much safer
- places...
-
-
- ΓòÉΓòÉΓòÉ 2.2.3. Home, Sweet Home ΓòÉΓòÉΓòÉ
-
- Home, Sweet Home
-
- This walk was fun, but all good things must come to an end. So we are back.
- And it's time to write some functions to comfort our precious new knowledge,
- isn't it?
-
- Two APIs are available, a C one and a REXX one.
-
- The SYSLEVEL C API
-
- This section describes the API which provides access to the syslevel files. The
- corresponding code is in CLEVEL.ZIP. It's just an include file, level.h and a
- small C file, level.c which can be included, say, in your favorite library. It
- has been tested with GCC/2, but it should work with any other C compiler...
-
- APIRET LvlOpenLevelFile(PSZ pszName, PHFILE phFile, ULONG ulOpenMode, PSZ
- pszCID)
- APIRET LvlCloseLevelFile(HFILE hFile)
- APIRET LvlQueryLevelFile (PSZ pszName, PSZ pszCID, PVOID pBuffer, ULONG
- ulBufSize)
- APIRET LvlQueryLevelData(HFILE hFile, ULONG ulWhat, PVOID pBuffer, ULONG
- ulBufSize, PULONG pulSize)
- APIRET LvlWriteLevelData(HFILE hFile, ULONG ulWhat, PVOID pBuffer, ULONG
- ulBufSize, PULONG pulSize)
-
- Design considerations
-
- This API has been modeled upon the profile (Prf) functions.
-
- Examples
-
- The following two figures show how to check for the existence of a component,
- and if a component needs updating, respectively.
-
- :
- #include <level.h>
- :
- int main()
- {
- HFILE hFile;
- :
- if(hFile = LvlOpenLevelFile("DBM",
- OLF_SCANDISKS | OLF_CHECKID,
- "123456789"))
- /* present */
- :
- else
- /* not present */
- :
- :
- LvlCloseLevelFile(hFile);
- :
- }
-
- Figure 4. Syslevel API usage sample - Checking for the existence of a
- component
-
- :
- #include <level.h>
- :
- BOOL _needUpdate(HFILE hFile)
- {
- CHAR achCSD[7];
- ULONG ulCount;
-
- if(LvlQueryLevelData(hFile, QLD_CURRENTCSD, achCSD, 7, &ulCount))
- /* shall we update it? */
- return strncmp(achCSD, "DBF0099",7) <= 0; /* for example */
- else
- /* an error occurred */
- :
- }
- :
-
- Figure 5. Syslevel API usage sample - Shall we update component?
-
- The SYSLEVEL REXX API
-
- Well, it's not really an API, it's in fact a single function. The
- corresponding code is in RLEVEL.ZIP. It's just a REXX file, named REXXLVL.CMD.
- Put it somewhere along your PATH. The zip file also contains MAKESYSL.CMD,
- which can be used to create SYSLEVEL files.
-
- This function has been modeled upon the STREAM function.
-
- RexxLvl()
-
- Example
-
- The following example is a REXX script. It allows you to easily create
- syslevel files.
-
- /* makesysl.cmd 940327 */
-
- say 'Component name:'; parse pull name
- say 'Component ID:'; parse pull ID
- say 'Component type (optional):'; parse pull type
- say 'Component version (as x.y[.z]):'; parse pull version
- say 'Current CSD Level:'; parse pull CSD
- say 'Component extension:'; parse pull ext
-
- file = RexxLvl("n", ext, ID)
- call RexxLvl "s", file, "n", name
- call RexxLvl "s", file, "c", csd
- call RexxLvl "s", file, "v", version
- call RexxLvl "s", file, "t", type
- rc = RexxLvl("c", file)
-
- if rc = 0 then say 'SYSLEVEL.'ext' created.'
-
- Figure 6. Creating a syslevel file in REXX.
-
-
- ΓòÉΓòÉΓòÉ 2.2.4. Summary ΓòÉΓòÉΓòÉ
-
- Summary
-
- Now you have enough information to use the SYSLEVEL files well. However, the
- advertised advantages would become a reality only if we use SYSLEVEL files
- extensively. So, if you like these perspectives, use them, ask them, require
- them, again and again, until you get satisfaction. :-)
-
- As a sidenote, the information exposed in the first part of this article is the
- result of my own exploration. If you find any inaccuracy or if you have more
- information, please, let me know.
-
-
- ΓòÉΓòÉΓòÉ <hidden> kind ΓòÉΓòÉΓòÉ
-
- SLK_BASE denotes a "base" component.
- SLK_EXTENSION denotes a system extension.
- SLK_STANDARD denotes a "standard" component. It's the suggested
- component kind value.
-
-
- ΓòÉΓòÉΓòÉ <hidden> ulOpenMode - input ΓòÉΓòÉΓòÉ
-
- ULONG field that describes the mode of the open function.
-
- OLF_OPEN open the specified file. The default behavior is to
- scan the current disk, starting from the current
- directory. It returns the first SYSLEVEL file whose
- extension matches pszName You can override this by
- combining OLF_OPEN with OLF_SCANDISK or OLF_CHECKID.
- OLF_SCANDISKS scans all disks (starting from C:). Use this flag to
- modify the default OLF_OPEN behavior.
- OLF_CHECKID finds file(s) whose ID matches the specified one. Use
- this flag to override the default OLF_OPEN behavior.
- OLF_CREATE creates the specified file in the current directory.
- A valid pszName and ID should be provided.
-
-
- ΓòÉΓòÉΓòÉ <hidden> ulWhat - input ΓòÉΓòÉΓòÉ
-
- The following flags can be used when querying (or writing) a SYSLEVEL file.
-
- QLD_MAJORVERSION Query (or update) the major version field. It's a
- one-character field. It should be in the range
- '0'-'9'. The value is placed in (or taken from) the
- first character of pBuffer. (Buffer size should be at
- least 1.)
-
- QLD_MINORVERSION Query (or update) the minor version field. It's a
- two-character field. It should be in range '00'-'99'.
- The value is placed in (or taken from) the first two
- chars of pBuffer. (Buffer size should be at least 2.)
-
- QLD_REVISION Query (or update) the revision field. It's should fit
- in a character. If it's '0', there's no revision
- available. It can be a letter as well as a digit.
- The value is placed in (or taken from) the first
- character of pBuffer. (Buffer size should be at least
- 1.)
-
- QLD_KIND Query (or update) the kind field. The value is placed
- in (or taken from) the first character of *pBuffer.
- (Buffer size should be at least 1.)
-
- QLD_CURRENTCSD Query (or update) the current CSD level (when you
- update this field, its old value is copied to the old
- CSD level field). It's a seven-character field, and
- it does not have to be null-terminated. The value is
- placed in (or taken from) the first seven characters
- of pBuffer. (Buffer size should be at least 7.)
-
- QLD_PREVIOUSCSD Query the previous CSD level. You can't update this
- field. The value is placed in the first seven chars
- of pBuffer. (Buffer size should be at least 7.)
-
- Note: CSD levels are not null-terminated. Be careful
- when using such a returned value.
-
- QLD_TITLE Query (or update) the component title field. It's an
- eighty-character string (required ending null
- included). The value is placed in (or taken from) the
- first eighty characters of pBuffer. On input, the
- buffer size should be at least 80. On output, the
- buffer size can exceed 80, but the written string is
- truncated (and null-terminated) to eighty characters.
-
- QLD_ID Query (or update) the component ID field. It's a
- nine-character field. It does not have to be
- null-terminated. The value is placed in (or taken
- from) the first nine characters of pBuffer. (Buffer
- size should be at least 9.)
-
- Note: IDs are not null-terminated. Be careful when
- using such a returned value.
-
- QLD_TYPE Query (or update) the component type field.
-
-
- ΓòÉΓòÉΓòÉ <hidden> LvlOpenLevelFile ΓòÉΓòÉΓòÉ
-
- APIRET LvlOpenLevelFile(PSZ pszName, PHFILE phFile, ULONG ulOpenMode, PSZ
- pszCID)
-
- Use this to find, open or create a SYSLEVEL file.
-
- It returns the following values:
-
- 0 NO_ERROR
- 2 ERROR_FILE_NOT_FOUND
- 3 ERROR_PATH_NOT_FOUND
- 4 ERROR_TOO_MANY_OPEN_FILES
- 5 ERROR_ACCESS_DENIED
- 12 ERROR_INVALID_ACCESS
- 26 ERROR_NOT_DOS_DISK
- 32 ERROR_SHARING_VIOLATION
- 36 ERROR_SHARING_BUFFER_EXCEEDED
- 82 ERROR_CANNOT_MAKE
- 87 ERROR_INVALID_PARAMETER
- 99 ERROR_DEVICE_IN_USE
- 108 ERROR_DRIVE_LOCKED
- 110 ERROR_OPEN_FAILED
- 112 ERROR_DISK_FULL
- 206 ERROR_FILENAME_EXCEED_RANGE
- 231 ERROR_PIPE_BUSY
-
-
- ΓòÉΓòÉΓòÉ <hidden> pszName - input ΓòÉΓòÉΓòÉ
-
- The syslevel file extension. It's a three-letter, null-terminated string. That
- is, LvlOpenLevelFile deals with syslevel files named syslevel.xxx, where xxx
- is pszName's value.
-
-
- ΓòÉΓòÉΓòÉ <hidden> LvlCloseLevelFile ΓòÉΓòÉΓòÉ
-
- APIRET LvlCloseLevelFile(HFILE hFile)
-
- Use this to close a SYSLEVEL file. It's just a DosClose alias, for API
- consistence.
-
- It returns the following values:
-
- 0 NO_ERROR
- 2 ERROR_FILE_NOT_FOUND
- 5 ERROR_ACCESS_DENIED
- 6 ERROR_INVALID_HANDLE
-
-
- ΓòÉΓòÉΓòÉ <hidden> LvlQueryLevelData ΓòÉΓòÉΓòÉ
-
- APIRET LvlQueryLevelData(HFILE hFile, ULONG ulWhat, PVOID pBuffer, ULONG
- ulBufSize, PULONG pulSize)
-
- Use this to query an already opened SYSLEVEL file.
-
- It returns the following values:
-
- 0 NO_ERROR
- 6 ERROR_INVALID_HANDLE
- 87 ERROR_INVALID_PARAMETER
- 122 ERROR_INSUFFICIENT_BUFFER
-
- When it returns ERROR_INSUFFICIENT_BUFFER, *pulSize contains the minimum
- requested size.
-
-
- ΓòÉΓòÉΓòÉ <hidden> pBuffer - input/output ΓòÉΓòÉΓòÉ
-
- Address of the buffer that contains the data to write/read.
-
-
- ΓòÉΓòÉΓòÉ <hidden> pulSize - output ΓòÉΓòÉΓòÉ
-
- Address of the variable to receive the number of bytes actually read or
- written.
-
-
- ΓòÉΓòÉΓòÉ <hidden> LvlWriteLevelData ΓòÉΓòÉΓòÉ
-
- APIRET LvlWriteLevelData(HFILE hFile, ULONG ulWhat, PVOID pBuffer, ULONG
- ulBufSize, PULONG pulSize)
-
- Use this to update an already opened SYSLEVEL file.
-
- It returns the following values:
-
- 0 NO_ERROR
- 6 ERROR_INVALID_HANDLE
- 19 ERROR_WRITE_PROTECT
- 29 ERROR_WRITE_FAULT
- 87 ERROR_INVALID_PARAMETER
- 122 ERROR_INSUFFICIENT_BUFFER
-
- When it returns ERROR_INSUFFICIENT_BUFFER, *pulSize contains the minimum
- requested size.
-
-
- ΓòÉΓòÉΓòÉ <hidden> ulBufSize - input ΓòÉΓòÉΓòÉ
-
- The length, in bytes, of pBuffer. This is the number of bytes to be read or
- write.
-
-
- ΓòÉΓòÉΓòÉ <hidden> phFile - output ΓòÉΓòÉΓòÉ
-
- Address of the handle for the file.
-
-
- ΓòÉΓòÉΓòÉ <hidden> pszCID - input ΓòÉΓòÉΓòÉ
-
- It's the component ID string. It's required when you specify the OLF_CHECKID
- flag when opening a syslevel flag. It's a nine-digit string, not
- null-terminated, which uniquely identifies the component in conjunction with
- pszName. That is, you can have multiple SYSLEVEL files with the same name, but
- you can't have multiple syslevel files with the same name and ID.
-
- If you are not using the OLF_CHECKID flag, set pszCID to NULL.
-
-
- ΓòÉΓòÉΓòÉ <hidden> RexxLvl() ΓòÉΓòÉΓòÉ
-
- ΓöÇΓöÇΓöÇRexxLvl(ΓöÇΓö¼ΓöÇC,ΓöÇΓöÇfileΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇ)ΓöÇΓöÇΓöÇ
- Γö£ΓöÇEΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé Γö£ΓöÇ,ΓöÇΓöÇextensionΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé Γöé ΓööΓöÇ,ΓöÇidΓöÇΓöñ
- Γöé ΓööΓöÇ,,ΓöÇΓöÇidΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γö£ΓöÇN,ΓöÇΓöÇextension,ΓöÇΓöÇidΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γö£ΓöÇO,ΓöÇΓöÇextension,ΓöÇΓöÇidΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γö£ΓöÇQ,ΓöÇΓöÇfile,ΓöÇΓöÇfieldΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- ΓööΓöÇS,ΓöÇΓöÇfile,ΓöÇΓöÇfield,ΓöÇΓöÇvalueΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
- RexxLvl returns a string describing the state of, or the result of an operation
- upon, a SYSLEVEL file. This function is used to request information on the
- state of a SYSLEVEL file, or to carry out some specific operation on the
- SYSLEVEL file.
-
- The first argument can be one of the following strings (of which only the first
- letter is needed) which describes the action to be carried out:
-
- "c[lose]" closes the specified syslevel file. File is a filename returned
- by a previous RexxLvl OPEN or NEW call.
-
- "e[num]" enumerates the matching SYSLEVEL files. Extension is (an
- optional) SYSLEVEL file extension. Id is (an optional)
- component ID. It returns the number of matching files, or
- 'ERROR'. The corresponding filenames are pushed on the current
- queue. Use PULL or PARSE PULL to get them back.
-
- "n[ew]" creates a new SYSLEVEL file, in the current directory. Extension
- is the SYSLEVEL file extension, and id is the component ID. It
- returns a file name to be used by subsequent RexxLvl calls.
-
- "o[pen]" opens the specified SYSLEVEL file. Extension is the SYSLEVEL
- file extension, and id is the component ID. It returns a file
- name to be used by subsequent RexxLvl calls, 'NOTFOUND' if the
- required file was not found or 'ERROR' if an error occurred
- while searching.
-
- Note: It returns the first matching SYSLEVEL file.
-
- "q[uery]" queries a SYSLEVEL file field. File is a filename returned by a
- previous RexxLvl OPEN or NEW call. Field is the field to be
- queried. It can be any of the following (of which only the
- first letter is needed):
-
- "n[ame]" component name. Its length cannot exceed 79 characters.
- "i[d]" component ID. It's a nine-digit string.
- "k[ind]" component kind. It can be 0 (if the component is a base
- one), 1 or 2 (if the component is a system extension) or 15
- otherwise.
- "v[ersion]" component version. It should follows the 'x.yy[.z]' format.
- "t[ype]" component type. It's a string.
- "c[csd]" current CSD level. It's a seven-byte string.
- "p[csd]" previous CSD level. It's a seven-byte string.
-
- It returns the field value or 'ERROR'.
-
- "s[et]" sets the specified SYSLEVEL file field. File is a filename
- returned by a previous RexxLvl OPEN or NEW call. Field is the
- field to be set. It can be any of the values taken by the field
- parameter of the RexxLvl "query" call, except "p[csd]" (you
- can't set the "p[csd]" field's value -- it is automatically sets
- when you update the c[csd] field). Value is the field's new
- value. It returns an empty string, or 'ERROR'.
-
-
- ΓòÉΓòÉΓòÉ <hidden> LvlQueryLevelFile ΓòÉΓòÉΓòÉ
-
- APIRET LvlQueryLevelFile(PSZ pszName, PSZ pszCID, PVOID pBuffer, ULONG
- ulBufSize)
-
- Use this to query/find existing SYSLEVEL files. This function enumerates all
- the SYSLEVEL files present in the system and returns the names as a list in the
- pBuffer parameter. Each SYSLEVEL file name is terminated with a NULL character
- and the last name is terminated with two successive NULL characters.
- Specifying pszName or pszCID (or both) restricts the enumeration to the
- corresponding SYSLEVEL files.
-
- It returns the following values:
-
- 0 NO_ERROR
- 87 ERROR_INVALID_PARAMETER
- 122 ERROR_INSUFFICIENT_BUFFER
-
- When it returns ERROR_INSUFFICIENT_BUFFER, the first ulBufSize bytes of pBuffer
- are correctly filled.
-
-
- ΓòÉΓòÉΓòÉ 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
-
- /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 Writing OS/2 2.1 Device Drivers in C, but could also be 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. (no-one has sent me
- any requests yet, and my personal library is nearly covered! If no-one writes,
- I will choose some myself). 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.
-
- I decided to review this book for two reasons. First of all, OS/2 needs more
- device drivers, as we all know, and I figured that reviewing this might prompt
- some would-be device-driver writers to buy it and get going. Secondly, I have
- heard many good things about this book, and so was naturally curious about it.
-
-
- ΓòÉΓòÉΓòÉ 3.1.2. Errata ΓòÉΓòÉΓòÉ
-
- Errata
-
- I have just picked up Watcom C/C++ 9.5, so things have changed a bit since last
- month. The makefile that comes with Real World Programming for OS/2 2.1 works
- fine, with a couple of modifications:
-
- 1. Add a section for C++, if you plan on using the makefile for C++
- programming. You can just copy the C section, and modify it as follows:
-
- .cpp.obj:
- @echo ╨╛╨╛╨╛ Compiling $*.cpp using WATCOM C/C++ options ╨┐╨┐╨┐
- wpp386 -d1 -zq -W2 -D__WATCOM__ $(WCL386OPTS) $*.cpp
-
- and add .cpp to the .EXTENSIONS directive after .c.
- 2. In each .DEP file, add .SYMBOLIC to the end of the ALL: line. This
- eliminates some error messages that otherwise occur.
-
-
- ΓòÉΓòÉΓòÉ 3.1.3. Writing OS/2 2.1 Device Drivers in C, 2nd Edition ΓòÉΓòÉΓòÉ
-
- Writing OS/2 2.1 Device Drivers in C, 2nd Edition
-
- This book is a must for device driver programmers! It has extensive reference
- material all the way through, and brief examples of how to use many of the
- functions. Skeleton code is presented throughout, to guide the novice and
- intermediate OS/2 device driver programmer. Strategies are explained and much
- of the inside workings of OS/2 and hardware are explained.
-
- Here are the chapter headings:
-
- 1. The Evolution of PC Device Drivers
- 2. Understanding Device Drivers
- 3. The PC Hardware Architecture
- 4. An Overview of the OS/2 Operating System
- 5. The Anatomy of an OS/2 Device Driver
- 6. Device Driver Strategy Commands
- 7. A Simple OS/2 Physical Device Driver
- 8. The Micro Channel Bus
- 9. OS/2 2.1 Virtual Device Drivers
- 10. Memory Mapped Adapters and IOPL
- 11. Direct Memory Access (DMA)
- 12. Extended Device Driver Interface
- 13. Debugging OS/2 2.1 Device Drivers
- 14. An Introduction to Presentation Drivers
- 15. Working with Pointers
- 16. PCMCIA Device Drivers
- 17. Tips and Techniques
- 18. Device Helper Reference
- 19. Reference Publications
- 20. Listings
- 21. OEMHLP and TESTCFG
-
- The first four chapters serve to introduce the area of device driver
- programming by way of explaining where we came from, and where OS/2 is headed.
- First, we are treated to a brief history of the micro-computer, starting with
- the Altair 8800, and covering the very early ways of programming directly for
- the hardware. This stuff is even worse than DOS, believe it or not. The very
- early programs each had their own built-in operating system!! The origins of
- micro-computer operating systems are outlined along with explanations of BIOS
- and some architecture basics, like the bus.
-
- In chapter three, the PC hardware architecture is explained, starting with the
- 8088, and going through the 80286, the AT bus, the PS/2, the Micro Channel bus,
- EISA, real mode, protect mode, addressing and the ring architecture of the
- 80386 and 80486. In chapter four we are then walked through the early versions
- of OS/2, disadvantages and all, to the OS we all know and love, OS/2 2.x.
-
- The book really starts in chapter five. The early chapters were very brief,
- and could be read comfortably in one sitting. This chapter gets more
- complicated, and has some spine chilling warnings like "It may be difficult or
- impossible to find a device driver problem using normal debugging techniques."
- Luckily, we have the OS/2 kernel debugger, KDB. Installation of the kernel
- debugger is explained, and then the basic OS/2 device driver design is
- explained step by step. The various components of the device driver are
- outlined, and code for a start-up routine given. Unfortunately, the start-up
- routine is in assembly code, and Watcom C/C++, my compiler, does not come with
- an assembler, so I could not follow this on my computer.
-
- Device drivers have a strategy section, which is basically a switch for the
- message type the OS calls the driver with. Depending on what the OS needs, a
- separate section of the device driver is entered, and the need fulfilled.
- Device drivers can either fulfil the request immediately, or it can acknowledge
- the receipt of the request, and fulfil it as time permits. There are quite a
- few different strategy commands that the OS can use, depending on what type of
- driver you are writing.
-
- Chapter seven explains a sample device driver for an 8-bit parallel port. You
- can enhance this code to suit your needs, if you have to program such a port.
- This is the only fairly complete device driver code that the book contains, but
- of course most people attempting to program a device driver have the
- specifications for the particular device they are interested in, and so the
- skeleton code suffices.
-
- The remainder of the chapters discuss various other types of device drivers,
- such as memory mapped drivers, presentation device drivers, and so on. These
- chapters are fairly introductory in nature, and no-one is going to get a free
- ride here. This book has to be supplemented with device specific reference
- material! On the other hand, I shudder to think how anyone would program a
- device driver for OS/2 without this book, or something similar. There are many
- efficiency considerations to take into account, and trying to program for OS/2
- with only DOS device driver knowledge would be like trying to climb Mont Blanc
- after walking up the local Devil's Hill. You are bound to do things wrong
- without some guidelines.
-
- Programming device drivers for OS/2 is not for the faint of heart, but neither
- is it impossible. It requires the right tools, the right attitude, the right
- information, the patience, and this book (or another similar book, but I have
- never heard of any other book like this). Like any difficult programming
- problem, successfully writing a device driver for OS/2 is tricky, but
- potentially very rewarding. Just take a look at the popularity of the SIO
- drivers, which are considered to be better than OS/2's own by most people. Good
- luck!
-
-
- ΓòÉΓòÉΓòÉ 3.1.4. Summary and Ratings ΓòÉΓòÉΓòÉ
-
- Summary and Ratings
-
- This is a very authoritative book, almost more of a reference book than a
- tutorial. It has a lot of tables of flag bits, device helper functions, PCMCIA
- card services, KDB keywords, ad infinitum. Although it is a large book (at 547
- pages), it still has a very terse feel to it, and is definitely aimed at
- advanced programmers. Anyone considering writing device drivers should
- definitely be comfortable with C, and familiar with computer architecture and
- the specific hardware they want to program for. This is a "bible" type of
- book, and as such is probably required reading for OS/2 device driver
- programmers in much the same way that the ARM is required for C++ programmers.
- The only downside is what is not there. IFS drivers are not covered, and
- neither are SCSI or ADD drivers. This is mentioned in the introduction,
- however, and is promised for the next printing. I did feel a little surprised
- by the fact that the DevHlp library used in the book has to be purchased
- separately, but I suppose it would be a little much to ask for it to be
- included with such a reasonably priced book.
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé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. Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- ΓöéWriting OS/2 2.1 Device Drivers in ΓöéAdvanced C ΓöéA- ΓöéThe only thing a device driver programmer would Γöé
- ΓöéC, 2nd Edition, Mastrianni, Van ΓöéProgrammers,Γöé Γöénot find in here is how to write SCSI, ADD, and Γöé
- ΓöéNostrand Reinhold. ISBN Γöéfamiliar Γöé ΓöéIFS drivers. Most everything else is in here, Γöé
- Γöé0-442-01729-4. US$35, CAN$45. Γöéwith Γöé Γöéalong with skeleton examples. An optional DevHlp Γöé
- Γöé Γöéhardware Γöé Γöélibrary of C-callable functions can be purchased Γöé
- Γöé Γöéprogramming Γöé Γöéby those who don't have time to write their own. Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
- 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. 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. Read the reviews carefully for what you are looking for.
-
- 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. 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 (sounds familiar :). Otherwise I will review
- OS/2 Presentation Manager GPI, Winn, or a REXX book. The books I intend to
- review are (not necessarily in this order):
-
- o The Art of OS/2 C Programming, Panov, Salomon and Panov
- o OS/2 Presentation Manager GPI, Winn
- o OS/2 Presentation Manager Programming, Petzold - 1994 - not yet published :(
- o The Design of OS/2, 2nd Edititon, Kogan and Deitel - 1994 - 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 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. Finally, 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. Introduction ΓòÉΓòÉΓòÉ
-
- Written by Gordon Zeglinski
-
- Introduction
-
- As my project enters its final stages, the work load associated with it has
- gone through the roof. Therefore, the column will be a tad shorter than usual.
-
- Drag and drop is one of OS/2's nicest features, but probably one of the most
- feared by new programmers. It's particularly painful, because you can't set
- breakpoints inside the processing of the DM_DRAG, DM_DRAGOVER, etc. messages.
- But since this is a C++ column, and drag and drop is a bit complex for a single
- "tad smaller than usual" article, we'll look at the drop half of drag and drop
- using the IBM PM class libraries. These class libraries do a lot more than just
- encapsulate the PM infrastructure; they abstract PM to such an extent, that
- they could be developed into a cross platform toolkit.
-
-
- ΓòÉΓòÉΓòÉ 3.2.2. Processing Drop ΓòÉΓòÉΓòÉ
-
- Processing Drop
-
- Drop Basics
-
- Before moving on to looking at the code which processes the drop actions, we
- will briefly look at the stages involved in processing a drop:
-
- 1. The application is notified of a drag occurring. The application checks
- what is being dragged over it. It then sets the return value to indicate
- to the OS, whether the dragged object(s) can be dropped.
-
- 2. When the user drops the dragged objects, the application is notified of the
- drop. It then performs the actions associated with the drag.
-
- Both the initiator and recipient of the drag and drop operation must agree upon
- the information being exchanged; this is done by using a rendering mechanism
- and format specifier, both of which are text strings. The OS/2 PM programming
- reference defines a set of standard rendering and format strings. In addition
- to these, the programmer can define application-specific rendering and format
- strings.
-
- Drop in the ICLUI
-
- The ICLUI uses several objects to encapsulate drag and drop. We will look at
- those classes which we will use in the sample program.
-
- Instances of the IDMItem or it's ancestors represent the objects being dragged.
- By subclassing IDMItem, we can create specialized drag items if we choose to
- implement our own rendering mechanisms. For this example, we create a new class
- called AFileItem but give it no "special" properties.
-
- class AFileItem : public IDMItem {
- public:
- AFileItem ( const IDMItem::Handle &item );
-
- virtual Boolean
- targetDrop ( IDMTargetDropEvent & );
- };
-
- The method targetDrop is called when the dragged objects are dropped. We
- override this function to handle our application specific processing of the
- drop event.
-
- The template class IDMItemProviderFor is derived from the class
- IDMItemProvider. We subclass IDMItemProviderFor to control various aspects of
- the drag and drop process. IDMItemProvider implies that this object creates
- IDMItem objects. However, it can do a lot more than just that. Below, we
- subclass the template class IDMItemProviderFor to provide support for drag over
- type events.
-
- class AFileProvider : public IDMItemProviderFor< AFileItem > {
-
- public:
- virtual Boolean
- provideEnterSupport ( IDMTargetEnterEvent &event );
- };
-
- We override the method provideEnterSupport so that when objects are dragged
- over our main window, we can test them to see if they can be dropped. Both the
- ICLUI classes we have looked at provide many more member functions that we can
- override to provide other drag and drop features, but we will not look at these
- here.
-
-
- ΓòÉΓòÉΓòÉ 3.2.3. Building a Simple Test Application ΓòÉΓòÉΓòÉ
-
- Building a Simple Test Application
-
- Our simple test application will consist of a frame window and a multi-line
- edit control. The frame window class will be subclassed by MyFrame. The MLE
- control will be a member of MyFrame. When a file is dropped on the MLE, the
- contents of the MLE are discarded and the file is loaded into the control. The
- following section of code checks the objects being dragged over the MLE.
-
- Boolean AFileProvider::provideEnterSupport( IDMTargetEnterEvent &event ){
-
- // Get handle to the drag target operation
- IDMTargetOperation::Handle targetOp = IDMTargetOperation::targetOperation();
-
-
- // only want to accept 1 file
- if(targetOp->numberOfItems()!=1){
- event.setDropIndicator(IDM::neverOk);
- return(true);
- }
-
- // Get the types for the drag item.
- IString strTypes = targetOp->item(1)->types();
-
- // See if it's marked as a "plain text" file
- if ((strTypes.indexOf(IDM::plainText))){
- event.setDropIndicator(IDM::ok);
- return(true);
- }
-
- // Type is not recognized - set the drop indicator to prevent a drop!
- event.setDropIndicator(IDM::neverOk);
- return(true);
- }
-
- If there is more than one object being dropped over, or the object isn't
- identified as "plain text", the application sets the drop indicator to neverOk.
- This will then prevent the drop from occurring, and change the pointer to
- indicate that a drop is not permitted. The following code snippet, loads the
- MLE with the dropped file.
-
- Boolean AFileItem::targetDrop( IDMTargetDropEvent & Event){
- IMultiLineEdit *DropWin=(IMultiLineEdit *)this->targetOperation()->targetWindow();
-
-
- IString
- fname = this->containerName() + this->sourceName();
-
- //erase the edit window
- DropWin->removeAll();
-
- //load the file into the edit window
- DropWin->importFromFile(fname);
-
-
- return true;
- }
-
- The constructor for the class MyFrame follows. The constructor enables drag
- and drop for the MLE and attaches an instance of our FileProvider to the MLE.
-
- MyFrame::MyFrame(const char *Title):
- IFrameWindow(Title,IResourceId(1), //-------------------
- IFrameWindow::titleBar| //
- IFrameWindow::sizingBorder| //
- IFrameWindow::minimizeButton| // Create the Frame
- IFrameWindow::systemMenu| // Window
- IFrameWindow::shellPosition| //
- IFrameWindow::minimizeButton| //
- IFrameWindow::windowList| //
- IFrameWindow::maximizeButton), //--------------------
- EditWin(10,this,this){ // Create the Edit Window
- // ID=10, use this frame
- // window as the parent and
- //owner
- //---------------------
-
- setIcon(IResourceId(1));
- setClient(&EditWin);
-
- //enable default drag and drop handler
- IDMHandler::enableDragDropFor(&EditWin);
- //attach the provider
- EditWin.setItemProvider(&FileProvider);
-
- show();
- }
-
- The file CPPDD.CPP contains the complete source code for the simple app. To
- compile the code simply execute the Rexx program GO.CMD.
-
-
- ΓòÉΓòÉΓòÉ 3.2.4. Summary ΓòÉΓòÉΓòÉ
-
- Summary
-
- Drag and drop is one of OS/2's most intuitive user interface features and the
- ICLUI completely encapsulates the direct manipulation API. However, as with
- other parts of the ICLUI its encapsulation strategy is not clearly documented.
- In this article, we have explored how to enable our ICLUI applications to
- accept dropped files.
-
- Yet, we still have only barely touched this topic's surface.
-
-
- ΓòÉΓòÉΓòÉ 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 introduced the WM_COMMAND and WM_CONTROL messages, which are -
- as you will see - very important in the development of many PM applications.
- We also looked at the HELLO dialog procedure in a little detail, and were
- introduced to three new APIs.
-
- This month, we will introduce some more APIs, will continue dissecting the
- dialog procedure, and will begin looking at our first window class in detail.
-
-
- ΓòÉΓòÉΓòÉ 3.3.3. New APIs ΓòÉΓòÉΓòÉ
-
- New APIs
-
- PM has a few specific APIs which are more "helper APIs" than anything else,
- because they replace two APIs, the first of which is always WinWindowFromID().
-
- HWND WinWindowFromID(HWND hwndParent,ULONG ulId);
-
- WinWindowFromID searches the children of hwndParent to find a window whose
- identifier (remember these from the first column in this series?) matches ulId.
- It returns the window handle if found, or NULLHANDLE otherwise.
-
- These new functions are listed below:
-
- BOOL WinSetDlgItemText(HWND hwndDlg,ULONG ulId,PSZ pszText);
-
- ULONG WinQueryDlgItemText(HWND hwndDlg,
- ULONG ulId,
- LONG ulSzBuffer,
- PCHAR pchBuffer);
-
- LONG WinQueryDlgItemTextLength(HWND hwndDlg,ULONG ulId);
-
- These three functions provide the equivalent of the WinSetWindowText(),
- WinQueryWindowText(), and WinQueryWindowTextLength() functions that we looked
- at last month. The only difference is that the above three functions call
- WinWindowFromID() first to determine the handle of the window you are
- interested in.
-
- Letter carriers and Bulletin Boards
-
- While thinking about the topics that I should cover this month, I realized
- that, although the terms sending and posting messages have been used liberally
- over the lifespan of this column, the functions to perform these two actions
- have never been discussed, nor has the difference between the two been
- discussed.
-
- MRESULT WinPostMsg(HWND hwndWnd,
- ULONG ulMsg,
- MPARAM mpParm1,
- MPARAM mpParm2);
-
- MRESULT WinSendMsg(HWND hwndWnd,
- ULONG ulMsg,
- MPARAM mpParm1,
- MPARAM mpParm2);
-
- Both WinSendMsg and WinPostMsg take the same parameter set:
-
- hwndWnd the window to receive the message to be posted or sent
- ulMsg the message identifier
- mpParm1, mpParm2 message-specific parameters. See the Programming Reference
- for detailed information about the parameters required for
- each message.
-
- The difference between posting and sending is that the former simply puts the
- message in the message queue of the recipient, while the latter is (logically
- speaking) a direct call to the window procedure of the recipient's window
- procedure. The significance of the last statement is that your window
- procedure will be blocked until the WinSendMsg() call returns, and that will
- not happen until the recipient finishes processing the message.
-
- Why is one used over the other? For one thing, since WinSendMsg() is a
- synchronous call, pointers that are specified are guaranteed to point to valid
- areas of memory (this is important if they point to local variables on the
- stack). Note the word valid instead of accessible; if you send a message to
- another process with a pointer, accessability to the pointer must be
- established either via shared memory or giveable/gettable memory. WinSendMsg()
- does have one disadvantage, however; it requires that the sender have a message
- queue. WinPostMsg(), on the other hand, can be sent from anywhere, regardless
- of whether or not WinCreateMsgQueue() was called previously (this is handy for
- secondary threads).
-
- Given this information, let us look at one more "dialogish" API -
- WinSendDlgItemMsg().
-
- MRESULT WinSendDlgItemMsg(HWND hwndDlg,
- ULONG ulId,
- ULONG ulMsg,
- MPARAM mpParm1,
- MPARAM mpParm2);
-
- This function, as you can imagine, behaves the same as WinSendMsg(), except
- that - as with the first three APIs discussed in this section - it calls
- WinWindowFromID() to get the handle of the window to whom the message should be
- sent. It should be noted that there is no function WinPostDlgItemMsg(). I
- have never been able to get a straight answer for why this is so,
- unfortunately.
-
- One last API to look at - WinDefDlgProc().
-
- MRESULT WinDefDlgProc(HWND hwndWnd,
- ULONG ulMsg,
- MPARAM mpParm1,
- MPARAM mpParm2);
-
- In volume 2, issue 1, we briefly noted how WinDefWindowProc() was used to
- handle all messages that we did not want to process in our window class
- procedure. WinDefDlgProc() has the same purpose except that it is used within
- dialog procedures. Please be aware that, using one when you should be using
- the other will result in very strange behavior, so be careful!
-
-
- ΓòÉΓòÉΓòÉ 3.3.4. nameDlgProc() Revisited ΓòÉΓòÉΓòÉ
-
- nameDlgProc() Revisited
-
- Let's look at nameDlgProc() one more time, this time in its entirety.
- Following that is the resource file definition for the dialog.
-
- MRESULT EXPENTRY nameDlgProc(HWND hwndWnd,
- ULONG ulMsg,
- MPARAM mpParm1,
- MPARAM mpParm2)
- {
- PNAMEDLGINFO pndiInfo;
-
- pndiInfo=(PNAMEDLGINFO)WinQueryWindowPtr(hwndWnd,0); // @1
-
- switch (ulMsg) {
- case WM_INITDLG: // @2
- {
- HAB habAnchor;
- HWND hwndLb;
- CHAR achText[64];
-
- pndiInfo=(PNAMEDLGINFO)PVOIDFROMMP(mpParm2); // @3
- WinSetWindowPtr(hwndWnd,0,(PVOID)pndiInfo); // @4
-
- WinSendDlgItemMsg(hwndWnd, // @5
- DNAME_EF_NAME,
- EM_SETTEXTLIMIT,
- MPFROMSHORT(sizeof(pndiInfo->achName)),
- 0);
-
- habAnchor=WinQueryAnchorBlock(hwndWnd);
- hwndLb=WinWindowFromID(hwndWnd,DNAME_LB_NAMELIST);
-
- WinLoadString(habAnchor, // @6
- NULLHANDLE,
- STR_TOM,
- sizeof(achText),
- achText);
-
- WinInsertLboxItem(hwndLb,LIT_END,achText); // @7
-
- WinLoadString(habAnchor,
- NULLHANDLE,
- STR_DICK,
- sizeof(achText),
- achText);
-
- WinInsertLboxItem(hwndLb,LIT_END,achText);
-
- WinLoadString(habAnchor,
- NULLHANDLE,
- STR_HARRY,
- sizeof(achText),
- achText);
-
- WinInsertLboxItem(hwndLb,LIT_END,achText);
- }
- break;
- case WM_CONTROL: // @8
- switch (SHORT1FROMMP(mpParm1)) {
- case DNAME_LB_NAMELIST:
- switch (SHORT2FROMMP(mpParm1)) {
- case LN_SELECT: // @9
- {
- 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: // @10
- WinPostMsg(hwndWnd,WM_COMMAND,MPFROMSHORT(DID_OK),0);
- break;
- default:
- return WinDefDlgProc(hwndWnd,ulMsg,mpParm1,mpParm2); // @11
- } /* endswitch */
- break;
- default:
- return WinDefDlgProc(hwndWnd,ulMsg,mpParm1,mpParm2);
- } /* endswitch */
- break;
- case WM_COMMAND:
- switch (SHORT1FROMMP(mpParm1)) {
- case DID_OK: // @12
- WinDismissDlg(hwndWnd,TRUE);
- break;
- case DID_CANCEL: // @13
- WinDismissDlg(hwndWnd,FALSE);
- break;
- default:
- return WinDefDlgProc(hwndWnd,ulMsg,mpParm1,mpParm2);
- } /* endswitch */
- break;
- default:
- return WinDefDlgProc(hwndWnd,ulMsg,mpParm1,mpParm2);
- } /* endswitch */
-
- return MRFROMSHORT(FALSE);
- }
-
- ------------------------------------------
-
- DLGTEMPLATE DLG_NAME LOADONCALL MOVEABLE DISCARDABLE
- {
- DIALOG "Input Required", DLG_NAME, 112, 59, 150, 100,
- WS_VISIBLE,
- FCF_SYSMENU | FCF_TITLEBAR
- {
- LTEXT "Select a name, or enter it below, and select ""Ok""" ".", -1, 10, 80, 130, 16, DT_WORDBREAK
- LISTBOX DNAME_LB_NAMELIST, 10, 45, 130, 35, LS_HORZSCROLL
- ENTRYFIELD "", DNAME_EF_NAME, 12, 30, 127, 8, ES_MARGIN
- DEFPUSHBUTTON "Ok", DID_OK, 10, 10, 40, 13
- PUSHBUTTON "Cancel", DID_CANCEL, 55, 10, 40, 13
- }
- }
-
- From the dialog template, we see that the dialog consists of five controls: a
- text control (LTEXT) whose identifier is -1 (see below), a listbox control
- (LISTBOX) whose identifier is DNAME_LB_NAMELIST, an entryfield control
- (ENTRYFIELD) whose identifier is DNAME_EF_NAME, and two pushbuttons (the first
- is DEFPUSHBUTTON meaning it's the default pushbutton and the second which is
- simply PUSHBUTTON) whose identifiers are DID_OK and DID_CANCEL, respectively.
-
- It is important to remember that, while the symbolic constants
- DNAME_LB_NAMELIST and DNAME_EF_NAME are defined in HELLORC.H, DID_OK and
- DID_CANCEL are defined in <pmwin.h> which is #include-d by <os2.h>.
-
- Looking at the easiest message first, at numbers @12 and @13 we see the
- processing of the WM_COMMAND message, which (if you'll remember from last
- month) is sent by a pushbutton whenever it is pressed ("selected" is the term
- typically used). You should remember that the identifier of the button is in
- SHORT1FROMMP(mpParm1), which we "switch" on to determine the appropriate action
- to take. Here, we simply dismiss the dialog with either TRUE or FALSE returned
- depending on whether the user completed the dialog or changed their mind and
- decided to select Cancel.
-
- At number @8 we see the WM_CONTROL message. Again, last month we looked at
- this message and you should remember that the identifier of the window sending
- the message is in SHORT1FROMMP(mpParm1), which we "switch" on to determine how
- to interpret the notification code. Since we're interested in the listbox
- only, we process "case DNAME_LB_NAMELIST" and let WinDefDlgProc() handle
- everything else (at number @11). At number @9 is the LN_SELECT notification,
- which is sent whenever a listbox item is selected. Number @10 is the LN_ENTER
- notification, which is sent whenever ENTER is pressed while the listbox has the
- input focus or any listbox item is double-clicked. Since we will not be
- looking at the listbox in any great detail until a future issue, I will not
- elaborate on these two notifications until that time.
-
- At number @2 is the dialog initialization code, which I will not discuss at
- this time due to its complexity relative to what has been covered by this
- column up to this point in time.
-
-
- ΓòÉΓòÉΓòÉ 3.3.5. The WC_ENTRYFIELD Window Class ΓòÉΓòÉΓòÉ
-
- The WC_ENTRYFIELD Window Class
-
- Entryfields belong to the class WC_ENTRYFIELD and are probably the easiest of
- the window classes to use, since there isn't a lot of variation involved in the
- control's design. An entryfield is used to get a single line of text from the
- user and has clipboard support built-in (the clipboard will be discussed in a
- later issue). In an entryfield, text can be selected with the mouse or the
- keyboard. A selection consists of an anchor point and a cursor point. The
- anchor point is the point at which the selection began, and the cursor point is
- the point where the selection ends, and may move depending on whether the
- selection is still in progress.
-
- An entryfield can have the following styles:
-
- ES_ANY relates to DBCS ("double byte character set") support and
- will not be discussed here.
- ES_AUTOSCROLL specifies that, when the user moves the cursor outside of
- the visible area, the entryfield should automatically
- scroll so that the cursor is in a visible area.
- ES_AUTOSIZE specifies that the entryfield should automatically size
- itself to insure that its contents are completely visible.
- ES_AUTOTAB specifies that, when the user enters the number of
- characters equal to the current text limit (see
- EM_SETTEXTLIMIT), the entryfield should automatically give
- the input focus to the next control on the dialog.
- ES_CENTER specifies that the text should be displayed centered.
- ES_COMMAND relates to online help and will not be discussed here.
- ES_DBCS relates to DBCS ("double byte character set") support and
- will not be discussed here.
- ES_LEFT specifies that the text should be displayed flush-left.
- ES_MARGIN
- ES_MIXED relates to DBCS ("double byte character set") support and
- will not be discussed here.
- ES_READONLY specifies that the user should not be able to change the
- contents.
- ES_RIGHT specifies that the text should be displayed flush-right.
- ES_SBCS relates to DBCS ("double byte character set") support and
- will not be discussed here.
- ES_UNREADABLE specifies that each character in the entryfield should be
- displayed as an asterisk ('*').
-
- The entryfield has a number of messages that it understands, and they are
- listed below. We will discuss some of them here, and will continue in the next
- issue.
-
- o EM_CLEAR
- o EM_COPY
- o EM_CUT
- o EM_PASTE
- o EM_QUERYCHANGED
- o EM_QUERYFIRSTCHAR
- o EM_QUERYREADONLY
- o EM_QUERYSEL
- o EM_SETFIRSTCHAR
- o EM_SETINSERTMODE
- o EM_SETREADONLY
- o EM_SETSEL
- o EM_SETTEXTLIMIT
-
- You've probably noticed that there are no messages for setting and retrieving
- the contents of an entryfield. This is done using the WinSetWindowText() and
- WinQueryWindowText() (and through the "dialogish" APIs discussed earlier this
- issue).
-
- Let's look at our first four messages - EM_QUERYCHANGED, EM_QUERYFIRSTCHAR,
- EM_QUERYREADONLY, and EM_QUERYSEL.
-
- EM_QUERYCHANGED
-
- This message is sent to determine if the text has changed since this message
- was last sent (or since the control was created).
-
- Parameters
-
- param1
-
- ulReserved (ULONG)
-
- Reserved, 0.
-
- param2
-
- ulReserved (ULONG)
-
- Reserved, 0.
-
- Returns
-
- reply
-
- bChanged (BOOL)
-
- changed indicator
-
- TRUE the contents have changed since the last time this message
- was sent.
- FALSE the contents have not changed since the last time this
- message was sent.
-
- EM_QUERYFIRSTCHAR
-
- This message is sent to determine the zero-based index of the first character
- visible in the entryfield.
-
- Parameters
-
- param1
-
- ulReserved (ULONG)
-
- Reserved, 0.
-
- param2
-
- ulReserved (ULONG)
-
- Reserved, 0.
-
- Returns
-
- reply
-
- sIndex (SHORT)
-
- the zero-based index of the first visible character.
-
- EM_QUERYREADONLY
-
- This message is sent to determine if the entryfield is read-only or not.
-
- Parameters
-
- param1
-
- ulReserved (ULONG)
-
- Reserved, 0.
-
- param2
-
- ulReserved (ULONG)
-
- Reserved, 0.
-
- Returns
-
- reply
-
- bReadOnly (BOOL)
-
- the read-only state of the entryfield.
-
- TRUE the entryfield is read-only.
- FALSE the entryfield is not read-only.
-
- EM_QUERYSEL
-
- This message is sent to determine the current selection, if any exists.
-
- Parameters
-
- param1
-
- ulReserved (ULONG)
-
- Reserved, 0.
-
- param2
-
- ulReserved (ULONG)
-
- Reserved, 0.
-
- Returns
-
- reply
-
- sFirst (SHORT)
-
- the zero-based index of the anchor point.
-
- sLast (SHORT)
-
- the zero-based index of the cursor point.
-
-
- ΓòÉΓòÉΓòÉ 3.3.6. Summary ΓòÉΓòÉΓòÉ
-
- Summary
-
- This month we learned a lot of new things:
-
- o We looked at a slew of new APIs, many of which are attuned to dialogs
- o We looked at nameDlgProc() is more detail
- o We began looking at the WC_ENTRYFIELD class in detail
-
- Next month, we will continue with the WC_ENTRYFIELD discussion, but will hold
- off from discussing nameDlgProc() until we look at the WC_LISTBOX window class.
-
-
- ΓòÉΓòÉΓòÉ 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).
-
-
- ΓòÉΓòÉΓòÉ 3.4.1. Gotcha Notes! ΓòÉΓòÉΓòÉ
-
- Gotcha Notes!
-
- Last week I was developing a multithreaded application that needed two-way
- communication between the main and secondary threads. The easiest solution, as
- you may well know, was to use an object window in the second thread with its
- own message loop. The purpose of the second thread was to perform some lengthy
- processing, but needed to be interruptable, i.e. if the user pressed the Abort
- button, the dialog would send the object window the appropriate message. After
- the thread terminated its processing, it would send a response back.
-
- A problem was created, though, that resulted in deadlock. Although it didn't
- take long to deduce because the code was still quite skeletal (making the
- process of elimination quite easy), I still do not know why the deadlock
- occurred. In any case, it is necessary to relate the situation to the readers
- so that they may avoid it in their own applications.
-
- The code looked something like the following:
-
- objectWndProc(...)
- {
- POBJECTINSTDATA poidData;
-
- :
- case MYM_ABORT:
- : /* Abort processing */
- WinSendMsg(poidData->hwndDlg,MYM_PROCESSINGABORTED,0,0);
- break;
- :
- }
-
- processDlgProc(...)
- {
- POBJECTINSTDATA poidData;
-
- :
- case WM_COMMAND:
- switch (SHORT1FROMMP(mpParm1)) {
- case DLG_PB_ABORT:
- WinPostMsg(poidData->hwndObj,MYM_ABORT,0,0);
- default:
- return WinDefDlgProc(hwndWnd,ulMsg,mpParm1,mpParm2);
- } /* endswitch */
- case MYM_PROCESSINGABORTED:
- WinDismissDlg(hwndWnd,DID_CANCEL);
- break;
- :
- }
-
- INT main(VOID)
- {
- SHORT sRc;
-
- :
- sRc=WinDlgBox(HWND_DESKTOP,
- HWND_DESKTOP,
- processDlgProc,
- NULLHANDLE,
- DLG_PROCESS,
- NULL);
- if (sRc!=DID_CANCEL) {
- :
- } /* endif */
- :
- }
-
- A lot was removed for clarity, but the pertinent parts are shown above. What
- would happen was that, while testing the communication mechanisms, whenever I
- would press the Abort button, the dialog would go away, but the application
- would not terminate; looking at the above, you can probably figure out what the
- problem was. The problem, in case you can't figure it out, is the
- WinSendMsg(...,MYM_PROCESSINGABORTED,...) call to the dialog. For some reason,
- if a message is sent intraprocess from the object window to the dialog and the
- dialog dismisses itself, the process will deadlock. Changing the WinSendMsg()
- to WinPostMsg() eliminated the problem.
-
- I suspect the answer to why lies in the existence of a message loop in the
- object window thread, but I cannot be sure. If anyone can give a definitive
- answer, I would be happy to publish it.
-
-
- ΓòÉΓòÉΓòÉ 3.4.2. Snippet(s) of the Month ΓòÉΓòÉΓòÉ
-
- Snippet(s) of the Month
-
- David Charlap (david@porsche.visix.com) sent us the following:
-
- You can include this snippet. SWEEP.CMD is a REXX program that allows you to
- apply any command-line to a recursive set of directories.
-
- Syntax is:
-
- SWEEP <command-line>
-
- The program will visit every subdirectory of the current directory (and all
- descendants thereof) and execute your command line in each one. For example,
- to delete every backup file on your drive, just "cd" to the root directory of
- the drive and type
-
- SWEEP DEL *.BAK
-
- If the command you want to execute is a CMD file, be sure to use the "CALL"
- command, or Rexx will complain:
-
- SWEEP CALL MyCmdFile.CMD myArgs...
-
-
- ΓòÉΓòÉΓòÉ 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) - this is still quite the "black magic"
- topic, about which we have seen only one article. There are many out there who
- do WPS programming for a living, but they have not been sufficiently
- enlightened about our need. :)
-
- 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) - we recently 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.
-
-
- ΓòÉΓòÉΓòÉ 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.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).
- 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 Martin Lafaix
- o Larry Salomon, Jr.
- o Carsten Whimster
- o Gordon Zeglinski
- o Network distributors
-
-
- ΓòÉΓòÉΓòÉ 5.1. Martin Lafaix ΓòÉΓòÉΓòÉ
-
- Martin Lafaix
-
- Martin Lafaix is a computer science student at the UniversitВ de Nice-Sophia
- Antipolis. He currently works on his PhD thesis (key areas: functional
- language, type as value, programming at large, ...).
-
- He can be reached at the following address: lafaix@sophia.inria.fr
-
-
- ΓòÉΓòÉΓòÉ 5.2. 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.
-
-
- ΓòÉΓòÉΓòÉ 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, and compiler courses as much as possible.
- This is not too difficult obviously, since this covers most of what they try to
- teach us in any case :). 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 am now using Watcom C/C++ 9.5, and Watcom VX-REXX 2.0, with
- Watcom C/C++ 10.0 becoming my mainstay, as soon as it comes out. I try to buy
- as many books as I can afford on OS/2 programming, but I don't have much money.
- If anyone sends me books, I will review them as time permits, provided they are
- topical. Finally, I am a TEAM-OS/2 member, and stay busy trying to keep up
- with several OS/2 groups on the Internet. My Mosaic homepage should get a lot
- more interesting over the summer as I get more time to spend on 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 (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!