home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Professional
/
OS2PRO194.ISO
/
os2
/
info
/
document
/
redbooks
/
os2redb4.inf
(
.txt
)
< prev
Wrap
OS/2 Help File
|
1992-08-27
|
644KB
|
19,998 lines
ΓòÉΓòÉΓòÉ 1. (C) Copyright IBM Corp. 1992 ΓòÉΓòÉΓòÉ
(C) Copyright International Business Machines Coporation 1992. All rights
reserved.
Note to U.S. Government Users - Documentation related to restricted rights -
Use, duplication or disclosure is subject to restrictions set forth in GSA ADP
Schedule Contract with IBM Corp.
ΓòÉΓòÉΓòÉ 2. Cover ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ <hidden> Title Page ΓòÉΓòÉΓòÉ
OS/2 Version 2.0
Volume 4: Application
Development
Document Number GG24-3774-00
April 1992
International Technical
Support Center
Boca Raton
ΓòÉΓòÉΓòÉ 3. Version Notice ΓòÉΓòÉΓòÉ
Take Note: Before using this information and the product it supports, be sure
to read the general information under Special Notices.
First Edition (April 1992)
This edition applies to Version 2.0 of Operating System/2.
Order publications through your IBM representative or the IBM branch office
serving your locality. Publications are not stocked at the address given below.
A form for reader's comments appears at the back of this publication. If the
form has been removed, address your comments to:
IBM Corporation, International Technical Support Center
Dept. 91J, Building 235-2 Internal Zip 4423
901 NW 51st Street
Boca Raton, Florida 33432
When you send information to IBM, you grant IBM a non-exclusive right to use or
distribute the information in any way it believes appropriate without incurring
any obligation to you.
MAK - Revision 1.0
ΓòÉΓòÉΓòÉ 4. Abstract ΓòÉΓòÉΓòÉ
This document describes application development for OS/2 Version 2.0. It forms
Volume 4 of a five volume set; the other volumes are:
OS/2 Version 2.0 - Volume 1: Control Program, GG24-3730
OS/2 Version 2.0 - Volume 2: DOS and Windows Environment, GG24-3731
OS/2 Version 2.0 - Volume 3: Presentation Manager and Workplace Shell,
GG24-3732
OS/2 Version 2.0 - Volume 5: Print Subsystem, GG24-3775
The entire set may be ordered as OS/2 Version 2.0 Technical Compendium,
GBOF-2254.
This document is intended for IBM system engineers, IBM authorized dealers, IBM
customers, and others who require a knowledge of application development under
OS/2 Version 2.0.
This document assumes that the reader is generally familiar with the function
provided in previous releases of OS/2.
MAK - Internal Revision 1.0
ΓòÉΓòÉΓòÉ 5. Acknowledgements ΓòÉΓòÉΓòÉ
The advisors for this project were:
Hans J. Goetz
International Technical Support Center, Boca Raton
Giffin Lorimer
International Technical Support Center, Boca Raton
The authors of this document are:
Alan Chambers
IBM United Kingdom
Franco Federico
IBM United Kingdom
Neil Stokes
IBM Australia
This document was compiled and published with the aid of the International
Technical Support Center, Boca Raton.
This document was converted to the Information Presentation Facility by:
Michael Kaply
IBM Development Laboratories, Austin
Thanks to the following people for the invaluable advice and guidance provided
in the production of this document:
Ian Ameline
IBM Development Laboratories, Toronto
Mike Cowlishaw
IBM United Kingdom Development Laboratories, Hursley
David Kerr
IBM Programming Center, Boca Raton
Michael Kogan
IBM Programming Center, Boca Raton
Peter Magid
IBM Programming Center, Boca Raton
Greg Milligan
IBM Canada
Larry Raper
IBM Development Laboratories, Austin
Oliver Sims
IBM United Kingdom
Thanks also to the many people, both within and outside IBM, who provided
suggestions and guidance, and who reviewed this document prior to publication.
Thanks to the following people for providing excellent tools, used during
production of this document:
Dave Hock (CUA Draw)
IBM Cary.
JБrg von KДnel (PM Spy)
IBM Yorktown Heights.
Georg Haschek (BM2IPF)
IBM Austria.
ΓòÉΓòÉΓòÉ 6. Figures ΓòÉΓòÉΓòÉ
Program Flow - Functional Decomposition Approach
Program Flow - Object-Oriented Approach
Subclassing an Application Object
Object-Oriented Development Progression
Encapsulation of Host Interaction Within Application Object
Message Flow in a Presentation Manager Application
Structure of an Application's Main Routine
Structure of a Window Procedure
Structure of a Dialog Procedure
Allocating Memory in Previous Versions of OS/2
Allocating Memory in OS/2 Version 2.0
Committing Storage During Allocation
Using a Guard Page With a Memory Object
Guard Page Exception Handler
Registering a Guard Page Exception Handler
Suballocating Memory
Allocating Shared Memory
Sample Application Main Routine (Part 1) - Registration
Sample Application Main Routine (Part 2) - Window Creation
WinAddSwitchEntry() Function
Storing Instance Data in Window Words
Retrieving Instance Data from Window Words
Releasing Instance Data Storage
WinSubclassWindow() Function
Subclass Window Procedure
WinDlgBox() Function
Communicating with a Control Window
Querying Information From a Control Window
Inserting an Item Into a List Box
Querying a Selected List Box Item
WinMessageBox() Function
Obtaining a Window Handle - WinQueryWindow() Function
Obtaining a Window Handle - WinWindowFromID() Function
Obtaining a Window Handle Using the Switch Entry
WinBroadcastMsg() Function
Calling External Macros
Workplace Shell Inheritance Hierarchy
Invoking a Method
Overriding an Existing Method
Adding a New Method
Adding an Item to a Context Menu
Invoking a Method via a Context Menu Item
Class Method Example
Invoking a Method in Another Object Class
A SOM Precompiler-generated Function Stub
Registering a Workplace Shell Object Class
Initializing Class Data
Freeing Class Data Items
Creating an Object
Object Setup
Initializing Instance Data
Opening an Object
Opening a Custom View of an Object
Automatically Instantiating an Object
Closing an Object
Saving an Object's State
Restoring an Object's State
Destroying an Object
Deregistering an Object Class
Creating a Transient Object
Workplace Shell Application Structure
Referencing an Object Using OBJECTID
Drag Initiation From a Container Window
Receiving a DM_PRINTOBJECT Message
Handling the DM_DRAGOVER Message
Handling the DM_DROP Message
Handling the DM_RENDER Message
Menu Bar Resource Definition
String Table Resource Definition
Loading a Text String Resource
Accelerator Table Resource Definition
Window Template Resource Definition
Dialog Template Resource Definition
Resource Script File
Loading Resources From a DLL
Loading a Dialog Resource From a DLL
Creating a Thread With an Object Window
Secondary Thread Creating an Object Window
Sample Object Window Procedure
Creating a Thread Without an Object Window
Starting a Child Process
DosKillThread() Function
Terminating a Process
Interprocess Communication Using Shared Memory (Part 1)
Interprocess Communication Using Shared Memory (Part 2)
Interprocess Communication Using Atoms (Part 1)
Interprocess Communication Using Atoms (Part 2)
Interprocess Communication Using Queues (Part 1)
Interprocess Communication Using Queues (Part 2)
Interprocess Communication Using Queues (Part 3)
Interprocess Communication Using Named Pipes (Part 1)
Interprocess Communication Using Named Pipes (Part 2)
Synchronization Using Presentation Manager Messages
Synchronization Using an Event Semaphore (Part 1)
Synchronization Using an Event Semaphore (Part 2)
Synchronization Using the DosWaitThread() Function (Part 1)
Synchronization Using the DosWaitThread() Function (Part 2)
DosWaitChild() Function
Dynamically Inserting a Menu Bar Item
Dynamically Inserting a Pulldown Menu
Disabling an Menu Bar/Pulldown Menu Item
Placing a Check Mark on a Pulldown Menu Item
Standard Dialogs - WinFileDlg() Function
WinFontDlg() Function - Sample Code
DosCreateThread() Function
DosAllocMem() Function
Declaring a 16-Bit Function in 32-Bit Code
Creating a 16-bit Window From Within a 32-bit Module
Passing a 16:16 Pointer as a Message Parameter
Mixed Model Programming - WinSetWindowThunkProc() Function
Mixed Model Programming - Thunk Procedure
16:16 to 0:32 Address Conversion
Development Process for New WPS Classes
Compiling and Linking an OS/2 Presentation Manager Application
Sample Module Definition File for Presentation Manager
Sample Module Definition File to Create a DLL
IPF Tag Language Example
Simple Help Panel Source
Displaying a Bitmap in a Help Window
Hypertext Link
Hypergraphic Link
Link File With Multiple Hypergraphic Links
Multiple Viewports Using Automatic Links
Application-Controlled Viewport
Help Table Resource Definition
WinCreateHelpInstance() Function
WinAssociateHelpInstance() Function
WinDestroyHelpInstance() Function
Help Pulldown Menu Definition
Network Domains
Production Libraries on a LAN Server
ΓòÉΓòÉΓòÉ 6.1. Program Flow - Functional Decomposition Approach ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 6.2. Program Flow - Object-Oriented Approach ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 6.3. Subclassing an Application Object ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 6.4. Object-Oriented Development Progression ΓòÉΓòÉΓòÉ
This diagram shows the interdependence of object-oriented design,
implementation and user interface.
ΓòÉΓòÉΓòÉ 6.5. Encapsulation of Host Interaction Within Application Object ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 6.6. Message Flow in a Presentation Manager Application ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 6.7. Structure of an Application's Main Routine ΓòÉΓòÉΓòÉ
int main()
{
<Global data declarations>
hAB = WinInitialize(...); /* Register application */
hMsgQ = WinCreateMsgQueue(...); /* Create message queue */
WinRegisterClass(...); /* Register window class */
:
hFrame = WinCreateWindow(...); /* Create frame window */
hClient = WinCreateWindow(...); /* Create client window */
WinAddSwitchEntry(...); /* Add task manager entry */
while (WinGetMsg(...)) /* Loop until WM_QUIT */
WinDispatchMsg(...);
WinRemoveSwitchEntry(...); /* Remove task mgr entry */
WinDestroyWindow(hFrame); /* Destroy main window */
WinDestroyMsgQueue(hMsgQ); /* Destroy message queue */
WinTerminate(hAB); /* Deregister application */
}
ΓòÉΓòÉΓòÉ 6.8. Structure of a Window Procedure ΓòÉΓòÉΓòÉ
MRESULT EXPENTRY wpMain(HWND hWnd, ULONG ulMsg, MPARAM mp1, MPARAM mp2)
{
switch (ulMsg)
{
case WM_CREATE:
WinDefWindowProc(hWnd, ulMsg, mp1, mp2);
<perform initialization of instance variables>
<define, create or establish access to data objects>
return((MRESULT)FALSE);
break;
case WM_COMMAND:
<determine command by examining message parameters>
<perform processing for menu command>
return((MRESULT)0);
break;
case WM_HELP:
<perform help processing>
return((MRESULT)0);
break;
:
:
case WM_DESTROY:
<back out any incomplete updates>
<close all open data objects>
return((MRESULT)0);
break;
default:
return((MRESULT)WinDefWindowProc(hWnd,
ulMsg,
mp1,
mp2));
break;
}
}
ΓòÉΓòÉΓòÉ 6.9. Structure of a Dialog Procedure ΓòÉΓòÉΓòÉ
MRESULT EXPENTRY dpDProc(HWND hWnd, ULONG ulMsg, MPARAM mp1, MPARAM mp2)
{
switch (ulMsg)
{
case WM_INITDLG:
<extract initialization data from message parameters>
<establish initial values for control window data>
return((MRESULT)TRUE);
break;
case WM_CONTROL:
<determine originator of message and message contents>
<perform control-specific processing>
return((MRESULT)0);
break;
case WM_COMMAND:
switch LOUSHORT(mp1):
{
case DID_OK:
<complete dialog>
WinDismissDlg(hWnd,TRUE);
break;
case DID_CANCEL:
<cancel dialog>
WinDismissDlg(hWnd,FALSE);
break;
}
return((MRESULT)0);
break;
default:
return((MRESULT)WinDefDlgProc(hWnd,
ulMsg,
mp1,
mp2));
break;
}
}
ΓòÉΓòÉΓòÉ 6.10. Allocating Memory in Previous Versions of OS/2 ΓòÉΓòÉΓòÉ
SEL sel1, sel2;
PVOID pSegment1, pSegment2;
DosAllocSeg(0, &sel1, SEG_NONSHARED);
DosAllocSeg(8192, &sel2, SEG_NONSHARED);
pSegment1=MAKEP(sel1, 0);
pSegment2=MAKEP(sel2, 0);
This example shows the use of the DosAllocSeg() function to allocate multiple
segments in order to access 72KB of memory.
ΓòÉΓòÉΓòÉ 6.11. Allocating Memory in OS/2 Version 2.0 ΓòÉΓòÉΓòÉ
PVOID pObject; /* 32-bit linear pointer to memory object */
DosAllocMem(&pObject, /* Allocate memory object */
73727, /* Size of memory object */
PAG_READ | /* Allow read access */
PAG_WRITE); /* Allow write access */
This example shows the use of the DosAllocMem() function to allocate a single
72KB memory object.
ΓòÉΓòÉΓòÉ 6.12. Committing Storage During Allocation ΓòÉΓòÉΓòÉ
PVOID pObject; /* 32-bit linear pointer to memory object */
DosAllocMem(&pObject, /* Allocate memory object */
73727, /* Size of memory object */
PAG_READ | /* Allow read access */
PAG_WRITE | /* Allow write access */
PAG_COMMIT); /* Commit storage immediately */
This example shows the use of the PAG_COMMIT flag with the DosAllocMem()
function.
ΓòÉΓòÉΓòÉ 6.13. Using a Guard Page With a Memory Object ΓòÉΓòÉΓòÉ
PVOID pObject; /* 32-bit linear pointer to memory object */
DosAllocMem(&pObject, /* Allocate memory object */
73727, /* Size of memory object */
PAG_READ | /* Allow read access */
PAG_WRITE); /* Allow write access */
DosSetMem(pObject, /* Set memory attributes for object */
8192L, /* Two pages (8192 bytes) */
PAG_DEFAULT | /* Default attributes from allocation */
PAG_COMMIT); /* Commit page */
DosSetMem(pObject+4096, /* Set memory attributes for object */
1L, /* Two pages (8192 bytes) */
PAG_DEFAULT | /* Default attributes from allocation */
PAG_COMMIT | /* Commit page */
PAG_GUARD); /* Flag page as guard page */
ΓòÉΓòÉΓòÉ 6.14. Guard Page Exception Handler ΓòÉΓòÉΓòÉ
ULONG GPHandler(PEXCEPTIONREPORTRECORD pX)
{
ULONG ulAttribs; /* Memory attributes */
ULONG ulSize; /* Range in pages */
if (pX->ExceptionNum == /* If guard page exception */
XCPT_GUARD_PAGE_VIOLATION)
{
ulSize=1L; /* One page */
DosQueryMem( /* Query memory attributes */
(PVOID)pX->ExceptionInfo[1], /* Page base address */
&ulSize, /* Single page */
&ulAttribs); /* Memory attributes */
if (((ulAttrs & PAG_FREE) || /* If page is available */
(ulAttrs & PAG_COMMIT))==0) /* but is not committed */
{
DosSetMem( /* Commit page */
(PVOID)pX->ExceptionInfo[1], /* Page base address */
1L, /* Single page only */
PAG_DEFAULT | /* Default attributes */
PAG_COMMIT); /* Set commit flag */
return(XCPT_CONTINUE_EXECUTION); /* Done */
}
}
if (pX->ExceptionNum == /* If access violation */
XCPT_ACCESS_VIOLATION)
{
if (pX->ExceptionInfo[1]) /* If page address not NULL */
{
ulSize=1L; /* One page */
DosQueryMem( /* Query memory attributes */
(PVOID)pX->ExceptionInfo[1], /* Page base address */
&ulSize, /* Single page */
&ulAttribs); /* Memory attributes */
if (((ulAttrs & PAG_FREE) || /* If page is available */
(ulAttrs & PAG_COMMIT))==0) /* but is not committed */
{
DosSetMem( /* Commit page */
(PVOID)pX->ExceptionInfo[1], /* Page base address */
1L, /* Single page only */
PAG_DEFAULT | /* Default attributes */
PAG_COMMIT); /* Set commit flag */
return(XCPT_CONTINUE_EXECUTION); /* Done */
}
}
}
return(XCPT_CONTINUE_SEARCH); /* Chain to next handler if */
} /* any other exception */
This exception handler also handles the situation where an application writes
directly to an uncommitted page rather than to the guard page, as is possible
with non-sequential write operations.
ΓòÉΓòÉΓòÉ 6.15. Registering a Guard Page Exception Handler ΓòÉΓòÉΓòÉ
EXCEPTIONREGISTRATIONRECORD Exception;
:
:
Exception.ExceptionHandler = (_ERR *)&GPHandler; /* Set entry point addr */
DosSetExceptionHandler(&Exception); /* Register handler */
This example shows the use of the DosSetExceptionHandler() function.
ΓòÉΓòÉΓòÉ 6.16. Suballocating Memory ΓòÉΓòÉΓòÉ
#define POOLSIZE 8192 /* Size of storage pool */
PVOID pPool; /* Base address of pool */
CTRLSTRUCT1 *Struct1; /* Control structure 1 */
CTRLSTRUCT2 *Struct2; /* Control structure 2 */
DosAllocMem(&pPool, /* Allocate storage for pool */
POOLSIZE, /* Size of memory object */
PAG_READ | /* Allow read access */
PAG_WRITE | /* Allow write access */
PAG_COMMIT); /* Commit storage immediately */
DosSubSet(pPool, /* Initialize for suballoc */
DOS_SUBINIT, /* Initialize flag */
POOLSIZE); /* Size of pool */
DosSubAlloc(pPool, /* Suballocate storage */
&Struct1, /* Pointer to memory object */
sizeof(CTRLSTRUCT1)); /* Size of storage required */
DosSubAlloc(pPool, /* Suballocate storage */
&Struct2, /* Pointer to memory object */
sizeof(CTRLSTRUCT2)); /* Size of storage required */
ΓòÉΓòÉΓòÉ 6.17. Allocating Shared Memory ΓòÉΓòÉΓòÉ
MYSTRUCT *MYSTRUCT;
APIRET rc;
rc = DosAllocSharedMem(&MyStruct, /* Allocate memory object */
NULL, /* Anonymous memory object */
sizeof(MYSTRUCT), /* Size of memory object */
OBJ_GIVEABLE | /* Object is giveable */
PAG_WRITE | /* Write access is allowed */
PAG_READ | /* Read access is allowed */
PAG_COMMIT); /* Commit storage immediately */
rc = DosGiveSharedMem(MyStruct, /* Give access to object */
pidOther, /* Process to receive access */
PAG_WRITE | /* Write access is allowed */
PAG_READ); /* Read access is allowed */
This example shows the use of the DosAllocSharedMem() function, declaring a
memory object as "giveable".
ΓòÉΓòÉΓòÉ 6.18. Sample Application Main Routine (Part 1) - Registration ΓòÉΓòÉΓòÉ
#define INCL_WIN
#include <os2.h>
#define WCP_MAIN "WCP_MAIN"
MRESULT EXPENTRY wpMain(HWND,ULONG,MPARAM,MPARAM);
int main()
{
struct MYSTRUCT InitData;
static CHAR szTitle[] = "Main Window";
FRAMECDATA fcdata; /* Control data for window */
HAB hAB; /* Anchor block handle */
HMQ hMsgQ; /* Message queue handle */
HWND hFrame, hClient; /* Window handles */
QMSG qMsg; /* Message queue structure */
APIRET rc; /* Flag */
hAB = WinInitialize(0); /* Register appl. to PM */
hMsgQ = WinCreateMsgQueue(hAB,0); /* Create message queue */
rc = WinRegisterClass(hAB, /* Register window class */
WCP_MAIN, /* Name of class */
wpMain, /* Window procedure name */
0L, /* No style */
4); /* 32 bits in window words */
ΓòÉΓòÉΓòÉ 6.19. Sample Application Main Routine (Part 2) - Window Creation ΓòÉΓòÉΓòÉ
fcdata.flCreateFlags = FCF_TITLEBAR | FCF_SYSMENU |
FCF_SIZEBORDER | FCF_MINMAX |
FCF_SHELLPOSITION;
hFrame=WinCreateWindow(HWND_DESKTOP, /* Create frame window */
WC_FRAME, /* Frame window class */
(PSZ)0, /* No window text */
0L, /* No style */
0,0,0,0, /* PM shell will position */
(HWND)0, /* No owner */
HWND_TOP, /* On top of siblings */
0, /* No window identifier */
&fcdata, /* Frame control data */
0); /* Presentation parameters */
hClient=WinCreateWindow(hFrame, /* Create client window */
WCP_MAIN, /* Window class */
szTitle, /* Window title */
01, /* Standard style */
0,0,0,0, /* PM shell will position */
(HWND)0, /* No owner */
HWND_TOP, /* On top of siblings */
FID_CLIENT, /* Client window identifier */
&InitData, /* Initialization data */
0); /* Presentation parameters */
/* <Create Window List entry for application> */
while (WinGetMsg(hAB, &qMsg, 0, 0, 0))
WinDispatchMsg(hAB, &qMsg);
/* <Remove Window List entry for application> */
WinDestroyWindow(hFrame); /* Destroy frame & children */
WinDestroyMsgQueue(hMsgQ); /* Destroy message queue */
WinTerminate(hAB); /* Deregister application */
}
ΓòÉΓòÉΓòÉ 6.20. WinAddSwitchEntry() Function ΓòÉΓòÉΓòÉ
SWCNTRL SwitchData; /* Switch control data block */
HSWITCH hSwitch; /* Switch entry handle */
:
:
SwitchData.hwnd = hFrame; /* Set frame window handle */
SwitchData.hwndIcon = 0; /* Use default icon */
SwitchData.hprog = 0; /* Use default program handle */
SwitchData.idProcess = 0; /* Use current process id */
SwitchData.idSession = 0; /* Use current session id */
SwitchData.uchVisibility = SWL_VISIBLE; /* Make visible */
SwitchData.fbJump = SWL_JUMPABLE; /* Make jumpable via Alt+Esc */
SwitchData.szSwTitle[0] = '\0'; /* Use default title text */
hSwitch = WinAddSwitchEntry(&SwitchData); /* Add switch entry */
This function adds the application to the OS/2 Window List. Note that under
OS/2 Version 2.0, the WinCreateSwitchEntry() function should be used.
ΓòÉΓòÉΓòÉ 6.21. Storing Instance Data in Window Words ΓòÉΓòÉΓòÉ
MYSTRUCT *MyStruct;
:
switch (ulMsg) /* Switch on message class */
{
case WM_CREATE:
WinDefWindowProc(hWnd, /* Perform default init */
ulMsg,
mp1,
mp2);
DosAllocMem(MyStruct, /* Allocate memory object */
sizeof(MYSTRUCT), /* Size of memory object */
PAG_READ | /* Allow read access */
PAG_WRITE | /* Allow write access */
PAG_COMMIT); /* Commit storage now */
hFrame=WinQueryWindow(hwnd, /* Get frame window handle */
QW_PARENT,
FALSE);
WinSetWindowULong(hFrame, /* Place pointer in window */
QWL_USER, /* words */
(ULONG)MyStruct);
return((MRESULT)0);
break;
:
This example shows the allocation of a memory object, and the storage of a
pointer to that memory object in window words.
ΓòÉΓòÉΓòÉ 6.22. Retrieving Instance Data from Window Words ΓòÉΓòÉΓòÉ
case WMP_MYMESSAGE:
hFrame=WinQueryWindow(hwnd,
QW_PARENT,
FALSE);
MyStruct=WinQueryWindowULong(hFrame,
QWL_USER);
<Perform action>
return((MRESULT)0);
break;
:
ΓòÉΓòÉΓòÉ 6.23. Releasing Instance Data Storage ΓòÉΓòÉΓòÉ
case WM_DESTROY:
hFrame=WinQueryWindow(hwnd,
QW_PARENT,
FALSE);
MyStruct=WinQueryWindowULong(hFrame,
QWL_USER);
<Release data objects>
<Release Presentation Manager resources>
DosFreeMem(MyStruct);
return((MRESULT)0);
break;
:
ΓòÉΓòÉΓòÉ 6.24. WinSubclassWindow() Function ΓòÉΓòÉΓòÉ
PFNWP pOldWinProc;
pOldWinProc = WinSubclassWindow(hWnd, wpSubclass);
ΓòÉΓòÉΓòÉ 6.25. Subclass Window Procedure ΓòÉΓòÉΓòÉ
MRESULT EXPENTRY wpSubclass(HWND hWnd,
ULONG ulMsg,
MPARAM mp1,
MPARAM mp2)
{
CHAR szClass[7];
CLASSINFO WinClass;
PFNWP pWinProc;
BOOL bSuccess;
ULONG ulRetLength;
switch (ulMsg)
{
case WMP_MESSAGE1:
:
<Perform application specific processing>
:
return((MRESULT)0);
break;
case WMP_MESSAGE2:
:
<Perform application specific processing>
:
break;
default:
break;
}
ulRetLength=WinQueryClassName(hWnd,
sizeof(szClass),
szClass);
bSuccess=WinQueryClassInfo(NULL,
szClass,
&WinClass);
pWinProc=WinClass.pfnWindowProc;
return((MRESULT)(*pWinProc)(hWnd,
ulMsg,
mp1,
mp2);
}
ΓòÉΓòÉΓòÉ 6.26. WinDlgBox() Function ΓòÉΓòÉΓòÉ
MYSTRUCT *MyStruct;
:
DosAllocMem(MyStruct, /* Allocate memory object */
sizeof(MYSTRUCT), /* Size of memory object */
PAG_READ | /* Allow read access */
PAG_WRITE | /* Allow write access */
PAG_COMMIT); /* Commit storage now */
<Initialize values in MyStruct> /* Set initialization data */
rc = WinDlgBox(HWND_DESKTOP, /* Desktop is parent */
hwnd, /* Current window is owner */
dpMyDialog, /* Entry point of dialog procedure */
(HMODULE)0, /* Resource is in EXE file */
DC_MYDIALOG, /* Dialog resource identifier */
MyStruct); /* Pointer to initialization data */
ΓòÉΓòÉΓòÉ 6.27. Communicating with a Control Window ΓòÉΓòÉΓòÉ
rc = WinSendDlgItemMsg(hDlgBox, /* Parent dialog box */
EF_PRODNAME, /* Control identifier */
EM_SETTEXTLIMIT, /* Message */
20, /* Message parameters */
0);
ΓòÉΓòÉΓòÉ 6.28. Querying Information From a Control Window ΓòÉΓòÉΓòÉ
rc = WinQueryDlgItemText(hDlgBox, /* Parent dialog box */
EF_PRODNAME, /* Control identifier */
sizeof(szBuffer), /* Size of buffer */
szBuffer); /* Pointer to buffer */
ΓòÉΓòÉΓòÉ 6.29. Inserting an Item Into a List Box ΓòÉΓòÉΓòÉ
hLBox = WinWindowFromID(hWnd, /* Get list box window handle */
LB_LIST);
ulIndex = WinInsertLboxItem(hLBox, /* Insert list box item */
LIT_END, /* Insert at end of list */
szItemText); /* Item text */
ΓòÉΓòÉΓòÉ 6.30. Querying a Selected List Box Item ΓòÉΓòÉΓòÉ
hLBox = WinWindowFromID(hWnd, /* Get list box window handle */
LB_LIST);
ulIndex = WinQueryLboxSelectedItem(hLBox); /* Get index of selected item */
ulLength = WinQueryLboxItemText(hLBox, /* Get item text */
usIndex, /* Index of item */
szBuffer, /* Text buffer */
sizeof(szBuffer)); /* Max no. of chars */
ΓòÉΓòÉΓòÉ 6.31. WinMessageBox() Function ΓòÉΓòÉΓòÉ
rc = WinMessageBox(HWND_DESKTOP, /* Desktop is parent */
hWnd, /* Current window is parent */
pszMsgText, /* Pointer to message text */
"Open the File" /* Message title */
0, /* Message box identifier */
MB_OKCANCEL | /* Include OK & Cancel buttons */
MB_DEFBUTTON1 | /* Default to OK */
MB_HELP); /* Include help button */
ΓòÉΓòÉΓòÉ 6.32. Obtaining a Window Handle - WinQueryWindow() Function ΓòÉΓòÉΓòÉ
hTarget = WinQueryWindow(hWnd, /* Base window for relation */
QW_PARENT, /* Relationship to base wndw */
FALSE); /* Do not lock window */
ΓòÉΓòÉΓòÉ 6.33. Obtaining a Window Handle - WinWindowFromID() Function ΓòÉΓòÉΓòÉ
hTarget = WinWindowFromID(hMainFrame, /* Parent window known */
FID_CLIENT); /* Window identifier */
ΓòÉΓòÉΓòÉ 6.34. Obtaining a Window Handle Using the Switch Entry ΓòÉΓòÉΓòÉ
hSwitch = WinQuerySwitchHandle(hWnd,0);
ulSuccess = WinQuerySwitchEntry(hSwitch,
SwitchData);
hTarget = WinWindowFromID(SwitchData.hwnd,
FID_CLIENT);
ΓòÉΓòÉΓòÉ 6.35. WinBroadcastMsg() Function ΓòÉΓòÉΓòÉ
rc = WinBroadcastMsg(hwnd, /* Current is parent */
WMP_MYMESSAGE, /* Message identifier */
mp1, /* 1st message parameter */
mp2, /* 2nd message parameter */
BMSG_POST); /* Post message via queue */
ΓòÉΓòÉΓòÉ 6.36. Calling External Macros ΓòÉΓòÉΓòÉ
#define INCL_REXXSAA
#include <rexxsaa.h>
:
PSZ szFileName; /* File to be accessed */
PSZ szOptions; /* Command arguments */
RXSTRING arg; /* REXX argument string */
RXSTRING RexxRetValue; /* Result */
LONG lRexxRC; /* REXX return code */
static RXSYSEXIT ExitList[] = {{"TIXXSIO", RXSIO}, /* Exit handler */
{NULL, RXENDLST}};
:
arg.strptr = szOptions; /* Set argument string */
arg.strlength = strlen(szOptions); /* Size of arg string */
rc = RexxStart(1, /* Call REXX */
&arg, /* Argument string */
(PSZ)"RexxProc", /* REXX proc file */
NULL, /* Procedure in file */
(PSZ)"TIXX", /* ADDRESS environment */
(SHORT)RXCOMMAND, /* REXX command */
(PRXSYSEXIT)ExitList, /* Exit list routines */
&lRexxRC, /* Return code address */
&RexxRetValue); /* Returned result */
This example shows the use of the RexxStart() function to call the REXX command
interpreter from within an application.
ΓòÉΓòÉΓòÉ 6.37. Workplace Shell Inheritance Hierarchy ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 6.38. Invoking a Method ΓòÉΓòÉΓòÉ
PWFolder *somSelf; /* Pointer to self */
PSZ szTitle; /* Title string */
_wpSetTitle(somSelf,szTitle); /* Set title string */
ΓòÉΓòÉΓòÉ 6.39. Overriding an Existing Method ΓòÉΓòÉΓòÉ
SOM_Scope BOOL SOMLINK pwfolder_wpSetTitle(PWFolder *somSelf,
PSZ pszNewTitle)
{
CHAR szBuf[100]; /* Character buffer */
PWFolderData *somThis = /* Get instance data */
PWFolderGetData(somSelf);
PWFolderMethodDebug("PWFolder", /* Set debug info */
"pwfolder_wpSetTitle");
strcpy(szBuf,pszNewTitle); /* Get current title */
if ((strcmp(_szCurrentPassword, /* If folder is locked */
_szPassword)) != 0)
if((strstr(szBuf,"LOCKED")) == NULL ) /* and <LOCKED> not in */
/* current title */
strcat(szBuf," <LOCKED>"); /* Add <LOCKED> to title */
return(parent_wpSetTitle(somSelf, /* Allow default proc to */
szBuf)); /* occur */
}
This example shows the _wpSetTitle method being overridden to add the word
"LOCKED" to the end of the title of a locked password-protected folder.
ΓòÉΓòÉΓòÉ 6.40. Adding a New Method ΓòÉΓòÉΓòÉ
SOM_Scope BOOL SOMLINK pwfolder_LockFolder(PWFolder *somSelf)
{
HPTR hLockedIcon;
PWFolderData *somThis = /* Get instance data */
PWFolderGetData(somSelf);
PWFolderMethodDebug("PWFolder", /* Set debug info */
"pwfolder_LockFolder");
strcpy(_szCurrentPassword, /* Invalidate current */
"NOPASSWD"); /* password */
_wpSetTitle(somSelf, /* Set title */
_wpQueryTitle(somSelf) );
hLockedIcon = WinLoadPointer(HWND_DESKTOP, /* Load "lock" icon */
(HMODULE)0,
LOCK);
_wpSetIcon(somSelf, /* Set icon to locked */
hLockedIcon); /* appearance */
return((BOOL)0); /* Return */
}
ΓòÉΓòÉΓòÉ 6.41. Adding an Item to a Context Menu ΓòÉΓòÉΓòÉ
#define MI_LOCK WPMENUID_USER+1
:
:
SOM_Scope BOOL SOMLINK pwfolder_wpModifyPopupMenu(PWFolder *somSelf,
HWND hwndMenu,
HWND hwndCnr,
ULONG iPosition)
{
PWFolderData *somThis = /* Get instance data */
PWFolderGetData(somSelf);
PWFolderMethodDebug("PWFolder", /* Set debug info */
"pwfolder_wpModifyPopupMenu");
_wpInsertPopupMenuItems(somSelf, /* Insert menu item */
hwndMenu, /* Menu handle */
iPosition, /* Default position */
hModule, /* Module handle */
MI_LOCK, /* Menu item id */
0); /* No submenu id */
return(parent_wpModifyPopupMenu(somSelf, /* Allow default proc to */
hwndMenu, /* occur */
hwndCnr,
iPosition));
}
ΓòÉΓòÉΓòÉ 6.42. Invoking a Method via a Context Menu Item ΓòÉΓòÉΓòÉ
SOM_Scope void SOMLINK pwfolder_wpMenuItemSelected(PWFolder *somSelf,
HWND hwndFrame,
ULONG MenuId)
{
PWFolderData *somThis = /* Get instance data */
PWFolderGetData(somSelf);
PWFolderMethodDebug("PWFolder", /* Set debug info */
"pwfolder_wpMenuItemSelected");
switch (MenuId) /* Switch on item id */
{
case MI_LOCK: /* If "Lock" item */
_LockFolder(somSelf); /* Lock folder */
break;
default: /* else */
parent_wpMenuItemSelected(somSelf, /* Allow default */
hwndFrame, /* processing to */
MenuId); /* occur */
break;
}
return;
}
ΓòÉΓòÉΓòÉ 6.43. Class Method Example ΓòÉΓòÉΓòÉ
PSZ szDefaultClassTitle = "Password Folder";
/*
*
* METHOD: wpclsQueryTitle PUBLIC
*
* PURPOSE:
* Return the string "Password Folder"
*
*/
#undef SOM_CurrentClass
#define SOM_CurrentClass M_PWFolderCClassData.parentMtab
SOM_Scope PSZ SOMLINK pwfoldercls_wpclsQueryTitle(M_PWFolder *somSelf)
{
/* M_PWFolderData *somThis = M_PWFolderGetData(somSelf); */
M_PWFolderMethodDebug("M_PWFolder","pwfoldercls_wpclsQueryTitle");
return(szDefaultClassTitle);
}
This example shows an overridden class method _wpclsQueryTitle, which is
modified to supply a default title for an object within the class.
ΓòÉΓòÉΓòÉ 6.44. Invoking a Method in Another Object Class ΓòÉΓòÉΓòÉ
SOMAny *RecordClass; /* Class object pointer */
somID idQueryMethod; /* Method id */
CHAR szQueryBuffer[100]; /* Query data buffer */
PVOID pFindData; /* Returned data buffer */
:
:
rc = DosAllocSharedMem(&pFindData, /* Alloc shared memory */
NULL, /* No name */
sizeof(szQueryBuffer)+1, /* Size of memory object */
OBJ_GIVEABLE | /* Make object giveable */
PAG_WRITE | /* Allow write access */
PAG_READ | /* Allow read access */
PAG_COMMIT); /* Commit storage now */
strcpy(pFindData,szQueryBuffer); /* Copy data to buffer */
RecordClass = _somFindClass(SOMClassMgrObject, /* Get class obj pointer */
SOM_IdFromString("Record"),
1,1));
idQueryMethod = SOM_IdFromString("clsQuery"); /* Get method id */
_somDispatchL(RecordClass, /* Invoke method */
idQueryMethod, /* Method id */
(void *)0, /* No descriptor string */
pFindData, /* Method parameters */
somSelf);
ΓòÉΓòÉΓòÉ 6.45. A SOM Precompiler-generated Function Stub ΓòÉΓòÉΓòÉ
/*
*
* METHOD: QueryInfo PRIVATE
*
* PURPOSE: Copy the PWFolder instance data into
* the PWF_INFO structure that pPWFolderInfo
* points to.
* ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇ2
*/ Γöé ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇ3
.
SOM_Scope BOOL SOMLINK pwFolder_QueryInfo(PWFolder *somSelf,
PPWF_INFO pPWFolderInfo)
{ ΓööΓöÇΓöÇΓöÇ1
PWFolderData *somThis = PWFolderGetData(somSelf); 4
PWFolderMethodDebug("PWFolder","pwfolder_QueryInfo"); 5
<application logic> 6
return((BOOL)0);
}
ΓööΓöÇΓöÇΓöÇΓöÇ7
Notes:
1 SOM_Scope declares the function scope according to the language being used.
For example, in C++, SOM_Scope would be defined as extern C but in C it is
simply defined as extern.
2 It can be seen that the external prefix "pwfolder_", which was specified in
the class definition file, has been placed in front of the function as
expected. Note that the SOM Precompiler generates a macro for this function in
the private header file:
#define _QueryInfo PWFolder_QueryInfo
This avoids the necessity for the programmer to type the full function name,
and helps make the code more readable.
3 Since SOM uses the C language, methods from SOM objects cannot be referenced
in a very elegant manner. The first parameter to a SOM method must be a
pointer to an object that can invoke that method. In the actual method
function, this pointer is given the name somSelf. For example, the difference
between C and C++ is as follows:
/* Let us say */
pMyObject = (pointer to an object);
// in C++ the following syntax may be used
pMyObject->Method(param1, param2....);
/* but in C the following is required */
Method(pMyObject, param1, param2....);
4 This statement uses the pointer to the object to initialize a pointer to
access the object's instance data. See Methods (Method Processing and Instance
Data) for further information on instance data.
5 This line will perform tracing. Tracing is switched on whenever the SOM
global variable SOM_TraceLevel is set to a non-zero value.
6 This section is left blank by the SOM Precompiler for the developer to fill
with the applicaton logic. This logic may include access to system and/or
Presentation Manager resources. For the password-protected folder example, the
_QueryInfo method must copy the instance variables to the PWF_INFO data
structure defined in the passthru section of the class definition file. The
code required to do this is as follows:
strcpy(pPWFolderInfo->szPassword, _szPassword);
strcpy(pPWFolderInfo->szCurrentPassword, _szCurrentPassword);
strcpy(pPWFolderInfo->szUserid, _szUserid);
This code must be inserted in the C source file by the programmer, after the
file is generated by the SOM Precompiler. This may be done using a normal text
editor.
7 Finally, the SOM Precompiler provides a default zero return statement,
typecast with the return data type of the method as declared in the methods
section of the class definition file. This statement may be altered by the
programmer if required, provided that consistency with the method's prototype
and declaration is maintained.
ΓòÉΓòÉΓòÉ 6.46. Registering a Workplace Shell Object Class ΓòÉΓòÉΓòÉ
PSZ pszClassName = "NewObject"; /* Class name */
PSZ pszModName = "NEWOBJ"; /* DLL module for class */
BOOL bSuccess; /* Success flag */
bSuccess = WinRegisterObjectClass(pszClassName, /* Register class */
pszModName); /* DLL module name */
ΓòÉΓòÉΓòÉ 6.47. Initializing Class Data ΓòÉΓòÉΓòÉ
HMODULE hModule;
:
:
SOM_Scope void SOMLINK pwfoldercls_wpclsInitData(M_PWFolder *somSelf)
{
CHAR ErrorBuffer[100]; /* Error buffer */
/* M_PWFolderData *somThis =
M_PWFolderGetData(somSelf); */
M_PWFolderMethodDebug("M_PWFolder", /* Set debug info */
"pwfoldercls_wpclsInitData");
DosLoadModule((PSZ) ErrorBuffer, /* Get module handle */
sizeof(ErrorBuffer), /* Size of error buffer */
"PWFOLDER", /* Name of DLL */
&hModule); /* Module handle */
parent_wpclsInitData(somSelf); /* Allow default proc */
}
ΓòÉΓòÉΓòÉ 6.48. Freeing Class Data Items ΓòÉΓòÉΓòÉ
SOM_Scope void SOMLINK pwfoldercls_wpclsUnInitData(M_PWFolder *somSelf)
{
/* M_PWFolderData *somThis
= M_PWFolderGetData(somSelf); */
M_PWFolderMethodDebug("M_PWFolder", /* Set debug info */
"pwfoldercls_wpclsUnInitData");
DosFreeModule(hModule); /* Free module handle */
parent_wpclsUnInitData(somSelf); /* Allow default proc */
}
ΓòÉΓòÉΓòÉ 6.49. Creating an Object ΓòÉΓòÉΓòÉ
PSZ pszClassName = "NewObject"; /* Class name */
PSZ pszObjectTitle = "My New Object"; /* Object title */
PSZ pszParams = "ICON=C:\\ICONS\\MYNEWICON.ICO"; /* Setup string */
PSZ pszLocation = "C:\\Desktop\\MyNewFolder"; /* Location for object */
ULONG ulFlags; /* Creation flags */
HOBJECT hObject; /* Object handle */
hObject = WinCreateObject(pszClassName, /* Create object */
pszObjTitle, /* Title for icon */
pszParams, /* Setup string */
pszLocation, /* Location for object */
CO_REPLACEIFEXISTS); /* Creation flags */
ΓòÉΓòÉΓòÉ 6.50. Object Setup ΓòÉΓòÉΓòÉ
SOM_Scope BOOL SOMLINK pwfolder_wpSetup(PWFolder *somSelf,
PSZ pszSetupString)
{
CHAR pszInitPword[20]; /* Buffer for password */
BOOL bFound; /* Success flag */
ULONG ulRetLength;
PWFolderData *somThis = /* Get instance data */
PWFolderGetData(somSelf);
PWFolderMethodDebug("PWFolder", /* Set debug info */
"pwfolder_wpSetup");
if (pszSetupString != NULL) /* If string is present */
{
bFound=_wpScanSetupString(somSelf, /* Scan setup string to */
pszSetupString, /* find keyword */
"PASSWORD"
pszInitPword,
&RetLength);
if (bFound) /* If parameter present */
{
strcpy(_szPassword, /* Copy p'word to folder */
pszInitPword); /* p'word and current */
strcpy(_szCurrentPassword, /* p'word - initialize */
pszInitPword); /* in unlocked state */
}
}
return (parent_wpSetup(somSelf, /* Allow default proc to */
pszSetupString)); /* occur */
}
This example shows an overridden _wpSetup method which parses the setup string
to extract class-specific parameters.
ΓòÉΓòÉΓòÉ 6.51. Initializing Instance Data ΓòÉΓòÉΓòÉ
SOM_Scope void SOMLINK pwfolder_wpInitData(PWFolder *somSelf)
{
CHAR ErrorBuffer[100]; /* Error data buffer */
PWFolderData *somThis = /* Get instance data */
PWFolderGetData(somSelf);
PWFolderMethodDebug("PWFolder", /* Set debug info */
"pwfolder_wpInitData");
strcpy(_szCurrentPassword, /* Initialize folder */
"password"); /* password */
strcpy(_szPassword, /* Set current password */
"password"); /* to folder password */
/* ie. Set unlocked */
return(parent_wpInitData(somSelf)); /* Perform default proc */
}
ΓòÉΓòÉΓòÉ 6.52. Opening an Object ΓòÉΓòÉΓòÉ
SOM_Scope HWND SOMLINK pwfolder_wpOpen(PWFolder *somSelf,
HWND hwndCnr,
ULONG ulView,
ULONG param)
{
ULONG ulResult;
CHAR szTitle[100];
PWFolderData *somThis =
PWFolderGetData(somSelf); /* Set instance data */
PWFolderMethodDebug("PWFolder", /* Set debug info */
"pwfolder_wpOpen");
if ((strcmp(_szCurrentPassword, /* If not locked */
_szPassword)) == 0)
return(parent_wpOpen(somSelf, /* Allow open to proceed */
hwndCnr, /* in normal way, using */
ulView, /* default processing */
param));
ulResult = WinDlgBox(HWND_DESKTOP, /* Display p'word dialog */
HWND_DESKTOP, /* Desktop is owner */
dpPassword, /* Dialog procedure */
hModule, /* Module handle */
DLG_PASSWORD, /* Dialog resource id */
(PVOID)somSelf); /* Object pointer */
if (ulResult == DID_OK) /* If not cancelled */
{
if ((strcmp(_szCurrentPassword, /* If correct password */
_szPassword)) == 0)
{
strcpy(szTitle, /* Get title string */
_wpQueryTitle(somSelf));
szTitle[strlen(szTitle)-9] = '\0'; /* Remove <LOCKED> */
_wpSetTitle(somSelf,szTitle); /* Reset title string */
<Set icon to unlocked state>
return (parent_wpOpen(somSelf, /* Allow default _wpOpen */
hwndCnr, /* processing to occur */
ulView, /* by invoking parent's */
param)); /* method */
}
else
{
WinMessageBox(HWND_DESKTOP, /* Display message box */
HWND_DESKTOP,
"Password incorrect. Folder remains locked.",
"Password Failed",
0, MB_OK | MB_CUAWARNING);
return((BOOL)0); /* Return FALSE */
}
}
}
This example shows the _wpOpen method, which is called by the system when a
view of an object is opened, being overridden to add password protection to a
folder.
ΓòÉΓòÉΓòÉ 6.53. Opening a Custom View of an Object ΓòÉΓòÉΓòÉ
HWND hView; /* View window handle */
typedef struct _OBJECTVIEW /* Object view structure */
{
SOMAny *Object; /* Object pointer */
USEITEM UseItem; /* USEITEM structure */
VIEWITEM ViewItem; /* VIEWITEM structure */
} OBJECTVIEW;
OBJECTVIEW *pObjectView; /* Pointer to structure */
<Create Window> /* Get window handle */
pObjectView = _wpAllocMem(somSelf, /* Allocate memory */
sizeof(OBJECTVIEW), /* Size of mem object */
NULL);
pObjectView->Record = somSelf; /* Initialize OBJECTVIEW */
pObjectView->UseItem.type = USAGE_OPENVIEW; /* structure */
pObjectView->ViewItem.view = OPEN_CUST;
pObjectView->ViewItem.handle = hView;
WinSetWindowULong(hView, /* Store pointer to */
QWL_USER, /* structure in window */
(ULONG)pObjectView); /* words */
_wpAddToObjUseList(somSelf, /* Add to Use List */
&pObjectView->UseItem); /* USEITEM structure */
_wpRegisterView(somSelf, /* Register view */
hView, /* View window handle */
"Customer Details") /* Title of view */
ΓòÉΓòÉΓòÉ 6.54. Automatically Instantiating an Object ΓòÉΓòÉΓòÉ
PSZ pszClassName = "NewObject"; /* Class name */
PSZ pszObjectTitle = "My New Object"; /* Object title */
PSZ pszParams = "OPEN=ICON"; /* Setup string */
PSZ pszLocation = "C:\\Desktop\\MyNewFolder"; /* Location for object */
ULONG ulFlags = CO_UPDATEIFEXISTS; /* Creation flags */
HOBJECT hObject; /* Object handle */
hObject = WinCreateObject(pszClassName, /* Create object */
pszObjTitle, /* Title for icon */
pszParams, /* Setup string */
pszLocation, /* Location for object */
ulFlags); /* Creation flags */
This example shows the use of the OPEN= keyword to automatically open a view of
an object upon creating the object.
ΓòÉΓòÉΓòÉ 6.55. Closing an Object ΓòÉΓòÉΓòÉ
SOM_Scope BOOL SOMLINK pwfolder_wpClose(PWFolder *somSelf)
{
PWFolderData *somThis = /* Get instance data */
PWFolderGetData(somSelf);
PWFolderMethodDebug("PWFolder", /* Set debug info */
"pwfolder_wpInitData");
_LockFolder(somSelf); /* Lock folder */
return(parent_wpClose(somSelf)); /* Allow default proc */
}
This example shows the _wpClose method being overridden in order to provide
class-specific processing for the password-protected folder.
ΓòÉΓòÉΓòÉ 6.56. Saving an Object's State ΓòÉΓòÉΓòÉ
SOM_Scope BOOL SOMLINK pwfolder_wpSaveState(PWFolder *somSelf)
{
PWFolderData *somThis = /* Get instance data */
PWFolderGetData(somSelf);
PWFolderMethodDebug("PWFolder", /* Set debug info */
"pwfolder_wpSaveState");
_wpSaveString(somSelf, /* Save folder password */
"PWFolder", /* Class name */
1L, /* Class-defined key */
_szPassword); /* String to be saved */
_wpSaveString(somSelf, /* Save current password */
"PWFolder", /* Class name */
2L, /* Class-defined key */
_szCurrentPassword); /* String to be saved */
return (parent_wpSaveState(somSelf)); /* Invoke default proc */
}
ΓòÉΓòÉΓòÉ 6.57. Restoring an Object's State ΓòÉΓòÉΓòÉ
SOM_Scope BOOL32 SOMLINK pwfolder_wpRestoreState(PWFolder *somSelf,
ULONG ulReserved)
{
ULONG ulResStrLen; /* String length */
PWFolderData *somThis = /* Get instance data */
PWFolderGetData(somSelf);
PWFolderMethodDebug("PWFolder", /* Set debug info */
"pwfolder_wpRestoreState");
_wpRestoreString(somSelf, /* Restore folder p'word */
"PWFolder", /* Class name */
1L, /* Class-defined key */
_szPassword, /* Target string */
&ulResStrLen); /* Length restored */
_wpRestoreString(somSelf, /* Restore curr p'word */
"PWFolder", /* Class name */
2L, /* Class-defined key */
_szCurrentPassword, /* Target string */
&ulResStrLen); /* Length restored */
return(parent_wpRestoreState(somSelf, /* Invoke default proc */
ulReserved));
}
ΓòÉΓòÉΓòÉ 6.58. Destroying an Object ΓòÉΓòÉΓòÉ
HOBJECT hObject; /* Object handle */
BOOL bSuccess; /* Success flag */
bSuccess = WinDestroyObject(hObject); /* Destroy object */
ΓòÉΓòÉΓòÉ 6.59. Deregistering an Object Class ΓòÉΓòÉΓòÉ
BOOL bSuccess;
bSuccess = WinDeregisterObjectClass(pszClassName); /* Deregister class */
ΓòÉΓòÉΓòÉ 6.60. Creating a Transient Object ΓòÉΓòÉΓòÉ
REPLY *Reply; /* Reply data structure */
SOMAny *NewObj; /* Object pointer */
case WMP_REQUEST_COMPLETE:
Reply = (REPLY *)mp1; /* Get reply data */
ClassID = SOM_IdFromString("CustClass"); /* Get class SOM ID */
TransClass = _somFindClass(SOMClassMgrObject, /* Get class pointer */
ClassID, /* Class SOM ID */
1,1); /* Major & minor version */
NewObj = _wpclsNew(TransClass, /* Create new object */
Reply->CustName, /* Title for object */
"", /* No setup string */
Reply->Folder, /* Location */
TRUE); /* Lock flag */
_SetCustInfo(NewObj, /* Set instance data */
Reply);
break;
ΓòÉΓòÉΓòÉ 6.61. Workplace Shell Application Structure ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 6.62. Referencing an Object Using OBJECTID ΓòÉΓòÉΓòÉ
HOBJECT hObject; /* Object handle */
/*************************************************************************/
/* Create a folder on the desktop with an OBJECTID of MYFOLDER */
/*************************************************************************/
hObject = WinCreateObject("WPFolder", /* Class Name */
"My Folder", /* Title */
"OBJECTID=<MYFOLDER>", /* Setup string */
"<WP_DESKTOP>", /* Location */
CO_REPLACEIFEXISTS); /* Create option */
/*************************************************************************/
/* Create a file object with an OBJECTID of MYFILE inside the folder */
/*************************************************************************/
hObject = WinCreateObject("WPDataFile", /* Class Name */
"My File", /* Title */
"OBJECTID=<MYFILE>", /* Setup string */
"<MYFOLDER>", /* Location */
CO_REPLACEIFEXISTS); /* Create option */
/*************************************************************************/
/* Create a shadow of the file object MYFILE on the desktop */
/*************************************************************************/
hObject = WinCreateObject("WPShadow", /* Class Name */
"My File", /* Title */
"SHADOWID=<MYFILE>", /* Setup string */
"<WP_DESKTOP>", /* Location */
CO_REPLACEIFEXISTS); /* Create option */
ΓòÉΓòÉΓòÉ 6.63. Drag Initiation From a Container Window ΓòÉΓòÉΓòÉ
PCONTRECORD pCRec;
PCNRDRAGINIT pcnrInit;
PDRAGINFO pDInfo;
DRAGITEM DItem;
DRAGIMAGE DImage;
APIRET rc;
:
:
case WM_CONTROL:
switch (SHORT2FROMMP(mp1))
{
case CN_INITDRAG:
pcnrInit = /* Get container data */
(PCNRDRAGINIT)mp2;
pCRec = (PCONTRECORD)pcnrInit->pRecord;
if (pCRec == NULL) /* If no item selected */
return(0); /* Return */
pDInfo = DrgAllocDraginfo(1); /* Allocate DRAGINFO */
DItem.hwndItem = hWnd; /* Initialize DRAGITEM */
DItem.ulItemID = (ULONG)pCRec;
DItem.hstrType =
DrgAddStrHandle("DRT_CUSTOMER");
DItem.hstrRMF =
DrgAddStrHandle("(DRM_SHAREMEM,DRM_PRINT)x(DRF_TEXT)");
DItem.fsControl = 0;
DItem.fsSupportedOps = DO_COPYABLE | DO_MOVEABLE;
rc = DrgSetDragItem(pDInfo, /* Set item in DRAGINFO */
&DItem, /* Pointer to DRAGITEM */
sizeof(DItem), /* Size of DRAGITEM */
0); /* Index of DRAGITEM */
DImage.cb = sizeof(DRAGIMAGE); /* Initialize DRAGIMAGE */
DImage.cptl = 0; /* Not a polygon */
DImage.hImage = hPostIcon; /* Icon handle for drag */
DImage.fl = DRG_ICON; /* Dragging an icon */
DImage.cxOffset = 0; /* No hotspot */
DImage.cyOffset = 0;
hDrop = DrgDrag(hWnd, /* Initiate drag */
pDInfo, /* DRAGINFO structure */
(PDRAGIMAGE)&DImage, /* DRAGIMAGE structure */
1, /* Only one DRAGIMAGE */
VK_ENDDRAG, /* End of drag indicator */
NULL); /* Reserved */
DrgFreeDragInfo(pDInfo); /* Free DRAGINFO struct */
break;
Another window class would perform these operations in response to a
WM_BEGINDRAG message, rather than a WM_CONTROL message with the CN_INITDRAG
indicator.
ΓòÉΓòÉΓòÉ 6.64. Receiving a DM_PRINTOBJECT Message ΓòÉΓòÉΓòÉ
case DM_PRINTOBJECT:
WinMessageBox(HWND_DESKTOP, /* Display message box */
hWnd, /* Curr window is owner */
"Printing customer details", /* Message box text */
"Print Message Received", /* Message box title */
0, /* No identifier */
MB_OK); /* Include okay button */
<Extract DRAGITEM pointer from mp1>
<Extract print queue name from mp2>
<Print item>
break;
ΓòÉΓòÉΓòÉ 6.65. Handling the DM_DRAGOVER Message ΓòÉΓòÉΓòÉ
PDRAGITEM pDItem; /* Pointer to DRAGITEM */
PDRAGINFO pDInfo; /* Pointer to DRAGINFO */
case DM_DRAGOVER:
pdinfo = (PDRAGINFO)mp1; /* Get DRAGINFO pointer */
DrgAccessDraginfo(pdinfo); /* Access DRAGINFO */
pditem = DrgQueryDragitemPtr(pdinfo, /* Access DRAGITEM */
0); /* Index to DRAGITEM */
if (!DrgVerifyRMF(pditem, /* Check valid rendering */
"DRM_SHAREMEM", /* mechanisms and data */
"DRF_TEXT")) /* formats */
{
DrgFreeDraginfo(pdinfo); /* Free DRAGINFO */
return(MPFROM2SHORT(DOR_DROP, /* Return okay to drop */
DO_COPY)); /* Copy operation valid */
}
else
{
DrgFreeDraginfo(pdinfo); /* Free DRAGINFO */
return(MPFROM2SHORT(DOR_NEVERDROP, /* Drop not valid */
0)); /* No valid operations */
}
break;
ΓòÉΓòÉΓòÉ 6.66. Handling the DM_DROP Message ΓòÉΓòÉΓòÉ
#define XFERMEM "\\SHAREMEM\\DragXfer.mem" /* Shared mem obj name */
PVOID pCust; /* Customer record ptr */
PDRAGITEM pDItem; /* DRAGITEM struct ptr */
PDRAGINFO pDInfo; /* DRAGINFO struct ptr */
:
case DM_DROP:
pDInfo = (PDRAGINFO)mp1; /* Get DRAGINFO pointer */
DrgAccessDraginfo(pDInfo); /* Access DRAGINFO */
pDItem = DrgQueryDragitemPtr(pdinfo, /* Access DRAGITEM */
0); /* Index to DRAGITEM */
DosAllocSharedMem(&pCust, /* Allocate shared mem */
XFERMEM, /* Named memory object */
sizeof(CUSTOMER), /* Size of memory object */
PAG_COMMIT | /* Commit storage now */
PAG_WRITE | /* Allow write access */
PAG_READ); /* Allow read access */
pdxfer = DrgAllocDragtransfer(1); /* Allocate DRAGTRANSFER */
pdxfer->cb = sizeof(DRAGTRANSFER); /* Init DRAGTRANSFER */
pdxfer->hwndClient = hWnd;
pdxfer->pditem = pDItem;
pdxfer->hstrSelectedRMF =
DrgAddStrHandle("<DRM_CUSTOMER,DRF_TEXT>");
pdxfer->hstrRenderToName =
DrgAddStrHandle(XFERMEM);
pdxfer->ulTargetInfo = 0;
pdxfer->usOperation = DO_COPY;
rc=DrgSendTransferMsg(pDInfo->hwndSource, /* Send msg to source */
DM_RENDER, /* DM_RENDER message */
(MPARAM)pdxfer, /* DRAGTRANSFER pointer */
NULL);
if (rc == TRUE) /* If rendered okay */
{
strcpy(msgtext, "Dialling number"); /* Build message text */
strncat(msgtext,
pxfercust->phone,
30);
WinMessageBox(HWND_DESKTOP, /* Display message box */
hWnd, /* Curr window is owner */
msgtext, /* Message text */
"Telephone Dialler", /* Message title */
0, /* No identifier */
MB_OK); /* Include okay button */
PhoneDial(pxfercust->phone); /* Dial number */
}
DrgFreeDragInfo(pdinfo); /* Release all data */
DrgFreeDragtransfer(pdxfer); /* structures */
DosFreeMem((PVOID)pxfercust);
break;
ΓòÉΓòÉΓòÉ 6.67. Handling the DM_RENDER Message ΓòÉΓòÉΓòÉ
PDRAGITEM pDItem; /* DRAGITEM pointer */
PDRAGINFO pDInfo; /* DRAGINFO pointer */
PDRAGTRANSFER pDXfer; /* DRAGTRANSFER pointer */
PCONTRECORD pCRec; /* Container record ptr */
PCUSTOMER pCust, /* Customer record ptrs */
pXferData;
CHAR xfermem[100]; /* Memory name buffer */
HWND hContainer; /* Container handle */
:
:
case DM_RENDER:
pDXfer = (PDRAGTRANSFER)mp1; /* Get DRAGTRANSFER ptr */
pDItem = pDxfer->pditem; /* Get DRAGITEM ptr */
pCRec = pditem->ulItemID; /* Get container rec ptr */
pCust = pCRec->cust; /* Get customer rec ptr */
DrgQueryStrName(pDXfer->hstrRenderToName, /* Get mem object name */
100, /* Size of buffer */
xfermem); /* Buffer */
DosGetNamedSharedMem((PPVOID)&pXferData, /* Get shared mem object */
xfermem, /* Name of mem object */
PAG_WRITE | /* Allow write access */
PAG_READ); /* Allow read access */
memcpy(pCust, /* Copy customer record */
pXferData, /* to shared mem object */
sizeof(CUSTOMER)); /* No. of bytes to copy */
DosFreeMem((PVOID)pCust); /* Free shared mem obj */
if (pDXfer->usOperation == DO_MOVE) /* If move operation */
{
hContainer = WinWindowFromID(hWnd, /* Get container window */
CONTAINER); /* handle */
RemoveCustomer(hContainer, /* Remove record from */
pCRec); /* container */
}
return((MRESULT)TRUE); /* Return TRUE */
break;
ΓòÉΓòÉΓòÉ 6.68. Menu Bar Resource Definition ΓòÉΓòÉΓòÉ
MENU MAIN PRELOAD
BEGIN
SUBMENU "~File", MI_FILE, MIS_TEXT
BEGIN
MENUITEM "~New...", MI_NEW, MIS_TEXT
MENUITEM "~Open", MI_OPEN, MIS_TEXT
MENUITEM "~Save", MI_SAVE, MIS_TEXT
MENUITEM "Save ~as", MI_SAVEAS, MIS_TEXT
END
SUBMENU "~Edit", MI_EDIT, MIS_TEXT
BEGIN
MENUITEM "Cu~t", MI_CUT, MIS_TEXT
MENUITEM "~Copy", MI_COPY, MIS_TEXT
MENUITEM "~Paste", MI_PASTE, MIS_TEXT
END
SUBMENU "~Window", MI_WINDOW, MIS_TEXT
BEGIN
MENUITEM "~Tile", MI_TILE, MIS_TEXT
MENUITEM "~Cascade", MI_CASC, MIS_TEXT
END
MENUITEM "E~xit", MI_EXIT, MIS_TEXT
MENUITEM "~Help", MI_HELP, MIS_HELP |
MIS_BUTTONSEPARATOR
END
ΓòÉΓòÉΓòÉ 6.69. String Table Resource Definition ΓòÉΓòÉΓòÉ
STRINGTABLE MAIN PRELOAD
BEGIN
STR_MAINTITLE, "Application Main Window"
STR_LIST1, "List of Objects"
STR_MSGTITLE1, "Title for Message Box"
END
ΓòÉΓòÉΓòÉ 6.70. Loading a Text String Resource ΓòÉΓòÉΓòÉ
ulLength = WinLoadString(hAB, /* Load string */
NULL, /* From appl resource file */
STR_MAINTITLE, /* String id in resource */
sizeof(szTitle), /* Number of characters */
szTitle); /* Target buffer */
ΓòÉΓòÉΓòÉ 6.71. Accelerator Table Resource Definition ΓòÉΓòÉΓòÉ
ACCELTABLE CHILD1
BEGIN
VK_F3, MI_EXIT, VIRTUALKEY
VK_F5, MI_TILE, VIRTUALKEY, SHIFT
"D", MI_DELETE, CHAR, CONTROL
END
ΓòÉΓòÉΓòÉ 6.72. Window Template Resource Definition ΓòÉΓòÉΓòÉ
WINDOWTEMPLATE WCP_0001
BEGIN
FRAME "Window Class X", 1, 10, 10, 320, 130
CTLDATA FCF_STANDARD
BEGIN
WINDOW "", FID_CLIENT, 0,0,0,0, "MyClass", 01
END
END
ΓòÉΓòÉΓòÉ 6.73. Dialog Template Resource Definition ΓòÉΓòÉΓòÉ
DLGTEMPLATE DC_CREATE
BEGIN
DIALOG "Create an Object", DC_CREATE, 22, 32, 260, 76,,
FCF_TITLEBAR | FCF_DLGBORDER
BEGIN
CONTROL "Enter the Object Name", -1, 7, 59, 246, 8, WC_STATIC,
SS_TEXT | DT_CENTER | DT_TOP | WS_GROUP | WS_VISIBLE
CONTROL "", 91, 43, 149, 8, WC_ENTRYFIELD,
ES_MARGIN | ES_LEFT | WS_TABSTOP | WS_VISIBLE
CONTROL "Enter", DID_OK, 38, 5, 38, 12, WC_BUTTON,
BS_PUSHBUTTON | BS_DEFAULT | WC_TABSTOP | WC_VISIBLE
CONTROL "Cancel", DID_CANCEL, 38, 5, 38, 12, WC_BUTTON,
BS_PUSHBUTTON | WC_TABSTOP | WC_VISIBLE
END
END
ΓòÉΓòÉΓòÉ 6.74. Resource Script File ΓòÉΓòÉΓòÉ
#include <os2.h>
#include "myappl.h"
#include "mydlg.h"
ICON MAIN APPLIC.ICO
ICON CHILD1 CHILD1.ICO
BITMAP INTRO LOGO.BMP
STRINGTABLE MAIN PRELOAD
BEGIN
STR_MAINTITLE, "Application Main Window"
STR_LIST1, "List of Objects"
STR_MSGTITLE1, "Title for Message Box"
END
MENU MAIN PRELOAD
BEGIN
SUBMENU "~File", MI_FILE, MIS_TEXT
BEGIN
MENUITEM "~New...", MI_NEW, MIS_TEXT
MENUITEM "~Open", MI_OPEN, MIS_TEXT
MENUITEM "~Save", MI_SAVE, MIS_TEXT
MENUITEM "Save ~as", MI_SAVEAS, MIS_TEXT
END
SUBMENU "~Edit", MI_EDIT, MIS_TEXT
BEGIN
MENUITEM "Cu~t", MI_CUT, MIS_TEXT
MENUITEM "~Copy", MI_COPY, MIS_TEXT
MENUITEM "~Paste", MI_PASTE, MIS_TEXT
END
MENUITEM "E~xit", MI_EXIT, MIS_TEXT
MENUITEM "~Help", MI_HELP, MIS_HELP |
MIS_BUTTONSEPARATOR
END
ACCELTABLE MAIN
BEGIN
VK_F3, MI_EXIT, VIRTUALKEY
VK_F5, MI_TILE, VIRTUALKEY, SHIFT
"D", MI_DELETE, CHAR, CONTROL
END
ACCELTABLE CHILD1
BEGIN
VK_F1, MI_HELP, VIRTUALKEY, HELP
VK_F3, MI_EXIT, VIRTUALKEY
"D", MI_DELETE, CHAR, CONTROL
END
rcinclude MYDLG.DLG
ΓòÉΓòÉΓòÉ 6.75. Loading Resources From a DLL ΓòÉΓòÉΓòÉ
rc = DosLoadModule(NULL, /* No object name */
0, /* No object length */
"MYDLL", /* DLL module name */
hModule); /* DLL handle (returned) */
ulLength = WinLoadString(hAB, /* Load string */
hModule, /* DLL module handle */
STR_TITLE, /* Resource ID within DLL */
sizeof(szTitle), /* Number of bytes */
szTitle); /* Target buffer */
ΓòÉΓòÉΓòÉ 6.76. Loading a Dialog Resource From a DLL ΓòÉΓòÉΓòÉ
BOOL CustInfoDialog()
{
HMODULE hModule; /* DLL module handle */
PFNWP dpDlgProc; /* Dialog procedure addr */
USHORT usResult; /* Result storage */
DosGetModuleHandle("WINDLL", /* Get DLL module handle */
hModule);
DosGetProcAddr(hModule, /* Get address of dialog */
"dpCustDlg", /* procedure */
dpDlgProc);
rc = WinDlgBox(HWND_DESKTOP, /* Load & process dialog */
NULL, /* No owner */
dpDlgProc, /* Dialog procedure addr */
hModule, /* DLL module handle */
DC_CUSTDLG, /* Dialog template id */
NULL); /* No create parameters */
return(usResult);
}
ΓòÉΓòÉΓòÉ 6.77. Creating a Thread With an Object Window ΓòÉΓòÉΓòÉ
#define STACKSIZE 8192
:
:
case WMP_DOLONGTASK:
_beginthread(thread, /* Entry point of thread routine */
&Stack, /* Pointer to stack memory object */
STACKSIZE, /* Size of stack memory object */
(PVOID)hwnd); /* Initialization data for thread */
break;
ΓòÉΓòÉΓòÉ 6.78. Secondary Thread Creating an Object Window ΓòÉΓòÉΓòÉ
void thread(HWND hWnd)
{
HMQ hMsgQ; /* Message queue handle */
HWND hWindow; /* Window handles */
QMSG qMsg; /* Message queue structure */
WinRegisterClass(hAB, /* Register window class */
WCP_OBJECT, /* Class name */
(PFNWP)wpObject, /* Window procedure */
0L, /* No class style */
0); /* No extra window words */
hObject=WinCreateWindow(HWND_OBJECT, /* Create object window */
WCP_OBJECT, /* Object handle is parent */
(PSZ)0, /* No window text */
0L, /* No style */
0,0,0,0, /* No position */
NULL, /* No owner */
HWND_TOP, /* On top of siblings */
0, /* No window id */
hWnd, /* Handle in WM_CREATE */
0); /* No pres. parameters */
while (WinGetMsg(hAB, /* Loop until WM_QUIT */
&qMsg,
(ULONG)0,
0, 0))
WinDispatchMsg(hAB, &qMsg);
WinDestroyWindow(hObject); /* Destroy object window */
WinDestroyMsgQueue(hMsgQ); /* Destroy message queue */
_endthread(); /* Terminate thread */
}
ΓòÉΓòÉΓòÉ 6.79. Sample Object Window Procedure ΓòÉΓòÉΓòÉ
MRESULT EXPENTRY wpObject(HWND hWnd,
ULONG ulMsg,
MPARAM mp1,
MPARAM mp2)
{
HWND hNotify;
HWND hObject;
switch (ulMsg)
{
case WM_CREATE:
WinDefWindowProc(hWnd,
usMsg,
mp1,
mp2);
<initialize instance data>
<open data objects>
hNotify=HWNDFROMMP(mp1);
hObject=MPFROMHWND(hWnd);
WinPostMsg(hNotify,
WMP_NOTIFY,
hObject,
0);
return((MRESULT)FALSE);
break;
case WMP_PUTDATA:
<put data into database>
<post message to logging object>
return((MRESULT)TRUE);
break;
case WMP_GETDATA:
<get data from database>
<post data to caller in message>
return((MRESULT)TRUE);
break;
case WM_DESTROY:
<close data objects>
<free any instance data areas>
return((MRESULT)0);
break;
default:
return(WinDefWindowProc(hWnd,
ulMsg,
mp1,
mp2));
}
}
ΓòÉΓòÉΓòÉ 6.80. Creating a Thread Without an Object Window ΓòÉΓòÉΓòÉ
case WMP_THREAD:
usReturn=DosCreateThread(ThreadID, /* Create thread */
ThreadRoutine, /* Routine to run in thread */
&InitData, /* Initialization data */
0L, /* Start immediately */
4096); /* Stack size for thread */
break;
ΓòÉΓòÉΓòÉ 6.81. Starting a Child Process ΓòÉΓòÉΓòÉ
CHAR szClient[7]; /* ASCII form of win handle */
CHAR LoadError[100]; /* Buffer for failure reason */
RESULTCODES ReturnInfo; /* Returned info from call */
PID pidServer; /* Child process id */
APIRET rc; /* Return code */
:
:
itoa(hWnd, szClient); /* Convert handle to ASCII */
rc = DosExecPgm(LoadError, /* Start child process */
sizeof(LoadError), /* Size of buffer */
EXEC_ASYNCRESULT, /* Execute asynchronously */
szClient, /* Window handle in ASCII */
0, /* No new environment vars */
&ReturnInfo, /* Returned info address */
"server.exe"); /* Name of program to start */
pidServer = ReturnCodes.termcodepid;
<Store pidServer in window words>
This example shows the use of the DosExecPgm() function to start a process from
another process within the application.
ΓòÉΓòÉΓòÉ 6.82. DosKillThread() Function ΓòÉΓòÉΓòÉ
<Retreive thread id from window words>
usReturn = DosKillThread(ThreadID); /* Destroy secondary thread */
This function allows the forced termination of a thread.
ΓòÉΓòÉΓòÉ 6.83. Terminating a Process ΓòÉΓòÉΓòÉ
<Retrieve process id from window words>
rc = DosKillProcess(1, /* Kill only this process */
pidServer); /* Process ID to be killed */
This example shows the use of the DosKillProcess() function to terminate a
single process.
ΓòÉΓòÉΓòÉ 6.84. Interprocess Communication Using Shared Memory (Part 1) ΓòÉΓòÉΓòÉ
REQUEST *Request; /* Request structure */
REPLY *Reply; /* Reply structure ptr */
:
CASE WMP_SENDREQUEST:
rc = DosAllocShrMem(&Request, /* Allocate memory obj */
NULL, /* Anonymous memory obj */
sizeof(REQUEST), /* Size of memory obj */
OBJ_GIVEABLE, /* Object is giveable */
PAG_WRITE | /* Allow write access */
PAG_READ | /* Allow read access */
PAG_COMMIT); /* Commit storage now */
rc = DosGiveSharedMem(Request, /* Give access to object */
pidServer, /* Process to get access */
PAG_WRITE | /* Write access allowed */
PAG_READ); /* Read access allowed */
rc = DosAllocShrMem(&Reply, /* Allocate memory obj */
NULL, /* Anonymous memory obj */
sizeof(REPLY), /* Size of memory obj */
OBJ_GIVEABLE, /* Object is giveable */
PAG_WRITE | /* Allow write access */
PAG_READ | /* Allow read access */
PAG_COMMIT); /* Commit storage now */
rc = DosGiveSharedMem(Reply, /* Give access to object */
pidServer, /* Process to get access */
PAG_WRITE | /* Write access allowed */
PAG_READ); /* Read access allowed */
Request->hRequester = hWnd; /* Set requester handle */
<Initialize other Request structure fields>
WinPostMsg(hServer, /* Post msg to server */
WMP_DOREQUEST, /* DO_REQUEST message */
(MPARAM)Request, /* Ptr to request object */
(MPARAM)Reply); /* Ptr to reply object */
DosFreeMem(Request); /* Release request obj */
break;
:
case WMP_REQUESTCOMPLETE:
Reply=(PVOID)mp1;
<Copy contents of Reply to private memory>
DosFreeMem(Reply); /* Release reply object */
break;
This example shows a "requester" window procedure issuing requests and
receiving replies by way of Presentation Manager messages.
ΓòÉΓòÉΓòÉ 6.85. Interprocess Communication Using Shared Memory (Part 2) ΓòÉΓòÉΓòÉ
CASE WMP_DOREQUEST:
Request = (REQUEST *)mp1; /* Get memory obj ptrs */
Reply = (REPLY *)mp2;
DosGetSharedMem(&Request, /* Obtain access to obj */
PAG_READ); /* Allow read access */
DosGetSharedMem(&Reply, /* Obtain access to obj */
PAG_WRITE | /* Allow write access */
PAG_READ); /* Allow read access */
ServiceRequest(Request,Reply); /* Complete request */
WinPostMsg(Request->hRequester, /* Post msg to requester */
WMP_REQUESTCOMPLETE, /* Message class */
(MPARAM)Reply, /* Ptr to reply struct */
(MPARAM)0);
DosFreeMem(Request); /* Free request object */
DosFreeMem(Reply); /* Free reply object */
break;
This example shows a "server" window procedure receiving and processing
Presentation Manager messages.
ΓòÉΓòÉΓòÉ 6.86. Interprocess Communication Using Atoms (Part 1) ΓòÉΓòÉΓòÉ
CASE WMP_SENDREQUEST:
hSysAtomTable = WinQuerySystemAtomTable(); /* Get atom table handle */
ReqAtom = WinAddAtom(hSysAtomTable, /* Add string to table */
szRequest); /* String to be added */
WinPostMsg(hServer, /* Post msg to server */
WMP_DOREQUEST, /* DO_REQUEST message */
(MPARAM)ReqAtom, /* Atom to access string */
(MPARAM)hWnd); /* Return window handle */
<Store ReqAtom in window words>
return((MRESULT)0); /* Return zero */
break;
:
:
case WMP_REQUESTCOMPLETE:
hSysAtomTable = WinQuerySystemAtomTable(); /* Get atom table handle */
ReplyAtom = (ATOM)mp1; /* Get atom for reply */
WinQueryAtomName(hSysAtomTable, /* Get string from atom */
ReplyAtom, /* Atom */
szReply, /* Buffer for string */
sizeof(szReply)); /* Size of buffer */
<Verify reply is correct>
WinDeleteAtom(hSysAtomTable, /* Delete atoms */
ReqAtom);
WinDeleteAtom(hSysAtomTable,
ReplyAtom);
return(TRUE);
break;
This example shows a "requester" window procedure issuing requests and
receiving replies by way of Presentation Manager messages.
ΓòÉΓòÉΓòÉ 6.87. Interprocess Communication Using Atoms (Part 2) ΓòÉΓòÉΓòÉ
CASE WMP_DOREQUEST:
hAtomTable = WinQuerySystemAtomTable(); /* Get atom table handle */
ReqAtom = (ATOM)mp1; /* Get atom for request */
hRequester = (HWND)mp2; /* Get requester handle */
ulLength = WinQueryAtomLength(hAtomTable, /* Get size of string */
ReqAtom);
szRequest = malloc(ulLength); /* Allocate buffer */
WinQueryAtomName(hSysAtomTable, /* Get string from atom */
ReqAtom, /* Atom */
szRequest, /* Buffer for string */
sizeof(szRequest)); /* Size of buffer */
ServiceRequest(szRequest,szReply); /* Complete request */
ReplyAtom = WinAddAtom(hSysAtomTable, /* Add string to table */
szReply); /* String to be added */
WinPostMsg(hRequester, /* Post msg to requester */
WMP_REQUESTCOMPLETE, /* Message class */
(MPARAM)ReplyAtom, /* Atom to access string */
(MPARAM)0); /* Return window handle */
free(szRequest); /* Free request buffer */
return((MRESULT)0); /* Return zero */
break;
This example shows a "server" window procedure receiving and processing
Presentation Manager messages.
ΓòÉΓòÉΓòÉ 6.88. Interprocess Communication Using Queues (Part 1) ΓòÉΓòÉΓòÉ
#define SRVQUEUENAME = "\\QUEUES\\SRV_QUEUE" /* Server queue name */
#define REQQUEUENAME = "\\QUEUES\\REQ_QUEUE" /* Requester queue name */
HQUEUE hReqQueue, hSrvQueue; /* Queue handles */
REQUESTDATA Server; /* Control information */
REQUEST *Request; /* Request data buffer */
REPLY *Reply; /* Reply data buffer */
BYTE Priority; /* Priority information */
ULONG ulBytes; /* Bytes read/written */
APIRET rc; /* Return code */
case WMP_SENDREQUEST:
rc = DosCreateQueue(&hReqQueue, /* Create req queue */
QUE_FIFO | /* First-in, first-out */
QUE_CONVERT_ADDRESS, /* Convert addresses */
REQQUEUENAME); /* Name of queue */
rc = DosOpenQueue(&pidServer, /* Open srv queue */
&hSrvQueue, /* Queue handle */
SRVQUEUENAME); /* Server queue name */
rc = DosAllocSharedMem(&Request, /* Allocate shared mem */
NULL, /* object for request */
sizeof(REQUEST), /* Size of memory object */
PAG_WRITE | /* Allow write access */
PAG_READ | /* Allow read access */
PAG_COMMIT); /* Commit storage now */
rc = DosGiveSharedMem(Request, /* Give mem to server */
pidServer, /* Server process id */
PAG_READ); /* Allow read only */
rc = DosWriteQueue(hSrvQueue, /* Add request to queue */
(ULONG)hWnd, /* Requester win handle */
sizeof(REQUEST), /* Size of request */
Request, /* Request buffer */
0); /* No priority */
rc = DosCloseQueue(hSrvQueue); /* Close srv queue */
DosFreeMem(Request); /* Free request buffer */
break;
This example shows elements being added to a queue by a "requester" process.
ΓòÉΓòÉΓòÉ 6.89. Interprocess Communication Using Queues (Part 2) ΓòÉΓòÉΓòÉ
#define SRVQUEUENAME = "\\QUEUES\\SRV_QUEUE" /* Server queue name */
#define REQQUEUENAME = "\\QUEUES\\REQ_QUEUE" /* Requester queue name */
HQUEUE hSrvQueue, hReqQueue; /* Queue handles */
REQUESTDATA Requester; /* Requester win handle */
REQUEST *Request; /* Request data buffer */
REPLY *Reply; /* Reply data buffer */
BYTE Priority; /* Element priority */
ULONG ulBytes; /* Bytes read/written */
APIRET rc; /* Return code */
rc = DosCreateQueue(&hSrvQueue, /* Create queue */
QUE_FIFO | /* First-in, first-out */
QUE_CONVERT_ADDRESS, /* Convert addresses */
SRVQUEUENAME); /* Name of queue */
while (!ProcessEnded) /* Until process ends */
{
rc = DosReadQueue(hSrvQueue, /* Read queue */
&Requester, /* Control information */
&ulBytes, /* Bytes read */
&Request, /* Data buffer pointer */
0, /* Get first element */
DCWW_WAIT, /* Wait synchronously */
&Priority, /* Priority of element */
0); /* No event semaphore */
ServiceRequest(Request); /* Process request */
rc = DosOpenQueue(&Requester.idpid, /* Open queue */
&hReqQueue, /* Queue handle */
REQQUEUENAME); /* Server queue name */
rc = DosAllocSharedMem(&Reply, /* Allocate shared mem */
NULL, /* object for request */
sizeof(REPLY), /* Size of memory object */
PAG_WRITE | /* Allow write access */
PAG_READ | /* Allow read access */
PAG_COMMIT); /* Commit storage now */
rc = DosGiveSharedMem(Reply, /* Give mem to requester */
&Requester.idpid, /* Req process id */
PAG_READ); /* Allow read only */
rc = DosWriteQueue(hReqQueue, /* Add request to queue */
0L, /* No control info */
sizeof(REPLY), /* Size of reply */
Reply, /* Reply buffer */
0); /* No priority */
rc = DosCloseQueue(hReqQueue); /* Close queue */
DosFreeMem(Request); /* Free request buffer */
WinPostMsg((HWND)Requester.ulData, /* Post notification msg */
WMP_REQUESTCOMPLETE, /* to requester window */
(MPARAM)Reply, /* Reply buffer pointer */
0);
DosFreeMem(Reply); /* Free reply buffer */
}
This example shows the creation of a queue and the processing of items from the
queue by a "server" process.
ΓòÉΓòÉΓòÉ 6.90. Interprocess Communication Using Queues (Part 3) ΓòÉΓòÉΓòÉ
case WMP_REQUESTCOMPLETE:
rc = DosReadQueue(hReqQueue, /* Read req queue */
&Server, /* Control information */
&ulBytes, /* Bytes read */
&Reply, /* Data buffer pointer */
0, /* Get first element */
DCWW_WAIT, /* Wait synchronously */
&Priority, /* Priority of element */
0); /* No event semaphore */
< Process reply>
DosFreeMem(Reply);
break;
This example shows returned data being read from a queue by a "requester"
process.
ΓòÉΓòÉΓòÉ 6.91. Interprocess Communication Using Named Pipes (Part 1) ΓòÉΓòÉΓòÉ
#define NPIPE_NAME "\\PIPE\\SRVPIPE" /* Pipe name */
void RequestThread(TRANS *Trans) /* Requester thread */
{
ULONG ulBytes; /* Bytes read/written */
APIRET rc; /* Return code */
rc = DosWaitNPipe(NPIPE_NAME, /* Wait on named pipe */
NP_WAIT_INDEFINITELY); /* Wait indefinitely */
rc = DosCallNPipe(NPIPE_NAME, /* Pipe name */
Trans->Request, /* Request buffer ptr */
sizeof(REQUEST), /* Size of buffer */
Trans->Reply, /* Reply buffer ptr */
sizeof(REPLY), /* Size of buffer */
&ulBytes, /* No. of bytes read */
10000); /* Timeout period */
WinPostMsg(Trans->hReturn, /* Notify calling window */
WMP_REQUESTCOMPLETE, /* Request is complete */
(MPARAM)Trans, /* Transaction structure */
0);
DosExit(0);
}
This example shows a secondary thread in a "requester" process, writing to and
reading from a named pipe.
ΓòÉΓòÉΓòÉ 6.92. Interprocess Communication Using Named Pipes (Part 2) ΓòÉΓòÉΓòÉ
#define NPIPE_NAME "\\PIPE\\SRVPIPE" /* Pipe name */
HFILE hPipe; /* Pipe handle */
REQUEST *Request; /* Request buffer */
REPLY *Reply; /* Reply buffer */
ULONG ulAction; /* Open action */
ULONG ulBytes; /* Bytes read/written */
APIRET rc; /* Return code */
rc = DosCreateNPipe(NPIPE_NAME, /* Create named pipe */
&hPipe, /* Pipe handle */
NP_ACCESS_DUPLEX, /* Allow duplex access */
NP_WAIT | /* Blocking mode */
NP_TYPE_MESSAGE | /* Msg oriented pipe */
NP_READMODE_MESSAGE, /* Msg oriented read */
0x01, /* Single instance only */
sizeof(REPLY), /* Outbound buffer size */
sizeof(REQUEST), /* Inbound buffer size */
0); /* Default timeout value */
while (!ProcessEnded) /* Until process ends */
{
rc = DosConnectNPipe(hPipe); /* Connect to requester */
rc = DosRead(hPipe, /* Read request */
Request, /* Request buffer */
sizeof(REQUEST), /* Size of buffer */
&ulBytes); /* No. of bytes read */
ServiceRequest(Request, Reply); /* Complete request */
rc = DosWrite(hPipe, /* Write reply to pipe */
Reply, /* Reply buffer */
sizeof(REPLY), /* Size of buffer */
&ulBytes); /* No. of bytes written */
rc = DosDisConnectNPipe(hPipe); /* Disconnect from req */
}
This example shows a "server" process creating and reading from a duplex named
pipe.
ΓòÉΓòÉΓòÉ 6.93. Synchronization Using Presentation Manager Messages ΓòÉΓòÉΓòÉ
:
case WMP_THREAD: /* Start secondary thread */
DosCreateThread(ThreadID, /* Thread ID */
Thread, /* Entry point for thread */
(PVOID)hwnd, /* Invoking window handle */
0L, /* Start immediately */
4096); /* Stack size for thread */
break;
case WMP_ENDOFTHREAD: /* Thread has completed */
<perform end-of-thread processing>
break;
:
:
int cdecl thread(hReturn) /* Thread routine */
HWND hReturn; /* Handle of calling window */
{
<Perform lengthy processing task>
WinPostMsg(hReturn, /* Post message to caller */
WMP_ENDOFTHREAD, /* Message class */
0,0); /* No parameters */
DosExit(EXIT_THREAD, /* Terminate thread */
0L);
}
ΓòÉΓòÉΓòÉ 6.94. Synchronization Using an Event Semaphore (Part 1) ΓòÉΓòÉΓòÉ
int cdecl thread()
{
ulResult = DosCreateEventSem("\SEM32\THREAD", /* Name of semaphore */
hSem, /* Semaphore handle */
NULL, /* Not used */
FALSE); /* Set immediately */
<Perform lengthy processing task>
usResult = DosPostEventSem(hSem); /* Release semaphore */
DosExit(0); /* Terminate thread */
}
This example shows the routine executing in the secondary thread.
ΓòÉΓòÉΓòÉ 6.95. Synchronization Using an Event Semaphore (Part 2) ΓòÉΓòÉΓòÉ
case WMP_THREAD:
usReturn = DosCreateThread(ThreadID, /* Create thread */
Thread, /* Entry point for thread */
NULL, /* No initialization data */
0L, /* Start immediately */
4096); /* Stack size for thread */
WinStartTimer(hAB, /* Start timer */
hwnd, /* Window to get WM_TIMER */
TID_THREAD, /* ID of timer */
500); /* Period in milliseconds */
break;
:
case WM_TIMER:
ulResult=DosOpenEventSem("\SEM32\THREAD", /* Get semaphore handle */
hSem); /* Semaphore handle */
ulResult=DosWaitEventSem(hSem, /* Check semaphore state */
0); /* Immediate timeout */
if (ulResult!=ERROR_TIMEOUT) /* Semaphore not set */
{
<perform end-of-thread processing> /* Thread has completed */
}
ulResult=DosCloseEventSem(hSem); /* Close semaphore */
break;
This example shows the window procedure in the primary thread, periodically
testing to determine whether the event semaphore has been released.
ΓòÉΓòÉΓòÉ 6.96. Synchronization Using the DosWaitThread() Function (Part 1) ΓòÉΓòÉΓòÉ
int cdecl thread()
{
<Perform lengthy processing task>
DosExit(EXIT_THREAD, /* Terminate thread */
0L); /* Return code */
}
This example shows the routine executing in the secondary thread.
ΓòÉΓòÉΓòÉ 6.97. Synchronization Using the DosWaitThread() Function (Part 2) ΓòÉΓòÉΓòÉ
case WMP_THREAD:
usReturn = DosCreateThread(ThreadID, /* Create thread */
Thread, /* Entry point for thread */
NULL, /* No initialization data */
0L, /* Start immediately */
4096); /* Stack size for thread */
<Store ThreadID in instance data block>
WinStartTimer(hAB, /* Start timer */
hwnd, /* Window to get WM_TIMER */
TID_THREAD, /* ID of timer */
50); /* Period in milliseconds */
break;
:
case WM_TIMER:
<Get ThreadID from instance data block>
ulReturn=DosWaitThread(ThreadID, /* Check thread status */
DCWW_NOWAIT); /* Immediate timeout */
if (ulReturn==ERROR_THREAD_NOT_TERMINATED) /* Thread still running */
break; /* Continue waiting */
else /* else */
<perform end-of-thread processing> /* Thread has completed */
break;
This example shows the window procedure in the primary thread, periodically
testing to determine whether the secondary thread has terminated.
ΓòÉΓòÉΓòÉ 6.98. DosWaitChild() Function ΓòÉΓòÉΓòÉ
rc = DosWaitChild(DCWA_PROCESS, /* Wait for this process only */
DCWW_WAIT, /* Wait until termination */
&ReturnInfo, /* Returned info */
&pidServer, /* Returned process ID */
pidServer); /* Process id to wait on */
This example assumes that the DosExecPgm() call shown in Figure "Starting a
Child Process" has already been executed.
ΓòÉΓòÉΓòÉ 6.99. Dynamically Inserting a Menu Bar Item ΓòÉΓòÉΓòÉ
hFrame = WinQueryWindow(hwnd, /* Current Window */
QW_PARENT); /* Parent */
hMenu = WinWindowFromID(hFrame, /* Get handle of */
FID_MENU); /* menu bar */
MenuItem.iPosition = MIT_END; /* Item position */
MenuItem.afStyle = MIS_TEXT; /* Item style */
MenuItem.afAttribute = 0; /* No attributes */
MenuItem.id = MI_OPENOBJECT; /* Item identifier */
MenuItem.hItem = 0; /* No handle */
MenuItem.hwndSubmenu = 0; /* No p'down handle */
rc = WinSendDlgItemMsg(hMenu, /* Send message */
MI_FILE, /* to File pulldown */
MM_INSERTITEM, /* Message class */
&MenuItem, /* Pointer to item */
szItemText); /* Text of menu item */
ΓòÉΓòÉΓòÉ 6.100. Dynamically Inserting a Pulldown Menu ΓòÉΓòÉΓòÉ
HWND hPulldown;
:
hPulldown = WinCreateMenu(hFrame, /* Create empty menu */
NULL); /* template */
MenuItem.iPosition = MIT_END; /* Item position */
MenuItem.afStyle = MIS_TEXT; /* Item style */
MenuItem.afAttribute = 0; /* No attributes */
MenuItem.id = MN_OPENOBJECT; /* Item identifier */
MenuItem.hItem = 0; /* No handle */
MenuItem.hwndSubmenu = hPulldown; /* No p'down handle */
rc = WinSendDlgItemMsg(hMenu, /* Send message */
MN_FILE, /* to File pulldown */
MM_INSERTITEM, /* Message class */
&MenuItem, /* Pointer to item */
szItemText); /* Text of menu item */
ΓòÉΓòÉΓòÉ 6.101. Disabling an Menu Bar/Pulldown Menu Item ΓòÉΓòÉΓòÉ
hMenu = WinWindowFromID(hFrame, /* Get menu bar handle */
FID_MENU);
rc = WinEnableMenuItem(hMenu, /* Menu bar handle */
MI_VIEW, /* Menu item identifier */
TRUE); /* Enable menu item */
ΓòÉΓòÉΓòÉ 6.102. Placing a Check Mark on a Pulldown Menu Item ΓòÉΓòÉΓòÉ
hMenu = WinWindowFromID(hFrame, /* Get menu bar handle */
FID_MENU);
rc = WinCheckMenuItem(hMenu, /* Menu bar handle */
MI_OPTION1, /* Menu item identifier */
TRUE); /* Set check mark */
ΓòÉΓòÉΓòÉ 6.103. Standard Dialogs - WinFileDlg() Function ΓòÉΓòÉΓòÉ
USHORT OpenFile(HWND hOwner)
{
extern PFNWP WinFileDlg(); /* Function prototype */
extern FILEDLG fild; /* File dlg control structure */
extern HFILE hFileToOpen; /* File handle */
extern USHORT usAction; /* Action indicator */
static BOOL fFirstTime = TRUE; /* Flag */
USHORT usReturn; /* Return code */
if (fFirstTime) /* If invoked for first time */
{ /* build control structure */
fild.cbSize = sizeof(FILEDLG); /* Set size of control struct */
fild.fl = FDS_OPEN_DIALOG | /* Set dialog type to "Open" */
FDS_CENTER | /* Centered in parent window */
FDS_HELP_BUTTON; /* Include help button */
fild.pszTitle = NULL; /* Use default title bar text */
fild.pszOKButton = NULL; /* Use default button text */
fild.pfnDlgProc = NULL; /* Use standard dlg proc */
fild.hmod = NULL; /* " " " " */
fild.idDlg = 0; /* " " " " */
fild.pszIType = NULL; /* No initial type setting */
fild.ppszITypeList = NULL; /* No list of types */
fild.pszIDrive = NULL; /* No initial drive setting */
fild.ppszIDriveList = NULL; /* No list of drivers */
fFirstTime = FALSE; /* Set flag to false */
}
WinFileDlg(hOwner, /* Invoke file dialog */
&fild); /* Control structure pointer */
rc = DosOpen(fild.szFullFile, /* Open returned file name */
&hFileToOpen, /* File handle */
&usAction, /* Action indicator */
0L, /* File size not applicable */
0, /* File attribute ignored */
0x0001, /* Open file if it exists */
0x00C2, /* Non-shared, read-write */
0L); /* No sharing mode */
return(rc); /* Return */
}
ΓòÉΓòÉΓòÉ 6.104. WinFontDlg() Function - Sample Code ΓòÉΓòÉΓòÉ
void SetFont(HWND hOwner, HPS hpsScreen, USHORT usCodePage)
{
extern PFNWP WinFontDlg(); /* Function prototype */
extern FONTDLG fntd; /* Dialog control struct */
static BOOL fFirstTime = TRUE; /* Flag */
CHARBUNDLE cbnd; /* Attributes */
if (FirstTime) /* If invoked for 1st time */
{ /* build control structure */
fntd.cbSize = sizeof(FONTDLG); /* Set size of structure */
fntd.fl = FNTS_CENTER | /* Specify centered dlg */
FNTS_HELPBUTTON; /* Include help button */
fntd.hpsPrinter = NULL; /* No printer font */
fntd.pszTitle = "Fonts"; /* Dialog title text */
fntd.pfnDlgProc = NULL; /* Use standard dlg proc */
fntd.hmod = NULL; /* " " " " */
fntd.idDlg = 0; /* " " " " */
fntd.pszPreview = NULL /* Default preview string */
fntd.pszPtSizeList = NULL; /* Default point sizes */
fntd.flFlags = 0L; /* Default flags */
fntd.szFamilyname[] = '\0'; /* System default */
fntd.fxPointSize = MAKEFIXED(12,0); /* 12-point vertical size */
fntd.usWeight = FWEIGHT_NORMAL; /* Weight or thickness */
fntd.usWidth = FWIDTH_NORMAL; /* Character width */
fntd.flType = 0L; /* No additional attribs */
fntd.flStyle = 0L; /* No additional styles */
fntd.flCHSOptions = 0L; /* No additional options */
fntd.clrFore = CLR_BLACK; /* Black characters */
fntd.clrBack = CLR_WHITE; /* White background */
fntd.fAttrs.usCodePage = usCodePage; /* Specified code page */
fFirstTime=FALSE; /* Reset flag */
}
fntd.hpsScreen=hpsScreen; /* Set presentation space */
WinFontDlg(hOwner, /* Invoke font dialog */
&fntd); /* Control structure ptr */
GpiCreateLogFront(hpsScreen, /* Create logical font */
"Name ", /* Name of font */
0, /* Local font identifier */
fntd.fAttrs); /* Returned attributes */
cbnd.lColor = fntd.clrFore; /* Set foreground color */
cbnd.lBackColor = fntd.clrBack; /* Set background color */
GpiSetAttrs(hpsScreen, /* Set attributes */
PRIM_CHAR, /* Character attributes */
CBB_COLOR | CBB_BACK_COLOR, /* Attributes to be set */
0L, /* Defaults mask */
(PBUNDLE)&cbnd); /* Attribute structure */
GpiCharStringPos(hpsScreen, /* Write character string */
NULL, /* No rectangle */
fntd.flCHSOptions, /* Options */
4, /* Number of bytes */
"Text", /* Text string */
NULL); /* Increment values */
}
ΓòÉΓòÉΓòÉ 6.105. DosCreateThread() Function ΓòÉΓòÉΓòÉ
APIRET rc; /* Return code */
PTID ThreadID; /* Thread identifier */
MYSTRUCT *ParmBlock; /* Initialization data */
rc = DosCreateThread(ThreadID, /* Create thread */
Thread, /* Entry point for thread */
ParmBlock, /* Parameters for thread */
0L, /* Start immediately */
8192); /* Stack size for thread */
This example shows the enhanced form of this function as implemented under OS/2
Version 2.0.
ΓòÉΓòÉΓòÉ 6.106. DosAllocMem() Function ΓòÉΓòÉΓòÉ
APIRET rc; /* Return code */
PVOID pObject; /* Pointer to memory object */
rc = DosAllocMem(&pObject, /* Allocate memory object */
73727, /* Size of memory object */
PAG_COMMIT | /* Commit memory immediately */
PAG_READ | /* Allow read access */
PAG_WRITE); /* Allow write access */
This function replaces the DosAllocSeg() function implemented in previous
versions of OS/2.
ΓòÉΓòÉΓòÉ 6.107. Declaring a 16-Bit Function in 32-Bit Code ΓòÉΓòÉΓòÉ
#pragma stack16(8192)
USHORT MyFunction(USHORT FirstNum, HWND _Seg16 hWnd);
#pragma linkage (MyFunction, far16 pascal)
ΓòÉΓòÉΓòÉ 6.108. Creating a 16-bit Window From Within a 32-bit Module ΓòÉΓòÉΓòÉ
32-bit Module
#pragma stack16(8192)
HWND MakeMyWindow(void); /* 16-bit function prototype */
#pragma linkage (MakeMyWindow, far16 pascal)
HWND _Seg16 hWindow; /* 16:16 window handle */
:
:
hWindow = MakeMyWindow(); /* Call registration routine */
16-bit Module
HWND EXPENTRY MakeMyWindow(void) /* Registration routine */
{
HWND hCurrWindow; /* 16:16 window handle */
WinRegisterClass(...); /* Register window class */
hCurrWindow = WinCreateWindow(...); /* Create window */
return(hCurrWindow); /* Return 16:16 window handle */
}
ΓòÉΓòÉΓòÉ 6.109. Passing a 16:16 Pointer as a Message Parameter ΓòÉΓòÉΓòÉ
typedef struct mystruct { /* Define data structure */
CHAR * _Seg16 Name;
ULONG ulA;
ULONG ulB;
USHORT usC;
} MYSTRUCT;
pragma seg16(MYSTRUCT) /* Define pragma directive */
MYSTRUCT * _Seg16 MyStruct; /* 16:16 pointer */
APIRET rc; /* Return code */
MPARAM mp1; /* Message parameter */
rc = DosAllocMem(&MyStruct, /* Allocate data structure */
4096, /* Size of data structure */
PAG_READ | /* Allow read access */
PAG_WRITE | /* Allow write access */
PAG_COMMIT); /* Commit storage immediately */
<Initialize structure if required>
mp1 = MPFROMP(MyStruct); /* Set message parameter */
This example shows the 32-bit code necessary to define and initialize a 16:16
pointer to be passed to a 16-bit window procedure.
ΓòÉΓòÉΓòÉ 6.110. Mixed Model Programming - WinSetWindowThunkProc() Function ΓòÉΓòÉΓòÉ
WinSetWindowThunkProc(hWindow, /* Window handle */
(PFN)ThunkProc16to32); /* Thunk proc entry point */
ΓòÉΓòÉΓòÉ 6.111. Mixed Model Programming - Thunk Procedure ΓòÉΓòÉΓòÉ
MRESULT EXPENTRY ThunkProc16to32(HWND hwnd, /* Window handle */
ULONG ulMsg, /* Message identifier */
MPARAM mp1, /* Message parameters */
MPARAM mp2,
PFNWP wpWindow); /* Window procedure */
{
switch (ulMsg)
{
case WMP_MSG1:
mp1=DosSeltoFlat(mp1); /* Thunk parameters */
mp2=DosSeltoFlat(mp2);
break;
case WMP_MSG2:
mp1=DosSeltoFlat(mp1); /* Thunk 1st parameter */
break;
}
return((*wpWindow)(hwnd, /* Call window proc */
ulMsg,
mp1,
mp2));
}
ΓòÉΓòÉΓòÉ 6.112. 16:16 to 0:32 Address Conversion ΓòÉΓòÉΓòÉ
PVOID CRMA16to32(PVOID pPointer) /* Perform conversion */
{
USHORT usTemp; /* Temporary variable */
if (pPointer) /* If not NULL */
{
usTemp=HIUSHORT(pPointer) >> 3; /* Shift right 3 bits */
return(MAKEP(uTemp, /* Swap hi & lo words */
LOUSHORT(pPointer)));
}
else
return(NULL);
}
ΓòÉΓòÉΓòÉ 6.113. Development Process for New WPS Classes ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 6.114. Compiling and Linking an OS/2 Presentation Manager Application ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 6.115. Sample Module Definition File for Presentation Manager ΓòÉΓòÉΓòÉ
; Sample Presentation Manager Module Definition File
NAME MYPROG WINDOWAPI
DESCRIPTION 'Sample PM Application (C) IBM Corporation 1991'
PROTMODE
STUB 'OS2STUB.EXE'
STACKSIZE 8192
HEAPSIZE 1024
EXPORTS ThisWindowProc
ThatWindowProc
TheOtherWindowProc
ΓòÉΓòÉΓòÉ 6.116. Sample Module Definition File to Create a DLL ΓòÉΓòÉΓòÉ
; Sample PM Module Definition File for Creating a DLL
LIBRARY MYDLL INITINSTANCE TERMINSTANCE
DESCRIPTION 'Sample PM Dynamic Link Library (c) IBM 1991'
PROTMODE
DATA MULTIPLE
EXPORTS RoutineNumberOne
RoutineNumberTwo
RoutineNumberThree
ΓòÉΓòÉΓòÉ 6.117. IPF Tag Language Example ΓòÉΓòÉΓòÉ
:h1.Adding Online Help and Documentation
:p.In line with the philosophy of making applications easy to use
through the provision of an intuitive, graphical user interface,
it is extremely useful to have an application provide online,
context-sensitive help and tutorial facilities to the end user.
Such...
ΓòÉΓòÉΓòÉ 6.118. Simple Help Panel Source ΓòÉΓòÉΓòÉ
:h2 res=12345 x=left y=bottom cx=50% cy=25%.Help Window Heading
:p.The sequence of operations you have performed was never
envisaged by the person who wrote this program, and no help
information has been written into these panels to deal with
this contingency. You are therefore totally beyond help.
Exciting, isn't it?
ΓòÉΓòÉΓòÉ 6.119. Displaying a Bitmap in a Help Window ΓòÉΓòÉΓòÉ
:h2 res=223.Bitmap Help Example
:p.This example shows how to display a bitmap in a help window
using the :artwork tag.
:artwork name='BITMAP.BMP' align=left.
ΓòÉΓòÉΓòÉ 6.120. Hypertext Link ΓòÉΓòÉΓòÉ
:h2 res=004.Hypertext Example
:p.This example shows the use of a
:link reftype=hd res=1013.hypertext link:elink.
to display another help window when the user selects the
hypertext item.
ΓòÉΓòÉΓòÉ 6.121. Hypergraphic Link ΓòÉΓòÉΓòÉ
:h2 res=0005.Hypergraphic Example
:p.This example shows how to define hypergraphic links in a
bitmap.
:p.The first item shows a single hypergraphic link.
:artwork name='BITMAP.BMP' align=left.
:artlink.
:link reftype=hd res=0107.
:eartlink.
:p.The next item shows multiple hypergraphic links in the same
bitmap.
:artwork name='BITMAP2.BMP' align=center linkfile='BMP2'.
ΓòÉΓòÉΓòÉ 6.122. Link File With Multiple Hypergraphic Links ΓòÉΓòÉΓòÉ
:artlink.
:link reftype=hd res=0110 x=0 y=0 cx=30 cy=20.
:link reftype=hd res=0111 x=31 y=21 cx=30 cy=20.
:link reftype=launch object='C:\APPLS\APPL1.EXE'
x=61 y=41 cx=20 cy=10.
:eartlink.
ΓòÉΓòÉΓòÉ 6.123. Multiple Viewports Using Automatic Links ΓòÉΓòÉΓòÉ
:h2 res=0120
x=center y=center width=50% height=50%.
Multiple Viewports Example
:link reftype=hd res=0121
auto dependent
vpx=left vpy=bottom vpcx=50% vpcy=100%
scroll=none titlebar=none rules=none.
:link reftype=hd res=0122
auto dependent
vpx=right vpy=bottom vpcx=50% vpcy=100%
scroll=vertical titlebar=none rules=none.
ΓòÉΓòÉΓòÉ 6.124. Application-Controlled Viewport ΓòÉΓòÉΓòÉ
:h1 res=0101
x=center y=center width=50% height=50%.
scroll=none.Application-Controlled Viewport Example
:acviewport dll='SAMPLES' objectname='flight' objectid=1
vpx=left vpy=bottom vpcx=50% vpcy=50%.
ΓòÉΓòÉΓòÉ 6.125. Help Table Resource Definition ΓòÉΓòÉΓòÉ
HELPTABLE MAINHELP
BEGIN
HELPITEM MAIN, SUBTABLE_MAIN, EXTHELP_MAIN
HELPITEM DIALOG1, SUBTABLE_DIALOG1, EXTHELP_DIALOG1
END
HELPSUBTABLE SUBTABLE_MAIN
BEGIN
HELPSUBITEM MI_FILE, 0010
HELPSUBITEM MI_EDIT, 0020
HELPSUBITEM MI_VIEW, 0030
HELPSUBITEM MI_EXIT, 0040
END
HELPSUBTABLE SUBTABLE_DIALOG1
BEGIN
HELPSUBITEM EF_ITEM1, 0101
HELPSUBITEM EF_ITEM2, 0102
HELPSUBITEM CK_ITEM3, 0103
HELPSUBITEM PB_ITEM4, 0104
HELPSUBITEM PB_ITEM5, 0105
END
ΓòÉΓòÉΓòÉ 6.126. WinCreateHelpInstance() Function ΓòÉΓòÉΓòÉ
PHELPINIT HelpInit;
HWND hHelp;
HelpInit=DosAllocMem(HelpInit, /* Allocate memory object */
sizeof(HELPINIT), /* Size of HELPINIT struct */
PAG_READ | /* Allow read access */
PAG_WRITE | /* Allow write access */
PAG_COMMIT; /* Commit storage now */
HelpInit->cb=sizeof(HELPINIT); /* Specify size of struct */
HelpInit->pszTutorialName=NULL; /* No tutorial */
HelpInit->phtHelpTable=MAINHELP; /* Help table identifier */
HelpInit->phtHelpTableModule=NULL; /* Help table in EXE file */
HelpInit->hmodAccelActionBarModule=NULL; /* Resource in EXE file */
HelpInit->idAccelTable=0; /* Resource in EXE file */
HelpInit->idActionBar=0; /* Default used */
HelpInit->pszHelpWindowTitle="Help"; /* Help window title */
HelpInit->usShowPanelID=CMIC_HIDE_PANEL_ID; /* Do not show panel ids */
HelpInit->pszHelpLibraryName="APPLHELP"; /* Name of help library */
hHelp = WinCreateHelpInstance(hAB, /* Create help instance */
HelpInit); /* HELPINIT structure */
ΓòÉΓòÉΓòÉ 6.127. WinAssociateHelpInstance() Function ΓòÉΓòÉΓòÉ
rc = WinAssociateHelpInstance(hHelp, /* Help instance handle */
hFrame); /* Frame window handle */
ΓòÉΓòÉΓòÉ 6.128. WinDestroyHelpInstance() Function ΓòÉΓòÉΓòÉ
rc = WinDestroyHelpInstance(hHelp); /* Destroy help instance */
ΓòÉΓòÉΓòÉ 6.129. Help Pulldown Menu Definition ΓòÉΓòÉΓòÉ
:
:
SUBMENU "~Help", ID_HELP
BEGIN
MENUITEM "~Help for help...", ID_HELP_FOR_HELP
MENUITEM "~Extended help...", SC_HELPEXTENDED, MIS_SYSCOMMAND
MENUITEM "~Keys help...", SC_HELPKEYS, MIS_SYSCOMMAND
MENUITEM "Help ~index...", SC_HELPINDEX, MIS_SYSCOMMAND
END
:
:
This example shows the "Help" pulldown menu included in the menu bar of the
default main help window used by IPF.
ΓòÉΓòÉΓòÉ 6.130. Network Domains ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 6.131. Production Libraries on a LAN Server ΓòÉΓòÉΓòÉ
Server Root Directory ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇ Compilers and link-editors
Γöé
Γö£ΓöÇΓöÇΓöÇ Application source code
Γöé
Γö£ΓöÇΓöÇΓöÇ Application include files
Γöé
Γö£ΓöÇΓöÇΓöÇ Presentation Manager resources
Γöé
Γö£ΓöÇΓöÇΓöÇ Installation code libraries
Γöé
ΓööΓöÇΓöÇΓöÇ Test data
ΓòÉΓòÉΓòÉ 7. Tables ΓòÉΓòÉΓòÉ
Window Identifiers
Application Object/Window Correlation
Presentation Manager Macros
New Presentation Manager Functions in OS/2 Version 2.0
Type Prefixes for Symbolic Constants
Type Prefixes for Variables
Type Prefixes for Pointers
Memory Management Functions
Session Management Functions
Task Management Functions
Exception Handling Functions
Anonymous Pipe Functions
Named Pipe Functions
Queue Functions
Semaphore Functions
Message Retrieval Functions
Timer Services Functions
Dynamic Linking Functions
Device I/O Functions
File I/O Functions
Code Page Functions
Error Management Functions
ΓòÉΓòÉΓòÉ 7.1. Window Identifiers ΓòÉΓòÉΓòÉ
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé Window Identifiers. This table shows the window identifiers Γöé
Γöé assigned by Presentation Manager to the children of a frame window. Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé CHILD WINDOW Γöé WINDOW IDENTIFIER Γöé DEFINED BY Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé Client Window Γöé FID_CLIENT Γöé Application Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé System Menu Γöé FID_SYSMENU Γöé Presentation Manager Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé Menu Bar Γöé FID_MENU Γöé Presentation Manager Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé Title Bar Γöé FID_TITLEBAR Γöé Presentation Manager Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé Min/Max Icon Γöé FID_MINMAX Γöé Presentation Manager Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé Vertical Scroll Bar Γöé FID_VERTSCROLL Γöé Presentation Manager Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé Horizontal Scroll Bar Γöé FID_HORZSCROLL Γöé Presentation Manager Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé NOTE: The "Defined by" column indicates whether the window procedure Γöé
Γöé that determines a window's appearance and behavior is supplied by Γöé
Γöé supplied by Presentation Manager or the application. Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
ΓòÉΓòÉΓòÉ 7.2. Application Object/Window Correlation ΓòÉΓòÉΓòÉ
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé Application Object/Window Correlation Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé APPLICATION OBJECT Γöé SUPPORTED Γöé IMPLEMENTATION Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé Message Communication Γöé Yes Γöé PM Message Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé Class Association Γöé Yes Γöé Window Class Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé Class Data Γöé Yes Γöé Defined in Window Proce- Γöé
Γöé Γöé Γöé dure Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé Instance Data Γöé Yes Γöé Stored in Window Words Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé Encapsulation Γöé Yes Γöé In Window Procedure Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé Polymorphism Γöé Yes Γöé In Window Procedure Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé Inheritance Γöé Partial Γöé Via Subclassing Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
ΓòÉΓòÉΓòÉ 7.3. Presentation Manager Macros ΓòÉΓòÉΓòÉ
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé Presentation Manager Macros. This table shows the "C" language macros Γöé
Γöé provided by Presentation Manager to facilitate the construction and Γöé
Γöé extraction of message parameters. Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé MACRO Γöé USAGE Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé MPFROMP Γöé Produces an MPARAM data type from a pointer Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé MPFROMHWND Γöé Produces an MPARAM data type from a window handle (HWND) Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé MPFROMCHAR Γöé Produces an MPARAM data type from an unsigned character Γöé
Γöé Γöé (UCHAR) Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé MPFROMSHORT Γöé Produces an MPARAM data type from a short integer Γöé
Γöé Γöé (SHORT or USHORT) Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé MPFROM2SHORT Γöé Produces an MPARAM data type from two short integers Γöé
Γöé Γöé (SHORT or USHORT) Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé MPFROMSH2CH Γöé Produces an MPARAM data type from a short integer Γöé
Γöé Γöé (SHORT or USHORT) and two characters (CHAR or UCHAR) Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé MPFROMLONG Γöé Produces an MPARAM data type from a long integer (LONG Γöé
Γöé Γöé or ULONG) Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé PVOIDFROMMP Γöé Produces a pointer from an MPARAM data type Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé HWNDFROMMP Γöé Produces a window handle (HWND) from an MPARAM data type Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé CHAR1FROMMP Γöé Produces a character (UCHAR) from bits 0-7 of an Γöé
Γöé Γöé MPARAM data type Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé CHAR2FROMMP Γöé Produces a character (UCHAR) from bits 8-15 of an Γöé
Γöé Γöé MPARAM data type Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé CHAR3FROMMP Γöé Produces a character (UCHAR) from bits 16-23 of an Γöé
Γöé Γöé MPARAM data type Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé CHAR4FROMMP Γöé Produces a character (UCHAR) from bits 24-31 of an Γöé
Γöé Γöé MPARAM data type Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé SHORT1FROMMP Γöé Produces an unsigned short integer (USHORT) from Γöé
Γöé Γöé bits 0-15 of an MPARAM data type Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé SHORT2FROMMP Γöé Produces an unsigned short integer (USHORT) from bits Γöé
Γöé Γöé 16-31 of an MPARAM data type Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé LONGFROMMP Γöé Produces an unsigned long integer (ULONG) from an Γöé
Γöé Γöé MPARAM data type Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
ΓòÉΓòÉΓòÉ 7.4. New Presentation Manager Functions in OS/2 Version 2.0 ΓòÉΓòÉΓòÉ
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé New Presentation Manager Functions in OS/2 Version 2.0 Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé FUNCTION Γöé DESCRIPTION Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé WinInsertLboxItem() Γöé Inserts a listbox item Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé WinDeleteLboxItem() Γöé Deletes a listbox item Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé WinSetLboxItemText() Γöé Sets the text of a specified listbox item Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé WinQueryLboxCount() Γöé Returns the number of items in a listbox Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé WinQueryLboxSelectedItem() Γöé Returns the offset (item number) of the Γöé
Γöé Γöé selected item in a listbox Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé WinQueryLboxItemText() Γöé Returns the text of a specified listbox Γöé
Γöé Γöé item Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé WinQueryLboxItemTextLength()Γöé(Returns the length of the text of a Γöé
Γöé Γöé specified listbox item Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé WinPopupMenu() Γöé Creates and presents a context (popup) Γöé
Γöé Γöé menu Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé WinCheckMenuItem() Γöé Sets a check mark against a pulldown Γöé
Γöé Γöé menu item Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé WinIsMenuItemChecked() Γöé Determines whether a menu item is Γöé
Γöé Γöé currently checked Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé WinEnableMenuItem() Γöé Enables or disables a menu bar or Γöé
Γöé Γöé pulldown menu item Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé WinIsMenuItemEnabled() Γöé Determines whether a menu bar or pulldown Γöé
Γöé Γöé menu item is currently enabled Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé WinSetMenuItemText() Γöé Sets the text of a specified menu bar or Γöé
Γöé Γöé pulldown menu item Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé WinFileDlg() Γöé Displays the standard SAA-conforming file Γöé
Γöé Γöé dialog box Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé WinDefFileDlgProc() Γöé Default processing function for Γöé
Γöé Γöé subclassing file dialog box Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé WinFontDlg() Γöé Displays the standard SAA-conforming font Γöé
Γöé Γöé dialog box Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé WinDefFontDlgProc() Γöé Default processing function for Γöé
Γöé Γöé subclassing font dialog box Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé WinQueryButtonCheckstate() Γöé Determines the current check state of a Γöé
Γöé Γöé check box or 3-state button. Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé WinSetDesktopBkgnd() Γöé Sets the current desktop background Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé WinQueryDesktopBackground() Γöé Queries information about the current Γöé
Γöé Γöé desktop background Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
ΓòÉΓòÉΓòÉ 7.5. Type Prefixes for Symbolic Constants ΓòÉΓòÉΓòÉ
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé Type Prefixes for Symbolic Constants Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé ITEM Γöé CONSTANT TYPE Γöé PREFIX Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé Menu Item (Command) Γöé Integer Γöé MI_ Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé Check Box Γöé Integer Γöé CK_ Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé Entry Field Γöé Integer Γöé EF_ Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé List Box Γöé Integer Γöé LB_ Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé Push Button Γöé Integer Γöé PB_ Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé Radio Button Γöé Integer Γöé RB_ Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé Static Text String Γöé String Γöé STR_ Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé Window Class Γöé String Γöé WC_ Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé Dialog Class Γöé String Γöé DC_ Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé Message Class (Application-defined) Γöé Integer Γöé WMP_ Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
ΓòÉΓòÉΓòÉ 7.6. Type Prefixes for Variables ΓòÉΓòÉΓòÉ
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé Type Prefixes for Variables Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DATA TYPE Γöé DEFINITION Γöé PREFIX Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé Boolean Γöé BOOL (flag) Γöé f Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé Character Γöé CHAR Γöé ch Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé Unsigned character Γöé UCHAR Γöé uch Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé String Γöé CHAR[] Γöé sz Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé Short integer Γöé SHORT Γöé s Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé Unsigned short integer Γöé USHORT Γöé us Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé Long integer Γöé LONG Γöé l Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé Unsigned long integer Γöé ULONG Γöé ul Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé Handle Γöé HWND, HMODULE,Γöé h Γöé
Γöé Γöé etc Γöé Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
ΓòÉΓòÉΓòÉ 7.7. Type Prefixes for Pointers ΓòÉΓòÉΓòÉ
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé Type Prefixes for Pointers Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DATA TYPE Γöé DEFINITION Γöé PREFIX Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé Pointer to CHAR Γöé CHAR * Γöé pch Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé Pointer to string Γöé PSZ Γöé psz Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé Pointer to function Γöé PFN, PFNWP Γöé pfn Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
ΓòÉΓòÉΓòÉ 7.8. Memory Management Functions ΓòÉΓòÉΓòÉ
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé Memory Management Functions. This table compares the OS/2 Γöé
Γöé Version 1.3 and OS/2 Version 2.0 memory allocation and Γöé
Γöé management functions. Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé 16-BIT FUNCTION NAME Γöé 32-BIT FUNCTION NAME Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosAllocSeg Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosAllocShrSeg Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosGetShrSeg Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosGetSeg Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosGiveSeg Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosReallocSeg Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosFreeSeg Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosAllocHuge Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosGetHugeShift Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosReallocHuge Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosCreateCSAlias Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosLockSeg Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosUnLockSeg Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosMemAvail Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosSizeSeg Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosGetResource Γöé DosGetResource Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosSubAlloc Γöé DosSubAlloc Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosSubFree Γöé DosSubFree Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosSubSet Γöé DosSubSet Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosSubUnSet Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosAllocMem Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosAllocSharedMem Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosGetNamedSharedMem Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosGetSharedMem Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosGiveSharedMem Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosFreeMem Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosSetMem Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosQueryMem Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
ΓòÉΓòÉΓòÉ 7.9. Session Management Functions ΓòÉΓòÉΓòÉ
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé Session Management Functions. This table compares the OS/2 Γöé
Γöé Version 1.3 and OS/2 Version 2.0 session management Γöé
Γöé functions. Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé 16-BIT FUNCTIONS NAME Γöé 32-BIT FUNCTION NAME Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosStartSession Γöé DosStartSession Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosSetSession Γöé DosSetSession Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosSelectSession Γöé DosSelectSession Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosStopSession Γöé DosStopSession Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosSMRegisterDD Γöé N/A Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
ΓòÉΓòÉΓòÉ 7.10. Task Management Functions ΓòÉΓòÉΓòÉ
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé Task Management Functions. This table compares the OS/2 Γöé
Γöé Version 1.3 and OS/2 Version 2.0 task management functions. Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé 16-BIT FUNCTION NAME Γöé 32-BIT FUNCTION NAME Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosCreateThread Γöé DosCreateThread Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosCWait Γöé DosWaitChild Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosWaitThread Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosResumeThread Γöé DosResumeThread Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosSuspendThread Γöé DosSuspendThread Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosEnterCritSec Γöé DosEnterCritSec Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosExecPgm Γöé DosExecPgm Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosExit Γöé DosExit Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosExitCritSec Γöé DosExitCritSec Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosExitList Γöé DosExitList Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosGetInfoSeg Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosGetInfoBlocks Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosGetPrty Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosKillProcess Γöé DosKillProcess Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosKillThread Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosSetPrty Γöé DosSetPriority Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosGetPID Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosGetPPID Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosR2StackRealloc Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosCallBack Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosRetForward Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosDebug Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosPTrace Γöé N/A Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
ΓòÉΓòÉΓòÉ 7.11. Exception Handling Functions ΓòÉΓòÉΓòÉ
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé Exception Handling Functions. This table compares the OS/2 Γöé
Γöé Version 1.3 and OS/2 Version 2.0 signal and exception Γöé
Γöé handling functions. Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé 16-BIT FUNCTION NAME Γöé 32-BIT FUNCTION NAME Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosHoldSignal Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosSetSignalHandler Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosSendSignal Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosSetKBDSigFocus Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosSetVec Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosSetExceptionHandler Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosUnSetExceptionHandler Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosRaiseException Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosUnwindException Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
ΓòÉΓòÉΓòÉ 7.12. Anonymous Pipe Functions ΓòÉΓòÉΓòÉ
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé Anonymous Pipe Functions. This table compares the OS/2 Γöé
Γöé Version 1.3 and OS/2 Version 2.0 anonymous pipe functions. Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé 16-BIT FUNCTION NAME Γöé 32-BIT FUNCTION NAME Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosMakePipe Γöé DosCreatePipe Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
ΓòÉΓòÉΓòÉ 7.13. Named Pipe Functions ΓòÉΓòÉΓòÉ
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé Named Pipe Functions. This table compares the OS/2 Version Γöé
Γöé 1.3 and OS/2 Version 2.0 named pipe functions. Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé 16-BIT FUNCTION NAME Γöé 32-BIT FUNCTION NAME Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosCallNmPipe Γöé DosCallNPipe Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosConnectNmPipe Γöé DosConnectNPipe Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosDisConnectNmPipe Γöé DosDisConnectNPipe Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosMakeNmPipe Γöé DosCreateNpipe Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosPeekNmPipe Γöé DosPeekNPipe Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosQNmPHandState Γöé DosQueryNPHState Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosQNmPipeInfo Γöé DosQueryNPipeInfo Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosQNmPipeSemState Γöé DosQueryNPipeSemState Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosRawReadNmPipe Γöé DosRawReadNPipe Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosRawWriteNmPipe Γöé DosRawWriteNPipe Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosSetNmPHandInfo Γöé DosSetNPHState Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosSetNmPipeSem Γöé DosSetNPipeSem Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosTransactNmPipe Γöé DosTransactNPipe Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosWaitNmPipe Γöé DosWaitNPipe Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
ΓòÉΓòÉΓòÉ 7.14. Queue Functions ΓòÉΓòÉΓòÉ
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
ΓöéQueue Functions. This table compares the OS/2 Version 1.3 Γöé
Γöé and OS/2 Version 2.0 queue management functions. Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé 16-BIT FUNCTION NAME Γöé 32-BIT FUNCTION NAME Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosCreateQueue Γöé DosCreateQueue Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosOpenQueue Γöé DosOpenQueue Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosCloseQueue Γöé DosCloseQueue Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosPeekQueue Γöé DosPeekQueue Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosPurgeQueue Γöé DosPurgeQueue Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosQueryQueue Γöé DosQueryQueue Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosReadQueue Γöé DosReadQueue Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosWriteQueue Γöé DosWriteQueue Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
ΓòÉΓòÉΓòÉ 7.15. Semaphore Functions ΓòÉΓòÉΓòÉ
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé Semaphore Functions. This table compares the OS/2 Version Γöé
Γöé 1.3 and OS/2 Version 2.0 semaphore functions. Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé 16-BIT FUNCTION NAME Γöé 32-BIT FUNCTION NAME Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosSemClear Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosSemRequest Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosSemSet Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosSemSetWait Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosSemWait Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosMuxSemWait Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosCloseSem Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosCreateSem Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosOpenSem Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosFSRamSemRequest Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosFSRamSemClear Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosCreateMutexSem Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosOpenMutexSem Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosCloseMutexSem Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosRequestMutexSem Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosReleaseMutexSem Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosQueryMutexSem Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosCreateEventSem Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosOpenEventSem Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosCloseEventSem Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosResetEventSem Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosPostEventSem Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosWaitEventSem Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosQueryEventSem Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosCreateMuxWaitSem Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosOpenMuxWaitSem Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosCloseMuxWaitSem Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosWaitMuxWaitSem Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosAddMuxWaitSem Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosDeleteMuxWaitSem Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé N/A Γöé DosQueryMuxWaitSem Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
ΓòÉΓòÉΓòÉ 7.16. Message Retrieval Functions ΓòÉΓòÉΓòÉ
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé Message Retrieval Functions. This table compares the OS/2 Γöé
Γöé Version 1.3 and OS/2 Version 2.0 message retrieval functions.Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé 16-BIT FUNCTION NAME Γöé 32-BIT FUNCTION NAME Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosGetMessage Γöé DosGetMessage Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosInsMessage Γöé DosInsertMessage Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosPutMessage Γöé DosPutMessage Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
ΓòÉΓòÉΓòÉ 7.17. Timer Services Functions ΓòÉΓòÉΓòÉ
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé Timer Services Functions. This table compares the OS/2 Γöé
Γöé Version 1.3 and OS/2 Version 2.0 timer services functions. Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé 16-BIT FUNCTION NAME Γöé 32-BIT FUNCTION NAME Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosGetDateTime Γöé DosGetDateTime Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosSetDateTime Γöé DosSetDateTime Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosSleep Γöé DosSleep Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosTimerAsync Γöé DosAsyncTimer Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosTimerStart Γöé DosStartTimer Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosTimerStop Γöé DosStopTimer Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
ΓòÉΓòÉΓòÉ 7.18. Dynamic Linking Functions ΓòÉΓòÉΓòÉ
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé Dynamic Linking Functions. This table compares the OS/2 Γöé
Γöé Version 1.3 and OS/2 Version 2.0 dynamic linking functions. Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé 16-BIT FUNCTION NAME Γöé 32-BIT FUNCTION NAME Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosLoadModule Γöé DosLoadModule Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosFreeModule Γöé DosFreeModule Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosGetProcAddr Γöé DosQueryProcAddr Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosGetModHandle Γöé DosQueryModuleHandle Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosGetModName Γöé DosQueryModuleName Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosQAppType Γöé DosQueryAppType Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosGetMachineMode Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé BadDynLink Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosGetVersion Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosGetEnv Γöé N/A Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
ΓòÉΓòÉΓòÉ 7.19. Device I/O Functions ΓòÉΓòÉΓòÉ
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé Device I/O Functions. This table compares the OS/2 Version Γöé
Γöé 1.3 and OS/2 Version 2.0 device I/O functions. Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé 16-BIT FUNCTION NAME Γöé 32-BIT FUNCTION NAME Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosBeep Γöé DosBeep Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosCLIAccess Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosPortAccess Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosDevConfig Γöé DosDevConfig Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosPhysicalDisk Γöé DosPhysicalDisk Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
ΓòÉΓòÉΓòÉ 7.20. File I/O Functions ΓòÉΓòÉΓòÉ
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé File I/O Functions. This table compares OS/2 Version 1.3 Γöé
Γöé and OS/2 Version 2.0 file I/O functions. Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé 16-BIT FUNCTION NAME Γöé 32-BIT FUNCTION NAME Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosBufReset Γöé DosResetBuffer Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosChDir Γöé DosSetCurrentDir Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosChgFilePtr Γöé DosSetFilePtr Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosClose Γöé DosClose Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosDelete Γöé DosDelete Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosDevIOCTL Γöé DosDevIOCTL Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosDupHandle Γöé DosDupHandle Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosEditName Γöé DosEditName Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosFileIO Γöé DosFileIO Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosFileLocks Γöé DosSetFileLocks Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosFindClose Γöé DosFindClose Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosFindFirst Γöé DosFindFirst Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosFindNext Γöé DosFindNext Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosFindNotifyClose Γöé DosFindNotifyClose Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosFindNotifyFirst Γöé DosFindNotifyFirst Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosFindNotifyNext Γöé DosFindNotifyNext Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosFSAttach Γöé DosFSAttach Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosFSCtl Γöé DosFSCtl Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosMkDir Γöé DosCreateDir Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosMove Γöé DosMove Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosNewSize Γöé DosSetFileSize Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosOpen Γöé DosOpen Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosQCurDir Γöé DosQueryCurrentDir Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosQCurDisk Γöé DosQueryCurrentDisk Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosQFHandState Γöé DosQueryFHState Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosQFileInfo Γöé DosQueryFileInfo Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosQFileMode Γöé DosQueryFileMode Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosQFSAttach Γöé DosQueryFSAttach Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosQFSinfo Γöé DosQueryFSInfo Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosQHandType Γöé DosQueryHType Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosQPathInfo Γöé DosQueryPathInfo Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosQSysInfo Γöé DosQuerySysInfo Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosQVerify Γöé DosQueryVerify Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosRead Γöé DosRead Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosReadAsync Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosRmDir Γöé DosDeleteDir Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosScanEnv Γöé DosScanEnv Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosSearchPath Γöé DosSearchPath Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosSelectDisk Γöé DosSetDefaultDisk Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosSetFHandState Γöé DosSetFHState Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosSetFileInfo Γöé DosSetFileInfo Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosSetFileMode Γöé DosSetFileMode Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosSetFsInfo Γöé DosSetFsInfo Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosSetMaxFH Γöé DosSetMaxFH Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosSetPathInfo Γöé DosSetPathInfo Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosSetVerify Γöé DosSetVerify Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosWrite Γöé DosWrite Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosWriteAsync Γöé N/A Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
ΓòÉΓòÉΓòÉ 7.21. Code Page Functions ΓòÉΓòÉΓòÉ
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé Code Page Functions. This table compares the OS/2 Version Γöé
Γöé 1.3 and OS/2 Version 2.0 file code page support functions. Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé 16-BIT FUNCTION NAME Γöé 32-BIT FUNCTION NAME Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosSetCp Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosSetProcCp Γöé DosSetProcessCp Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosGetCp Γöé DosQueryCp Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosGetCtryInfo Γöé DosQueryCtryInfo Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosCaseMap Γöé N/A Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosGetDBCSEv Γöé DosQueryDBCSEnv Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosGetCollate Γöé DosQueryCollate Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
ΓòÉΓòÉΓòÉ 7.22. Error Management Functions ΓòÉΓòÉΓòÉ
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé Error Management Functions. This table compares the OS/2 Γöé
Γöé Version 1.3 and OS/2 Version 2.0 error management functions. Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé 16-BIT FUNCTION NAME Γöé 32-BIT FUNCTION NAME Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosErrClass Γöé DosErrClass Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé DosError Γöé DosError Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
ΓòÉΓòÉΓòÉ 8. Special Notices ΓòÉΓòÉΓòÉ
This publication is intended to help the customer in the design and
implementation of OS/2 Presentation Manager applications under OS/2 Version
2.0, using object-oriented design and programming principles. The information
in this publication is not intended as the specification of any programming
interfaces that are provided by OS/2 Version 2.0. See the PUBLICATIONS section
of the IBM Programming Announcement for OS/2 Version 2.0 for more information
about what publications are considered to be product documentation.
References in this publication to IBM products, programs or services do not
imply that IBM intends to make these available in all countries in which IBM
operates. Any reference to an IBM product, program, or service is not intended
to state or imply that only IBM's product, program, or service may be used.
Any functionally equivalent program that does not infringe any of IBM's
intellectual property rights may be used instead of the IBM product, program or
service.
Information in this book was developed in conjunction with use of the equipment
specified, and is limited in application to those specific hardware and
software products and levels.
IBM may have patents or pending patent applications covering subject matter in
this document. The furnishing of this document does not give you any license
to these patents. You can send license inquiries, in writing, to the IBM
Director of Commercial Relations, IBM Corporation, Purchase, NY 10577.
The information contained in this document has not been submitted to any formal
IBM test and is distributed AS IS.
The information about non-IBM ("vendor") products in this manual has been
supplied by the vendor and IBM assumes no responsibility for its accuracy
completeness.
The use of this information or the implementation of any of these techniques is
a customer responsibility and depends on the customer's ability to evaluate and
integrate them into the customer's operational environment. While each item
may have been reviewed by IBM for accuracy in a specific situation, there is no
guarantee that the same or similar results will be obtained elsewhere.
Customers attempting to adapt these techniques to their own environments do so
at their own risk.
The following document contains examples of data and reports used in daily
business operations. To illustrate them as completely as possible, the
examples contain the names of individuals, companies, brands, and products. All
of these names are fictitious and any similarity to the names and addresses
used by an actual business enterprise is entirely coincidental.
The following terms, which are denoted by an asterisk (*) in this publication,
are trademarks of the International Business Machines Corporation in the United
States and/or other countries:
C/2
COBOL/2
Common User Access
CommonView
CUA
DATABASE 2
DB2
DCF
Document Composition Facility
FORTRAN/2
IBM
Macro Assembler/2
Micro Channel
OfficeVision
Operating System/2
OS/2
Personal System/2
Presentation Manager
PS/2
SAA
System/370
Systems Application Architecture
WIN-OS/2
Workplace Shell
The following terms, which are denoted by a double asterisk (**) in this
publication, are trademarks of other companies.
Intel is a trademark of Intel Corporation.
Lotus is a trademark of the Lotus Development Corporation.
Microsoft is a trademark of Microsoft Corporation.
MS-DOS is a registered trademark of Microsoft Corporation.
Smalltalk/V is a trademark of Digitalk Inc.
Windows is a trademark of Microsoft Corporation.
286, 386, 486, SX are trademarks of Intel Corporation.
ΓòÉΓòÉΓòÉ 9. Preface ΓòÉΓòÉΓòÉ
This document is intended as a general introduction to the concepts involved in
the design and implementation of applications which will execute in the OS/2
Presentation Manager and Workplace Shell environments under OS/2 Version 2.0.
It is not intended to be an exhaustive reference on the subject of Presentation
Manager programming, and should be used in conjunction with the official IBM
product documentation, and other reference books and documents, which are
mentioned herein.
It must be stressed that this document is not intended to teach the reader how
to program in the "C" language or how to use the Presentation Manager
programming interface, nor is it intended to teach the theory of
object-oriented programming. Rather, it serves as a guide to the integration
of various object-oriented software engineering techniques with the
Presentation Manager application model, in order to produce well-structured,
easily-maintainable applications which conform to CUA guidelines.
The information given in this document is generally independent of programming
language implementations (with certain exceptions noted in the text), and may
be used to develop applications in any supported programming language.
However, programming syntax examples used in this document are shown using the
"C" language, since this language is commonly used for Presentation Manager
application development, and most clearly illustrates the structure of the
Presentation Manager and Workplace Shell application models.
This document is intended for:
Application designers, planners and development managers who require an
understanding of the application of object-oriented principles to the
Presentation Manager environment, and the productivity gains to be achieved
from the use of such principles.
Programmers who wish to understand the structure of Presentation Manager and
Workplace Shell applications, and the techniques by which applications may be
constructed so as to achieve maximum function, with optimal levels of
reusability and maintainability.
The code examples used in this document are available in electronic form via
CompuServe** or through a local IBM Support BBS, as package RB3774.ZIP. IBM
employees may obtain the code examples from the package GG243774 PACKAGE on
OS2TOOLS.
First Edition: This First Edition includes programming information relating to
application development under OS/2 Version 2.0, and supercedes
the ITSC Technical Bulletin Presentation Manager Application
Development, GG24-3543.
The document is organized as follows:
Overview provides a brief introduction to the topics covered in this
document.
This chapter is recommended for all readers of the document.
Operating System/2 provides a brief technical overview of the OS/2 Version
2.0 environment, comparing and contrasting it with the DOS environment and
previous versions of OS/2. The major features of OS/2 Version 2.0 are
described and their use by applications is discussed.
This chapter is recommended for those readers who are not familiar with the
OS/2 Version 2.0 operating system environment, in order to provide them with
a basic understanding of the capabilities of OS/2 Version 2.0.
Object-Oriented Applications explains the basic principles of object-oriented
design and programming. The object-oriented approach is compared and
contrasted with the traditional procedural approach in terms of a simple
application model, before the extension of the object-oriented paradigm into
more complex scenarios is discussed. Some suggestions and guidelines are
also offered with regard to application design and implementation using the
object-oriented approach.
This chapter is recommended for readers who do not already possess an
understanding of the basic principles of object-oriented programming. This
knowledge is essential in order to understand the programming guidelines
presented later in the document.
The Presentation Manager Application Model describes the Presentation Manager
application model, and illustrates the way in which the application model
implements the object-oriented principles introduced in Object-Oriented
Applications.
This chapter is recommended for all readers of this document, since it
explains the basic structure of a Presentation Manager application, and the
way in which the Presentation Manager application model facilitates the
creation of object-oriented applications.
The Flat Memory Model describes the 32-bit flat memory model implemented in
OS/2 Version 2.0, and discusses the programming considerations which arise
from the differences between this memory model and the segmented memory model
used by previous versions of OS/2.
This chapter is recommended for all programmers who intend to develop
applications under OS/2 Version 2.0.
Building a Presentation Manager Application describes the major programming
techniques required to implement a Presentation Manager application,
including recommendations and established conventions in areas such as
methods of opening and closing windows, displaying dialogs, communication
between windows, managing user responsiveness etc. The chapter also
discusses certain software engineering techniques which may be used to
enhance the level of modularity and optimize the granularity of the resulting
application code.
This chapter is recommended for programmers and development managers who will
be working on the implementation of Presentation Manager applications.
Workplace Shell and the System Object Model describes the system object model
introduced in OS/2 Version 2.0, and its implementation by the OS/2 Version
2.0 Workplace Shell. The chapter describes the object-oriented application
layer provided by the Workplace Shell, and explains how Workplace Shell
objects are defined, created and implemented.
This chapter is recommended for programmers and development managers who wish
to create objects for use on the Workplace Shell desktop.
Direct Manipulation explains the implementation of direct manipulation (drag
and drop) techniques for carrying out required tasks in the Presentation
Manager and Workplace Shell environments. The chapter discusses the use of
these techniques both by Presentation Manager windows and by Workplace Shell
objects.
This chapter is recommended for programmers who wish to implement direct
manipulation in their Presentation Manager applications or Workplace Shell
object classes.
Presentation Manager Resources discusses the concept of Presentation Manager
resources. The chapter covers the types of application resources which may
be defined in the Presentation Manager environment, their definition and
conventions governing their use.
This chapter is recommended for all programmers who will develop Presentation
Manager applications, since resources are used in most if not all
applications.
Multitasking Considerations describes the ways in which multiple threads of
execution may be used within a Presentation Manager application, in order to
isolate long-running application tasks from the user interface and thereby
provide greater application responsiveness to the end user.
This chapter is recommended for programmers and development managers who will
be building Presentation Manager applications which carry out lengthy
processing tasks, or which require access to remote devices or systems.
Systems Application Architecture CUA Considerations discusses the
implementation of various SAA CUA user interface specifications in
Presentation Manager applications. The chapter provides coding examples for
a number of CUA techniques such as menu bar handling.
This chapter is recommended for programmers who wish to implement SAA CUA
guidelines in their applications.
Application Migration discusses the migration of Presentation Manager
applications to OS/2 Version 2.0 from previous versions of OS/2. Differences
in implementation are described, along with additional facilities provided by
Presentation Manager under OS/2 Version 2.0.
This chapter is recommended for application developers with Presentation
Manager applications written for previous versions of OS/2, which they wish
to modify in order to take full advantage of the capabilities of OS/2 Version
2.0.
Mixing 16-Bit and 32-Bit Application Modules describes the way in which
32-bit applications under OS/2 Version 2.0 may make use of existing 16-bit
functions and window procedures, along with restrictions and programming
considerations to be borne in mind when developing such applications.
This chapter is recommended for those programmers working in organizations
with existing 16-bit runtime libraries or DLLs, and who wish to make use of
functions contained within these libraries.
Compiling and Link Editing an Application describes the steps necessary to
compile and link edit a Presentation Manager application under OS/2 Version
2.0, including the use of module definition files. and the creation of
dynamic link libraries to contain application code and Presentation Manager
resources.
This chapter is recommended for all programmers who will develop Presentation
Manager applications, and who wish to understand how to create executable
modules and dynamic link libraries.
Adding Online Help and Documentation examines the provision of online,
context-sensitive help information for Presentation Manager applications
using the IPF provided with Presentation Manager, and the use of this
facility to create online documentation.
This chapter is recommended for application developers who wish to provide
online help for their applications, or who wish to develop online
documentation and tutorial programs.
Problem Determination describes some simple techniques for problem
determination and resolution in the Presentation Manager environment, and
discusses some common application problems.
This chapter is recommended for all application developers involved in
testing and debugging Presentation Manager applications.
Generic Application Modules discusses the use of generic routines to perform
commonly used functions within a Presentation Manager application, and
identifies a number of areas where generic functions may be successfully
applied.
This chapter is recommended for planners and development managers who will
manage a number of application developers working on one or more Presentation
Manager applications, and who wish to understand the benefits in terms of
consistency and productivity which can be achieved through the use of common
routines.
Managing Development provides some guidelines for the use of a local area
network (LAN) to facilitate centralized control and administration of the
workstation-based application development process.
This chapter is recommended for planners and development managers who will
manage a number of application developers working on one or more Presentation
Manager applications, and who wish to understand some of the ways in which a
distributed development process may be managed and controlled.
The following appendixes are included in this document:
Naming Conventions provides some guidelines for naming conventions to be used
with symbols, subroutines and variables in the Presentation Manager
environment. These guidelines cover the use of Hungarian Notation for such
names.
This chapter is recommended for planners and development managers who wish to
implement a standard series of naming conventions for the application
development projects under their control.
Application Program Construction presents guidelines for the structuring of
applications and their component modules in order to achieve the optimum
level of modularity and granularity within an application, thus promoting
reuse of application code.
This chapter is recommended for planners and development managers who wish to
gain the maximum productivity benefit over a number of Presentation Manager
application development projects.
OS/2 Kernel API Functions compares the operating system kernel functions
provided in OS/2 Version 2.0 with those provided in OS/2 Version 1.3.
This chapter is recommended for programmers who will be migrating
applications from previous versions of OS/2.
Problem Reporting Worksheet provides a worksheet which may be used when
following the steps given in Problem Determination, to provide effective
problem documentation which can then be used to reproduce application errors.
This chapter is recommended for application developers involved in testing
and debugging Presentation Manager applications.
ΓòÉΓòÉΓòÉ 10. Related Publications ΓòÉΓòÉΓòÉ
The following publications are considered particularly suitable for a more
detailed discussion of the topics covered in this document.
Prerequisite Publications
IBM OS/2 Version 2.0 Application Design Guide, 10G6260
IBM OS/2 Version 2.0 Control Program Reference
IBM OS/2 Version 2.0 Presentation Manager Reference
IBM OS/2 Version 2.0 Programming Tools Reference.
Additional Publications
OS/2 Version 2.0 - Volume 1: Control Program, GG24-3730
OS/2 Version 2.0 - Volume 2: DOS and Windows Environment, GG24-3731
OS/2 Version 2.0 - Volume 3: Presentation Manager and Workplace Shell,
GG24-3732
OS/2 Version 2.0 - Volume 5: Print Subsystem, GG24-3775
OS/2 Version 2.0 Remote Installation and Maintenance, GG24-3780
The Design of OS/2, Harvey M. Deitel and Michael J. Kogan, Addison Wesley
1992 ISBN 0-201-54889-5 (SC25-4005)
Object Oriented Programming: An Evolutionary Approach, Brad J. Cox, Addison
Wesley 1987 ISBN 0-201-10393-1
Programmer's Guide to the OS/2 Presentation Manager, Michael J. Young, Sybex
1989 ISBN 0-89588-569-7
Programming the OS/2 Presentation Manager, Charles Petzold, Microsoft Press
1989 ISBN 1-55615-170-5
IBM OS/2 Version 2.0 Technical Library - Procedures Language/2 REXX
Reference, 10G-6268
IBM C Set/2 User's Guide, SC09-1310
IBM C Set/2 Migration Guide, SC09-1369
IBM Systems Application Architecture CUA Advanced Guide to User Interface
Design, SC34-4289
IBM Systems Application Architecture CUA Advanced Interface Design Reference,
SC34-4290
IBM Systems Application Architecture Common Programming Interface
Presentation Reference, SC26-4359.
ΓòÉΓòÉΓòÉ 11. Overview ΓòÉΓòÉΓòÉ
IBM* OS/2* Presentation Manager* is a graphical user interface facility that
allows the creation of object-oriented, event-driven applications which conform
to IBM Systems Application Architecture* (SAA*) Common User Access* (CUA*)
guidelines. Presentation Manager provides an application execution environment
under which such applications are executed, and under which they may take full
advantage of the advanced capabilities of the OS/2 operating system
environment, as well as a system-level mechanism to handle interaction between
the application and the user in a consistent and intuitive manner.
The object-based Presentation Manager application model facilitates the use of
object-oriented software engineering principles such as data abstraction and
encapsulation. The application of these principles enhances application
modularity and thereby contributes to increased potential for code reuse and
easier application maintenance through containment of change, thereby achieving
higher levels of productivity in the areas of application development and
maintenance.
This document examines the Presentation Manager execution environment in order
to describe the structure and implementation of Presentation Manager
applications, and to illustrate the facilities provided by Presentation Manager
to support object-oriented techniques. In addition, the document examines the
ways in which CUA guidelines may be implemented by Presentation Manager
applications within the object-oriented application model. Particular emphasis
is given to the use of software engineering principles which facilitate the
creation of reusable code for common application services. This is one of the
primary concerns of the object-oriented approach to application design, and is
also one aspect of the Systems Application Architecture Common Applications
("red layer") component.
The document also discusses the management of workstation-based application
development projects. Historically, workstation applications have typically
fallen into the systems software category, or have been "one-off" applications
and hence have not been subject to the same rules and disciplines imposed upon
the traditionally host-based line-of-business applications. However, as the
OS/2 environment begins to provide a viable platform for the implementation of
workstation-based and cooperative line-of-business applications, typical
corporate investments in workstation software are increasing rapidly, and
therefore the management and maintenance of these investments must be
considered. Some suggestions on the management of the workstation-based
development process are given in Managing Development.
ΓòÉΓòÉΓòÉ 11.1. User Interface ΓòÉΓòÉΓòÉ
The Presentation Manager user interface model facilitates an intuitive user
interface. While people typically approach their work tasks from a
"problem-domain" viewpoint, computers tend to adopt an "operator/operand"
approach that is inherently alien to the end user. Traditionally, the required
translation between approaches has been left to the user, with applications and
their user interfaces written to conform to the computer's viewpoint rather
than that of the user. This approach has often led to users having difficulty
relating to the technology, with consequently greater amounts of time and money
spent in user training.
In recent times, a growing school of thought has emerged which contends that,
with the increasing power of computer systems and particularly with the advent
of powerful programmable workstations, the responsibility for this interface
translation should lie primarily with the application or the computer system
rather than with the user. In order to achieve this, user interfaces must be
redesigned in order to operate in an object-action, event-driven manner which
corresponds with the users' problem domain viewpoint.
Presentation Manager implements such a user interface, and Presentation Manager
applications may thus be designed and implemented in such a way as to provide
improved user-friendliness and encourage learning by exploration. The details
of the Presentation Manager user interface are described in OS/2 Version 2.0 -
Volume 3: Presentation Manager and Workplace Shell.
Presentation Manager also facilitates consistency between applications by
handling the interface between user and application at a system level,
providing a number of standard constructs which may be exploited by
applications. Since these constructs typically appear and behave in the same
way regardless of the application under which they are implemented, a user need
learn only one set of user interface guidelines to be able to interact with
multiple applications. This consistency reduces confusion for users who work
with multiple applications, and reduces the need for extensive application
training.
The SAA CUA component provides guidelines for the use of these constructs to
fulfill particular input/output requirements within an application, such that a
level of consistency is achieved not only in the behaviour of the constructs
themselves, but also in their relationship to one another and thus in the
behaviour of the application as a whole. These guidelines are documented in
the IBM Systems Application Architecture CUA Advanced Guide to User Interface
Design.
ΓòÉΓòÉΓòÉ 11.2. Object-Oriented Applications ΓòÉΓòÉΓòÉ
Many definitions of the term object-oriented programming may be found in
various publications and presentations appearing over the last few years.
These definitions often differ widely, and have resulted in a great deal of
confusion and debate as to the "true" meaning of the term. It may be
justifiably argued that there is no such true meaning, and the term
object-oriented may be used to describe techniques ranging from simple data
abstraction to the full inheritance hierarchies implemented by certain
object-oriented development tools.
ΓòÉΓòÉΓòÉ 11.2.1. Object-Oriented Design ΓòÉΓòÉΓòÉ
For the purpose of discussion within this document, an object-oriented
application will be defined as one where data objects are the focus of the
application. A data object is defined to be a particular representation of a
logical data entity. For example, a document being edited may exist in two
places: as an image in memory and as a file on a fixed disk. Each of these two
forms constitutes a separate data object.
The procedures that operate upon these data objects in order to carry out
application functions are encapsulated with the data objects to form
application objects. Application objects are logically independent units
comprising both data and function, which communicate with one another to
request actions, conveyed in the form of messages passed between the
communicating objects. In object-oriented terminology, the procedures that are
invoked to carry out the required actions are known as methods.
Several rules apply to the design and behaviour of application objects. These
are listed below:
A data object should be accessible only from within a single application
object which "owns" the data object. The definition, creation and/or
establishment of access to the data object should also be achieved from
within the application object; this is known as the principle of
encapsulation.
The behaviour of and output from an application object should depend upon,
and only upon, the type and contents of the messages it receives. The
behaviour of an object should not depend upon any other external source.
As a corollary to the foregoing principle, the result of passing a particular
type of message may also vary, depending upon the type of application object
to which it is passed, and that object's interpretation of the message.
Adherence to this rule allows the behaviour of an object to differ, depending
upon the nature of the messages received by that object; this differing
behaviour is known as polymorphism.
For ease of processing, application objects with similar properties are grouped
into object classes. Each object in a class is said to be an instance of that
class. Application objects within the same class share properties such as data
object definitions, class-specific variable definitions and values, and
methods. Objects therefore take on the properties of their class; this is
known as inheritance.
It is the concept of inheritance that provides a distinguishing factor between
the two major schools of thought which exist under the object-oriented
paradigm:
The basic precept of the class-based theory of object-oriented design is that
objects are defined in terms of their class, and that new classes are defined
in terms of existing classes, with certain additions and modifications which
distinguish the new class. Thus there is a measure of interdependence
between object classes, and an inheritance hierarchy is formed.
The primary advantage of the class-based approach is that it eases the task
of defining object classes, since each new class belongs to a hierarchy of
previously defined classes with their own properties and methods. The
application developer therefore need only explicitly define the
distinguishing characteristics of each class.
The major disadvatange of the class-based approach is the consequent high
level of interdependence between objects. Since the unit of modularity is
the entire inheritance hierarchy, rather than the individual object, reuse of
a particular object presupposes reuse of all those objects in its hierarchy
upon which the definition of the required object depends.
The class-based approach therefore provides a high initial productivity to
the application developer, although with a consequent reduction in the level
of granularity and an increase in run-time overhead.
The module-based theory of application development contends that while
objects are defined in terms of their class, each new class is totally
defined in its own right, and is not dependent upon the definitions of other
classes. Hence there is no inheritance hierarchy under the module-based
approach.
The primary advantage of the module-based approach is that it avoids the
object interdependence associated with the class-based approach, since each
object class contains its own complete definition of properties and methods.
Thus the unit of modularity is the individual application object.
The disadvantage of this approach lies in the fact that the application
developer is required to define each object class in its entirety, and
typically cannot rely on previous definitions. [This may be overcome to some
extent through subclassing, which is explained later in this chapter. ] The
module-based approach therefore attains a higher level of modularity and
independence between application objects, but at the expense of higher
initial development time.
The object-oriented approach to application design is most suited to
applications where the data is the focus of the application, and is less
suitable where the procedure or sequence of actions is the critical factor in
the design. However, in mixed situations where only certain parts of an
application or application system are procedurally oriented, as is the case
with many work tasks, and where the provision of an event-driven user interface
is desirable, the object-oriented paradigm can be extended to encompass
procedurally oriented tasks. This is discussed further in Object-Oriented
Applications.
While object-oriented applications deal primarily with the manipulation of data
entities and their logical representations, there are many situations where an
application must deal with other entities such as remote devices or systems.
Administrative procedures defined by or imposed upon an organization may also
be viewed as logical entities with which an application must interact. The
incorporation of such entities into the object-oriented application paradigm
requires an expansion of the concept of an application object to include the
definition of and methods pertaining to any type of entity addressed by the
application. This broadened definition is fundamental in making the
object-oriented application model applicable to virtually any application
scenario.
ΓòÉΓòÉΓòÉ 11.2.2. Object-Action Interfaces ΓòÉΓòÉΓòÉ
For the purpose of discussion within this document, an object-oriented
application will also be defined as one that implements an event-driven,
object-action user interface such as that specified in the IBM Systems
Application Architecture CUA Advanced Guide to User Interface Design. With
such an interface, a user first selects an object to manipulate, then selects
one or more of a defined set of actions to be performed upon that object. The
sequence of these actions, and hence the sequence of the dialog with the user,
is controlled by the user rather than by the application, where this is
possible within the requirements of the work task being performed.
The concepts of object-oriented design and an object-action user interface are
distinct but complementary. While it is possible to design and create an
object-oriented application without an object-oriented user interface, it it
far more difficult to implement a truly event-driven, object-action style of
user interface without embracing, at least a certain degree, the
object-oriented approach to design and implementation. It thus follows that
the SAA CUA user interface model cannot be fully implemented without some
measure of adherence to object-oriented design principles. It is the provision
of an intuitive, event-driven user interface that constitutes one of the great
strengths of the object-oriented paradigm.
ΓòÉΓòÉΓòÉ 11.2.3. Benefits of the Object-Oriented Approach ΓòÉΓòÉΓòÉ
A fundamental benefit of an object-oriented approach from the viewpoint of the
end user is the ability for an application to behave in a manner that parallels
a typical human being's natural approach to problem solving. The flexibility
of the object-action interface allows scope for individual variation in the
approach to a particular work task. However, such a user interface relies upon
an object-oriented application implementation in order to allow such
flexibility. Such an implementation is in turn dependent upon the correct
design approach, which must begin with a focus upon the entities that affect
the application, rather than upon the procedures to be performed upon those
entities.
The object-oriented paradigm also encourages the concept of data abstraction
and encapsulation, whereby the definition of and establishment of access to
data objects is achieved from within the application object. Ideally, all
access to and manipulation of a data object is carried out from within a single
application object, thereby facilitating change management and application
maintenance.
Another great benefit of the object-oriented approach is the increased
potential for creation of reusable code. The independent nature of application
objects enables them to be coupled together in various ways to achieve desired
results, with the internal implementation details of each object and its data
structures being isolated from the other objects with which it communicates.
Applications that manipulate existing data objects may therefore be assembled
from a number of existing application objects, thus reducing the time and
effort required to develop the application.
This potential for object reuse has also given rise to one of the great
criticisms levelled at the object-oriented approach; the "myth" of the
completely generic object. Due to the impracticability of foreseeing all
possible actions that might be performed on a data object, it is impossible to
produce a complete set of methods for that object. Hence an application object
might require modification at some stage in its life cycle, and is not truly
reusable.
The object-oriented approach overcomes this potential problem by the use of a
concept known as subclassing, whereby a new application object is created
comprised of a data object and a number of new or modified methods which act
upon that object. Messages destined for the original application object are
diverted to the new object; the original object is said to have been
subclassed. If the message is of a type with which the new object is
explicitly concerned, it processes the message using its own methods. If not,
it passes the message on to the original object for processing. In the
subclassing process, neither the sending object nor the original receiving
object should be aware that subclassing has taken place. Subclassing therefore
provides a transparent means for modifying or adding to the behaviour of an
existing application object without modifying the object itself.
The general principles of object-oriented design and programming, as they apply
to the Presentation Manager environment, are explored more fully in
Object-Oriented Applications.
ΓòÉΓòÉΓòÉ 11.3. Presentation Manager Application Model ΓòÉΓòÉΓòÉ
Contrary to popular belief, Presentation Manager provides far more than merely
the ability to achieve a windowed, graphical user interface for the display of
information on the screen. Rather, Presentation Manager provides a
message-driven, object-based execution environment that facilitates the
provision of an event-driven, object-action user interface, and supports the
implementation of object-oriented design techniques.
Presentation Manager enables the implementation of an object-action user
interface by providing an application programming interface that conforms to
the guidelines laid down in the IBM Systems Application Architecture Common
Programming Interface Presentation Reference, and a set of underlying system
services that support an object-oriented, event-driven application model. The
Presentation Manager programming interface provides user interface constructs
which conform to CUA guidelines. However, it must be strongly emphasized that
the term "presentation interface" is a misnomer, since Presentation Manager is
concerned with far more than merely the display of information on the screen.
The Presentation Manager application model is centered around the concept of
windows. While a window typically appears as a rectangular area on the screen,
it is in fact a "handle" to a data object; a window concerned with data being
displayed on the screen is termed a display window, whereas a window concerned
with an internal data object is known as an object window. Each window belongs
to a window class and is associated with a window procedure, which contains the
definition of the window's data object(s) and also contains methods to perform
all of the processing associated with that window. Windows and their
associated window procedures communicate with the user and with each other, by
the use of messages that are routed to the appropriate window by Presentation
Manager.
Since a window procedure may contain all the processing related to a particular
data object, along with the definition of and establishment of access to that
data object, Presentation Manager provides a suitable environment for data
encapsulation and abstraction, in that the internal representation and workings
of a data object may be "hidden" within the window procedure that "owns" the
data object. Provided the external interfaces (that is, the message formats)
of the window procedure remain unchanged, other window procedures within an
application are insulated from changes to the data object or its processing.
This provides a powerful tool for the enhancement of application modularity and
the containment of change within an application. This in turn facilitates the
task of application maintenance and change management, since affected
application modules may be easily identified.
A close corellation may be drawn between the concept of an application object
and that of a window under Presentation Manager. The window becomes the
identity of, or "handle" to an object; the data referenced by the window
(whether a display space on the screen or a data file) becomes a data object;
the window procedure associated with a window contains the methods to act upon
that data object; and actions to be performed by the application object on its
data object are conveyed by way of messages routed to the window by
Presentation Manager. Although Presentation Manager provides window classes to
allow grouping of objects with similar characteristics, a full inheritance
hierarchy is not supported, and thus Presentation Manager conforms more closely
to the module-based theory of object-oriented design than to the class-based
approach. Development tools such as Smalltalk V/PM** are available to extend
the Presentation Manager application model and facilitate implementation of a
full inheritance hierarchy.
The Presentation Manager application model, along with the underlying OS/2
environment, affords the ability to store an application object (that is, a
data object definition, along with the methods associated with that data
object, contained within a window procedure) in a library that may be
dynamically linked with an application. This in turn provides the potential to
develop and implement applications composed of one or more generic objects
linked by a custom-built application harness, which allows applications to be
assembled more quickly and at less cost.
The Presentation Manager programming interface includes a mechanism for
subclassing a window, whereby messages destined for a particular window may be
transparently diverted to another window for specialized processing.
Implementing an application using generic objects with subclassing to provide
specialized methods may greatly reduce the amount of coding required, and
consequently reduce the development time and cost of applications.
The general implementation of and support for object-oriented programming
principles under Presentation Manager is discussed further in The Presentation
Manager Application Model. The subject is examined in more detail, and
specific examples are discussed, in Building a Presentation Manager
Application.
ΓòÉΓòÉΓòÉ 11.3.1. Systems Application Architecture Conformance ΓòÉΓòÉΓòÉ
While Presentation Manager supports and facilitates the implementation of
object-oriented design techniques and provides support for the user interface
constructs and guidelines laid down by the CUA component of Systems Application
Architecture, it does not force an application developer to conform to
object-oriented design principles or CUA-conforming user interface guidelines.
While the rich function set provided by the Presentation Manager programming
interface allows an application developer to interpret and implement CUA
guidelines in a number of ways, there are emerging conventions with regard to
the implementation of these guidelines.
In order to achieve the benefits which accrue from adherence to object-oriented
and CUA principles, a measure of discipline is required on the part of the
application developer, so as to implement the application in such a way that
the maximum degree of object-independence and reusability is attained, and that
the optimal level of conformance to CUA conventions is achieved. The subject
of CUA conformance is discussed in detail in Systems Application Architecture
CUA Considerations.
Note that CUA conformance, along with consistency in the implementation of
application functions and user interface constructs, may be enforced or
enhanced through the use of standard functions and subroutines contained in
code libraries. The creation of such libraries is facilitated by the modular
nature of the Presentation Manager environment, and by the dynamic linking
capabilities of the OS/2 operating system. This subject is discussed further
in Generic Application Modules.
ΓòÉΓòÉΓòÉ 11.3.2. Online Help and Documentation ΓòÉΓòÉΓòÉ
Presentation Manager also supports the development of online, context-sensitive
help panels, along with online documents for support of applications, business
processes and computer-based training. Such information may be displayed in
windows on the Presentation Manager desktop, using the Information Presentation
Facility (IPF), which is shipped with the operating system.
Help panels displayed using IPF are context-sensitive, thereby allowing the
user to request help on a specific topic, and the application to that help in a
window on the Presentation Manager desktop. Help panels within an application
may be indexed, which allows a user to search for help on related topics in
addition to the topic initially requested.
Phrases or illustrations within panels may be marked as selectable, and used to
display additional information, initiate application events or start new
applications. This capability is provided by the hypertext and hypergraphics
facilities of IPF.
Online documents may also be generated by IPF. Such documents are not linked
to applications; they act as applications in their own right, and indeed may be
used to initiate the execution of application programs using the hypertext
facility of IPF. Online documents may also be indexed, and keyword searches
may be conducted on document files; these facilities are part of IPF.
Information Presentation Facility is described in detail in Adding Online Help
and Documentation.
ΓòÉΓòÉΓòÉ 11.4. The Workplace Shell ΓòÉΓòÉΓòÉ
Under OS/2 Version 1.3, the Presentation Manager provides a basis for the
implementation of object-oriented software engineering principles, allowing the
developer to take advantage of the benefits inherent in the object-oriented
approach. However, the Presentation Manager application model lacks a built-in
inheritance hierarchy, and therefore prevents the developer from realizing the
productivity and consistency benefits that may be achieved under the principle
of inheritance.
OS/2 Version 2.0 extends the object-based Presentation Manager user interface
with the introduction of the Workplace Shell*, and also provides an
object-oriented application model that allows applications to exploit the
principle of inheritance. The Workplace Shell application model views an
application as a series of objects, typically represented by icons on the
Workplace Shell desktop, which are manipulated by the user to achieve the
required result.
Objects may represent entities such as files, programs or devices, or may be
containers that allow the user to logically group related objects. The
properties or contents of an object may be examined using a view of the object,
which is typically implemented as a Presentation Manager window.
The Workplace Shell application model is based upon the system object model,
which defines a set of classes to form a basic inheritance hierarchy, and a set
of protocols for interaction between application objects. The Workplace Shell
defines its own object classes that extend the inheritance hierarchy, and an
application developer can continue to extend the hierarchy, subclassing
existing object classes to create new classes.
The Workplace Shell therefore brings both the end user and the application
developer closer to the concept of direct object manipulation, and allows
exploitation of the class-based theory of object-oriented programming. The
Workplace Shell application model, along with the creation and manipulation of
Workplace Shell objects, is described in detail in Workplace Shell and the
System Object Model.
ΓòÉΓòÉΓòÉ 11.5. Summary ΓòÉΓòÉΓòÉ
Presentation Manager facilitates the implementation of an event-driven,
object-action user interface and provides predefined constructs that enable a
consistent, intuitive user interface for multiple applications, in line with
the objectives of the Systems Application Architecture Common User Access
component. However, in order to gain the fullest benefit from such an
interface, the application developer must adopt a certain degree of
object-oriented principles in the design and implementation of applications.
In order to support the implementation of an event-driven interface and
facilitate the incorporation of object-oriented design techniques, Presentation
Manager provides an object-based, event-driven execution environment with an
application architecture that conforms closely to object-oriented theory,
within the framework of the Systems Application Architecture Common
Programming Interface. Windows become the handles by which the application
references data objects, and windows communicate with one another and with the
user in an event-driven manner. With the addition of the Workplace Shell in
OS/2 Version 2.0, the user and the programmer may deal directly with objects
and take full advantage of the concept of inheritance.
Benefits to be gained from the adoption of such principles include enhanced
opportunity for code reuse with consequent reductions in development costs, and
easier containment of change through encapsulation and data isolation. As the
programmable workstation becomes more widely utilized as the platform for
line-of-business applications, the importance of sound software engineering
principles in the design and implementation of workstation applications will
increase, in accordance with the requirement to be able to adequately manage
and maintain these applications. OS/2 and Presentation Manager together with
the Workplace Shell, which extends the paradigm to further exploit
object-oriented concepts, provide a platform for the implementation of such
principles.
It must be emphasized that Presentation Manager provides an application
architecture at the operating system level which supports the implementation of
certain object-oriented software engineering principles, and provides many of
the facilities required by such an approach. However, while Presentation
Manager supports an object-oriented approach to application design, it does not
force the application developer to conform to object-oriented design practices.
Presentation Manager does not provide, nor does it seek to provide, a complete
development environment for object-oriented applications; the provision of
such function is the responsibility of application-enabling products that may
reside and execute in the Presentation Manager environment.
The remainder of this document will further explore the relationship between
OS/2 Version 2.0, Presentation Manager and object-oriented programming, and
examine the techniques by which object-oriented applications may be implemented
in the Presentation Manager environment, using both the Presentation Manager
and Workplace Shell application models.
ΓòÉΓòÉΓòÉ 12. Operating System/2 ΓòÉΓòÉΓòÉ
This chapter briefly explains the differences between the PC DOS and Operating
System/2 (hereafter referred to as OS/2) environments, and describes the
features and capabilities of IBM OS/2 Version 2.0. The chapter discusses
OS/2's retention of compatibility with existing DOS applications, while
providing support for multiprogramming and multitasking, larger memory,
multiple concurrent communications, etc.
ΓòÉΓòÉΓòÉ 12.1. History ΓòÉΓòÉΓòÉ
IBM and Microsoft** introduced OS/2 in 1987 as a successor to the PC DOS/MS
DOS** operating system [For simplicity, the term "DOS" will be used throughout
this document to refer to both the PC DOS and MS DOS products. ] in the
programmable workstation environment. In the years since its inception in the
early 1980s, DOS has grown in both capabilities and sophistication, but by 1987
advanced workstation users were demanding more sophistication from their
applications, to an extent which was beyond the capabilities of DOS to deliver.
The choice for operating system developers lay between further enhancing the
existing DOS architecture to support more powerful processors, larger memory
and so on, or migrating to a new, more powerful operating system architecture
which offered more facilities to satisfy user requirements, a broader platform
for application development, and potential for future expansion. The latter
choice was taken, and the result was OS/2.
The OS/2 operating system environment provides a great deal more power and
flexibility than the DOS environment, while maintaining a level of
compatibility with existing DOS applications and data. Enhancements made in
OS/2 Version 1.3 include:
Effective use of the advanced capabilities of the Intel 80286 processor
Support for system memory above 640 kilobytes (KB)
Support for multiprogramming and multitasking
Dynamic linking for system and application modules.
In addition, numerous other functions are provided to support and complement
these capabilities.
OS/2 Version 2.0 was developed as an extension of the original 16-bit
implementation used in OS/2 Version 1.3, and is an advanced 32-bit multitasking
operating system for machines equipped with the Intel 80386** or compatible
processors. The following new features are implemented in OS/2 Version 2.0:
Support for the Intel 80386 32-bit microprocessor instruction set; previous
versions of OS/2 only supported the 80386 in 80286 emulation mode.
32-bit memory management with a flat memory model; previous versions of OS/2
required applications to use the segmented memory model. See Memory
Management for further information.
Enhanced hardware exploitation.
Support for multiple concurrent DOS applications with pre-emptive
multitasking and full memory protection.
Support for Microsoft Windows** applications.
New 32-bit programming environment.
Binary-level compatibility with previous versions of OS/2, allowing 16-bit
applications written for previous versions to execute under Version 2.0
without modification.
An enhanced Presentation Manager user shell, known as the Workplace Shell,
which implements the 1991 IBM Systems Application Architecture CUA Workplace
Environment.
The remainder of this chapter describes the features of OS/2 Version 2.0, and
also makes reference to architectural features implemented in previous versions
of OS/2 where appropriate.
ΓòÉΓòÉΓòÉ 12.2. Intel 80386 32-Bit Microprocessor Support ΓòÉΓòÉΓòÉ
The basis for OS/2 Version 2.0 is its support for the Intel 80386
microprocessor; previous versions of OS/2 were developed for the Intel 80286
processor, and supported the 80386 in 80286 emulation mode only. Full support
of the 80386 means that a powerful set of 32-bit features now becomes available
to the operating system and applications, including enhanced memory management
and more sophisticated multitasking capabilities. The Intel 80386 and 80486
offer significant improvements over the previous generation of 16-bit
microprocessors, while retaining compatibility with these processors.
The memory addressing capacity of the 80386 processor is significantly greater
than that of the 80286:
4 gigabyte (GB) physical address space; this compares with the 640 kilobyte
(KB) address space of DOS and the 16 megabyte (MB) address space of OS/2
Version 1.3.
64 terabyte (TB) virtual address space; DOS does not support virtual memory,
and OS/2 Version 1.3 supports 2 GB of virtual memory.
1 byte to 4 gigabyte memory objects; this compares with a 64 KB maximum size
under DOS or OS/2 Version 1.3.
OS/2 Version 2.0 uses many of these processor features and capabilities to
provide a more powerful and flexible operating system platform. Note that OS/2
Version 2.0 does not implement the full 64 TB virtual address space provided by
the 80386, since this requires use of the segmented memory model; OS/2 Version
2.0 uses a flat memory model, as described in Memory Management.
ΓòÉΓòÉΓòÉ 12.3. Memory Management ΓòÉΓòÉΓòÉ
Memory management is the way in which the operating system allows applications
to access the system's memory. This includes the way in which memory is
allocated, either to a single application or to be shared by multiple
applications. The operating system must check the amount of memory available
to an application, and must handle the situation where there is insufficient
free memory to satisfy an application's requests.
Memory management under DOS and OS/2 Version 1.3 was achieved using units of
memory known as segments, which could be from 16 bytes to 64 KB in size. The
memory model implemented by these operating systems was therefore known as a
segmented memory model. The use of data structures larger than 64KB required
the use of multiple segments, the management of which was the responsibility of
the application. This led to increased size and complexity, and reduced
performance in applications which handled large data structures.
In OS/2 Version 2.0, memory management has been enhanced to provide a flat
memory model, which takes advantage of the 32-bit addressing scheme provided by
the Intel 80386 architecture. This means that through memory management, the
system's memory is seen as one large linear address space of 4 GB. Applications
have access to memory by requesting the allocation of memory objects. Under
OS/2 Version 2.0, these memory objects can be of any size between 1 byte and
512 MB. The use of a flat memory model removes the need for application
developers to directly manipulate segments, thereby simplifying application
development and removing a significant obstacle in porting applications between
OS/2 Version 2.0 and other 32-bit environments such as AIX*.
OS/2 Version 2.0 manages memory internally using pages, each of which is 4 KB
in size. Each memory object is regarded by the operating system as a set of
one or more pages. For practical purposes therefore, memory is allocated in
units of 4 KB, although a page may be broken down into smaller parts and may
contain multiple memory objects.
One of the useful aspects of paged memory is the way in which memory
overcommitment is handled; that is, what happens when there is no more real
memory left to load applications or satisfy a request for memory from an
application. Under OS/2 Version 2.0, individual pages may be swapped to and
from disk storage, rather than entire memory objects. This improves swapping
performance, particularly when large memory objects exist in the system. The
fixed page size also improves swapping performance since the operating system
need not be concerned with moving memory objects about in order to accomodate
the various object sizes, as was the case with previous versions of OS/2.
For a more detailed discussion of memory management under OS/2 Version 2.0,
readers should refer to OS/2 Version 2.0 - Volume 1: Control Program.
ΓòÉΓòÉΓòÉ 12.4. Multiprogramming and Multitasking ΓòÉΓòÉΓòÉ
A multiprogramming operating system allows the concurrent execution of multiple
applications in the same machine. A multitasking operating system is an
extension of the multiprogramming concept, which distributes processor time
among multiple applications by giving each application access to the processor
for short periods of time. OS/2 implements both multiprogramming and
multitasking.
Multitasking may be supported in two forms:
Cooperative multitasking requires the active support of applications running
in the system, which must explicitly relinquish control of the processor to
allow other applications to execute. This form of multitasking is unreliable
and frequently leads to poor performance, since an ill-behaved application
can monopolize the processor.
Pre-emptive multitasking uses a scheduler as part of the operating system;
the scheduler is responsible for selectively dispatching and suspending
multiple concurrent tasks in the system. This form of multitasking is more
sophisticated, typically leads to greater overall system throughput, and
allows implementation of priority dispatching schemes for various tasks.
Numerous mechanisms exist for providing multiprogramming support under DOS;
these include products such as Microsoft Windows. However, since such
facilities are ultimately dependent upon the single-tasking architecture of the
DOS operating system, they typically provide only limited multitasking
capabilities; where pre-emptive multitasking is supported, schedulers are
typically primitive and performance is relatively poor. Pre-emptive
multitasking is not possible during input/output operations, since these
operations are performed by the single-tasking DOS operating system.
OS/2 provides pre-emptive multitasking under the control of the operating
system, which is designed to use the multitasking protected mode of the Intel
80286 and 80386 processors. OS/2 implements a pre-emptive task scheduler with
a multi-level priority scheme, which provides dynamic variation of priority and
round-robin dispatching within each priority level. The dynamic variation of
priority is achieved on the basis of current activity, and is intended to
improve overall system performance and ensure that the system as a whole
responds adequately to user interactions. For circumstances where dynamic
variation of priority is inappropriate, the dynamic variation may be disabled
using a command in the CONFIG.SYS file, and task priority then becomes
absolute. In either case, task priority may be set and altered dynamically
using a number of operating system functions available to OS/2 application
programmers.
The management of tasks executing in the system is further simplified and
streamlined under OS/2 Version 2.0. This is due primarily to the fact that
support for processes executing in real mode (such as the DOS Compatibility Box
in OS/2 Version 1.3) is no longer required, since the execution of DOS
applications is supported using virtual DOS machines which run as protected
mode processes. See DOS Application Support for further information.
ΓòÉΓòÉΓòÉ 12.4.1. Application Support ΓòÉΓòÉΓòÉ
OS/2 Version 2.0 supports concurrent execution of the following types of
applications:
DOS applications, in full-screen mode or in windows on the Presentation
Manager desktop
Microsoft Windows applications, in windows on the Presentation Manager
desktop
16-bit OS/2 applications developed for previous versions of OS/2
New 32-bit applications developed for OS/2 Version 2.0.
All applications execute as protected mode processes under OS/2 Version 2.0,
and are therefore provided with pre-emptive multitasking and full memory
protection; each application is isolated from other applications and from the
OS/2 Version 2.0 operating system itself.
ΓòÉΓòÉΓòÉ 12.4.2. Processes and Threads ΓòÉΓòÉΓòÉ
The term task (as in multitasking) refers to a hardware-defined task state.
While OS/2 supports multitasking, it does not directly use the concept of a
task as defined by the Intel 80386 processor architecture. Instead, OS/2 makes
a differentiation between processes and threads.
Processes
A process is most easily defined as a program executing in the system. Since it
is possible for a single program to be invoked multiple times in a multitasking
system such as OS/2, multiple processes may be executing the same program, and
each such process is known as an execution instance of the program. A process
owns system resources such as threads, file handles etc, and a memory map that
describes the region of memory owned by that process. Since each process owns
its own resources and memory map, which are administered by the operating
system on behalf of the process, the resources of one process are protected
from access by any other process. In situations where communication between
processes is required, OS/2 provides a number of architected mechanisms by
which they may be achieved. These mechanisms are described in Interprocess
Communication and Synchronization.
Threads
A thread is the unit of dispatching for the operating system's scheduler, and
therefore equates closely with the notion of an 80386 task as defined by the
processor architecture. Each thread is owned by a process, and a single
process may have multiple threads. When a process is created, one thread
(known as the primary thread ) is always created to run the code specified in
the process creation system call. Thus a process always has at least one
thread. Secondary threads are often used to perform lengthy operations such as
document formatting, remote communications etc, thereby allowing the primary
thread to continue interaction with the user. Secondary threads may be created
and terminated at any time during execution of a process. When the primary
thread of a process is terminated, the process itself terminates.
A thread executes for a short period of time before the operating system's
scheduler preempts the thread and gains control. The scheduler may then
determine that there is some other thread that ought to run; if so, the
scheduler saves the task state of the current thread and dispatches the new
thread, which executes for a period of time until it too is preempted and
control returns to the scheduler.
OS/2 Version 2.0 supports up to 4096 threads within the system. Note that this
limit includes those threads used by the operating system and by applications
executing under operating system control, such as the print spooler. The
number of threads available to applications will therefore be somewhat less
than 4096.
Since each thread is owned by a process, all threads within that process share
the resources and memory map belonging to that process, and thus have access to
those resources. OS/2 does not protect memory resources from being accessed by
multiple threads within the same process; this is the responsibility of the
application developer. However, OS/2 provides a number of architected
mechanisms to aid the application developer in maintaining the integrity of the
application's resources.
ΓòÉΓòÉΓòÉ 12.4.3. Interprocess Communication and Synchronization ΓòÉΓòÉΓòÉ
Since OS/2 provides support for concurrent execution of multiple processes,
with memory protection between these processes, it must also provide mechanisms
to facilitate synchronization and communication between different processes and
threads executing in the system, which may wish to share data and control
information. OS/2 provides a number of such mechanisms, as follows:
Shared memory
Queues
Pipes (both named and anonymous)
Presentation Manager messages
Semaphores.
These mechanisms allow application developers to implement applications using
multiple processes or threads, while retaining the ability to communicate data
and control information in a controlled manner, and to achieve synchronization
between various components of an application.
Shared Memory
The OS/2 memory management architecture utilizes the protect mode of the Intel
80386 processor to achieve memory isolation between processes. A process has
addressability only to its own memory objects. However, in certain
circumstances processes may wish to communicate and pass data to each other;
OS/2 allows this by the use of shared memory objects. Shared memory objects
are dynamically requested from the operating system by the application during
execution, and are flagged as shareable by OS/2. It is the responsibility of
the applications concerned however, to correctly synchronize the flow of data
between processes. OS/2 provides a number of mechanisms by which this
synchronization may be achieved. Shared memory and its usage is discussed in
the IBM OS/2 Version 2.0 Application Design Guide.
Queues
Queueing system calls are implemented by a system service routine that uses
shared memory and semaphores (see below) for serialization. A queue is created
by a process that then becomes the owner of that queue; only the owner may read
from the queue. Other processes may write to the queue, but only the owner may
look at elements on the queue, remove elements from the queue, purge or delete
the queue. Queues may be specified with FIFO (first-in, first-out) or LIFO
(last-in, first-out) dispatching priority.
A queue has a name, similar to a file name, by which it is known to both
processes and by which it is referred to when the queue is first accessed by a
particular process. A series of operating system functions is provided by OS/2
to create and access queues. Queues are discussed in detail in the IBM OS/2
Version 2.0 Application Design Guide.
Pipes
A pipe is a FIFO data structure that permits two processes to communicate using
file system I/O calls. The first process writes data into the pipe and the
second process reads the data from the pipe. However, the data is never
actually written to an external file, but is held in a shared area in memory.
A pipe may be named, in which case it has a name similar to a file name which
is known by both processes, or it may be anonymous in which case read and write
handles to the pipe are returned by the operating system when the pipe is
created. It is then the responsibility of the creating process to communicate
these handles to other threads or processes.
The creation of pipes is achieved using a number of OS/2 function calls; once
created, pipes are then accessed using file system I/O functions. Pipes and
their manipulation are discussed in the IBM OS/2 Version 2.0 Application Design
Guide.
Presentation Manager Messages
In the OS/2 Presentation Manager programming environment, application routines
known as window procedures communicate by receiving messages from one another
and from Presentation Manager itself. Messages may be passed between window
procedures executing in the same thread, between different threads in a
process, or between processes.
Messages may be used to pass data between routines executing in different
threads or processes, or to communicate events in order to achieve
synchronization between threads and/or processes. Presentation Manager
messages may be used to invoke processing routines in either a synchronous or
asynchronous manner. The Presentation Manager messaging model conforms closely
to object-oriented programming practices, and is described further in The
Presentation Manager Application Model.
Atoms
Where character strings must be passed between threads, it is relatively simple
to pass a pointer to the character string, since all threads within a process
share access to memory objects. Where strings must be passed between processes
however, more complex methods such as shared memory must normally be used.
OS/2 provides a way to simplify the passing of strings between processes, using
atoms.
An atom is effectively a "handle" to a string that is stored in an area of
shared memory known as an atom table. Atom tables are maintained by the
operating system, and may be private to a particular process or shared by all
processes in the system. OS/2 creates a system atom table at system
initialization time, which is accessible by all processes in the system.
A process may add a string to an atom table, and obtain an atom that may
subsequently be used to access the string. Atoms that reference strings in the
system atom table may be passed between processes using any of the methods
described in the foregoing sections, and used by another process to obtain the
contents of the string.
Semaphores
OS/2 applications may be implemented using multiple threads within one or more
processes. Within a single process, the OS/2 memory management architecture
provides no memory protection for different threads, and hence multiple threads
may have addressability to the same data areas. It is important that the
integrity of resources such as common data areas or files, shared between
threads, be protected at all times. Such resources must be accessed in a
serialized fashion. Although OS/2 provides no automatic protection for data
resources between threads within a process, OS/2 allows an application to
achieve this serialization of access by using semaphores.
A semaphore is a data structure that may be "owned" by only one thread at any
time. Semaphores may be used as flags by an application, to indicate that a
data resource is being accessed. A thread may request ownership of the
semaphore; if the semaphore is already owned by another thread, the requesting
thread is blocked until the first thread releases it.
OS/2 Version 2.0 provides a number of different types of semaphores, to be used
in different circumstances:
Mutex semaphores provide mutually exclusive access to a particular resource
such as a shared memory object. These semaphores offer a useful means of
synchronizing access to such resources between different threads or
processes.
Event semaphores are used to signal system or application events. These
semaphores provide a means of signalling events to other threads or
processes, allowing such threads to suspend their execution and "wait" for a
particular event to occur.
MuxWait semaphores may be used when waiting for multiple events to occur or
multiple mutex semaphores to clear.
Within these semaphore types, OS/2 Version 2.0 provides both private and shared
semaphores. The system semaphores and RAM semaphores provided by previous
versions of OS/2 are also supported, retaining compatibility with applications
developed for previous versions of the operating system. Each process in the
system may have up to 65535 private semaphores, and there may be up to 65535
shared semaphores in the system.
OS/2 Version 2.0 provides a number of operating system functions allowing the
creation and manipulation of semaphores. Semaphores are discussed in the IBM
OS/2 Version 2.0 Application Design Guide.
ΓòÉΓòÉΓòÉ 12.5. DOS Application Support ΓòÉΓòÉΓòÉ
OS/2 Version 1.3 provides the capability for a single DOS application to be
executed in the system using a facility known as the DOS Compatibility Box. The
DOS application executes in real mode, and is automatically suspended if the
DOS Compatibility Box is switched to the background; that is, pre-emptive
multitasking is not supported in the DOS Compatibility Box under OS/2 Version
1.3.
OS/2 Version 2.0 provides the capability to pre-emptively multitask DOS
applications along with OS/2 applications, using the Multiple Virtual DOS
Machines feature of OS/2 Version 2.0. The DOS support has been totally
rewritten in OS/2 Version 2.0 and allows multiple concurrent DOS applications
where each is executed as a single-threaded, protected mode OS/2 program. This
method of implementation provides pre-emptive multitasking for DOS
applications, and allows normal OS/2 levels of memory protection; that is, it
provides isolation of system memory and other applications, protection from
illegal memory accesses by ill-behaved applications, and the ability to
terminate sessions where applications are "hung".
DOS support is achieved through the use of virtualization techniques, allowing
the creation of multiple instances of separate, independent virtual DOS
machines. Through this technique, a virtual interface is provided to each DOS
machine, giving the impression that each application owns all of the required
resources, both hardware and software.
Each virtual DOS machine has more memory than the DOS Compatability Box
implemented in previous versions of OS/2, and OS/2 Version 2.0 supports the use
of Lotus**-Intel-Microsoft (LIM) expanded memory (EMS) and extended memory
(XMS) to provide additional memory for those DOS applications that are capable
of using such extensions. OS/2 Version 2.0 maps this extended or expanded
memory into the system's normal linear memory address space, and manages it in
the same manner as any other allocated memory.
The ability of a virtual DOS machine to run within a Presentation Manager
window provides immediate productivity gains to existing DOS applications,
since they may utilize Presentation Manager desktop features. These features
include window manipulation and the ability to cut/copy/paste information
between applications using the clipboard.
Application compatibility in the virtual DOS machine is also enhanced over
previous versions of OS/2. The virtual DOS machine can be used to execute
DOS-based communications applications and other applications that address
hardware I/O devices, through the use of virtual device drivers that map the
device driver calls from the applications to the appropriate physical device
driver within the operating system. Applications using hardware devices that
are not required to be shared with other applications in the same system may be
accessed using the standard DOS device drivers, without the need for a virtual
device driver. Certain restrictions still apply with respect to communications
line speed and time-critical interrupt handling.
For applications that require specific versions of DOS in order to operate,
OS/2 Version 2.0 provides the capability to load a physical copy of that
version into a virtual DOS machine. This provides compatability for those
applications that internally manipulate DOS data structures or that use
undocumented interfaces.
Application compatability in a virtual DOS machine is further enhanced by the
DOS settings feature, which allows virtual DOS machines to be customized to
suit the requirements of the applications running in them. Properties such as
video characteristics, hardware environment emulation, and the use of memory
extenders can all be customized using this feature.
Multiple Virtual DOS Machines is described in more detail in OS/2 Version 2.0 -
Volume 2: DOS and Windows Environment.
ΓòÉΓòÉΓòÉ 12.6. Microsoft Windows Application Support ΓòÉΓòÉΓòÉ
OS/2 Version 2.0 provides the capability for Microsoft Windows applications to
run under OS/2 Version 2.0, in virtual DOS machines. This support allows
applications written for Windows 3.0 and previous versions of Windows to
coexist and execute concurrently in the same machine.
Each Windows applications executes as a protected mode process. Windows
applications are therefore subject to the full memory protection facilities
provided to protected mode applications under OS/2 Version 2.0, and are
protected from one another and from DOS or OS/2 applications executing in the
system. This is in contrast to the native Windows 3.0 environment, where
limited protection is provided for Windows 3.0 applications, and none at all
for DOS applications unless Windows is running in enhanced mode.
The execution of Windows applications as protected mode tasks also allows these
applications to take full advantage of the pre-emptive multitasking
capabilities of OS/2 Version 2.0, with full pre-emptive multitasking between
Windows applications, DOS applications and OS/2 applications. This is again in
contrast to the native Windows 3.0 environment, where pre-emptive multitasking
is available only for DOS applications, only when Windows 3.0 is running in
enhanced mode, and only when no input/output operations are being performed,
thereby impacting performance and preventing many applications written for
previous versions of Windows from executing. OS/2 Version 2.0 has no such
restriction.
As with DOS applications, Windows applications may make use of EMS and XMS
memory extenders in order to access memory above 640 KB. This support is
provided in an identical manner to that provided for DOS applications.
Support for Microsoft Windows applications under OS/2 Version 2.0 is discussed
in more detail in OS/2 Version 2.0 - Volume 2: DOS and Windows Environment.
ΓòÉΓòÉΓòÉ 12.7. Dynamic Linking ΓòÉΓòÉΓòÉ
OS/2 system services are requested by application programs using function
calls; the external code references generated by such calls are resolved when
the program is loaded or when the segments of the program are loaded, rather
than at link-edit time. This deferred resolution of external references is
known as dynamic linking, and is available to applications, which may
incorporate their own routines into dynamic link libraries (DLLs).
Dynamic linking may be achieved in two ways under OS/2;
Load-time dynamic linking resolves external references within a code segment
at the time the segment is loaded into memory.
Run-time dynamic linking postpones the resolution until the actual execution
of the code, at which time the appropriate module is explicitly loaded and
invoked by the application.
Load-time dynamic linking is the simplest mechanism; as already mentioned,
OS/2 system services are implemented in this way. Load-time dynamic linking is
used whenever an application developer wishes to provide common services that
may be used by multiple applications, and which are implemented independently
of the applications that will use them. Run-time dynamic linking is used where
particular routines may or may not be used by an application, and thus should
not be loaded into memory unless required. If an application requires that such
a routine be executed, the application may then explicitly load the routine and
execute it.
Dynamic linking provides an architected method of extending the services of the
operating system; all of the application programming interfaces supported by
OS/2 are implemented using dynamically linked modules. An application
developer may use the same facilities to create his or her own dynamically
linked modules to provide additional services or standard routines that may be
used by applications executing in the system.
Dynamic linking is of benefit in that routines contained in DLLs are completely
independent of application code, and may be modified without the need to
re-link applications. In this way, DLLs contribute to the containment of change
within applications. In addition, the contents of DLLs are not limited to
application code. Presentation Manager resources such as icons, bitmaps,
graphics fonts, window definitions etc, may be generated and stored in a DLL
for subsequent use by applications. See Presentation Manager Resources for a
further discussion of Presentation Manager resources. DLLs thus provide a
powerful mechanism for the creation of reusable modules for both full-screen
and Presentation Manager applications.
Secondly, the creation of DLLs as re-entrant routines reduces the storage
requirements for OS/2 applications, since multiple applications may make use of
the same memory-resident copy of a DLL. This re-entrancy and reusability, in
conjunction with the code independence gained by using a DLL, makes the DLL a
useful vehicle for implementation of standard service routines, which may be
accessed by any application or process within the system. This contributes to
standardization within the business organization, which in turn can result in
improved productivity and reduced maintenance effort since the code to
implement a particular function need reside in only one location.
Note that a DLL is not a process under OS/2. The re-entrant nature of a DLL
allows multiple applications to use the same memory-resident copy of the code;
however, each instance executes under the control of the process that invoked
it.
ΓòÉΓòÉΓòÉ 12.8. Summary ΓòÉΓòÉΓòÉ
OS/2 provides the programmable workstation platform for the delivery of Systems
Application Architecture application functionality in the standalone
workstation and cooperative processing environments. OS/2 overcomes the
limitations of the DOS operating system by providing support for large physical
and virtual address spaces and supporting concurrent execution of multiple
applications with memory isolation and automated task dispatching. While
enforcing memory protection between applications, OS/2 provides architected
mechanisms to allow interprocess communication and data sharing in a controlled
manner.
OS/2 also provides compatibility with existing DOS applications, since OS/2
Version 1.3 allows a single DOS application to run using the DOS Compatibility
Box, and OS/2 Version 2.0 allows multiple concurrent DOS applications to
execute in virtual DOS machines. OS/2 Version 2.0 also supports Microsoft
Windows applications in a similar manner to DOS applications. This allows
users of OS/2 systems to continue to use their existing DOS and Windows
applications under the new operating system.
OS/2 also implements dynamic linking, which allows an application developer to
isolate common application services in separate modules known as dynamic link
libraries (DLLs). Calls to application services provided in a DLL are resolved
at execution time, which means that any modifications to the routines contained
in a DLL do not require any maintenance to applications using that DLL. In
addition, DLLs are created as re-entrant code, thus allowing multiple
applications to use the same memory-resident copy of the DLL code and thereby
reducing storage requirements.
OS/2 provides an operating system environment for the programmable workstation
that enables a far greater degree of functionality and sophistication on the
part of application programs. OS/2 Version 2.0 provides architected methods
for overcoming most of the inherent limitations of the DOS and OS/2 Version 1.3
environments, and providing the workstation user with a higher level of
capability in the workstation. OS/2 provides the vehicle that will enable the
fulfillment of the Systems Application Architecture cooperative processing
direction.
ΓòÉΓòÉΓòÉ 13. Object-Oriented Applications ΓòÉΓòÉΓòÉ
This chapter provides a brief overview of some concepts involved in
object-oriented application design and programming, and the way in which this
approach differs from traditional top-down functional decomposition. It is not
intended as an indepth analysis of object-oriented programming, since such a
task is beyond the scope of this document, but serves merely to provide a
background against which the implementation of object-oriented principles under
Presentation Manager may be discussed.
ΓòÉΓòÉΓòÉ 13.1. Object-Oriented Concepts ΓòÉΓòÉΓòÉ
Object-oriented application design places the focus of an application on the
logical entities or objects (typically items of data) upon which a program will
operate, and attaches procedures or routines to manipulate these objects. A
logical data entity (such as a group of records) may have multiple
representations within the system. Each of these representations is known as a
data object, and each data object may have a finite set of actions performed
upon it. The data object itself, along with the routines (known as methods)
used to perform these actions, are together regarded as an application object.
Note that in the remainder of this document, the term data object will be used
to denote a particular representation (for example, on the screen or in a disk
file) of a logical data entity. The term application object will be used to
denote the conjunction of a data object and its methods. While these terms are
not in general use, they will be used here in order to provide a distinction
between a data item, and the conjunction of that data item and the routines
that act upon it.
Application objects typically respond to events, which originate outside the
object and which may be system-initiated or user-initiated. The sequence of
these events determines the sequence of operations within the application, and
the progression of dialog between the application and the user, rather than the
application determining the sequence of the dialog, as is traditionally the
case. Such an object-oriented application environment is thus said to be
event-driven.
Events are communicated to an application object by means of a series of
defined messages, which are not considered to be part of the objects between
which they are passed. The focus of the program thus becomes the object,
rather than the procedure, and the program becomes a flow of messages between
cooperating objects.
Actions on a data object should be possible only by sending messages to the
associated application object; an object's methods should not be directly
accessible from another object, nor should the behavior of an object be
dependent upon any external source other than the messages it receives. A
message should also specify only the action that is to be carried out, and not
the way in which it is to be accomplished. It is the responsibility of the
receiving object to determine the way in which to carry out a requested action.
Consequently, the behavior of an application object may differ, depending upon
the class and content of its input messages. A corollary of this statement is
that the result of passing the same message class may vary, depending on the
target object class and its interpretation of that message. These guidelines
outline the concept of polymorphism.
One of the primary properties of an application object is its modularity;
objects that obey the foregoing rules should be largely independent of one
another, and the implementation of one object should not be dependent upon the
internal details of another. Data belonging to an application object should be
accessible only by that object; requests for access by other objects should be
made via appropriate messages sent to the application object that "owns" the
data object. Thus the only information necessary to use an application object
is a knowledge of the messages it can receive and operate upon (through its
methods). This rule encompasses the principle of encapsulation, which states
that a data object should be defined, created and/or accessed solely from
within its "owner" application object.
Since a number of application objects may exist with similar characteristics,
such objects are usually grouped into object classes. A class consists of those
objects that share similar properties and methods. An object class is
typically associated with a single data object or type of data object, and has
a defined, finite set of methods associated with it. It is the class that
normally defines the messages and methods applicable to an object. Each object
belonging to a particular class is then known as an instance of that class.
Each instance inherits data objects and values defined for its class, and may
also contain its own data, known as instance data; the properties of instance
data are typically obtained from the definition of the object class, but the
values are defined uniquely by each instance.
The object-oriented approach is most suited to situations where the purpose of
the application is the manipulation of data, whether on the screen or in a data
file, and where the exact sequence of actions is not critical, provided all
necessary actions are carried out. The focus of an object-oriented application
is the data objects that are being manipulated; the functions to be performed
are subordinate to the data objects upon which they will act. In addition, the
event-driven user interface places the user in control of the sequence of
actions, and provides flexibility with respect to the way in which the desired
result is achieved.
An advantage of the object-oriented design approach for data manipulation
applications is that a particular data object is "owned" by one application
object, and that the definition of and establishment of access to that data
object is achieved from within the application object. Since application
objects may be made relatively independent of one another, other objects may be
isolated from changes to the data structure. This greatly simplifies
application maintenance, since all necessary changes need only be made within a
single object.
Note that since application objects are closely related only to their
associated data objects, and not to the applications from which they are
accessed, it follows that application objects may be constructed for each data
object, and accessed from multiple applications. An application need not be
aware of the internal workings of an application object, but need only know the
correct type and format of the messages through which to interact with the
object. Thus the object-oriented approach facilitates code reusability.
ΓòÉΓòÉΓòÉ 13.1.1. Object-Oriented vs Functional Decomposition ΓòÉΓòÉΓòÉ
Under a traditional functional decomposition approach to program design, often
referred to as structured programming, the function or procedure is the unit of
modularity; programs are designed and implemented by placing a number of
well-defined procedures in a particular order, and executing these procedures
to achieve a desired result. The focus of the design is the procedure or
action to be performed. Objects such as data structures are attached to
procedures and passed between them using parameters. A user typically selects
an action to be performed, and then selects or enters a data object upon which
to perform that action.
Figure "Program Flow - Functional Decomposition Approach"
The functional decomposition approach is best suited to situations where the
procedure is necessarily the focus of the application (for instance, a process
management application), and where the correct sequencing of operations to be
performed is a crucial factor in the successful execution of the required task.
Under this approach, the application defines the sequence of actions which the
user performs; that is, the application controls the user interface.
In an object-oriented approach, the application object is the unit of
modularity. Application objects communicate with each other and pass messages
containing actions to be performed. Object-oriented programming is hence the
conceptual inverse of functional decomposition, and is a logical extension of
the industry trend toward data-centric application design.
Figure "Program Flow - Object-Oriented Approach"
This is not to say that an object-oriented application should not be
structured. Although such an application consists of objects that are largely
independent of one another in programming terms, normal structured coding
techniques should be followed in the creation of the methods within each
application object.
The object-oriented approach also requires firm management of the application
development process in order to achieve the greatest possible level of
productivity through code reuse. Administration and control of existing
objects is vital in order to allow application developers to access and use
these objects in their applications. Management of the application development
process is discussed in greater detail in Managing Development, and the
structuring of application source modules in order to provide optimal
granularity is described in Application Program Construction.
While it is possible for an application designed according to functional
decomposition principles to implement some of the characteristics of
object-oriented applications such as message passing, such applications should
not be regarded as truly object-oriented. If the design approach centers on
procedures rather than data objects, then the application is designed along
functional decomposition guidelines. In this case, message passing is merely a
replacement of the normal subroutine call mechanism, and does not significantly
affect the structure of the application.
ΓòÉΓòÉΓòÉ 13.1.2. Class-Based vs Module-Based ΓòÉΓòÉΓòÉ
The notion of object classes, and the extent to which this concept is taken,
provides the distinguishing factor between two primary schools of thought
within the object-oriented paradigm. Under a class-based approach, objects are
defined in terms of their class, and each class is defined in terms of other
previously defined classes, the properties and methods of which are
automatically conveyed upon the new class; this is known as the principle of
inheritance.
For example, the object class "horse" may be defined as a sub-class of the
object class "quadruped", with the additional properties of being able to be
ridden and eating grass. A further object class "pony" may then be defined as
being a sub-class of the class "horse", with an additional upper limit on size.
While this is a somewhat frivolous example, it illustrates the principle that
an object class is defined in terms of other object classes, and need only
explicitly define those properties and methods that are unique to that object
class. All other properties and methods are inherited from its parent class or
classes. This introduces the concept of an inheritance hierarchy, in that an
object inherits not only the properties and methods of its class, but also
those of other classes by way of which that class was defined.
The major advantage of such an inheritance hierarchy is that, given a
well-documented set of existing objects, it becomes extremely easy to create
new object classes, simply by defining the new class in terms of other classes
that already exist, and simply specifying any new or different properties or
methods that apply to the new class. This of course assumes the use of
adequate object documentation and management practices. Without such
practices, it becomes difficult if not impossible to identify a suitable base
object from a large library of existing object classes.
However, many existing implementations of the class-based approach extend the
inheritance hierarchy to a great degree, such that almost all imaginable object
classes are defined in terms of parent object classes. While this provides a
unified approach to the problem of object definition, the significant
disadvantage of such an approach is the increased level of interdependence
between objects. The unit of modularity becomes the complete hierarchy rather
than the individual object, since an object has no complete definition in its
own right. The reuse of a single object therefore requires the inclusion of
its complete parent hierarchy. Since it is typical for this parent hierarchy
to be defined dynamically using run-time definitions for parent classes rather
than defined statically at application generation, it is also possible for
changes to a parent class to cause unforeseen side-effects in the behavior of
descendant object classes. Thus inheritance hierarchies require careful
management to ensure that such side effects do not occur and adversely affect
the integrity of applications and data.
Where the inheritance hierarchy is taken to the extent of providing
system-defined object classes, to which all application-defined object classes
are linked, the hierarchy and thus the application is dependent upon the
existence of a virtual machine conceptual environment, which must also be
accepted along with the hierarchy. This in turn may result in significant
penalties in terms of application efficiency and run-time performance.
A module-based approach to object-oriented programming defines each object as
complete in its own right. Objects may still be grouped into classes for
easier definition and processing, but each class possesses its own complete set
of properties and methods, and is not dependent upon another class for a part
of this definition. The primary advantage of the module-based approach is the
increased level of independence between objects, with a finer degree of
granularity in the application allowing object reuse with a lower level of
overhead. The main disadvantage of this approach is that each object class
must be completely defined, requiring more work on the part of the application
developer at the time the object is created.
The concept of inheritance, while providing great potential for productivity
enhancement during the application development process, must be carefully
managed in order to avoid additional complications in application management
and maintenance due to object interdependencies. Side effects arising from
modification to parent object classes may adversely affect the integrity of an
application. The alternative course of action, that of prohibiting the
modification of existing objects in favor of creating new objects that inherit
only the unmodified properties of the existing object, is often not viable due
to the increased application overhead and managerial effort required to
maintain and control an ever-expanding inheritance hierarchy. Reliance on the
behavior of existing objects must therefore be viewed with extreme caution in
the absence of effective management controls over object modification.
The increase in development productivity provided by the use of inheritance may
often be offset by the increased time and effort spent in regression testing of
existing applications in order to determine any effects on these applications
caused by the modification of existing object classes. Tight managerial
controls over development must therefore be maintained in order to identify and
isolate those existing object classes that are modified and which are likely to
affect existing applications.
One technique that can be used to minimize the impact on existing applications
is for the development organization to adopt a standard whereby, once an
application object is deployed in a production environment, new applications
that use the object may only modify its behavior through the use of subclassing
(see Subclassing). This means that the object itself is not modified, and
other applications that use the object are not affected.
ΓòÉΓòÉΓòÉ 13.1.3. Subclassing ΓòÉΓòÉΓòÉ
As already mentioned, the object-oriented approach facilitates the reuse of
application code; generic objects may be created and used by multiple
applications to perform actions upon the same data object or type of object.
However, one of the criticisms often levelled at this capability is that it
becomes impossible to foretell the total set of actions that may ever be
required with respect to a particular data object, and that an object is
therefore never truly reusable.
The object-oriented approach overcomes this difficulty by providing a way for
applications to modify the behavior of existing application objects without
modifying the objects themselves; this is known as subclassing the object. A
subclass application object is composed of a data object definition and a
certain number of methods to manipulate that object. The subclass application
object may contain methods that are not contained within the original
application object created for that data object, or methods that are modified
in some way from those contained in the original object. In this way a
subclass application object may add new methods to perform actions which are
not performed by the original object class, or to handle certain types of
message in a different way than that normally carried out by the original
object class.
Figure "Subclassing an Application Object"
When an application object has been subclassed, all messages intended for that
object are directed to the subclass application object first. The sending
object need not be aware that the message has been diverted. If the subclass
application object does not contain a method to deal with a particular message,
it should then pass the message on to the original application object, for
processing by one of that object's methods. The original application object
receiving a message in this way should also be unaware that it has been
subclassed.
A useful application of the subclassing principle occurs when a generic
application object is defined and stored away for use by many applications,
taking advantage of the reusability aspects of the object-oriented approach.
Where one application wishes to perform a particular action in a slightly
different manner than that performed by the methods associated with the generic
object, a subclass application object may be created containing a new method
for that specific action only, and passing all other messages to the original
application object for regular processing. It can be seen that subclassing is
a technique for application of the concept of inheritance, through its ability
to transparently add properties and methods to existing objects.
Subclassing also provides a way to overcome the danger of inadvertently
impacting the behavior of other applications by modifying an existing
application object. If a standard is adopted whereby existing application
objects in a production environment may only be modified through subclassing,
such changes do not impact applications using the original object or which may
themselves have subclassed that object. In this way the need for regression
testing of affected applications is eliminated, and the degree of
object-management required is significantly reduced.
When a functional requirement may be satisfied by modifying the methods of an
existing application object (through subclassing), a decision must be made
regarding the relative merits of modifying the object, against creating a new
object. Various texts advocate a rule whereby a new object should be created
when more than 10% or 20% of an existing object's methods must be modified.
However, the decision of whether to modify an existing object or create a new
object must be taken on the basis of object complexity, degree of modification
and experience.
ΓòÉΓòÉΓòÉ 13.2. User View vs Application View ΓòÉΓòÉΓòÉ
A primary benefit of the object-oriented approach is its intuitive user
interface; a user selects an object and performs a series of predefined actions
upon that object. This object-action style of interface encourages the user to
explore the application through context-sensitive actions, and reduces the
overall complexity of the user's interaction by reducing the levels of
hierarchy required for the application.
However, the end user may have a different view of an object-oriented
application from that which must necessarily be taken by the application
developer. For instance, in the case of a text editor application editing a
file, there may in fact be two versions of this file; one existing in memory,
being manipulated by the application, and the other stored on a disk. The
application would consider these as two separate data objects, each with its
own set of methods, and would create two application objects.
Normal user interaction would take place with one object (the memory
representation of the file), and when the user selects a "Save" action for the
file, a message is passed to the second object (the disk representation of the
file) with the information necessary to save updates on disk storage. The user
considers the logical data entity as the object being manipulated, while the
application must distinguish between the representations of that data entity in
various locations within the system. The user's metaphorical view of the data
object is therefore not carried over to the application's view, which must by
necessity be more concerned with the reality of that object's manipulation.
Note however, that this distinction between representations should not be
apparent to the end user. The end user should perceive a single object (the
text file) upon which he or she would perform actions. Thus there is a
distinction between the user's view and the application's view of the objects.
An understanding of this distinction is important in order to comprehend the
difference between an object-action user interface and an object-oriented
application design.
Figure "Object-Oriented Development Progression"
The two concepts are complementary but distinct. An event-driven,
object-action user interface necessarily emerges from an object-oriented
application design and implementation. It is not possible to provide such an
interface unless the application structure conforms to a certain level of
object-oriented principles and practices. This in turn is dependent upon an
object-oriented application design. For this reason, the proper implementation
of the graphical user interface concepts defined in the IBM Systems Application
Architecture CUA Advanced Guide to User Interface Design, requires applications
to be designed and implemented using object-oriented guidelines.
ΓòÉΓòÉΓòÉ 13.3. Object-Oriented Design ΓòÉΓòÉΓòÉ
The success of object-oriented design lies in the correct and intelligent
definition of application objects and their methods as coherent and independent
units. The secret of a successful approach to this task is the consideration
of the data objects themselves as the focus, rather than the procedures that
will operate upon these objects. Since the objects are typically associated
with data, an entity-relationship model is often a useful starting point.
Correctly-designed application objects facilitate reusability, since the data
object and applicable actions are all defined within the application object.
Additional applications that require manipulation of that data object may use
the existing application object to achieve the required actions. Certain
applications may require additional, unforeseen actions, or that existing
actions be carried out in a different manner; in such cases, subclassing the
application object allows such modifications to be carried out. One of the
aims in the high-level design of an object-oriented application should be to
make maximum use of existing application objects where possible, in order to
reduce the design, coding and testing effort required. This not only reduces
the time and expense involved in application development, but enables
application solutions to be delivered in a shorter time frame, allowing the
business enterprise to respond more quickly to a dynamic marketplace.
The correct definition of application objects and their boundaries also
facilitates change management and maintenance of application code, since
changes to a particular data object should affect only the application
object(s) dealing with that data object. Thus the effects of change are
ideally confined to a single application object. Modifications to a method
within an application object should not affect the workings of other objects
with which that application object interacts, provided the external interfaces
of that object are not altered by the modification. This containment of change
within a single application object has the potential, in conjunction with
proper configuration management techniques, to greatly ease the effort and cost
involved in application maintenance.
The following steps are necessary in the design of an object-oriented
application:
1. Identify the data objects (that is, the different representations of the
logical data entity or entities upon which the application is to operate)
and the relationships between data objects.
2. Determine the set of applicable actions to be performed on each data
object.
3. Determine whether application objects have been previously been created for
the data objects to be manipulated by the application, and to what extent
these existing objects perform the required set of actions for each object.
4. Determine the message classes required to achieve the desired communication
and to initiate required actions that are not already satisfied through
existing application objects.
5. Design the methods necessary to carry out the additional actions.
These steps are generic in nature, and must be combined with suitable
management controls, checkpoints and documentation standards to ensure adequate
design quality at each stage in the process.
ΓòÉΓòÉΓòÉ 13.3.1. Object Identification ΓòÉΓòÉΓòÉ
The identification of data objects and their relationships should begin with
the definition of a normal entity-relationship model, and the extension of this
model to reflect the representations of data objects as well as the logical
data entities involved. The objective should be to achieve an optimal balance
between the number of object classes and the size and complexity of each class,
since each object may itself be composed of other objects, also bearing in mind
that multiple objects of the same class may exist. Optimizing the number of
object classes will allow the number of message classes to be minimized, which
in turn simplifies the design of the methods and the eventual testing of the
object classes.
ΓòÉΓòÉΓòÉ 13.3.2. Action Identification ΓòÉΓòÉΓòÉ
Having defined the data objects and their relationships, the set of actions
pertaining to each data object should be determined. Once this point is
achieved, the high-level design of the application objects, and therefore of
the application itself, is essentially complete, and should be documented and
approved by all concerned parties before the detailed design of methods
commences. Note that it is not necessary to define all of the applicable
actions for each data object, since the essentially independent nature of
methods allows additional actions to be added to an application object.
ΓòÉΓòÉΓòÉ 13.3.3. Search for Existing Objects ΓòÉΓòÉΓòÉ
Once the data objects and the set of actions required for each object have been
defined, the application designer should determine the existence of any
previously-created application object classes for that type of data object.
The use of existing application objects, with additional actions and methods
handled through subclassing, can significantly reduce the amount of coding
required.
The accurate identification of existing application object classes requires
that each application object, upon completing its final testing, must be placed
in an object library, and its external interfaces (both input and output) must
be fully documented and placed in a retrieval system from which the object's
description may be recalled by designers of future applications. The
organization and level of sophistication of such a system is largely at the
discretion of the development organization, but becomes more crucial as the
number of application objects grows larger over time. It is strongly
recommended that any organization embarking on a strategy of object-oriented
application development should adopt an efficient object library management
system from the outset.
ΓòÉΓòÉΓòÉ 13.3.4. Message Definition ΓòÉΓòÉΓòÉ
When the high-level design is complete, the message classes and their contents
must be defined for each action that will be performed on and by an object.
Note also that the same message class may be used with different object classes
to achieve a different result, in accordance with the principle of
polymorphism, thus reducing the number of defined message classes and
simplifying the design of the application objects and their methods.
The message classes comprise the interfaces between objects, and provide the
input and output for the methods associated with the object. These message
interfaces must therefore be documented to facilitate reusability of the
newly-created application objects by documenting the valid inputs and outputs
for each object class, and the behavior of the object in response to these
messages.
Since the messages received and dispatched by an object constitute the inputs
and outputs required and expected of that object, the documented message
interfaces provide a valuable starting point for developing a test plan for the
object. Since the inputs, actions and outputs are known, a comprehensive set
of test data may then be formulated to test the methods associated with each
action, with both valid and invalid message inputs.
ΓòÉΓòÉΓòÉ 13.3.5. Method Design ΓòÉΓòÉΓòÉ
Traditional functional decomposition techniques may then be used in the design
of the methods to complete the required actions. If the high-level design has
been completed correctly, the application objects should be relatively
independent of one another. It should therefore be possible to complete the
development and testing of the methods for each object class as a separate task
with each class, its methods and valid interfaces defined and unit-tested
before the application is brought together for final integration-testing.
ΓòÉΓòÉΓòÉ 13.4. Object-Oriented Implementations ΓòÉΓòÉΓòÉ
There has been much discussion in the computing industry press concerning
application development products and tools that support the creation of
object-oriented applications. While the use of such products is a valuable aid
in designing and developing an object-oriented application, it should not be
construed that their use is essential to the successful implementation of an
object-oriented approach.
It is quite possible to implement module-based object-oriented principles to a
practical and beneficial degree in the Presentation Manager environment, using
a "conventional" programming language such as "C". However, the degree of
discipline and amount of work required of the application developer is greater
when a standard programming language is used. Object-oriented tools or
language extensions make the task of the application developer much easier,
since many of the object-oriented concepts are handled by the tools themselves,
without the need for the developer to concern him/herself with the details of
their implementation.
Object-oriented programming tools fall into two general categories:
Those that provide extensions to an existing programming language and
implement certain object-oriented conventions, such as C++. These languages
typically provide object-oriented constructs but do not force an application
developer into the use of such constructs. The strength of such
implementations is their flexibility, but they have the inherent weakness
that it is easy to develop application code that does not conform to
object-oriented programming practices.
Those that provide a complete programming language syntax, which obeys and
implements object-oriented principles, such as Smalltalk V**. These languages
provide an additional benefit in that they force the application developer
into obeying object-oriented programming practices, but at the expense of
flexibility.
The tools that are marketed as "object-oriented" and which are currently
available in the marketplace tend to implement the class-based approach to
object-oriented programming. Their primary benefit is thus that they provide
an inheritance hierarchy, and so make the task of object creation much easier
for the application developer, albeit at the risk of reduced code efficiency
and possible dependence upon a conceptual run-time environment.
The choice of an object-oriented programming tool is very much an individual
one, and depends on the requirements and priorities of the development
organization, the skills and prior experience of the application developers
concerned, and the degree to which object-oriented practices are to be enforced
within the organization.
ΓòÉΓòÉΓòÉ 13.5. More Complex Objects ΓòÉΓòÉΓòÉ
For relatively simple applications where a data object is retrieved,
manipulated and saved again, the foregoing definition of an application object
will suffice. However, the situation often arises when an application must
perform some processing that is rather more complicated. Either the application
must interface with another system or external device or a certain work task
must be performed in a particular sequence of operations that is critical to
the correct completion of the task. The incorporation of such requirements
into the object-oriented paradigm requires an expansion of the application
object concept.
The key to successful expansion of the object-oriented paradigm lies in the
definition of a data object. Whereas a data object was previously defined as a
manifestation of a logical data entity, the definition will now be expanded to
include any other type of logical entity or source of information, such as an
external system or a procedures manual.
ΓòÉΓòÉΓòÉ 13.5.1. Device Manipulation ΓòÉΓòÉΓòÉ
The entity represented by an application object may be a physical device. For
example, suppose an application is required to access a particular type of
external data input device such as an MICR reader. The definition of the
protocols and specialized access routines necessary to interact with such a
device can be encapsulated within an application object, and the various
actions performed by the device on behalf of the application (such as getting
the next MICR document) then become the methods associated with that object.
The application thus regards the MICR reader as an object to which it passes
messages in order to perform actions; the results of those actions are then
conveyed back to the application, also by way of messages.
ΓòÉΓòÉΓòÉ 13.5.2. Access to Remote Systems ΓòÉΓòÉΓòÉ
The representation of a physical device as an application object may be
extended to encompass any external entity with which an application must
interact. Suppose that an application executing in a programmable workstation
must interface with a number of server applications executing in a System/370
host, using the SRPI interface. The host system may be regarded as a logical
entity, and a single application object created to interact with that entity.
All communications-related and interface-specific code may then be encapsulated
within that object, and other objects within the application need not concern
themselves with the details of the SRPI communication. A message passed to the
application object by a requesting object elsewhere in the application will
contain the name of the server application to be invoked, and the data to be
passed to the server application. A return message from the host-interaction
object will contain the reply data from the server application.
Figure "Encapsulation of Host Interaction Within Application Object"
The isolation of programming interfaces and protocols specific to the
communications architecture, within the "Host" application object provides an
easy means of insulating the remainder of the application from changes to
communications network configurations or to the remote system itself. Such
changes would only require modification to the "Host" object.
ΓòÉΓòÉΓòÉ 13.5.3. Procedure Manuals ΓòÉΓòÉΓòÉ
An administrative procedure, which is merely a set of information that
documents the way in which a task must be performed, may also be regarded as a
procedural entity that may be encapsulated in an application object. Such an
application object typically contains a small number of methods, and may
possibly contain only one.
In the case of an object that contains only a single method and merely accepts
data from a calling application object rather than possessing data objects of
its own, the object may be regarded as simply a method rather than an
application object in its own right. Where it is desirable to invoke the
procedure from a number of applications, the procedure may be placed in a
separate executable module and dynamically bound to its calling applications,
thereby maintaining independence of the procedure from the applications.
A message is passed to the application object identifying the action to be
performed and providing the necessary input data. The application object will
then typically carry out a modal dialog (or possibly a series of dialogs) with
the end user to obtain any further information, leading the user through the
necessary steps in the required order. When the procedure has been completed,
the application object terminates the dialog and possibly passes a message to
its caller or to another application object, containing an acknowledgement of
completion, or information collected during the procedure. Where completion of
a method is mandatory to correct execution of the application, this
acknowledgement of completion provides a useful mechanism for the caller to
determine that the method has been successfully executed.
If such procedures are correctly defined at a generic level (for example, Enter
the customer data), their application objects may be stored in a library and
used by multiple applications. More complex procedures may be constructed
within an application by invoking a number of such application objects in
sequence. Acknowledgement messages from the application objects can be used to
verify that the required steps have taken place.
Thus it can be seen that the object-oriented paradigm, when the definition of a
data object is sufficiently expanded to include all types of logical entity,
and when properly applied with correctly designed application objects obeying
the aforementioned rules and guidelines, is generally applicable to almost all
applications. A wide variety of applications may therefore achieve the
modularization and reusability benefits afforded by an object-oriented design
approach.
ΓòÉΓòÉΓòÉ 13.6. Summary ΓòÉΓòÉΓòÉ
It can be seen from the foregoing discussion that the object-oriented paradigm
is a logical consequence of the move toward data-centered application design.
An object-oriented approach provides many benefits for applications which
manipulate data, not the least of which is the ability to implement an
intuitive, event-driven user interface where the user manipulates a number of
conceptual objects in a metaphorical manner that mirrors the "real-life"
manipulation of those objects.
It should be stressed however, that object-oriented programming is not
necessarily suited to all applications; its use is recommended only where data
is the central factor in the application's task. There may be situations where
the procedure, rather than the data, is necessarily the focus of the
application, or where an event-driven style of user interface is not
appropriate to the task being performed. In such cases, traditional structured
programming techniques hold advantages over object-oriented programming.
However, in situations where only a portion of the work task is procedurally
oriented, it is possible for the two approaches to coexist within the same
application.
Object-oriented programming focuses on the principles of data abstraction and
encapsulation, with all access to a data object being controlled by the
application object which "owns" that data object. This principle allows the
object-oriented approach to facilitate the creation of reusable application
objects, since the interface to an object is defined only by the messages it
receives and dispatches. The implementation details of the data objects or
methods belonging to an application object are typically transparent to other
application objects. Thus the effects of changes to these data objects or
methods may be contained within a single application object, easing the task of
change management and application maintenance.
A distinction must also be drawn between an object-oriented application design
and an event-driven, object-action user interface. The two concepts are
complimentary in that the provision of a truly event-driven interface for the
end user is dependent upon the application being designed and implemented
according to object-oriented principles. However, while the two concepts are
complimentary, they are not identical and the difference must be borne in mind
when designing an application.
Object-oriented application design begins with a definition of logical data
entities and their representations (data objects) in the system. Once these
data objects are defined, the actions relevant to each may be determined, and
the design of the messages to convey each action and the methods necessary to
achieve the actions may be undertaken. The definition of messages and actions
completes the high-level design of the application, and traditional functional
decomposition techniques may then be applied to designing and developing the
individual methods. The independent nature of application objects and of the
methods within an object facilitates modularization of the application, and
allows the design, development and testing of the methods for each object to
take place independently of the methods for other objects.
A number of programming languages and tools exist which implement
object-oriented programming practices to varying degrees. These may exist in
the form of object-oriented extensions to an existing programming language, or
as complete programming languages in their own right. The degree to which
these products enforce object-oriented practices also varies from one product
to the next. It should be stressed however, that the implementation of
object-oriented techniques in application design and development is not
dependent upon the use of any particular tool or programming language, but
rather depends on the correct application of object-oriented design concepts.
When such concepts are correctly applied in the design of an application, it is
quite possible to develop object-oriented applications in conventional
programming languages such as "C". The difference lies in the amount of
latitude given to the individual application developer with respect to the
interpretation of object-oriented principles.
It may be argued with some justification, that according to many
popularly-accepted definitions, the techniques offered in this chapter do not
constitute a truly object-oriented application model. However, such concepts
as a full inheritance hierarchy are not directly supported by execution
environments such as Presentation Manager, and are difficult to provide without
the use of additional object-oriented programming tools. It must be stressed
that the methodology outlined herein is not intended to be a purist
implementation of the full object-oriented paradigm, but is intended to
illustrate the application of certain object-oriented principles to the design
and implementation of Presentation Manager applications, in accordance with the
module-based approach to object-oriented programming.
These principles, when applied to the Presentation Manager environment, afford
significant enhancements in the areas of code reusability and application
modularity, and subsequent benefits with respect to reduced development time
and effort, and easier application maintenance and change management.
Additional tools may be utilized to apply further object-oriented principles to
Presentation Manager application design, in order to achieve the benefits
associated with a class-based approach to object-oriented programming. However,
such tools typically have additional drawbacks that must be weighed against
their advantages, with regard to the specific development scenario.
ΓòÉΓòÉΓòÉ 14. The Presentation Manager Application Model ΓòÉΓòÉΓòÉ
The Presentation Manager environment lends itself to the implementation of
object-oriented programs under the module-based approach to object-oriented
design. Presentation Manager provides far more than merely a means of
displaying information on the screen. It implements an event-driven,
object-based application execution environment and provides many services
required for the definition and manipulation of application objects and
messages.
This chapter will examine the execution environment provided by Presentation
Manager, describe the structure of a Presentation Manager application, and
illustrate the implementation of basic object-oriented concepts in the
Presentation Manager environment.
ΓòÉΓòÉΓòÉ 14.1. Windows ΓòÉΓòÉΓòÉ
A window is the embodiment of an application object within the Presentation
Manager application model. To the end user, a window appears as a rectangular
display area on the screen. From an application viewpoint however, the concept
of a window is far more powerful than this. Windows may be of two basic types:
Display windows have a physical identity represented by a rectangular area on
a screen; in this case the window represents a view of a conceptual display
surface known as a presentation space, which is in fact a data entity being
represented on the screen. This is the average end user's concept of a
window.
Object windows have no physical manifestation, and are merely addresses or
"handles" to which messages may be directed. An object window is typically
associated with an entity such as a file or database, and is used to access
this entity and perform actions upon it. The object window concept is very
important to the implementation of object-oriented principles under
Presentation Manager, since it enables the creation of non-visual objects
within the Presentation Manager application model. See Parent/Child
RelationShip (Object Windows) for further information.
Windows respond to events, communicated by way of messages, which may originate
from Presentation Manager as a result of user interaction, or from other
windows existing in the system. Messages are routed to and between windows by
Presentation Manager on behalf of the application. Windows may interpret and
process messages in different ways, in accordance with the concept of
polymorphism.
Each window existing in the system has a unique identifier known as its window
handle, which is assigned by Presentation Manager when the window is created.
This handle is used to identify a window in all communication between that
window and other parties, such as Presentation Manager or the user. The window
handle is specified as the destination address used when passing messages to a
window. See Messages for further discussion of Presentation Manager messages.
A window is always aware of its own handle, since the handle is part of every
message passed to the window. Presentation Manager provides a number of
mechanisms by which a window may determine the handles of other windows in the
system in order to pass messages to those windows; these mechanisms are
described in Window Communication.
ΓòÉΓòÉΓòÉ 14.1.1. Window Classes ΓòÉΓòÉΓòÉ
Since many windows may be in existence at any time, windows having similar
properties and behavior are grouped into window classes, with each window
belonging to a class being an instance of that class. Window classes may be
public (defined by Presentation Manager and usable by all applications in the
system) or private (defined by the application and accessible only by that
application unless an application developer decides otherwise; see Creating
Reusable Code). Private window classes are registered to Presentation Manager
by the application upon initialization of the application.
Presentation Manager maintains control information relating to each window
created in the system, including properties such as window text, current size
and location, etc. In addition to this information, an application may specify
an additional area of storage to be included within the window control block
for application data relating to that window. This storage is known as window
words. The presence and size of window words is determined for each window
class at the time the class is registered to Presentation Manager. However, a
new storage area is defined for each instance of the class, and window words
may therefore be used for instance data. Window words typically contain
pointers to dynamically-defined application data structures, which in turn
contain the instance data.
ΓòÉΓòÉΓòÉ 14.1.2. Window Procedures ΓòÉΓòÉΓòÉ
Each window class is associated with a window procedure, which defines and/or
establishes access to data objects and performs processing related to that
window class. In object-oriented terms, the window procedure contains the
methods to carry out actions upon the data object referenced by the window.
A window procedure is normally invoked by Presentation Manager on behalf of the
application. The window procedure interprets messages passed by Presentation
Manager to the window and invokes a method (that is, a coherent set of
application statements and/or routines) depending on the nature and contents of
the message.
See Window Procedures for a more complete discussion of window procedures'
structure and behavior.
ΓòÉΓòÉΓòÉ 14.2. Messages ΓòÉΓòÉΓòÉ
All interaction between the user and windows, or between one window and another
in the Presentation Manager environment, takes place by way of messages.
Whenever the user presses a key, moves or clicks the mouse, selects an item
from a menu, etc., a message is generated and placed on a system message queue.
Presentation Manager takes these messages in the order they were received by
the system, determines the window for which each message is intended, and
routes the message to a message queue belonging to the application that "owns"
that window. The application then dequeues each message in turn, and routes
the message via Presentation Manager to the window procedure associated with
that window, which processes the message.
Messages may be of three types:
User-initiated ; that is, the message is generated as the result of the user
selecting an action-bar item, pressing a key, etc.
Application-initiated ; that is, the message is generated by one window
within the application for the communication of an event or required action
to another window.
System-initiated ; that is, the message is generated by Presentation Manager
as the result of some system event such as a window having been resized or
moved.
A Presentation Manager application has the ability to process messages of any
of the three types, which allows the application to respond to any type of
event, regardless of its origin.
ΓòÉΓòÉΓòÉ 14.2.1. Message Classes ΓòÉΓòÉΓòÉ
Messages are grouped into message classes, with each class representing a
particular type of event such as character input, mouse movement, etc. Many
message classes are defined by Presentation Manager, and messages of these
classes are usually dispatched by Presentation Manager to inform an application
of system-initiated events. These system-defined message classes are
described, along with the default processing provided by Presentation Manager
for each class, in the IBM OS/2 Version 2.0 Presentation Manager Reference.
An application developer may define additional message classes unique to his or
her particular application, for use by that application. Application-defined
messages typically serve as a means of communication between windows, where one
window passes information to another window, for processing by the window
procedure associated with that window. The destination window may then return
a message to the calling window indicating completion, or may pass a message to
a third window to trigger an additional action, dependent upon the requirements
and design of the application.
For example, the user may elect to update a file by selecting an item from a
menu bar. The window procedure associated with the display window to which the
menu bar belongs may pass a message to an object window associated with the
file to be updated. The window procedure for this window would make the change
and then pass a message to a third object window, which logs the update before
passing a message back to the original window procedure indicating that the
update is complete.
Note that message classes need not be specific to a particular window class;
messages of the same class may be passed to different window classes, with
different results depending upon the processing of that message by the window
procedure belonging to that window class. This is in accordance with the
object-oriented principle of polymorphism.
ΓòÉΓòÉΓòÉ 14.2.2. Message Structure ΓòÉΓòÉΓòÉ
In order to allow any window the ability to process any message class,
Presentation Manager defines a standard format for messages. In the
Presentation Manager environment, a message is composed of four distinct
attributes:
A window handle identifying the window for which the message is intended
A message ID identifying the particular class of message
Two message parameters, which are 32-bit fields containing a variety of
information, depending upon the class of message received.
All Presentation Manager applications must contain a message processing loop,
which receives the message from Presentation Manager (see Application
Structure), and routes it, using Presentation Manager message-dispatching
functions, to the appropriate window procedure for processing. Thus
Presentation Manager actually invokes the window procedure on the application's
behalf.
Message Identifier
The message ID identifies the message class to which each message belongs, and
is in fact an integer value which is typically replaced by a symbolic name for
ease of use. The symbolic names for all system-defined message classes are
defined by Presentation Manager; symbolic names for application-defined
(private) message classes must be declared by the application developer in the
application's source code. This is typically achieved by declaring an integer
constant, the value of which is specified as an offset from the system-defined
value WM_USER. For example:
#define WMP_MYMESSAGE WM_USER+6
The use of an offset to a system-defined constant, rather than an absolute
numeric value, eliminates the chance of using the same integer value as a
system-defined message class (with consequently unpredictable results), and
avoids the necessity to alter application code should the number or definition
of system-defined message classes be altered in future versions of Presentation
Manager.
Message Parameters
As noted above, message parameters may contain a variety of information. When
used for communication between window procedures, the window handle of the
calling window may be passed to the destination window as one of the message
parameters, in order that the destination window procedure may dispatch an
acknowledgement or reply message to the calling window. Qualifiers to the
message type or small items of data may also be passed; for example, the
Presentation Manager-defined WM_COMMAND message class (indicating a menu
selection by the user) uses the first message parameter to identify the menu
item selected.
When large data structures are required to be passed between window procedures,
and the data obviously cannot be contained within the two 32-bit message
parameters, the convention is to allocate a memory object for the required data
structure using the DosAllocMem() function, and to pass a pointer to that
memory object as a parameter to the message. Presentation Manager provides a
number of macros to enable various types of data to be placed into and
retrieved from message parameters. The insertion and retrieval of data into
and from message parameters is described in Creating Message Parameters.
ΓòÉΓòÉΓòÉ 14.2.3. Message Processing ΓòÉΓòÉΓòÉ
Messages passed to a window may be processed in one of two basic ways:
Synchronously, in which case the message is passed directly to the target
window and is processed immediately; the window from which the message
originated suspends its execution until the message is processed.
Asynchronously, in which case the message is placed on a queue from which it
is subsequently retrieved and passed to the target window; the window from
which the message originated continues execution immediately after the
message is placed on the queue.
Synchronous and asynchronous processing are described in more detail in Window
Procedures (Invoking a Window Procedure).
A message may also be dispatched to multiple windows at the same time, using
the message broadcasting facilities provided by the Presentation Manager
programming interface. Broadcasting may be either synchronous or asynchronous.
The implementation of message broadcasting is discussed in more depth in Window
Communication.
Messages that are not explicitly processed by an application in its window
procedures are passed to a default window procedure supplied by Presentation
Manager, which contains default processing for all message classes (in the case
of application-defined message classes, this default window procedure simply
ignores the message). This technique is in accordance with the principle of
inheritance, in that a window procedure only contains methods for those message
classes with which it is directly concerned, and allows other messages to be
processed by the existing default window procedure. Default processing for
each message class is described in the IBM OS/2 Version 2.0 Presentation
Manager Reference.
For message classes that are processed by the application's window procedures,
the last operation in the message processing should be to provide a return code
to Presentation Manager. In many cases, this return code determines whether
Presentation Manager performs its default message processing, after the
application's own message processing is complete. The default message
processing may or may not be desirable, depending upon application
requirements. This ability allows system-initiated events to be easily
detected and trapped by a Presentation Manager, enabling the application to
perform its own processing for the event before allowing the default processing
to occur.
ΓòÉΓòÉΓòÉ 14.3. Application Structure ΓòÉΓòÉΓòÉ
All Presentation Manager applications have a similar structure. The
application is composed of a main routine, which performs initialization and
termination functions, and which contains the application's main message
processing loop, and a number of window procedures that process messages for
window classes created and/or used by the application. These window procedures
are invoked and messages passed to them by Presentation Manager on behalf of
the application, as shown in Figure "Message Flow in a Presentation Manager
Application".
Window procedures may also pass messages between one another in order to
communicate events. The flow of messages between the window procedures is also
controlled by Presentation Manager on behalf of the application.
ΓòÉΓòÉΓòÉ 14.3.1. Main Routine ΓòÉΓòÉΓòÉ
The main processing routine of a Presentation Manager application performs a
number of initialization and termination functions for the application, as
shown in Figure "Structure of an Application's Main Routine".
The application's main routine registers the application to Presentation
Manager, creates the application's message queue and defines private window and
message classes for the application before actual processing takes place.
Other application-specific initialization processing may also take place at
this time, such as the definition of global data items. Note however, that the
use of global data increases the interdependence of application modules and
reduces the potential for subsequent code reuse. Hence global data should be
avoided wherever possible.
The main routine also creates the application's main window. Note that from an
application viewpoint, a display window is actually a group of windows that
appear and behave as a single unit. Therefore the frame (with its associated
title bar, menu bar, etc.) and the client areas are created separately, as
shown in Figure "Structure of an Application's Main Routine". This concept is
explained in more detail in Window Hierarchy.
During execution of the application, the only function of the main routine is
to accept messages from the system queue and route them to window procedures
via Presentation Manager. This is performed using a message processing loop,
which continues until a message of the system-defined class WM_QUIT is
received, at which point the loop terminates and allows the application's
termination processing to occur.
Upon termination of the application, the main routine destroys any remaining
windows, along with the application's message queue, and deregisters the
application before terminating. Any global data items acquired during
initialization are also released at this time.
When the user selects "Exit" from the menu bar, or selects the "Close" option
on the system menu of the application's main window, the application is not
automatically terminated. These messages are passed to the window procedure
for that window, and may be processed by the application. The typical action
performed by the window procedure in such cases is that a message of class
WM_QUIT is posted to the application's message queue, which causes the message
processing loop to terminate. Conventions for closing windows and terminating
applications are discussed further in Window Closure.
Since Presentation Manager actually informs the application that it is being
terminated rather than simply shutting the application down, the application is
given a chance to perform any necessary termination processing and exit in an
orderly manner. When a window is destroyed, it receives a WM_DESTROY message
from Presentation Manager, which may be processed by the window procedure to
allow orderly termination of processing. This enables the preservation of data
integrity by Presentation Manager applications, which need not rely on the user
completing a logical unit of work before terminating; any uncompleted units of
work may be placed in an interim storage area on disk, or simply backed out as
part of the WM_DESTROY message processing.
This feature is also used by the "Shutdown" procedure of the Workplace Shell.
When the user selects "Shutdown" from the menu bar, Presentation Manager posts
a WM_QUIT message to the main window of each application executing in the
system, informing the application that it is being terminated and allowing any
termination processing to take place. This facility allows for an orderly
shutdown of the system and preserves the integrity of data objects.
ΓòÉΓòÉΓòÉ 14.3.2. Window Procedures ΓòÉΓòÉΓòÉ
It has already been mentioned that each window class within an application,
whether a display window or an object window, is associated with a window
procedure, which receives all messages intended for windows within that class.
The window procedure contains the methods used to perform actions upon the data
object to which the window pertains, and thus contains the application logic
for the manipulation of data objects. It may thus be said that window
procedures form the "heart" of a Presentation Manager application.
Upon invocation, the window procedure determines the type of message passed to
it, and may either process the message explicitly or pass it on to a default
window procedure supplied by Presentation Manager for standard processing. A
window procedure is essentially an extended CASE statement, as illustrated in
Figure "Structure of a Window Procedure". Each case within the window
procedure contains a set of application statements and/or routines necessary to
perform a particular action. Thus in object-oriented terminology, each case is
a method in its own right.
A window procedure is declared to return the type MRESULT, which is a 32-bit
data type declaration provided by Presentation Manager, and indicates the
nature of the window procedure's return value. Note that in the above example,
the returned values differ depending upon the message class; see Returning from
a Window Procedure below for further discussion. Note also that in the default
case shown in Figure "Structure of a Window Procedure", the window procedure
did not decide the return value itself, but used the value returned by the
Presentation Manager-supplied default window procedure. This is an established
Presentation Manager convention.
A window procedure should always be declared with the system linkage
convention; this is typically achieved by declaring the function to be of type
EXPENTRY. This type identifier is defined in the system header file OS2DEF.H,
and simply specifies use of the system linkage convention. Use of the system
linkage convention is required since a window procedure is invoked by
Presentation Manager on the application's behalf, rather than directly by the
application. Note that under previous versions of OS/2, the EXPENTRY keyword
resulted in use of the pascal linkage convention, for precisely the same
reason.
Subject to programming language conventions, a window procedure has the ability
to define a data object or instance data, or to establish access to an existing
data object as part of its initialization processing. When a window is created
by Presentation Manager in response to an application's request, Presentation
Manager immediately dispatches a message of the system-defined class WM_CREATE
to that window (see Figure "Structure of a Window Procedure"). The window
procedure may process this message in order to define instance data or
establish access to data objects. Typically, a window procedure requests the
allocation of a memory object as a control block for its instance data.
Initial values for the instance data are then placed in the control block, and
a pointer to the control block is stored in the window words. A window
procedure thus supports the object-oriented concept of encapsulation, by
allowing the dynamic allocation of and establishment of access to data objects,
within a single application object.
Note that prior to allocating instance data or performing any other processing
for the WM_CREATE message, a window procedure should invoke the default message
processing provided by Presentation Manager in the WinDefWindowProc() function.
This ensures that the initialization of Presentation Manager's control data for
the window is completed prior to WM_CREATE processing by the window procedure.
This in turn ensures that the window handle, window words, etc., will be
available during the window procedure's WM_CREATE processing.
Invoking a Window Procedure
A window procedure is invoked by dispatching a message to a window of the class
with which the window procedure is associated. Messages passed to a window are
typically initiated as the result of user interaction or application events, or
by Presentation Manager to indicate system events.
While window procedures may be invoked directly using a normal subroutine call,
it is recommended that messages be used for all communication between window
procedures. This conforms to standard object-oriented practice, in that an
object should be accessible only via a message passed to it.
Messages may be used to invoke a window procedure in two ways:
A message may be sent directly to the window procedure using the WinSendMsg()
call, in which case the window procedure executes synchronously, and control
does not return to the calling procedure until processing is completed. This
method of invocation is similar to a normal subroutine call, but preserves
the message-driven structure of the application. Note that since the message
is sent directly to the window procedure and not placed on a queue, the
normal serialization of message processing is disturbed. This may cause
different results from those intended by the user; thus WinSendMsg() should
be used with care.
A window procedure may also be invoked by posting a message to a queue
associated with the window procedure, using the WinPostMsg() call. With this
call the window procedure executes asynchronously, and control returns to the
calling procedure immediately after the message is placed in the queue. This
method of invocation provides a convenient and powerful means for serialized
and yet asynchronous processing. It then becomes the responsibility of the
application developer to ensure synchronization between different window
procedures.
Invoking a window procedure by posting a message to it via a queue has an
advantage over the use of WinSendMsg() or a direct subroutine call in that,
where multiple windows are passing messages to a single receiving window, these
messages are queued by Presentation Manager and dispatched to the receiving
object in the order in which they were initiated. Provided all sending windows
obey the established conventions and post messages to queues, this ensures the
correct sequencing of message processing by the receiving window, helps
preserve the user's intention and facilitates maintaining the integrity of data
objects.
A window procedure accepts four parameters upon invocation; these correspond to
the four attributes of a message as described in Messages and to the parameters
of the WinSendMsg() and WinPostMsg() functions, and are as follows:
1. The handle of the window for which the message was intended
2. A message-class identifier
3. Two 32-bit message parameters.
Note that the behavior of a window procedure, and the result obtained from
processing by a window procedure, are dependent upon the class and contents of
the message sent to it. Similarly, the same message class may be interpreted
in a different manner by window procedures belonging to different window
classes. In this way, a window procedure supports the object-oriented concept
of polymorphism.
Window Procedure Processing
A window procedure will normally determine the message class, and take action
based upon that class and the contents of the message parameters. Where the
action involves the manipulation of data objects and/or instance data, the
window procedure typically obtains access to the window's control block by
retrieving its pointer from the window words. The window procedure then has
access to the data values, resource handles, etc., required to complete the
action.
Note that the example given earlier in this chapter contains explicit
processing options for only four types of messages; the application allows
Presentation Manager to handle all other types of messages, by passing the
message to the system-supplied default window procedure using the
WinDefWindowProc() function. This illustrates one of the basic principles of a
Presentation Manager application; the window procedure processes only those
messages with which it is explicitly concerned, and passes all other messages
to Presentation Manager for default processing. A window procedure must pass
such messages on to Presentation Manager, or unpredictable results may occur.
This "catchall" approach to implementation also allows the stepwise
implementation of methods during application development. An application
developer may code a window procedure such that all command messages are, by
default, passed to a routine that displays a message informing the user that
the requested action is not yet implemented. As the method for each action is
designed and coded, a case for that action may be added to the window
procedure. Thus implementation of methods for an object proceeds in a stepwise
and independent fashion until all necessary methods are implemented.
As mentioned earlier in this chapter and illustrated in Figure "Structure of a
Window Procedure", a window procedure may process messages of any type,
including the WM_DESTROY message, which is posted to a window upon termination.
A window procedure may explicitly process this message in order to close files
and terminate access to data objects in an orderly manner, thus preserving the
integrity of those data objects. This ability allows the window procedure to
further support the principle of encapsulation.
Returning from a Window Procedure
By convention, a window procedure typically returns a Boolean value (type
MRESULT) to its caller, to indicate the result of message processing for that
message. The value returned is significant, since Presentation Manager takes
action depending upon that value. The defined return values for each
system-defined message class, along with the default processing provided by
Presentation Manager for each class, are given in the IBM OS/2 Version 2.0
Presentation Manager Reference. Naturally, the return values for user-defined
message classes are defined by the application developer.
If the window procedure has been invoked synchronously using WinSendMsg(), the
result is returned by Presentation Manager to the calling window procedure,
which may interrogate and act upon it. If the window procedure has been
invoked asynchronously using the WinPostMsg() function, the result is returned
to Presentation Manager only. Presentation Manager then uses this result to
determine whether any post-processing should be carried out for the message.
Note that while the WinPostMsg() function call also provides a Boolean return
code to the caller, this code only indicates whether the message was
successfully posted to the queue, and not the successful processing of the
message by the target window procedure.
ΓòÉΓòÉΓòÉ 14.3.3. Dialog Procedures ΓòÉΓòÉΓòÉ
A dialog procedure is a special type of window procedure that is associated
with a modal dialog box and processes messages intended for that dialog box.
The structure of a dialog procedure is similar to that of a "normal" window
procedure, and it processes messages in the same way, although certain message
classes received by a dialog procedure are different from those received and
processed by a normal window procedure. The structure of a typical dialog
procedure is shown in Figure "Structure of a Dialog Procedure".
Since modal dialog boxes do not belong to a class, they are not registered to
Presentation Manager in the manner of a normal window. A dialog procedure is
associated with a dialog box as part of a WinDlgBox() call, which loads a modal
dialog box and processes the dialog as a single operation, or a WinLoadDlg()
call, which loads the dialog box into memory but does not process it; the
dialog box may subsequently be processed by a WinProcessDlg() call. The
processes of providing input to and obtaining results from a dialog procedure
are discussed in Building a Presentation Manager Application.
Note that since a modeless dialog box is simply an optimized (non-sizable)
window with no other inherent properties such as modality, it receives the same
messages as a standard window, and its methods are therefore contained within a
normal window procedure rather than a dialog procedure.
Note that a dialog box must use the system linkage convention, since it is
simply a specialized form of window procedure. This is achieved using the
EXPENTRY keyword.
Upon creation, a dialog box receives a message of the system-defined class
WM_INITDLG. This is similar to the WM_CREATE message received by a normal
window upon creation, and may be processed in a similar way. The first
parameter in the WM_INITDLG message may be used to pass a pointer to the dialog
procedure, referencing a data structure containing initialization information
or other application-specified data.
A dialog box also receives messages of class WM_CONTROL indicating events
occurring in control windows within the dialog box. The window identifier of
the control window that dispatched the message, along with the nature of the
message, is indicated in the message parameters. The WM_CONTROL message is
described in the IBM OS/2 Version 2.0 Presentation Manager Reference. The
dialog procedure may wish to explicitly process events indicated by WM_CONTROL
messages, or it may allow such messages to pass on to the default Presentation
Manager-supplied dialog procedure WinDefDlgProc().
A dialog box also typically receives WM_COMMAND messages, which are generated
when a pushbutton within the dialog box is pressed by the user. The identity of
the pushbutton is indicated in the first parameter of the WM_COMMAND message.
The symbolic names DID_OK and DID_CANCEL are defined by Presentation Manager,
and by convention are used to refer to the "OK" and "Cancel" pushbuttons
respectively. The definition of dialog boxes is described in detail in
Presentation Manager Resources.
A dialog procedure is terminated and the dialog box is destroyed when the
dialog procedure issues a WinDismissDlg() call to Presentation Manager,
typically as a result of the user pressing a pushbutton. By convention, this
call specifies a parameter indicating TRUE if the user completed the dialog by
pressing an "Enter" or "OK" pushbutton, or FALSE if the user cancelled the
dialog by pressing a "Cancel" pushbutton. The value specified in this
parameter is returned to the window procedure that issued the WinDlgBox() or
WinProcessDlg() call, as the return value from that call.
Message boxes do not require an application-supplied procedure to carry out
their processing. The simple nature of the message box dialog allows it to be
processed by Presentation Manager on the application's behalf, and to return
the result to the application for subsequent action.
ΓòÉΓòÉΓòÉ 14.3.4. Subroutines ΓòÉΓòÉΓòÉ
Subroutines may be used in a Presentation Manager application, in the same way
as they are used in any other application. However, in order to conform to
object-oriented practices, subroutine calls should only be used to achieve
functional isolation within the methods of a single application object, or to
perform a standard processing function that is common to a number of objects;
in this case, the scope of each execution instance of the subroutine is limited
to a single object. In accordance with object-oriented programming guidelines,
communication between objects (windows) should be achieved using messages, and
hence window procedures should not be invoked directly as subroutines. See
Passing Control for further discussion on the use of subroutines in
Presentation Manager applications.
ΓòÉΓòÉΓòÉ 14.3.5. Partitioning the Application ΓòÉΓòÉΓòÉ
With the dynamic linking capabilities of OS/2, it is possible to partition an
application into a number of executable modules. A single base program may be
augmented by one or more dynamic link libraries. Such an approach has a number
of advantages:
Application code that is only executed in exceptional circumstances, such as
little-used functions, exception and error-handling routines etc, is not
loaded unless it is required. This may significantly reduce the load time
and memory requirements of the application.
Common functions may be shared between applications, since dynamic link
libraries are re-entrant and a single memory-resident copy of the library
code may be used by all applications. This can further reduce the memory
requirements of an application.
Functions placed in dynamic link libraries are isolated from the main
application, and may be modified without the need to re-link the application.
This facilitates application maintenance and update, since only the new
version of the DLL need be distributed.
Applications written for the Workplace Shell should be partitioned in this
manner. Since the shell displays all objects on the desktop at system
initialization, all applications must potentially be loaded at this time. This
can dramatically increase the time required for system initialization, along
with the overall memory requirements of the system.
These requirements may be significantly reduced by having only the minimum code
(that is, the code required to accept and identify messages) loaded at
application startup, and placing all processing function into dynamic link
libraries that are loaded only when one of their entry points is called.
Application developers must give careful consideration to correct partitioning
of the application. Groups of functions that are interdependent and which call
one another, or are typically called in close sequence should be placed in a
single DLL module. Functions that are independent of one another should be
placed in separate DLLs. This approach will minimize the load time and memory
requirements of the application.
ΓòÉΓòÉΓòÉ 14.4. Presentation Manager Resources ΓòÉΓòÉΓòÉ
Presentation Manager allows the application developer to define application
resources externally to the application code. Resources may include
definitions for the following items:
Fonts Graphic fonts may be created and modified using the
Font Editor supplied as part of the IBM Developer's
Toolkit for OS/2 2.0.
Icons Application and window icons, mouse-pointers and
bitmaps may be created and modified using the Icon
Editor supplied as part of the IBM Developer's Toolkit
for OS/2 2.0.
Menus Menu bars and pulldown menus may be defined for
display windows.
String Tables Tables of text strings may be defined for use by an
application.
Accelerator Tables Tables of accelerator keys (for example, F3 for Quit)
may be defined for display windows.
Help Tables Tables of help panels may be defined for each display
window or each control window in a dialog box. See
Adding Online Help and Documentation for further
discussion of help panels.
Dialog Templates Dialog boxes may be created or modified and stored as
dialog templates, using the Dialog Box Editor supplied
as part of the IBM Developer's Toolkit for OS/2 2.0.
Window Templates Window templates may be created or modified and stored
as window templates, using the dialog editor supplied
as part of the IBM Developer's Toolkit for OS/2 2.0.
Except where noted above, resources are defined in a resource script file, an
ASCII text file that may be manipulated using a standard text editor. This
resource script file serves as input to a resource compiler, which is provided
as part of the IBM Developer's Toolkit for OS/2 2.0. The resource compiler
produces a precompiled version of the resources, which is then incorporated
into the application's executable code or stored in a dynamic link library for
use by one or more applications.
It is usual for simple text-based resources such as menus and string tables to
be placed directly into the resource script file using an ASCII text editor.
However, non-textual resources such as icons or bitmaps, or more complex
text-based resources such as dialog templates, are typically stored in separate
files and referenced from the resource script file.
A major benefit of defining such resources externally to the application is
that changes may be made to resource definitions without affecting the
application code itself. Modifications such as new icons, altered commands or
menus, etc., may be implemented quickly and easily by making simple changes at
a single point in the application.
As a further example, the task of providing national language versions of an
application is simplified, since all text such as menus and messages may be
defined outside the application code, and multiple language-specific versions
of such resources may be linked into a single version of the application code.
In this way, the user interface properties of a display window may be modified
without affecting the internal implementation of the window procedure or its
methods.
The creation and use of Presentation Manager resources is discussed in
Presentation Manager Resources.
ΓòÉΓòÉΓòÉ 14.5. Creating Reusable Code ΓòÉΓòÉΓòÉ
The ability to define resources such as window and dialog templates externally
to the application, in conjunction with the dynamic linking facilities provided
by the OS/2 operating system, provides a powerful tool for the creation of
generic application objects, comprised of window/dialog templates and their
associated window or dialog procedures. These application objects may be
defined and stored in dynamic link libraries for subsequent use by one or more
applications. This practice is in accordance with the guidelines for Systems
Application Architecture Common Applications, which provide for common
application services within and between environments, as well as common user
applications. This concept is further discussed in Generic Application
Modules. Note however, that the use of generic application objects presupposes
that the nature of and message interfaces to such application objects are
well-defined and documented, in order to allow application developers to
correctly select and interact with the generic objects.
For instance, a standard dialog box that will be used by many applications
could be defined in a dialog template, resource compiled and stored in a
dynamic link library, along with the dialog procedure which performs the
processing for that dialog. The dialog can then be loaded from the DLL by any
application which needs to use it. The dialog need be coded only once, and may
be modified at any time while requiring no source code changes to the
applications that access it. The fact that DLL code is not bound with the
application at link edit time like other library code also means that no
changes are required to the object code of the applications, and thus
recompilation and link edit is not required. An example of this technique is
given in Presentation Manager Resources.
The window or dialog procedure associated with a generic object should contain
all the methods normally used to perform actions upon that object, but need not
contain every action that will ever be necessary. If an application requires a
specialized action on a generic object (that is, a previously undefined action
or a modification of an existing action), the window acting as a handle to that
object may be subclassed, and a new window procedure substituted for the
existing window procedure. This new window procedure would contain methods to
process the specific messages in which it has an interest, and would then
invoke the original window procedure to handle any other message classes, in
accordance with the object-oriented principle of inheritance. Subclassing is
discussed further in Subclassing.
ΓòÉΓòÉΓòÉ 14.6. Window Hierarchy ΓòÉΓòÉΓòÉ
Presentation Manager organizes windows hierarchically; each window in the
system has a parent, and may optionally have an owner. These parent and owner
relationships determine the behavior of the window in response to certain
messages, and may be used by applications to navigate the window hierarchy.
ΓòÉΓòÉΓòÉ 14.6.1. Parent/Child Relationship ΓòÉΓòÉΓòÉ
The parent/child relationship between windows is mentioned in OS/2 Version 2.0
- Volume 3: Presentation Manager and Workplace Shell, with regard to the
clipping of a child window to the borders of its parent. However, this
hierarchy goes further in Presentation Manager, since all windows, both display
windows and object windows, have a designated parent window. For top-level
display windows, this parent window is the desktop, and is identified by the
HWND_DESKTOP constant. Other display windows within an application, which are
child windows of the application's main window, may have the top-level
application window as their parent, or indeed subsequent levels of the window
hierarchy may be created, dependent on application requirements. A window's
parent is identified to Presentation Manager by the application when the window
is created. Thus the window hierarchy within a particular desktop is
dynamically defined at execution time.
As well as being uniquely identified by its window handle, a child window may
also be identified by a window identifier, which is unique between children of
a particular parent window. This identifier is an integer value, which in
practice is usually replaced by a more meaningful symbolic name that defines an
integer constant. The window identifier is supplied as a parameter when the
application requests creation of the window by Presentation Manager. When a
window's parent and identifier are known, the WinWindowFromID() function may be
used to determine its window handle so that operations may be performed upon
it. See Window Communication for further information.
The parent/child hierarchy is useful for application design purposes, since in
many cases, a window and its children may be regarded and manipulated as a
single unit. For example, sizing a parent window automatically clips all
children of that window to the boundaries of the parent, and closing a parent
window results in each of its children being closed. This simplifies the
application logic required for applications that create multiple windows.
Frame and Client Windows
The concepts of frame and client areas for a window are discussed in OS/2
Version 2.0 - Volume 3: Presentation Manager and Workplace Shell. In fact,
these frame and client areas are separate windows in their own right; the frame
window of the application's "main window" is a top-level window with the
desktop as its parent, and the client window is a child of the frame window.
Frame control windows such as maximize/minimize icons, the title bar, the menu
bar, etc., are also separate windows from the application viewpoint, and are
regarded as children of the frame window. Note that although they are separate
windows, the end user perceives and manipulates the entire group as a single
unit.
The frame window and its children all belong to system-defined generic window
classes, and thus have their own window procedures defined by Presentation
Manager. The exception is the client window, the window class of which is
defined by the application; the window procedure is therefore defined to
Presentation Manager when the window class is registered. Note that window
procedures for system-defined window classes may be subclassed by the
application in order to provide specialized processing of certain messages.
The children of a frame window have specific window identifiers assigned to
them by Presentation Manager. These window identifiers are unique for each
frame window. The predefined window identifiers are shown in Table "Window
Identifiers".
These identifiers may be used to communicate with child windows of a particular
frame window, without the necessity to determine the window handle of the child
window. This concept is applicable to all windows including control windows
within a dialog box. See Window Communication for further information.
Object Windows
Object windows do not have a parent in the visual sense, as considerations such
as clipping do not arise (since the window is never displayed). For the
purposes of standardization, Presentation Manager considers every object window
to have a conceptual parent; this parent may be referenced using the constant
HWND_OBJECT. This technique allows an object window to be created using the
same Presentation Manager function as that used to create a display window. It
is also useful in allowing logical grouping of windows with similar functions,
or which need to be treated as a group for application purposes, under a single
conceptual parent.
For example, all the object windows created by a particular application may be
grouped as children of a single "dummy" parent window. When the application
terminates and wishes to destroy all these windows, only a single function call
to destroy the parent need be issued; Presentation Manager will automatically
destroy each of the children in turn before destroying the parent. Due to the
way in which Presentation Manager destroys windows by first passing a
WM_DESTROY message to the window, each object window is given a chance to exit
in an orderly manner.
ΓòÉΓòÉΓòÉ 14.6.2. Window Ownership ΓòÉΓòÉΓòÉ
A window may have an owner as well as having a parent. While a window's
relationship to its parent is mainly concerned with display, the relationship
with its owner is concerned primarily with function. The owner is assumed to
have some interest in events that take place within a window. For example, a
frame window is the parent of its frame control windows (icons, menu bar,
etc.,) and is also their owner. When certain events take place, such as the
user selecting an item from a menu bar, the control windows notify their owner
by dispatching notification messages (the menu bar for instance, typically
dispatches a message of class WM_COMMAND). Thus the owner receives
notification of the event, and may perform some action in response.
The concept of ownership is usually applied to system-defined window classes
such as control windows. Since the window procedures for these window classes
are defined by Presentation Manager rather than by the application, it is
necessary for a control window to notify its owner of any event that may be
significant to the owner.
There is typically no owner relationship between frame and client windows.
Messages received by the frame window that are deemed to be of possible
interest to the client window are passed to the client window automatically by
the system-supplied frame window procedure, by virtue of the predefined
parent/child relationship between the frame and client windows.
Should application requirements dictate, the application developer may
establish an owner relationship between any two windows within his/her
application, provided those windows are created by the same thread. Owner
relationships are not permitted between windows created by different threads.
ΓòÉΓòÉΓòÉ 14.6.3. Z-Order ΓòÉΓòÉΓòÉ
A desktop is typically regarded as a two-dimensional display space; in fact, a
desktop is three-dimensional, since when windows overlap on the desktop, one
window is conceptually "on top of" the other. This concept of "stacking"
windows applies even when windows do not actually overlay one another on the
desktop. The order in which windows appear on the desktop is known as the
z-order. The z-order is known to Presentation Manager, and a number of function
calls are provided that enable an application to request window handles of
specific windows in the z-order using the WinGetNextWindow() function to obtain
the handle of the next window in the z-order, or the WinQueryWindow() function
to obtain the handle of a window at a specified position in the z-order.
Since the z-order changes dynamically as different applications create and
destroy windows, Presentation Manager takes a "snapshot" of the desktop state
when the application issues a WinBeginEnumWindows() call. This function
accepts a window handle as a parameter, and the z-order of all immediate
children of that window is recorded by Presentation Manager. A call to this
function should be issued before any WinGetNextWindow() call is issued, or
before any WinQueryWindow() call is issued that specifies a position in the
z-order. When the application no longer wishes to interrogate the recorded
window hierarchy, a WinEndEnumWindows() call should be made.
The concepts of z-order and window enumeration are useful in circumstances
where an operation or sequence of operations must be performed on a number of
windows in order. Windows with the same parent always appear contiguously in
the z-order, and thus may be easily processed in succession.
ΓòÉΓòÉΓòÉ 14.7. Subclassing ΓòÉΓòÉΓòÉ
Windows may be subclassed by replacing the window procedure defined by the
window class with another window procedure. This new subclass window procedure
typically processes some of the messages routed to it, and then calls the
original window procedure to process any other messages. This technique
parallels the definition of subclassing given in Object-Oriented Applications.
Presentation Manager implements subclassing by having the application call the
WinSubclassWindow() function, specifying the handle of the window to be
subclassed and the new subclass window procedure. Note that only the window
specified is affected by the WinSubClassWindow() function call; other windows
of the same class are not subclassed. Once the call is successfully issued,
any messages destined for the original window procedure are automatically
routed to the subclass window procedure by Presentation Manager. The object
(whether a window or the operating system) from which the message originated is
unaware of the subclass window procedure's interference. An example of a
subclass window procedure is given in Figure "Subclass Window Procedure".
The subclassing concept enables messages destined for particular windows to be
intercepted and the processing resulting from certain messages to be altered.
This provides a powerful mechanism that facilitates the creation and use of
generic windows (application objects), while retaining the ability for the
application to modify the behavior of such windows should the need arise. The
use of subclassing enables a newly created window to take on the properties and
methods of existing window classes in accordance with the principle of
inheritance.
Presentation Manager enables the effect of subclassing a window to be reversed
by the application issuing the WinSubclassWindow() call a second time for the
same window, specifying the original window procedure. Presentation Manager
then routes messages directly to their intended destination. This capability
allows windows to be temporarily subclassed to meet changing requirements at
different points during application execution.
ΓòÉΓòÉΓòÉ 14.8. Summary ΓòÉΓòÉΓòÉ
It can be seen from the foregoing discussion that Presentation Manager provides
a base that facilitates the implementation of module-based object-oriented
conventions by application programs. The concepts of an application object and
its methods are implemented under Presentation Manager as a window and its
window procedure.
Windows are grouped into classes and a window procedure is associated with a
window on the basis of its class, in a parallel to the concept of allocating
methods to an object class rather than to individual instances of that class.
Window classes are defined in isolation however, and the concept of an
inheritance hierarchy is not imposed by Presentation Manager, thus further
enhancing the potential for efficient reuse by increasing object granularity.
Presentation Manager allows windows to be subclassed, in order to allow
additional or modified methods to be applied to an object in response to new or
specialized actions. This provides an additional enhancement to the capability
of code reuse, since it is not necessary to create a new object class in order
to implement small modifications to an existing class.
Windows communicate with the system and with each other by way of messages,
which are queued and routed by Presentation Manager, and which are processed in
a serial fashion by the target window procedure. This messaging model is a
practical implementation of the message-driven communication precept of
object-oriented application design.
While not supported explicitly by Presentation Manager, the object-oriented
concept of encapsulation is supported implicitly by the ability of a window
procedure to define and thus "own" a data object. The concept of polymorphism
is also supported by Presentation Manager, since the behavior and results
obtained from a window procedure are dependent upon, and only upon the class
and contents of messages sent to that window procedure. In a similar fashion,
the result of a message is dependent upon the window procedure (application
object) to which it is passed. The isolation of data objects within an
application object facilitates the containment of change by enhancing
application modularity, thus easing the task of change management and
application maintenance. Table "Application Object/Window Correlation"
The ability to encapsulate the definitions of data objects with the methods
used to manipulate those objects, and to store the resulting application
objects in object libraries, facilitates the notion of reusability, which is
one of the central precepts of object-oriented programming. The dynamic
linking facilities provided by OS/2 further extend the potential for reusable
application objects. Reusable objects may be defined and stored for use by
multiple applications; indeed, multiple objects may direct messages to a
single instance of an object executing in the system. The message queueing and
serialization provided by Presentation Manager ensures the correct sequence of
processing to preserve the user's intention and facilitate the integrity of
data objects.
It may be seen that the concept of an application object as defined in
Object-Oriented Applications and the implementation of a window under
Presentation Manager have a strong correlation. A window may be regarded as
the identity of an application object. That object is associated with a data
object and a set of methods (the window procedure) that perform actions upon
the data object. Class-specific data is defined within the window procedure,
while storage for instance data is defined dynamically and pointers typically
stored in window words. Windows communicate with the user and with one another
by way of messages. Thus the window is the implementation of an application
object under Presentation Manager.
Hence Presentation Manager provides an execution environment and a basic
application architecture that supports the implementation of object-oriented
applications, within the boundaries of IBM Systems Application Architecture.
Although it does not provide a complete development environment that enforces
object-oriented guidelines, it offers the basis upon which such a development
environment may be based.
ΓòÉΓòÉΓòÉ 15. The Flat Memory Model ΓòÉΓòÉΓòÉ
The task of dynamically allocating memory within an application is greatly
simplified in the 32-bit OS/2 Version 2.0 environment through use of the flat
memory model. The application developer need no longer be concerned with the
maximum 64KB segment size imposed by the 80286 processor architecture. Larger
amounts of memory may be allocated and subsequently manipulated as single units
known as memory objects, rather than as multiple segments as was the case with
previous versions of OS/2. This reduces application complexity, facilitating
improved performance and reducing application development time.
This chapter describes the use of the flat memory model for application
programming, in order to allocate and manipulate system memory. The chapter
also examines the facilities provided by OS/2 Version 2.0 that enable
applications to handle memory protection exceptions.
The concept of the flat memory model is described in OS/2 Version 2.0 - Volume
1: Control Program. The functions necessary to manipulate memory from within
applications are described in detail in the IBM OS/2 Version 2.0 Control
Program Reference.
ΓòÉΓòÉΓòÉ 15.1. DosAllocMem() Function ΓòÉΓòÉΓòÉ
The DosAllocSeg() function implemented under previous versions of OS/2 is
replaced in Version 2.0 by the DosAllocMem() function, which allows allocation
of memory objects greater than 64KB in size. To take an example, Figure
"Allocating Memory in Previous Versions of OS/2" shows the code necessary under
OS/2 Version 1.3 to allocate a 72KB area of memory for use by an application.
The application must then use pSegment1 to reference the lower 64KB and
pSegment2 to reference the upper 8KB of the memory object. This requires
conditional testing for each memory reference, and thereby introduces
additional complication to the application code. Use of the DosAllocHuge()
function simplifies this slightly, but arithmetic is still required in order to
correctly calculate offsets within the higher area of memory.
Under OS/2 Version 2.0, a single DosAllocMem() function call is required in
order to perform the same task, as shown in Figure "Allocating Memory in OS/2
Version 2.0". Subsequent references to this memory object may simply use a
32-bit offset within the allocated address range.
Note that since OS/2 Version 2.0 uses paged memory internally, memory allocated
using DosAllocMem() is always allocated in multiples of 4KB. Thus, a request
for 10 bytes will actually result in a full 4KB page being committed in real
storage. Since this will lead to high fragmentation and consequent waste of
memory, the allocation of many small memory objects using DosAllocMem()
directly is not recommended. Application developers should initially use
DosAllocMem() to allocate the maximum storage likely to be required, and then
use the DosSubAlloc() function to allocate individual memory objects. This
technique allows the storage of multiple small memory objects within the same
4KB page, thereby reducing fragmentation and making more efficient use of
storage.
Note that the DosAllocHuge() function provided under previous versions of OS/2
has no counterpart under Version 2.0. This function is not required since
DosAllocMem() allows the theoretical allocation of memory objects of a size up
to that of the application's entire process address space.
Memory objects allocated using DosAllocMem() may be freed using the
DosFreeMem() function.
ΓòÉΓòÉΓòÉ 15.2. Allocating versus Committing Memory ΓòÉΓòÉΓòÉ
Under OS/2 Version 2.0, there is a distinction between allocating a memory
object and committing that object. This distinction was not present in previous
versions of OS/2, and is a very important concept for the application developer
to grasp. When a memory object is allocated, space is reserved in the linear
address space, but no real storage or swap file space is reserved for the
object. This space is only reserved when the memory object or parts thereof
are committed. A memory object that has not been committed is known as a
sparse object.
A memory object may be committed in two ways:
It may be committed (in its entirety) at the time it is allocated, using the
PAG_COMMIT flag in the DosAllocMem() function.
It may be committed in stages at some later point, using the DosSetMem()
function.
The former technique is intended for small memory objects, the size of which is
fixed and can be determined in advance by the application developer. The
latter technique is intended for memory objects such as external data files,
which may vary in size.
Memory must be committed prior to being accessed by the application. Failure to
do this will result in a page fault (Trap 000E) exception.
ΓòÉΓòÉΓòÉ 15.2.1. Committing Storage at Allocation ΓòÉΓòÉΓòÉ
For memory objects that have a fixed size, such as internal application
storage, control blocks and most instance data, memory objects should be
committed immediately upon allocation, allowing the application to access the
memory object without the inconvenience and additional overhead of explicitly
committing the storage at a later time.
Storage for a memory object may be committed using the PAG_COMMIT flag in the
DosAllocMem() function call used to allocate the memory object, as shown in
Figure "Committing Storage During Allocation". The above example creates a 72KB
memory object in a similar manner to that shown in Figure "Allocating Memory in
OS/2 Version 2.0", but commits the storage during allocation, so that is
immediately available for use by the application.
ΓòÉΓòÉΓòÉ 15.2.2. Dynamically Committing Storage ΓòÉΓòÉΓòÉ
Under DOS and previous versions of OS/2, it is common for an application to
allocate a small memory segment to contain a data structure. If the data
structure outgrows the size of the segment, the segment size may be
progressively increased using the DosReallocSeg() or DosReallocHuge()
functions, moving the segments within the machine's physical memory in order to
accommodate the increased size requirements. This is not possible under
Version 2.0, since the paged memory implementation does not allow memory
objects to be moved within memory once they are allocated; hence the
DosReallocSeg() and DosReallocHuge() functions have no counterparts in the
32-bit environment.
Under OS/2 Version 2.0, an application can allocate an area of storage in its
process address space, but may commit only a small amount of that storage at
the time the application is initialized. In this way, the application does not
use a large amount of storage in a situation where it is not required, and
thereby avoids placing unnecessary resource demands on the operating system.
This can result in improved overall system performance.
If the storage requirements for a memory object increase during execution (for
example, the size of a spreadsheet increases), and exceed the amount of storage
initially committed, the application may dynamically commit additional storage
up to the maximum specified in the DosAllocMem() function call that allocated
the memory object.
This dynamic commitment of storage is typically achieved using the guard page
technique. A page within the memory object may be specified as a guard page
using the PAG_GUARD flag in the DosAllocMem() function call or in a DosSetMem()
call made subsequent to the allocation. Once this is done, any memory
reference to that page will generate a guard page exception. The guard page
exception warns the application that the upper boundary of the committed
portion of a memory object has been reached, and allows appropriate action to
be taken in order to avoid a page fault exception.
Note that the memory protection scheme implemented by OS/2 Version 2.0
allocates pages to individual processes. An exception is only generated when
an application attempts to write into a page which is not allocated to the
current process under which the application is running. If the page is
allocated to the current process, no exception is generated. Use of the guard
page technique is therefore strongly recommended in circumstances where the
amount of data to be written into a memory object is variable, or where the
size of the memory object or its data may grow during execution.
The recommended method of using guard pages is to initially allocate the memory
object as a sparse object, and then commit the amount of storage required for
the current size of the data, flagging the uppermost page of the memory object
as a guard page. This technique is shown in Figure "Using a Guard Page With a
Memory Object".
The example shown in Figure "Using a Guard Page With a Memory Object" allocates
a memory object that is 72KB in size as a sparse object, commits the first two
pages (8KB) of the object and specifies the uppermost of the two pages as a
guard page. Any attempt by the application to write into this uppermost page
will result in a guard page exception.
The guard page exception generated when an application attempts to write into a
guard page can be trapped and processed by an application-registered exception
handler, to commit further pages within the memory object. A simple guard page
exception handler is shown in Figure "Guard Page Exception Handler".
The exception handler shown in Figure "Guard Page Exception Handler" handles
two types of exception: the guard page exception and the page fault exception.
The latter occurs when an application attempts to write to an uncommitted page
in the memory object that is not the guard page. This can occur when a memory
object is accessed in a non-sequential manner.
The example shown above handles the guard page exception simply by committing
the next page in the memory object, and making this page the new guard page.
Guard page exceptions should not be allowed to pass through to the operating
system's default guard page exception handler, since the default handler
operates by committing the next lower page in the memory object and making this
the new guard page. This is done because the default handler is intended
mainly to handle dynamic stack growth; stacks are always propagated downward.
The exception handler shown in Figure "Guard Page Exception Handler" also
handles the page fault exception, where a write operation is attempted into a
page other than the guard page, which has not previously been committed. The
exception handler responds to this exception by querying the properties of the
page in question and, if the page has been allocated but not yet committed,
proceeds to commit the page.
If the page has not been allocated (that is, it does not lie within the
boundaries of the memory object), or if the exception is neither a guard page
exception nor a page fault exception, the exception handler does not process
the exception, and returns control to the operating system, which will invoke
any other exception handlers registered for the current thread (see Exception
Handling).
A guard page exception handler is registered by the application using the
DosSetExceptionHandler() function. This function is illustrated in Figure
"Registering a Guard Page Exception Handler".
The DosSetExceptionHandler() function can also be used to register exception
handlers for other types of system exception; see Exception Handling for
further information.
Note that OS/2 Version 2.0 provides its own exception handlers within the
service layers for all 32-bit system functions. These exception handlers allow
the service routines to recover from page fault exceptions and general
protection exceptions encountered due to bad pointers in applications' function
calls. The function call returns an ERROR_BAD_PARAMETER code rather than a
Trap 00D or Trap 00E code, thereby allowing the application to recover. This
represents a significant enhancement over previous versions of OS/2, since it
allows easier debugging and more flexible pointer handling.
ΓòÉΓòÉΓòÉ 15.3. Suballocating Memory ΓòÉΓòÉΓòÉ
Under OS/2 Version 2.0, the granular unit of memory is the page. This means
that the minimum possible memory allocation for a single DosAllocMem() function
call is 4KB. For example, if an application requests the allocation of 10
bytes of storage, the operating system will allocate a full 4KB page; the
remaining storage in this page will be wasted.
It is therefore recommended that for dynamic allocation of small memory objects
for uses such as instance data, each window procedure should use a single
DosAllocMem() function call to allocate a storage pool, and subdivide this
storage as required using the DosSubAlloc() function, as shown in Figure
"Suballocating Memory".
Storage must be suballocated in multiples of 8 bytes. Any requested
suballocation which is not a multiple of 8 bytes will have its size rounded up
to a multiple of 8 bytes.
Storage to be suballocated must first be allocated using the DosAllocMem()
function, and initialized for suballocation using the DosSubSet() function.
Note that control information for the suballocation uses 64 bytes of the
storage pool; this must be taken into account when determining the size
requirements for the pool.
In Figure "Suballocating Memory", the storage in the pool is committed during
allocation, since the example assumes that the total storage requirement is
known in advance. In situations where the exact size of the storage required is
not known, the storage may be allocated but not committed, and the
suballocation procedure will then progressively commit storage as required.
This is indicated by specifying the DOS_SPARSE_OBJ flag in the DosSubSet()
function call.
Memory that has been suballocated using the DosSubAlloc() function may be freed
using the DosSubFree() function. The storage is then available for future
suballocation. Note, however, that the suballocation procedure does not
reorganize suballocated memory objects within a pool. Thus freeing objects
within the pool may result in memory fragmentation.
A storage pool initialized for suballocation using the DosSubSet() function
should be removed using the DosSubUnset() function before the memory in the
pool is freed. This function call releases the operating system resources used
by the suballocation procedure.
When using the C Set/2 compiler, the malloc() function may be used to allocate
memory. This function has many of the advantages of the DosSubAlloc()
function, but avoids the need for the application to explicitly allocate, set
and suballocate memory. The malloc() function also provides greater
independence for application code from the platform upon which it executes,
allowing the application to be more easily migrated to platforms other than
OS/2 Version 2.0.
The malloc() function works as follows:
The first call to malloc() from a particular application (process) causes
malloc() to request a memory object from the operating system. The malloc()
service routine adds 16 bytes to the size specified in the function call, and
rounds the result upward to the next even power of 2. This amount of memory
is then requested from the operating system using a DosAllocMem() call. The
operating system will then allocate memory, rounding the service routine's
request size upward to the nearest multiple of 4KB. The malloc() function
then fulfills the application's request, with some wastage due to the
page-granular allocation.
For subsequent calls to malloc(), the malloc() service routine first checks
whether it has sufficient memory remaining from a previous request; if so, it
allocates that memory and returns control to the application. If not, the
service routine requests additional memory from the operating system using
the DosAllocMem() function.
Note that the free() function, used to free memory which has been allocated
using malloc(), does not return the memory to the operating system; rather,
that memory is held by malloc() for future use. In order to return memory to
the operating system, the application must issue a heapmin() function call.
ΓòÉΓòÉΓòÉ 15.4. Exception Handling ΓòÉΓòÉΓòÉ
The following outcomes are possible when a memory object is referenced by the
application:
If the memory has not been allocated or committed, a general protection
exception (Trap 000D) will occur.
If the memory has been allocated but not committed, a page fault exception
(Trap 000E) will occur.
In both of the above cases, the exception is reported to the application's
general protection exception handler, if one has been registered by the
application. The application may then deal with the error. If an exception
handler has not been registered by the application, the default exception
handler provided by the operating system will terminate the application.
If the page to be referenced has been defined as a guard page, a guard page
exception is generated. If the application has not registered its own
handler for this exception, the system's default handler will commit the
page, and mark the next page in the memory object as the new guard page for
the object. Once the guard page exception has been processed, execution
proceeds normally.
If none of the above conditions occur, the memory object is accessed and
execution proceeds normally.
Exception handlers for the various types of exception may be registered using
the DosSetExceptionHandler() function, as shown in Figure "Registering a Guard
Page Exception Handler".
Note that unlike previous versions of OS/2, application handlers need not be
written in assembly language; high-level programming languages may be used.
Exception handlers are registered on a per-thread basis, and multiple exception
handlers may be registered for each thread. When more than one exception
handler is registered, the handlers are chained, with the most recent addition
being placed at the start of the chain. When an exception occurs, control is
passed to the first handler, which may handle the exception and return
XCPT_CONTINUE_EXECUTION, in which case the operating system returns control to
the application.
If the exception handler cannot handle a particular exception, it returns
XCPT_CONTINUE_SEARCH, in which case the operating system passes control to the
next exception handler in the chain. In this way, control is eventually passed
to the operating system's default exception handlers.
When an exception handler is no longer required, it can be removed from the
chain using the DosUnsetExceptionHandler() function.
Exception handling and the various operating system exceptions that can occur
are described in the IBM OS/2 Version 2.0 Control Program Reference.
ΓòÉΓòÉΓòÉ 15.5. Shared Memory Objects ΓòÉΓòÉΓòÉ
By default, memory objects allocated by an application are private to the
process in which that application executes. However, OS/2 allows memory to be
shared among applications for interprocess communication. Shared memory
objects are allocated in a similar manner to private memory objects, using the
DosAllocSharedMem() function.
Note that while private memory objects are allocated using addresses upward
from the lower limit of the process address space, shared memory objects are
allocated downward from the upper limit of the process address space. Hence the
private and shared memory arenas grow toward one another as more memory objects
are allocated during execution.
Shared memory objects may be freed in the same manner as private memory
objects, using the DosFreeMem() function.
ΓòÉΓòÉΓòÉ 15.5.1. Named versus Anonymous Shared Memory Objects ΓòÉΓòÉΓòÉ
Shared memory objects may be named or anonymous. Named shared memory objects
have names of the form:
\SHAREMEM\<objectname.ext>
A named shared memory object may be accessed by another process using the
DosGetNamedSharedMem() function.
An anonymous shared memory object must be declared as "giveable" or "gettable"
when it is allocated, in order that it may be made available to other processes
using the DosGiveSharedMem() or DosGetSharedMem() functions. An example is
given in Figure "Allocating Shared Memory".
The DosGiveSharedMem() function can be used at any time to provide another
process with a specified level of access to a memory object, provided that the
owner of the memory object knows the process ID of the process to which access
is to be given.
ΓòÉΓòÉΓòÉ 15.5.2. Committing Shared Memory Objects ΓòÉΓòÉΓòÉ
Like private memory objects, shared memory objects have a distinction between
allocating and committing storage. Shared memory objects may be committed upon
allocation, or subsequently using exception handlers and the DosSetMem()
function. The guard page technique may be used with shared memory objects as
well as private memory objects.
One distinction between shared memory objects and private memory objects is
that private memory objects may be "de-committed" if the required amount of
memory reduces during execution; that is, physical storage is released without
releasing the corresponding address ranges in the process address space.
Shared memory objects may not be de-committed, to avoid the situation where one
process may de-commit a page that is being accessed by another process.
ΓòÉΓòÉΓòÉ 15.6. Summary ΓòÉΓòÉΓòÉ
Dynamic memory allocation is greatly simplified under OS/2 Version 2.0, since
the application developer is no longer required to explicitly code for the
80286 segmented memory model, with its size limitation of 64KB per segment.
Larger units of memory may be allocated and manipulated as single units,
simplifying application code and reducing development time for applications
that manipulate large data structures.
When executable modules compiled for different environments are executed within
the same process, the operating system handles interaction between these
modules through thunk layers. The conversions made within the thunk layers are
transparent to the application modules themselves, and do not require
consideration by the application developer. This enables executable files,
dynamic link libraries, and resources from different environments to be mixed
within the same application.
In general, application developers using OS/2 Version 2.0 are provided with a
greater level of function and, at the same time, may take advantage of greatly
simplified application development through use of the 32-bit flat memory model,
which removes much of the inherent complexity of memory manipulation within the
application. Developers may produce applications more efficiently under
Version 2.0, and may easily migrate their applications to and from the OS/2
Version 2.0 environment.
ΓòÉΓòÉΓòÉ 16. Building a Presentation Manager Application ΓòÉΓòÉΓòÉ
While the steps necessary to create a Presentation Manager application are
generally similar to those required to create any kind of application in the
programmable workstation environment under OS/2, there are some specific
considerations to be borne in mind with regard to the implementation of
object-oriented concepts in Presentation Manager applications, since the
Presentation Manager environment does not force the application developer to
obey such guidelines. Therefore, this chapter will discuss the implementation
of the general concepts outlined in The Presentation Manager Application Model,
in such a way that they conform to object-oriented principles and achieve the
highest level of modularity.
For the purposes of discussion, this chapter will assume that the source code
is written using the "C" language. Other programming languages may be used to
create Presentation Manager applications while preserving the overall
application architecture, provided these languages support the creation of
reentrant code and allow recursion.
ΓòÉΓòÉΓòÉ 16.1. Language Considerations ΓòÉΓòÉΓòÉ
Presentation Manager applications may be written using the following
programming languages:
Assembler language
"C"
COBOL (OS/2 Version 1.2 and above)
FORTRAN (OS/2 Version 1.2 and above)
The use of Assembler language should be avoided wherever possible. While
coding to such a low-level language may provide significant performance
improvements in critical applications, it is typically more costly in terms of
programmer productivity and subsequent code maintenance. Assembler code is
also less portable than that written using higher-level languages.
The requirements of the Presentation Manager execution environment restrict the
use of the COBOL and FORTRAN languages. Presentation Manager requires window
procedures to be reentrant, and neither FORTRAN nor COBOL support the creation
of reentrant code. In addition, much of the default message processing
provided by Presentation Manager results in synchronous messages being sent to
window procedures. This practice is effectively a recursive subroutine call,
and requires window procedures to be written in a language that supports
recursion. Neither COBOL nor FORTRAN provide such support.
In order to create COBOL or FORTRAN source code that executes in the
Presentation Manager environment, the application developer must adopt one of
two solutions:
1. Create a "C" program to provide the Presentation Manager windowing and
dialog management functions, and combine this program with called COBOL or
FORTRAN subprograms to perform the actual processing for the application.
2. Create a "winproc-less" application, where a main routine written in COBOL
or FORTRAN creates a message-processing loop, captures and explicitly
processes all message classes. Such an application has no window
procedures.
3. Use the "language support window procedure" provided with the OS/2
Programmer's Toolkit under OS/2 Version 1.3, which provides processing for
most message classes and returns selected messages to the application for
processing.
Where the use of COBOL or FORTRAN is unavoidable, solution (1) above is
recommended, since it provides additional flexibility, maintains SAA
conformance, retains much of the object-oriented nature of the application, and
allows the best use to be made of existing host COBOL or FORTRAN application
code, since the subprograms used are invoked using standard language
conventions, and data is passed to them using a normal parameter list and
returned the same way. The subprograms therefore interact with the calling
application in much the same way as an ISPF dialog, minimizing the requirement
for modification of existing code and reducing the need to retrain application
developers.
Object-oriented programming languages such as Smalltalk and C++ are becoming
increasingly popular for the creation of object-oriented code, and are
well-suited to the Presentation Manager application model. Organizations may
wish to investigate the viability of these languages for particular development
projects and environments.
ΓòÉΓòÉΓòÉ 16.2. Function and Data Types ΓòÉΓòÉΓòÉ
Presentation Manager provides a number of specialized function and data type
definitions (such as MRESULT, MPARAM, etc.) for use by Presentation Manager
applications. While these type definitions are not "standard" C language
types, their use is strongly recommended. OS/2 maps these type definitions
into standard C language types using #define statements embedded in the OS/2
header file os2.h. Since the mapping may vary between OS/2 Version 1.3 and
Version 2.0 due to differences between the 16-bit and 32-bit operating system
architectures, the use of Presentation Manager's type definitions insulates the
application source code from the underlying architecture.
ΓòÉΓòÉΓòÉ 16.3. Object-Oriented Programming Practices ΓòÉΓòÉΓòÉ
While Presentation Manager allows an application developer to implement the
fundamental concepts of object-oriented programming in his or her applications,
it does not restrict the application developer to the use of these
conventions. Therefore to ensure the correct implementation of object-oriented
conventions and to enable the maximum level of granularity, a number of
guidelines are offered:
The use of multi-purpose application objects (window procedures) should be
avoided; for example, a single window procedure should not handle both user
interaction and file access. Manipulation of separate data objects should be
achieved using separate window procedures. Background data objects (that is,
files or databases) should be manipulated using object windows.
As a corollary of the above rule, multiple window procedures should not be
created to act upon a single data object; where possible, all actions on a
particular data object should be performed by a single window procedure.
This behavior simplifies any future maintenance should the definition of the
logical data entity or its representation change. Note that this guideline
may need to be overridden in circumstances where an action requires lengthy
processing, in order to preserve application responsiveness.
The definition, creation and/or establishment of access to data objects
should be achieved, where possible, from within a window procedure in order
to preserve the concept of data encapsulation. That is to say, the use of
global data should be minimized in order to enhance modularity and maximize
object independence.
The input, output and behavior associated with a window procedure should
depend solely on the class and contents of the messages it receives, and
should not depend on any other external data or parameter, other than a data
structure to which a pointer is passed as a message parameter. This
preserves the concept of object polymorphism and enhances the potential for
reuse.
These guidelines, when obeyed, will enable an application to conform to the
established guidelines for object-oriented programming as discussed in
Object-Oriented Applications.
ΓòÉΓòÉΓòÉ 16.4. Application Main Routine ΓòÉΓòÉΓòÉ
A sample application main routine is illustrated in Figure "Sample Application
Main Routine (Part 1) - Registration" and Figure "Sample Application Main
Routine (Part 2) - Window Creation". The functions performed by the main
routine are as follows:
1. Register the application to Presentation Manager, and obtain an anchor
block handle (that is, an application handle), using the WinInitialize()
function.
2. Create a message queue, into which Presentation Manager will place all
messages intended for the application, using the WinCreateMsgQueue()
function and passing both the anchor block handle and the required queue
size to Presentation Manager, which returns a message queue handle to the
application. Note that if the queue size specified is zero (as shown in
the example above) then the default queue size of 10 messages is used.
3. Register one or more window classes, for the windows that will be created
by the application, and associate a window procedure with each window
class, using using the WinRegisterClass() function. Parameters passed to
this function include the name of the window class and the name of the
window procedure to be associated with the class. Presentation Manager
returns a Boolean value indicating success or failure. Note the 4 bytes
(32 bits) requested for window words, which may be used by the window
procedure to store the address of its instance data block.
4. Create a main display window for the application, using two consecutive
WinCreateWindow() calls (as shown in Figure "Sample Application Main
Routine (Part 2) - Window Creation") or a single WinCreateStdWindow() call.
Note the separate handles used for the frame and client windows. The values
specified for fcdata.flCreateFlags control the appearance of the window,
the controls it contains and its position on the screen.
5. Optionally, create an entry for the application in the Workplace Shell
Window List, using the WinAddSwitchEntry() function. Note that this step
is omitted from Figure "Sample Application Main Routine (Part 2) - Window
Creation" for reasons of clarity, and is shown separately in Figure
"WinAddSwitchEntry() Function".
Note that under OS/2 Version 2.0, the WinCreateSwitchEntry() function is
provided in addition to the WinAddSwitchEntry() function. These two
functions accept identical parameters and carry out identical tasks; the
WinCreateSwitchEntry() function is intended to provide consistent function
naming conventions. The WinAddSwitchEntry() function is retained under
OS/2 Version 2.0 for compatability with existing applications, but use of
the WinCreateSwitchEntry() function is recommended.
6. Establish a message processing loop, whereby the application requests
Presentation Manager to supply messages from the system queue and
subsequently invokes Presentation Manager to dispatch them to the
appropriate window procedure. This loop uses nested WinGetMsg() and
WinDispatchMsg() calls.
7. Upon receivng the special message class WM_QUIT, which will cause
WinGetMsg() to return false and hence terminate the while loop, remove any
remaining windows using the WinDestroyWindow() function, remove the
application's entry from the Window List using the WinRemoveSwitchEntry()
function, destroy the message queue and deregister the application before
terminating. These latter functions are achieved using the
WinDestroyMsgQueue() and WinTerminate() calls.
The structure of the main routine is similar for both the application (that is,
the application's primary thread) and any secondary threads created by the
application. See Multitasking Considerations for further discussion on
secondary threads.
In Figure "Sample Application Main Routine (Part 1) - Registration", note the
use of the EXPENTRY keyword in the function prototype to specify the system
linkage convention for the window procedure wpMain. This is required whenever
declaring a window procedure or dialog procedure, since such procedures are
normally invoked by Presentation Manager on the application's behalf, rather
than directly by the application.
If the application is to appear in and be selectable from the Workplace Shell
Window List, the main routine must issue a WinAddSwitchEntry() function call,
after creating the application's main window and before entering the message
processing loop. [Note that under OS/2 Version 2.0, use of the
WinCreateSwitchEntry() function is recommended, for reasons of consistency in
function names. ] This function call is shown in Figure "WinAddSwitchEntry()
Function".
Note that the application may set the swTitle field of the SwitchData structure
to NULL. Presentation Manager will then determine the title under which the
application was started from the Presentation Manager shell, and use this title
for the switch entry.
The WinAddSwitchEntry() function returns a switch entry handle, which may be
stored by the application and used during termination to remove the switch
entry from the Workplace Shell Window List using the WinRemoveSwitchEntry()
function.
The switch entry may be accessed by a window procedure at any time during
application execution. The switch entry handle is obtained using the
WinQuerySwitchHandle() function, and the SwitchData control structure may then
be obtained using the WinQuerySwitchEntry() function, and altered using the
WinChangeSwitchEntry() function. This capability may be used to allow a window
procedure to obtain the handle of the application's main window, in order to
post or send messages to that window. This is discussed in Identifying the
Destination Window.
ΓòÉΓòÉΓòÉ 16.5. Using Windows ΓòÉΓòÉΓòÉ
As mentioned in Window Procedures, window procedures within a Presentation
Manager application are reentrant; that is, the same window procedure is used
for multiple instances of the same window class. However, a window class may
have separate data objects associated with each instance of that class, which
may be used to store temporary data necessary during the existence of that
object; such data is known as instance data. These data objects may need to
be created/opened and initialized. Upon the window being closed, data
objects may need to be closed or destroyed in a controlled fashion.
Presentation Manager allows such function to be performed by a window
procedure, since messages are sent to a window by Presentation Manager
informing the window procedure of events such as creation or closure of the
window. These messages are discussed below.
ΓòÉΓòÉΓòÉ 16.5.1. Window Creation ΓòÉΓòÉΓòÉ
A window is created by Presentation Manager in response to the application
issuing a WinCreateStdWindow() function call or a WinCreateWindow() call; an
example of the WinCreateWindow() call is given in Figure "Sample Application
Main Routine (Part 2) - Window Creation".
The first statement in the example specifies the attributes of the frame
window, which are contained in the data variable fcdata.flCreateFlags. These
values determine the control windows that are created with the frame window
(FCF_SYSMENU, FCF_MINMAX etc), and also indicate to Presentation Manager that
it should select the position of the window on the desktop (FCF_SHELLPOSITION).
The window is then created in two steps; firstly the frame window is created,
with the desktop as its parent, and then the client window is created with the
frame window as its parent. The frame window belongs to the system-defined
window class WC_FRAME, whereas the client window belongs to an
application-defined window class WCP_MAIN, which is assumed to have already
been defined to Presentation Manager using a WinRegisterClass() call.
If it is necessary to pass initialization information to a window upon its
creation, this may be achieved using the CtlData parameter in the
WinCreateWindow() function. This parameter is a 32-bit pointer, which may
reference an application-defined data structure. This pointer is passed to
the window as the first parameter of the WM_CREATE message. The window may,
during its processing of this message, extract the pointer from the message
parameter and use it to access the data structure. See Figure "Sample
Application Main Routine (Part 2) - Window Creation" for an example of this
technique.
When an application requests that Presentation Manager creates a window of a
particular class, a message of the system-defined class WM_CREATE is sent to
the window procedure associated with that class. The window procedure may
capture this message by including a case for it, and perform any processing
such as opening files or databases, allocating memory objects and setting
instance data to initial default values.
In coding the method for this message class, the first statement should be a
call to WinDefWindowProc(), which will enable Presentation Manager to perform
default processing and complete the initialization of the window (such as
allocating a window handle) before the application-specific processing is
carried out. If the default processing is not completed first, the window
handle and any window words may not be allocated before the application makes
function calls that reference them, thus causing these calls to fail.
Where instance data or resource handles will be used by the window, and must be
maintained beyond the processing of a single message, a data structure should
be defined to contain these items. Memory for the data structure should be
requested from the operating system, and a pointer to the memory object stored
in the window words, as part of the WM_CREATE processing. See Instance Data
and Window Words for further information.
ΓòÉΓòÉΓòÉ 16.5.2. Window Processing ΓòÉΓòÉΓòÉ
During execution, a window processes messages passed to it by Presentation
Manager, using the methods defined in its window procedure. Upon receiving a
message, the window procedure performs three basic tasks:
1. The window procedure determines the message class by examining the message
class identifier.
2. Depending upon the message class, the window procedure executes a series of
application instructions and/or subroutines to perform the action requested
by the message.
3. The window procedure passes a return code to Presentation Manager.
As part of the second step above, the window procedure may extract necessary
information from the parameters passed with the message, using a number of
macros provided by Presentation Manager. These macros are described in
Creating Message Parameters.
The window procedure may also gain access to instance data or resource handles
stored in a control block during processing of previous messages. This control
block is generally allocated upon creation of the window and a pointer to it
stored in the window words. The window procedure may retrieve this pointer
from the window words at the start of processing for the current message. See
Instance Data and Window Words.
ΓòÉΓòÉΓòÉ 16.5.3. Window Closure ΓòÉΓòÉΓòÉ
A window is closed (removed from the screen and destroyed) by Presentation
Manager in response to the application issuing a WinDestroyWindow() call,
specifying the handle of the window to be destroyed. In normal circumstances
the handle of the frame window is specified; destroying the frame window
destroys that window and all of its children, including the client window
associated with that frame.
When an application requests that Presentation Manager close a window, a
system-defined message of class WM_DESTROY is sent to the client window, and
thus to the window procedure associated with that class. The window procedure
may capture and process this message, backing out any uncompleted units of
work, and destroying or terminating access to data objects. The window
procedure should then return a value of zero.
Note that although closing and destroying a parent window will also close and
destroy all children of that window, the WM_DESTROY message is sent to the
parent window, and processed before the children are destroyed. Hence when
processing a WM_DESTROY message, a window procedure may assume that all its
children still exist.
If the user explicitly requests closure of a window by selecting the "Close"
option on the system menu, a system-defined message of class WM_CLOSE is sent
to the window procedure. The window procedure may also capture and process
this message in a similar manner to that used for WM_DESTROY messages.
Note that explicit processing of the WM_CLOSE message class is recommended for
all Presentation Manager windows, since the default processing provided by
Presentation Manager causes a WM_QUIT message to be posted to the application's
message queue. This may result in unwarranted termination of the application.
The window procedure for a child window should process a WM_CLOSE message by
issuing a WinDestroyWindow() call for its frame window. The window procedure
for an application's main window should process a WM_CLOSE message by posting a
WM_QUIT message to itself. This will cause the application to terminate (see
Terminating an Application).
In order to handle the closure of a window in the most elegant manner, the
following course of action is recommended:
Explicit processing should be provided for both WM_CLOSE and WM_DESTROY
messages:
- A window procedure should process a WM_CLOSE message by issuing a
WinDestroyWindow() call for its own frame window if it is a child window,
or a WM_QUIT message to itself if it is an application's main window. In
both cases, the window procedure should then return a value of zero.
- A window procedure should process a WM_DESTROY message by closing any
files or databases that it has opened, and freeing any resources such as
memory objects.
Selection of the "Exit" option from a menu bar should result in the closure
of the window to which the menu bar belongs, by having the window procedure
issue a WinDestroyWindow() call for its frame window. If the window is the
application's main window, it should be closed by having the window procedure
post a WM_QUIT message to itself (see Terminating an Application). This will
result in a WM_DESTROY message being posted to the main window and each of
its children as part of the application's termination processing. These
messages may be captured and processed by the appropriate window procedures
in order to close data objects, back out incomplete units of work, etc.
The release of data objects and Presentation Manager resources is discussed in
Instance Data and Window Words.
ΓòÉΓòÉΓòÉ 16.5.4. Instance Data and Window Words ΓòÉΓòÉΓòÉ
For data that is private to a particular instance of a window class, each
window may have an area of storage associated with it, assigned by Presentation
Manager and located within the Presentation Manager control block for that
window. This area is known as the window words. The amount of space allocated
for window words in a particular window class is variable, and is defined in
the WinRegisterClass() function call at the time the class is registered to
Presentation Manager.
It is recommended that for storage of amounts of data larger than four bytes, a
memory object is obtained from the operating system using the DosAllocMem() or
DosSubAlloc() functions, and a pointer to this object is placed in the window
words of the associated window. An example of this technique is given in
Figure "Storing Instance Data in Window Words".
A memory object corresponding to the size of the data structure MYSTRUCT is
obtained from the operating system using the DosAllocMem() function, and a
pointer to this memory object is set by the application. This pointer is then
placed in the window words of the current window's parent (that is, the frame
window) using the WinSetWindowULong() function, at offset QWL_USER. A number
of predefined Presentation Manager window classes, including the frame window
class, contain a 32-bit word at this offset, which is available for application
use.
Note the use of the PAG_COMMIT flag in the DosAllocMem() function call. This
flag causes storage to be allocated immediately for the memory object being
created, since OS/2 Version 2.0 by default uses a two-phase process for dynamic
memory allocation.
The concept of committing memory is new to Version 2.0, and allows a storage
map for the application to be defined, but the storage is not reserved in
memory until it is needed, at which time the application may explicitly commit
the storage using the DosSetMem() function. Optionally, the application may
set the PAG_COMMIT flag in the DosAllocMem() function call to commit the
storage immediately upon allocation.
Failure to commit storage, either by use of the PAG_COMMIT flag or the
DosSetMem() function, will result in a page fault exception (Trap 000E) when
the application attempts to write to the storage area. The concept of
allocating and committing storage is explained fully in OS/2 Version 2.0 -
Volume 1: Control Program, and the use of these techniques by applications is
described in The Flat Memory Model.
After the memory object containing instance data is initially allocated, the
window procedure may access it during processing of subsequent messages by
issuing a WinQueryWindowULong() call to Presentation Manager, as shown in
Figure "Retrieving Instance Data from Window Words".
Upon termination of the window by the application, the window procedure
receives a WM_DESTROY message. As described in Window Closure , the window
procedure should process this message by releasing any resources to which it
has access. This includes the instance data control block, which must be
released using the DosFreeMem() function as shown in Figure "Releasing Instance
Data Storage".
In the above example, the pointer to the instance data control block is first
retrieved from the window words, giving access to the handles of any data
objects or Presentation Manager resources obtained by the window, in order that
these may be released. Once this has been achieved, the memory object
containing the control block is released by the window procedure. Failure to
release the data objects and resources before freeing the memory object would
result in a general protection exception (Trap 000D) when the data objects or
resources were subsequently released.
ΓòÉΓòÉΓòÉ 16.5.5. Subclassing a Window ΓòÉΓòÉΓòÉ
The use of subclassing to modify the methods of an existing window class has
been described in Subclassing. An application subclasses a particular window
instance (rather than the entire window class) by creating a subclass window
procedure, and registering this window procedure to Presentation Manager using
the WinSubclassWindow() function.
The use of the WinSubclassWindow() function is shown in Figure
"WinSubclassWindow() Function".
The WinSubclassWindow() function substitutes a new window procedure, known as
the subclass window procedure, for the original window procedure associated
with the window being subclassed. The window handle of the window, along with
the entry point of the subclass window procedure, is passed to the
WinSubclassWindow() function. The function returns the entry point address of
the original window procedure for that window.
Once a window has been subclassed, Presentation Manager routes messages
destined for that window to the subclass window procedure. The subclass window
procedure may:
Process the message itself, if it indicates an action for which the method
must be modified.
The subclass window procedure then returns control immediately to
Presentation Manager.
Pass the message on to the original window procedure for that window, if the
subclass window procedure is not explicitly concerned with the action
indicated by the message.
The original window procedure is directly invoked by the subclass window
procedure; note that this is one of the few instances where direct invocation
of a window procedure is recommended. The return code from the original
window procedure is then returned to Presentation Manager.
Both of the above, if the subclass window procedure must perform some
processing in addition to that normally performed by the original window
procedure.
The additional processing performed by the subclass window procedure may be
performed either before or after the processing performed by the original
window procedure. This sequence is at the discretion of the application
developer, and depends largely on the desired modification in the window's
behavior.
A subclass window procedure is similar in structure to a "normal" window
procedure, except that instead of calling the WinDefWindowProc() function as
its default case, it should invoke the original window procedure. This means
that the entry point address of the original window procedure must be known to
and accessible from the subclass window procedure. Note also that the entry
point address might not be that of the original window procedure specified when
the window class was registered to Presentation Manager, since the window might
previously have been subclassed, and the current subclassing operation might be
effectively subclassing the subclass window procedure.
The entry point address of the original procedure can be supplied to the
subclass window procedure in a number of ways:
It may be determined from the information returned by the WinSubclassWindow()
call, and passed to the subclass window procedure in an application-defined
message. The subclass window procedure may then store the entry point
address in a global variable or in the window words of the window, assuming
the available window words are not already in use.
It may be determined by the subclass window procedure itself by querying
Presentation Manager. Note, however, that this method will only work if the
window has not previously been subclassed, since Presentation Manager only
records the original window procedure (as specified in the WinRegisterClass()
function call) in the CLASSINFO structure for the window.
An example of a subclass window procedure, including a query to obtain the
original entry point address from the Presentation Manager class information,
is given in Figure "Subclass Window Procedure". Figure "Subclass Window
Procedure" shows each of the possible cases listed above. The message class
WMP_MESSAGE1 is explicitly processed by the subclass window procedure, which
then returns control to Presentation Manager with a return statement upon
completion.
The message class WMP_MESSAGE2 is also explicitly processed by the subclass
window procedure, but in this case it is required that the processing performed
by the original window procedure be allowed to occur, after the subclass window
procedure's processing. The subclass window procedure therefore does not
return control immediately to Presentation Manager, but merely terminates the
switch statement, allowing the final four statements to be executed.
For other message classes with which the subclass window procedure is not
concerned, the default case also terminates the switch statement, allowing the
final four statements to be executed.
These final statements determine the entry point address of the original window
procedure, using the WinQueryClassName() and WinQueryClassInfo() functions to
access control information held by Presentation Manager. This entry point
address is then used to invoke the original window procedure to process
messages with which the subclass window procedure is not concerned, or for
which the normal processing must be allowed to occur.
The last four statements in the example above are common to all subclass window
procedures, and organizations undertaking development of Presentation Manager
applications may wish to incorporate them into a standard subroutine and place
them in a library for access by developers.
Note that a subclass window procedure, like all window and dialog procedures,
must use the system linkage convention. This is normally achieved by declaring
the subclass window procedure using the EXPENTRY keyword.
ΓòÉΓòÉΓòÉ 16.6. Window Communication ΓòÉΓòÉΓòÉ
Presentation Manager provides a number of mechanisms for communicating between
windows. All of these mechanisms use the Presentation Manager message concept.
The exact technique used in any particular situation is dependent upon the
nature of the communications and the types of windows involved.
ΓòÉΓòÉΓòÉ 16.6.1. Standard Windows ΓòÉΓòÉΓòÉ
Data may be passed to a window upon its creation, using the CtlData parameter
of the WinCreateWindow() function. The contents of this parameter (a 32-bit
pointer) are passed to the target window as a parameter to the WM_CREATE
message. The contents may then be extracted from the message parameter and
used by the window procedure.
When an application wishes to pass a message between two standard windows that
currently exist, whether they are display windows or object windows, either of
two methods may be used, depending on whether the desired communication is to
be synchronous or asynchronous.
When a synchronous message is to be passed, the WinSendMsg() function is
used, and the target window procedure is invoked directly by Presentation
Manager, in a similar fashion to a normal function call. The return code
from the window procedure is passed by Presentation Manager to the calling
window procedure, where it may be interrogated and acted upon.
When a message is to be processed asynchronously, the WinPostMsg() function
is used. In this case the message is posted to a queue associated with the
thread that created the target window, and the return code to the calling
window procedure merely indicates that the message was successfully placed on
the queue. In order for the target window procedure to pass a return code or
acknowledgement back to the calling window procedure, it must include another
WinPostMsg() call as part of the processing of the message.
The use of WinPostMsg() is recommended over that of WinSendMsg(), since posted
messages are processed in the order in which they arrive in the queue, and the
integrity of the user's intention is thus preserved in the order of processing.
In addition, synchronous window procedures are invoked and executed without the
original window procedure completing its processing and returning control to
the message processing loop. Thus the application is prevented from
processing additional user interaction, which may lead to violation of the SAA
CUA responsiveness guidelines.
ΓòÉΓòÉΓòÉ 16.6.2. Dialog Boxes ΓòÉΓòÉΓòÉ
Communication between a standard window and a modeless dialog box is achieved
in a similar fashion to that used between two standard windows, since the
modeless dialog box is merely a normal window without a sizable border.
However, communication between a standard window and a modal dialog box must be
achieved in a different manner, since a modal dialog box is typically loaded
and processed in a single WinDlgBox() function call, and the dialog box only
has an existence during the execution of that function call. An example of the
WinDlgBox() function is shown in Figure "WinDlgBox() Function".
Data may be passed to a dialog procedure at initialization time by creating a
data structure and passing a pointer to that structure in the CreateParams
field of the WinDlgBox() function, as shown in Figure "WinDlgBox() Function".
This pointer is passed to the dialog procedure as the second parameter of the
WM_INITDLG message, and may be accessed by the dialog procedure during the
processing of this message. Note that this is the only time at which input may
be passed to a dialog box, since the dialog is processed within the scope of a
single application statement; either a WinDlgBox() call or a WinProcessDlg()
call may be used. The WM_INITDLG message is described in the IBM OS/2 Version
2.0 Presentation Manager Reference.
Information may be conveyed from a dialog procedure to its calling window
procedure in one of two ways:
The dialog box may provide an unsigned integer (USHORT) parameter to the
WinDismissDlg() function, and this value is passed to the calling window
procedure as the return code from the WinDlgBox() function. This technique
is useful where an acknowledgement or simple return data must be conveyed.
The dialog box may issue a WinPostMsg() call to pass a message to the queue
associated with its calling window. The window procedure may then receive and
process that message in the normal way. This technique is useful when more
complex data or structures must be conveyed.
The latter technique above may also be used to convey information to a window
other than the window that invoked the dialog. This may be necessary in
situations where a dialog box is invoked by one window procedure on behalf of a
group of windows.
ΓòÉΓòÉΓòÉ 16.6.3. Control Windows ΓòÉΓòÉΓòÉ
As mentioned in Systems Application Architecture CUA Considerations, control
windows are typically used in dialog boxes, and are hence accessed from the
dialog procedure associated with their parent dialog box. Such communication
is synchronous in nature, since it usually involves insertion or retrieval of
data into or from control windows, or other tasks that are part of the modal
dialog with the user.
Under OS/2 Version 2.0, some additional functions have been introduced into the
Presentation Manager programming interface, to ease more complex
communications, such as those involving list boxes. Since communication with
list boxes is therefore somewhat different from that involving other control
window classes, list boxes are discussed separately in List Boxes below.
General Control Windows
Communication between a dialog procedure and the control windows associated
with its dialog box is typically achieved using the WinSendDlgItemMsg()
function, which is documented in the IBM OS/2 Version 2.0 Presentation Manager
Reference. This function is similar in function and behavior to the
WinSendMsg() function, in that it passes a synchronous message to the
destination window. However, instead of accepting the handle of the
destination window as its first parameter, it accepts the handle of the
control window's parent and the window identifier of the control window itself
as the first two parameters of the call. For example, to send a message of
class EM_SETTEXTLIMIT to an entry field named EF_PRODNAME, which is a child of
the dialog box with handle hDlgBox, the function call shown in Figure
"Communicating with a Control Window" is used.
It is possible to perform an equivalent function using the WinSendMsg() call,
by obtaining the control window's handle using the WinWindowFromID() function.
However, for purposes of standardization and in accordance with emerging
conventions, it is recommended that the WinSendDlgItemMsg() function be used to
send messages to control windows. Note that for this purpose, the definition
of control windows includes both the system menu and menu bar; messages sent
to these menus (in order to insert, modify or delete items) should be sent
using the WinSendDlgItemMsg() function.
Similarly, it is recommended that the WinSetDlgItemText() and
WinQueryDlgItemText() functions be used to set and query the contents of
control windows from within the application. For example, assume that the user
has completed interaction with a dialog box, and pressed the "Enter" or "OK"
button, and the application wishes to obtain the contents of an entry field
named EF_PRODNAME, which is child of the dialog box with handle hDlgBox. The
function call call shown in Figure "Querying Information From a Control Window"
is used.
The WinQueryDlgItemText() function copies the contents of the entry field into
the string szBuffer, and returns the number of characters copied.
The WinSetDlgItemText() function is typically used in situations where some of
the information necessary to complete an action is known; this information is
then displayed in the appropriate entry fields within the dialog box, and the
user fills in the missing fields. Another use of this function is to provide
default values for entry fields. Both the WinSetDlgItemText() and
WinQueryDlgItemText() functions are documented in the IBM OS/2 Version 2.0
Presentation Manager Reference.
List Boxes
The complexity of communication with list boxes has been greatly reduced under
OS/2 Version 2.0. The Presentation Manager programming interface now includes
a number of functions that allow most communication requirements to be achieved
in a single step. Note that these functions may also be used for communication
with a combo box (prompted entry field).
Insertion and deletion of list box items is carried out using the
WinInsertLboxItem() and WinDeleteLboxItem() functions, which are new to OS/2
Version 2.0. The WinInsertLboxItem() function is illustrated in Figure
"Inserting an Item Into a List Box".
An application may obtain the text of a selected item in the list box using the
WinQueryLboxSelectedItem() and WinQueryLboxItemText() functions. The use of
these functions is illustrated in Figure "Querying a Selected List Box Item".
Other functions include the WinQueryLboxCount() function, which returns the
number of items in a list box, and the WinQueryLboxItemTextLength() function,
which returns the length of list box item's text.
All of these list box manipulation functions are described in the IBM OS/2
Version 2.0 Presentation Manager Reference.
ΓòÉΓòÉΓòÉ 16.6.4. Message Boxes ΓòÉΓòÉΓòÉ
Communication between a window or dialog procedure and a message box is
relatively simple. The message box is created and processed using the
WinMessageBox() function, and the only input data provided to this function is
the title of the message box and the text of the message to be displayed. The
application may affect the style of the message box, by specifying style
attributes in the function call, as described in the IBM OS/2 Version 2.0
Presentation Manager Reference.
An example of the WinMessageBox() function is given in Figure "WinMessageBox()
Function".
The result of the user's interaction with the message box (that is, the
identifier of the button that was pressed) is communicated to the application
in the form of an unsigned integer returned by the WinMessageBox() call. The
application may then interrogate this returned value to determine the
subsequent action to be taken.
ΓòÉΓòÉΓòÉ 16.6.5. Identifying the Destination Window ΓòÉΓòÉΓòÉ
When passing messages between windows using the WinPostMsg() or WinSendMsg()
functions, the window handle of the destination window must be known and
specified in the message. If window handles are not defined globally, the
required handle must be obtained from Presentation Manager. This may be
achieved in a number of ways:
If the target window has a known relationship to the current window or to
another window for which the handle is already known, the WinQueryWindow()
function may be used to obtain the window handle of the target window. For
example, if a window wishes to post a message to its own parent window, the
technique shown in Figure "Obtaining a Window Handle - WinQueryWindow()
Function" may be used.
The WinQueryWindow() call returns the handle of the required window.
Relationships other than parent/child may also be used by this function; the
valid relationships are described, along with the WinQueryWindow() function,
in the IBM OS/2 Version 2.0 Presentation Manager Reference.
If the parent window and window identifier of the target window are known,
the WinWindowFromID() function may be used to obtain the window handle of the
target window. For example, if a window wishes to post a message to the
client window of its application's main window, assuming the frame window
handle is known, the method shown in Figure "Obtaining a Window Handle -
WinWindowFromID() Function" may be used.
The WinWindowFromID() function also returns the handle of the required
window.
If the target window is the application's main window, its handle may be
obtained by first querying the application's switch entry in the Workplace
Shell Window List to obtain the handle of the main frame window (using the
WinQuerySwitchHandle() and WinQuerySwitchEntry() functions), then using the
WinWindowFromID() function to obtain the handle of the client window, as
shown in Figure "Obtaining a Window Handle Using the Switch Entry".
The above example assumes that the application has been added to the OS/2
Window List using the WinAddSwitchEntry() function, and the handle of its
main frame window supplied as a parameter. See Figure "WinAddSwitchEntry()
Function".
When passing messages synchronously to control windows using the
WinSendDlgItemMsg() function, it is generally assumed that the target control
window is a child of the current window or dialog box. Thus the parent window
handle is the handle of the current window, and the window identifier is also
known to the current window procedure. An exception is the case where a window
procedure wishes to send a message to a frame control of its own parent frame
window. In this case a WinQueryWindow() call must be issued with the QW_PARENT
parameter to determine the handle of the frame window. The WinSendDlgItemMsg()
function may then be used with this handle and the window identifier of the
required frame control.
ΓòÉΓòÉΓòÉ 16.6.6. Creating Message Parameters ΓòÉΓòÉΓòÉ
Before a message can be passed to a target window, its message parameters must
be created from the necessary data items. As mentioned in Messages, message
parameters are 32-bit fields. Presentation Manager provides a number of macros
to convert existing data types into the correct representation, and to extract
data from message parameters within the target window procedure. These macros
are described in Table "Presentation Manager Macros". For example, to create
message parameter mp1 composed of two unsigned integers usInt1 and usInt2, the
following statement is used:
mp1 = MPFROM2SHORT(usInt1,usInt2);
Similarly, to extract two unsigned integers usInt3 and usInt4 from the message
parameter mp2, the following statements are used:
usInt3 = SHORT1FROMMP(mp2);
usInt4 = SHORT2FROMMP(mp2);
Characters, pointers, window handles, etc., may all be placed into and
retrieved from message parameters using macros supplied by Presentation
Manager.
ΓòÉΓòÉΓòÉ 16.6.7. Broadcasting Messages ΓòÉΓòÉΓòÉ
In certain circumstances, a window procedure may wish to indicate an event to
multiple windows, and therefore need to pass the same message to each of these
windows. Presentation Manager provides the capability for a message to be
broadcast to multiple windows with a single WinBroadcastMsg() function call.
The WinBroadcastMsg() function passes a message of a specified class to the
descendants of a specified parent window, as shown in Figure "WinBroadcastMsg()
Function".
The example shown in Figure "WinBroadcastMsg() Function" passes a message of
the application-defined class WMP_MYMESSAGE to all children of the current
window (that is, the window associated with the window procedure in which the
function call is made), with message parameters as shown. The message is
posted to the target windows via a message queue, and is thus processed
asynchronously; the WinBroadcastMsg() function also allows for synchronous
processing using the BMSG_SEND flag.
The parent/child hierarchy allows windows to be grouped in particular ways to
suit application requirements. For example, all the object windows created by
an application may be created as children of a "dummy" master object window.
If a particular message must then be sent to all these object windows (for
example, to close all the windows), this can be done by broadcasting the
message to all children of the master object window.
The BMSG_DESCENDANTS flag may be set in the WinBroadcastMsg() call to cause a
message to be passed to all descendants of the specified parent window, rather
than just the direct children of that parent. This enables a message to be
broadcast to a wider target group, should the application so require.
Alternatively, the BMSG_FRAMEONLY flag may be set, causing the message to be
passed only to frame windows. This is useful in situations where an
application wishes to initiate an action by multiple display windows at the
same time.
The WinBroadcastMsg() function must be used with caution, particularly when it
may cause messages to be sent to windows created by other applications. This
is possible if the BMSG_DESCENDANTS flag is set and the desktop window is
specified as the parent, and may cause complications in other applications.
For example, consider the following message definitions:
Application 1
#define WMP_REFRESH WM_USER+12
Application 2
#define WMP_CLOSEALL WM_USER+12
In the example above, each application defines a message class, and each
message is to be used for a different purpose. However, both messages have the
same message identifier. Now let us assume that Application 1 makes the
following function call:
rc = WinBroadcastMsg(HWND_DESKTOP,
WMP_REFRESH,
mp1,
(MPARAM)0,
BMSG_POST);
This function call would cause a WMP_REFRESH message to be passed to all
display windows in Application 1 and Application 2. However, the windows in
Application 2 would interpret the message as a WMP_CLOSEALL message, with
possibly undesirable results.
It is therefore strongly recommended that developers exercise extreme care in
using the WinBroadcastMsg() function, in order to accurately determine the
potential results of the messages being broadcast.
ΓòÉΓòÉΓòÉ 16.7. Passing Control ΓòÉΓòÉΓòÉ
The use of functions and subroutines in an object-oriented application
executing in the Presentation Manager raises some issues with regard to object
boundaries. In general, the scope of a function or subroutine should be
restricted to a single application object, and the processing performed by that
subroutine should therefore relate only to the data object(s) owned by that
application object. If a subroutine invoked from one application object will
perform processing on a data object related to a different application object,
then the subroutine should be invoked by the second application object, by way
of a message passed from the first application object.
Four general types of subroutines may exist within an object-oriented
application. These are discussed in the following sections, and are classified
according to the nature of their inputs and outputs.
ΓòÉΓòÉΓòÉ 16.7.1. Direct Invocation/Direct Return ΓòÉΓòÉΓòÉ
This type of subroutine corresponds to the "conventional" subroutine call, in
that a parameter list is passed to the subroutine from the calling routine, and
a number of parameters and/or a return code is returned at the end of the
subroutine's execution. Within an object-oriented application, such
subroutines should be used to perform processing that is limited in scope to a
single application object (such as an SQL query on a database owned by the
application object), or to perform a standard processing function that is
common to a number of objects, but where the scope of each execution instance
is limited to a single object. For example, a function DrawCircle may be
called by a number of window procedures to display a circular graphics
primitive; however, each invocation of the function is from a single window
procedure.
ΓòÉΓòÉΓòÉ 16.7.2. Direct Invocation/Message Return ΓòÉΓòÉΓòÉ
This type of subroutine should be used where the scope of the processing
performed by a subroutine is limited to a single application object, but where
the result of that processing must be communicated to an application object
other than the one that invoked the subroutine. Since the conventional method
of achieving communication between objects is via messages, the subroutine
posts a message to the affected application object using the WinPostMsg()
call, or synchronously passes the message to the application object using the
WinSendMsg() call (this latter call should be used with caution; see Message
Invocation/Direct Return). The message is routed to the destination window by
Presentation Manager. The subroutine typically returns to its caller in the
normal fashion; this method of passing control is therefore merely a variation
of the previously described Direct Invocation/Direct Return method.
Assuming that the calling routine is a window procedure, the return code (if
any) from the subroutine is passed to the calling window procedure and that
procedure completes its execution before the message resulting from the called
subroutine is processed.
Note that this technique can be used where the called subroutine executes in a
secondary thread, and the resulting message is passed back to the calling
window procedure in the primary thread to indicate the completion of the
secondary thread's processing. See Multitasking Considerations for further
discussion of multiple threads.
ΓòÉΓòÉΓòÉ 16.7.3. Message Invocation/Direct Return ΓòÉΓòÉΓòÉ
This type of subroutine occurs with window procedures that are invoked
synchronously via a WinSendMsg() call. The message is processed, and the
return code from the window procedure is routed to the calling routine by
Presentation Manager. The calling routine then completes its execution. If
any queued messages are generated by the called window procedure or subroutine,
these messages are not processed until the calling routine completes its
execution and the application issues its next WinGetMsg() call. This is so,
even if the called window procedure or subroutine executes in a separate
thread.
This type of invocation should be used for access to another application
object, where the function to be performed must be executed synchronously and
the result returned directly to the caller. However, use of the WinSendMsg()
call in preference to the WinPostMsg() call for communication between objects
may result in messages being processed out of order due to the application
pre-empting the normal order of execution determined by the message queue.
The WinSendMsg() function should thus be used with care. The use of this call
may also extend the time interval between successive WinGetMsg() calls to
Presentation Manager, thus decreasing the application's responsiveness to user
interaction.
ΓòÉΓòÉΓòÉ 16.7.4. Message Invocation/Message Return ΓòÉΓòÉΓòÉ
This is the case for window procedures invoked in the standard way using a
WinPostMsg() call from another window or using the WinDispatchMsg() function
from the application's main routine. In this case the message is processed,
and any messages generated during execution are posted to the appropriate
queue, but the return code from the window procedure is passed only to
Presentation Manager, and does not reach the calling window procedure. For this
reason, it is important that any message that requires acknowledgement be
handled in such a way that the window procedure generates a message that is
routed to the calling window, and that contains the required acknowledgement.
This type of invocation should be used for access to other application objects,
where the function to be performed need not be performed synchronously, and
where acknowledgement or completion of the processing may be indicated by a
subsequent message posted to the caller.
Note that this should be the default method of invocation for window
procedures, since the asynchronous nature of the processing allows the
application to maintain the highest level of responsiveness to user
interaction.
Note also that a window may receive messages from a number of sources. This
allows a window to service requests from a number of other windows, in
accordance with a client-server architecture. This concept is discussed further
in Client-Server Applications.
ΓòÉΓòÉΓòÉ 16.7.5. External Macros ΓòÉΓòÉΓòÉ
An application may also pass control synchronously to an external routine such
a macro or subprogram written using the Restructured Extended Executor (REXX)
procedure language. This can be achieved quite easily by calling the REXX
command interpreter using the RexxStart() function from any point within the
application. This function is illustrated in Figure "Calling External Macros".
Commands are passed to the REXX interpreter using command strings defined using
the RXSTRING data type, which is defined in the rexxsaa.h header file. This
structure contains the string pointer and an unsigned long integer containing
the length of the string in bytes. A number of commands may be passed in a
single operation, by specifying an array of RXSTRING structures in the second
parameter to the RexxStart() function. The first parameter specifies the
number of commands being passed.
The third parameter to the RexxStart() function defines the name of the REXX
procedure to be invoked. In Figure "Calling External Macros", the procedure is
contained in the file REXXPROC, with an assumed default file extension of .CMD.
If the REXX procedure invoked by the application issues its own commands such
as SAY (to output information to the screen), a subcommand handler must be
specified in the RexxStart() function call, in order to trap such output. A
subcommand handler is simply a subroutine which accepts, as parameters, the
function and subfunction names issued by the REXX procedure, along with a
pointer to an RXSTRING structure which may be used by the subcommand handler to
return any information to the REXX procedure. A subcommand handler may reside
within the application's main executable module or in a DLL, and must be
registered prior to issuing the RexxStart() function call, using the
RexxRegisterSubcomExe() or RexxRegisterSubcomDll() functions.
The REXX interpreter's operating environment may be customized through the use
of user exits, whereby special routines may be inserted at particular points in
the interpreter's execution. Such routines are specified using an array of
RXSYSEXIT structures, which identify the exit point and the entry point address
of the routine to be invoked at that point. The address of this array is
passed in the RexxStart() function call.
Use of the REXX interpreter, the RexxStart() function and its supporting
functions are described in detail in the IBM OS/2 Version 2.0 Technical Library
- Procedures Language/2 REXX Reference.
ΓòÉΓòÉΓòÉ 16.8. Terminating an Application ΓòÉΓòÉΓòÉ
A Presentation Manager application is normally terminated by a message of the
class WM_QUIT being posted to the application's message queue. The message may
be posted by any window procedure or subroutine within the application, or by
Presentation Manager as the result of the user selecting the "Shutdown" option
from the Presentation Manager desktop. The message may result from the user
selecting an "Exit" option from the menu bar, or selecting the "Close" option
in the system menu of the application's main window.
The WM_QUIT message causes the next WinGetMsg() call to return FALSE. This in
turn causes the application's message processing loop to terminate.
By convention, a Presentation Manager application performs standard termination
processing such as:
Destroying the application's main window
Destroying the application's message queue
Deregistering the application from Presentation Manager.
The application may additionally perform its own termination functions such as
closing or destroying any global data objects. Secondary threads are normally
terminated from within the window procedure that created them, as part of that
window procedure's WM_DESTROY message processing. See Multitasking
Considerations for further information.
ΓòÉΓòÉΓòÉ 16.9. Summary ΓòÉΓòÉΓòÉ
It can be seen that by making effective use of the facilities provided by
Presentation Manager, and by following a number of simple guidelines in the
design and implementation of applications, it is relatively simple to develop a
Presentation Manager application that conforms to module-based object-oriented
programming standards, and achieves benefits through reduced development effort
and easier application maintenance, due to code reuse and encapsulation.
It must be accepted however, that some deviation from strict object-oriented
practice may be necessary in order to preserve other important goals such as
the preservation of responsiveness to the end user. Adherence to academic
principles should not take precedence over achievement of the required result.
The mapping of data objects into application objects must be approached with
great care in the design stage of a Presentation Manager application.
Presentation Manager allows the creation of window procedures (application
objects) that operate on more than one data object, and of multiple window
procedures that operate on the same data object. This practice should be
discouraged however, since it reduces the level of encapsulation in the
application object, increases the interdependence between application objects,
and consequently reduces the benefits attainable through code reuse and
containment of change.
Notwithstanding, the Presentation Manager environment affords great opportunity
for the development of applications that implement the general principles of
the object-oriented approach. A central precept of object-oriented design is
the generic nature and consequent reusability of the objects so created.
Adherence to guidelines that promote conformance to object-oriented concepts
such as data abstraction, encapsulation and polymorphism, in conjunction with
the facilities provided by Presentation Manager for object creation,
communication and subclassing, and by the OS/2 operating system in the form of
dynamic linking, facilitates the development of highly granular, reusable
generic objects in the Presentation Manager environment.
ΓòÉΓòÉΓòÉ 17. Workplace Shell and the System Object Model ΓòÉΓòÉΓòÉ
The Workplace Shell provided under OS/2 Version 2.0 introduces an
object-oriented layer into the Presentation Manager environment. It provides a
mechanism for the registration of object classes, creation of objects within
those classes, and the inheritance of characteristics and behaviors from
existing object classes. Using the Workplace Shell, an application may be
created as a series of objects that interact on the desktop, and which the user
manipulates to perform the required application processing. Each object
possesses data, which may be defined for the entire class or for each instance,
and a set of methods that operate upon that data.
The Workplace Shell functions that allow the creation and manipulation of
objects are based upon the system object model, which establishes a basic
inheritance hierarchy for objects in the system and defines the underlying
protocols which regulate the relationships between objects. The concepts
behind the system object model are described in detail in OS/2 Version 2.0 -
Volume 3: Presentation Manager and Workplace Shell.
ΓòÉΓòÉΓòÉ 17.1. Objects in the Workplace Shell ΓòÉΓòÉΓòÉ
An object in the Workplace Shell conforms closely to the definition of an
application object given in The Presentation Manager Application Model, in that
it consists of a set of data and a number of methods that operate upon that
data. Each Workplace Shell object is an instance of a particular object class.
In accordance with normal object-oriented theory, the class defines the basic
characteristics of the object and the way in which the object responds to
events.
ΓòÉΓòÉΓòÉ 17.1.1. Inheritance Hierarchy ΓòÉΓòÉΓòÉ
Each object class is descended from another class, known as its parent class.
Since the system object model supports the object-oriented concept of
inheritance, a class may inherit data and methods from its parent class, which
in turn may inherit data and methods from its parent, and so on. A class which
inherits properties from other classes is therefore known as a descendant of
those classes, and the classes from which it inherits are known as ancestors.
The implementation of inheritance in the Workplace Shell means that when
creating a new object class, a programmer simply subclasses the parent class,
and need only define those characteristics that are not defined by, or are
different from those of the parent class. This greatly simplifies the process
of creating a new object class.
Under the system object model, every object class is a descendant of the base
class SOMObject. This class defines the basic characteristics and behaviors
common to all objects in the system. Other object classes are subclasses of
this class. The system object model provides two additional classes, SOMClass
and SOMClassManager, to form the basis of an inheritance hierarchy. The
Workplace Shell extends this hierarchy by creating a number of classes of its
own, based upon the SOMObject class. These Workplace Shell object classes
define the characteristics of the object types that are defined and implemented
by the Workplace Shell itself.
The inheritance hierarchy implemented by the Workplace Shell is illustrated in
Figure "Workplace Shell Inheritance Hierarchy".
As well as being descended from the system object model base inheritance
hierarchy, all Workplace Shell object classes are descended from one of three
base storage classes defined by the Workplace Shell. These classes are so named
because they directly influence the storage of control information and instance
data for the class. The three predefined base storage classes are:
WPAbstract, which is the base class for abstract objects such as programs,
devices, etc., and for which control information is stored in the system
initialization file OS2.INI
WPFileSystem, which is the base class for objects that are stored as files in
the file system, and for which control information is stored in the file
system as extended attributes
WPTransient, which is the base class for objects that only exist during
execution of a particular program; that is, the object is created and used
for a particular purpose during processing, and then immediately deleted from
the system.
An application developer may extend the Workplace Shell inheritance hierarchy
by introducing new object classes based upon those already implemented by the
Workplace Shell itself. Indeed, the developer may even introduce new base
classes, although this is definitely a non-trivial exercise and should be
approached with caution.
ΓòÉΓòÉΓòÉ 17.1.2. Metaclasses ΓòÉΓòÉΓòÉ
Just as each Workplace Shell object is an instance of a class, the class itself
is an instance of another class known as its metaclass. Just as an object has
instance data and methods that pertain only to a specific instance of the
class, so the metaclass has class data and methods that pertain to the entire
class. Such methods are known as class methods, whereas methods that operate
only for a particular instance of the class are known as instance methods.
Class methods and data are available to the programmer when creating new object
classes. A programmer may introduce new class data and methods for an object
class, as well as instance data and methods. Similarly, a new object class may
override existing class methods to modify the processing performed by those
methods.
ΓòÉΓòÉΓòÉ 17.1.3. Class Implementation ΓòÉΓòÉΓòÉ
Each object class in the Workplace Shell resides in a dynamic link library. A
programmer creates an object class by defining its characteristics in a class
definition file. This file is then used as input to the SOM Precompiler, in
order to produce "C" source code and header files for the object class. This
source code includes basic definitions for the object class's data and methods;
the code is then edited by the programmer to include the logic for each of the
required methods. Once the code is complete, it is compiled and link edited in
the normal way to produce a dynamic link library; see Compiling and Link
Editing an Application for further information on compiling and link editing.
When an object class has been created, it must be registered with the Workplace
Shell, which includes the DLL in a list of libraries loaded at initialization
time. The entry points for the DLL are known to the Workplace Shell, and may
be called in order to invoke the object's methods.
The process of creating an object class from a class definition file is
described in Defining an Object.
ΓòÉΓòÉΓòÉ 17.2. Object Structure ΓòÉΓòÉΓòÉ
In the simplest case, an object in the Workplace Shell consists of methods and
instance data. The Workplace Shell communicates events to the object using
messages, which in turn invoke the object's methods to perform the processing
indicated by the event. This is in accordance with the definition of an
application object given in The Presentation Manager Application Model. Note
that since the Workplace Shell provides a more extensive inheritance hierarchy
than the base Presentation Manager application model, the method invoked by a
particular message may belong explicitly to the object in question, or may
belong to its parent (and be inherited from that parent).
The structure of an object in the Workplace Shell is therefore very similar to
that of a window in the conventional Presentation Manager application model;
the Workplace Shell object simply takes the object-oriented concepts to a
higher degree of implementation. The constructs implemented by Presentation
Manager under previous versions of OS/2 can, therefore, often be implemented
more elegantly with the Workplace Shell.
For the remainder of this chapter, an example will be used to explain the
structure and behavior of an object class. The example used is that of a
specific type of Workplace Shell folder, which has a password defined so that
it can be locked to prevent access by an unauthorized user. This object class
is implemented by subclassing the WPFolder class to create a new object class
named PWFolder, adding new methods and overriding existing methods where
appropriate. Sample code is provided in the text for the various methods used
to add the password protection to the folder.
ΓòÉΓòÉΓòÉ 17.2.1. Methods ΓòÉΓòÉΓòÉ
In a Presentation Manager application, a window procedure receives messages
from Presentation Manager, determines the type of message and invokes a series
of program statements (which effectively constitute a method) as a result of
that message. A Workplace Shell object operates in a similar fashion, except
that the Workplace Shell itself determines the type of message and invokes the
corresponding method, without any explicit action on the part of the object.
Therefore, whereas the Presentation Manager window procedure comprises a case
statement with each case being a method, the Workplace Shell object eliminates
the need for the case statement and allows the Workplace Shell to invoke the
methods directly. The syntax for invoking a method from within an object or
application is hence very similar to that for invoking a subroutine; the only
real difference is that a method may be accessed from outside the object itself
(that is, from another object or from an application), while a subroutine is
normally private to the object.
Many methods are defined by the WPObject class, from which application-defined
classes are typically descended. When creating a new object class, a
programmer may override the methods already defined by the class's ancestors,
and/or include new methods specific to the class being created. The methods
defined by the WPObject class are described in the IBM OS/2 Version 2.0
Presentation Manager Reference. Programmers who wish to create new object
classes descended from this case should read the descriptions of these methods
to determine the extent of the modifications necessary.
Invoking a Method
As mentioned in The Presentation Manager Application Model, methods within an
object are invoked as a result of messages that communicate events to the
object. These events may be initiated by the user (for example, as a result of
clicking the mouse on an object's context menu), by the object itself or
another object, or by the system to indicate a system event such as opening or
closing a view of the object.
The syntax for invoking a method is similar to that for invoking a subroutine,
with the exception that since a method is invoked by the Workplace Shell, the
first parameter passed in the call is therefore not a parameter used by the
method, but a pointer to an object that is capable of invoking the method; this
is typically a pointer to the object itself. This is illustrated in Figure
"Invoking a Method", where a sample invocation of a method named _wpSetTitle is
shown.
The _wpSetTitle method is defined by the WPObject class, and is inherited by
all classes descended from the class. The method accepts a title string and
sets the title of the object; that is, the text that appears below the object's
icon on the Workplace Shell desktop.
The pointer somSelf is defined by the SOM Precompiler when it creates the "C"
source code from the class definition file. In the example above, somSelf is
defined as a pointer to an object of class PWFolder and within a method, allows
the method to access the instance data of the object to which it belongs. The
need to pass this pointer arises from the limitations of the "C" language
syntax under which the current implementation of the Workplace Shell operates;
other languages such as C++ may be able to invoke methods in a more elegant
manner.
Method Processing and Instance Data
Within a method, the somSelf pointer, passed as the first parameter in the call
to the method, acts as a pointer to the method's own object, and allows the
method to access its instance data. The SOM Precompiler automatically provides
a base pointer named somThis that references the instance data, and includes a
call to a method that initializes this pointer from the object pointer:
PWFolderData *somThis = PWFolderGetData(somSelf);
When this statement has successfully executed upon entry to the method, the
method has access to the object's instance data. For example, the
password-protected folder has a password string, which may be accessed by a
method using the following name:
somThis->szPassword
To make things simpler, the SOM Precompiler generates a macro for each instance
variable, in a manner similar to that used for function names:
#define _szPassword (somThis->szPassword)
#define _szCurrentPassword (somThis->szCurrentPassword)
#define _szUserid (somThis->szUserid)
This macro is included in a header file for the object class, and avoids the
need for the programmer to type the complete name throughout the source code.
Once the instance data is available to the method, any application logic may be
performed, including the use of OS/2 and Presentation Manager resources. See
Accessing Presentation Manager Resources From a Workplace Shell Object for
additional considerations on the use of Presentation Manag er resources from
within a Workplace Shell object.
Returning from a Method
In order to return control to its calling routine, a method simply uses the
return statement. Any valid form of return code may be passed to the calling
routine as a parameter to this statement, provided that the data type of the
return code is consistent with the declaration of the method. The data type of
the return code is typically set by the SOM Precompiler, and a default return
statement provided, based on information supplied by the programmer when the
method is defined in the Methods section of the class definition file (see
Class Definition File).
Overriding Existing Methods
A new object class may override one or more of the existing methods defined by
its parent class, either to completely replace the processing performed by
these methods, or to add its own processing to that already performed by the
parent. An example of an object class overriding the _wpSetTitle method is
shown in Figure "Overriding an Existing Method".
The example given in Figure "Overriding an Existing Method" shows the use of
class-specific processing to modify the title of a password-protected folder.
The inclusion of the string "<LOCKED>" at the end of the user-specified title
provides a visual indication to the user that the folder is locked. Additional
visual indication is provided by modifying the icon when the folder is in the
locked state; the code that carries out this operation is included in the
_LockFolder method shown in Figure "Adding a New Method".
The strings _szCurrentPassword and _szPassword are instance data items defined
by the new object class. These data items are actually accessed using the
somThis pointer; however, the SOM Precompiler defines a macro for each instance
data item, as described in Method Processing and Instance Data above.
Note that the default processing supplied by the parent class is invoked at the
end of the class-specific processing. For all but the most exceptional
circumstances, default processing should be allowed to occur in order to ensure
that the normal behavior of the object class is preserved.
Adding New Methods
In addition to overriding existing methods defined by the parent class, an
object class may also add new methods to carry out processing for events not
handled by the parent class. For example, the password-protected folder
example must have a mechanism to lock the folder. This is implemented as a new
method named _LockFolder, as shown in Figure "Adding a New Method".
This method simply copies a default string to the variable _szCurrentPassword
that contains the last supplied password entry from the user, so that when a
comparison is made between this variable and the folder's password, the two do
not match. This effectively locks the folder and prevents any view of it being
opened. To provide a visual indication to the end user that the folder is
locked, a "locked" icon is loaded using the Presentation Manager
WinLoadPointer() function, and the _wpSetIcon method is invoked to set this as
the folder's new icon on the desktop.
Note that the definition for adding a new method is very similar to that for
overriding an existing method. The primary difference is that, since the new
method is specific to the object class and is not defined by the parent class,
there is no need to invoke the parent class's method to perform default
processing for the method.
Attaching a Method to the Context Menu
A method may be invoked as a result of the user selecting an item from the
object's context menu. In order to allow this, an item must be added to the
context menu, and an appropriate action must be taken by the object when that
item is selected by the user.
An item can be added to the context menu for an object class by overriding the
_wpModifyPopupMenu method defined by the WPObject class, and including a call
to the _wpInsertPopupMenuItems method to insert the item. This technique is
shown in Figure "Adding an Item to a Context Menu".
The example shown in Figure "Adding an Item to a Context Menu" adds a Lock item
to the context menu for the password-protected folder object. This allows the
folder to be locked by the user at any time, irrespective of whether a view of
the folder is currently open.
The _wpInsertPopupMenuItems method adds a menu item or a submenu to the
existing context menu for the object. The item identifier for the menu item or
submenu (MI_LOCK in the above example) is an integer constant that is typically
defined in the header file. Note that the value of this constant should be
specified as an offset from the system-defined constant WPMENUID_USER, rather
than an absolute integer value. Following this convention will avoid any
clashes with item identifiers defined by the Workplace Shell for default
context menu items.
Since the password-protected folder is a descendant of the WPFolder class
defined by the Workplace Shell, the default context menu items for the WPFolder
class should also appear. The default processing for the parent class is
therefore invoked as part of the _wpModifyPopupMenu processing for the new
object class.
Once the required item is added to the context menu, the object must be able to
detect when the item is selected in order to invoke the appropriate method. By
default, the _wpMenuItemSelected method is invoked by the system whenever the
user selects an item from the context menu. This method, which is defined by
the WPObject class, may be overridden by a new object class in order to check
for the presence of a new item and invoke the appropriate method. The item
identifier of the selected item is passed as a parameter to the
_wpMenuItemSelected method, and is normally interrogated using a case
statement, as shown in Figure "Invoking a Method via a Context Menu Item".
The _wpMenuItemSelected method consists of a case statement that determines the
item selected from the context menu. In the above example, an explicit case is
included only for the MI_LOCK item defined by this class. All other menu items
are defined by the parent class, and their selection is therefore handled by
allowing the parent class's default processing to occur.
Class Methods
Most object methods are instance methods; that is, they act upon one particular
instance of an object class, rather than upon all instances of the class.
However, there are times when it is useful to have methods that operate on the
object class itself. These methods may operate on class data rather than
instance data, thereby affecting the entire class rather than a single instance
of the class. Such methods are known as class methods. The class method
_wpclsQueryTitle is defined by the WPObject class, and is overridden in the
password-protected folder example. An example of the overridden
_wpclsQueryTitle method is given in Figure "Class Method Example".
The purpose of this class method is to provide the password-protected folder
with a default title. This is the title that will appear with the folder's
template icon in the Templates folder, and which is given to any instances of
the class that are instantiated without a title. Since the default title
applies to all instances of the class, it is implemented in a class method
rather than an instance method.
The prefix "M_" denotes the metaclass in the SOM-generated "C" source. As
already mentioned, the first parameter passed to a method is a pointer to a
type of object that can invoke that method; this is true for both instance
methods and class methods; for a class method the first parameter contains a
pointer to an instance of the metaclass.
Pointer to instance of metaclass
which is a class object ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
pwfoldercls_wpclsQueryTitle(M_PWFolder *somSelf)
Type is Metaclass ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
Since a class is also an object, it follows that the class itself has its own
"instance data"; hence the next line of code appears as follows:
/* M_PWFolderData *somThis = M_PWFolderGetData(somSelf); */
This statement would access the SOM object's class data. However, since no
class data is specified in the .CSC file, there is nothing to access and so the
SOM Precompiler has commented the line out to reflect this.
For simple examples, it is easier to use global variables in the DLL for class
data. This technique has been used in Figure "Class Method Example"; the
default title string is stored at the beginning of the program into the global
variable szDefaultTitle. However, using this technique means that class data
can be accessed by instance methods, which is never desirable, and may have
adverse consequences, although these may generally be avoided by sound
programming techniques.
Invoking Another Object's Methods
An object may invoke a method in another object class. This technique is
useful in a client-server situation, where one object creates another object of
a different class and then wishes to have that object perform certain actions.
The system object model provides programming functions that can be used to
determine the necessary information and invoke the method. An example is given
in Figure "Invoking a Method in Another Object Class".
The example given in Figure "Invoking a Method in Another Object Class" shows
part of a "database client" object that sends a database query to a "database
server" object. The client first allocates a shared memory object into which
it loads the query. The client then uses the _somFindClass method and the
SOM_IdFromString macro to determine the object pointer for the object, and the
method identifier for the required method. The _somDispatchL method is then
used to invoke the method.
It is also possible to invoke a class method using the object pointer to that
class, obtained using the _somFindClass method shown in Figure "Invoking a
Method in Another Object Class". This requires the header file for the class
to be included in the source code for the class that will invoke the method,
using a #include statement. In the module definition file for the invoking
class, the following IMPORT statements must be provided:
IMPORTS
record.RecordCClassData
record.RecordClassData
record.RecordNewClass
record.M_RecordCClassData
record.M_RecordClassData
record.M_RecordNewClass
When these steps have been carried out, a method in the other class may be
invoked directly, as follows:
_clsQueryDatabase(RecordClass, /* Invoke class method */
pQuery, /* Method specific */
Folder); /* parameters */
While this technique is less clean than the previous approach since it requires
the inclusion of the header file and import statements, it provides better
performance.
ΓòÉΓòÉΓòÉ 17.2.2. Subroutines ΓòÉΓòÉΓòÉ
Subroutines may be accessed from within a Workplace Shell object, in much the
same manner as from any other program. Normal programming language calling
conventions are used. Subroutines used by the object may reside within the
same DLL as the object itself, or may be in a different DLL.
A number of guidelines for the use of subroutines within Presentation Manager
applications are given in The Presentation Manager Application Model. Note
that similar guidelines apply to the use of subroutines within Workplace Shell
objects, since these objects should also adhere to object-oriented programming
principles.
ΓòÉΓòÉΓòÉ 17.3. Defining an Object ΓòÉΓòÉΓòÉ
The definition of an object is achieved using a language known as the Object
Interface Definition Language. The statements that define an object class are
entered into the class definition file for the class, which is an ASCII file
and may thus be created using any normal text editor. The class definition
file is used as input to the SOM Precompiler, which will generate a number of
files from the class definition file.
ΓòÉΓòÉΓòÉ 17.3.1. Files ΓòÉΓòÉΓòÉ
The SOM Precompiler generates a number of files that are used to define an
object class to the Workplace Shell and to other classes that may wish to
inherit the characteristics and behaviors of the class. These files are:
.H A public header file for programs that use the class.
.PH A private header file, which provides usage bindings to any private
methods implemented by the class.
.IH An implementation header file, which provides macros, etc., to support
the implementation of the class.
.C A template C file, to which code may be added to implement the class.
.SC A language-neutral class definition.
.PSC A private language-neutral core file, which contains private parts of
the interface for the class.
.DEF An OS/2 DLL module definition file containing the relevant exports need
to implement the class.
These files may then be used as input to a C compiler, generating object code
that is in turn linked to create a dynamic link library, which implements the
object class.
ΓòÉΓòÉΓòÉ 17.3.2. Class Definition File ΓòÉΓòÉΓòÉ
The class definition file contains all the information necessary to implement a
new class. The file is divided into the following sections:
1. Include section
2. Class section
3. Parent Class section
4. Release Order section
5. Metaclass section
6. Passthru section
7. Data section
8. Methods section.
Each of these sections is described in more detail below, using examples from
the password-protected folder class described earlier in this chapter.
Include Section
Since all system object model classes have a parent, it is necessary to know
the name of the parent class and the location of its interface definition. The
include section specifies the location of the interface definition file for the
parent. In the folder example, only a single line is included:
#
# Include the class definition file for the parent class
#
include <wpfolder.sc>
Since the folder example is simply a specialized form of the WPFolder class, it
uses this class as its parent and inherits much of its behavior from the
WPFolder class. The include section therefore specifies the interface
definition for the WPFolder class. A full list of Workplace Shell classes and
their definition files can be found in the IBM OS/2 Version 2.0 Presentation
Manager Reference.
Note that the comments that start with a "#" are discarded by the SOM
Precompiler; hence the comment in the example above will not be seen in the SOM
Precompiler-generated files.
Class Section
This section provides basic information about the new class, specifying its
name and various attributes. The password folder example has the following
class section entry:
#
# Define the new class
#
class: PWFolder,
file stem = pwfolder,
external prefix = pwFolder_,
class prefix = pwFoldercls_,
major version = 1,
minor version = 1,
local;
-- PWFolder is a Password-protected folder.
-- Its derived as follows:
-- SOMOject
-- - WPObject
-- - WPFileSystem
-- - WPFolder
-- - PWFolder
All class definition files must contain a class section. Certain statements
within the class section are mandatory, while others are optional.
The first item in the class section is a name:
class: PWFolder,
All classes must have a name.
The file stem specifies the file name to be used by the SOM Precompiler for the
generated files. For example, if the file stem statement reads:
file stem = myfile
then the .DEF file generated by the SOM Precompiler would be called myfile.def.
The external prefix specifies a prefix to be used by the SOM Precompiler on all
function names. Hence if an external prefix of "pwFolder_" is specified and a
method is named "SetInfo", the function name generated by the SOM Precompiler
would be "pwFolder_SetInfo".
The SOM Precompiler normally generates a macro for all methods defined by the
class, such that the method is referenced in the source code by its defined
name, preceded by an underscore character. For example, the method
pwFolder_SetInfo described above would be referenced simply as _SetInfo. This
helps make the source code more readable and avoids the need for the programmer
to type the full name when editing the code.
The class prefix is similar to the external prefix, except that it is used
specifically for functions that are class methods. The differences between
class methods and instance methods are discussed in Methods (Class Methods).
The major version and minor version are used to ensure that the bindings are at
the right level for the class implementation code.
The local option is used to specify that binding files should be linked
locally. In " C" programming terms, this means that the following source code
is generated:
#include "wpfolder.h"
If the global option is used, the resulting source code would be as follows:
#include <wpfolder.h>
The last part of the class section is for comments. Using "--" as the comment
style causes a comment block to be passed through to the interface definition
(.SC) file.
Parent Class Section
The parent class section specifies the parent of the new class. All classes
must have this section. The parent class section for the password-protected
folder example appears as follows:
#
# Parent class
#
parent: WPFolder;
Release Order Section
This section allows the programmer to specify the sequence in which the methods
and public data will be released. Since this sequence is maintained by the SOM
Precompiler, other programs using this class will not need to be recompiled
every time something new is added to the class.
The password-protected folder example has only one public method in addition to
those already defined by its ancestor classes. This method is seen in the
release section as follows:
#
# Specify the release order of new methods
#
release order: LockFolder;
Since other public methods are defined by the parent class or by its ancestors,
the programmer creating an object class need not define these methods in the
class definition file. Hence the programmer need not be aware of the existing
methods in the parent class, unless they require modification for use by the
new class. This is in accordance with the object-oriented concept of
encapsulation.
Metaclass Section
For the password-protected folder example (and in most other cases) an explicit
metaclass is not required. The concept of metaclasses is discussed in
Metaclasses. Readers desiring more knowledge of programming using metaclasses
should refer to the IBM SOM Programming Reference.
Passthru Section
This section allows the programmer to define blocks of C source code that are
passed through to any of the files generated by the SOM Precompiler. Each
passthru block is distinguished by an identifier, the syntax of which is as
follows:
passthru: <language>.<suffix>
The password-protected folder example has two passthru sections. The first
passthru is "C.h", which passes the code block to the C binding file
pwfolder.h. This block of code defines a DebugBox macro, which can be used
anywhere in the code for the new class.
#
# Passthru a debug message box to the .ih file
# (for inclusion in the .c file)
#
passthru: C.h, after;
#define DebugBox(Title, Text) WinMessageBox(HWND_DESKTOP,
HWND_DESKTOP,
(PSZ)Text,
(PSZ)Title,
0,
MB_OK |
MB_INFORMATION)
endpassthru;
The second passthru block is "C.ph"; this passes the code block to the C
binding file pwfolder.ph. This block is used to define a data structure that
is accessed by the private methods _GetInfo and _SetInfo, and is used to pass
information to and from the dialog procedure that prompts the user for the
folder password.
#
# Passthru private definitions to the .ph file
# (for inclusion in the .c file)
#
passthru: C.ph;
typedef struct _PWF_INFO {
CHAR szPassword[20&rbk.;
CHAR szCurrentPassword[20];
CHAR szUserid[20];
} PWF_INFO;
typedef PWF_INFO *PPWF_INFO;
endpassthru;
Data Section
This section lists the instance variables used by the class. In the
password-protected folder example, three variables are defined as follows:
#
# Define instance data for the class
#
data:
CHAR szPassword[20];
-- This is the password that locks the folder
CHAR szCurrentPassword[20];
-- This is the password the user has entered to be
-- checked against the lock password
CHAR szUserid[20];
-- The userid data is here for future expansion
Note that the szUserid instance variable is not used in the version discussed
in this document, since the current example assumes only a single workstation
user. However, it is feasible for user identification to be obtained at
startup, and held by the system for authentication against a password to
determine whether access is permitted.
Methods Section
The last section in the class definition file contains a list of all the
methods to be defined by the object class. ANSI C function-prototype syntax is
used to define each method. When coding these definitions, it is recommended
that the methods be divided into the following parts:
1. Methods that are new for this class
2. Methods that are overridden from ancestor classes.
The following section shows two methods taken from the folder example's class
definition file.
This first method will be used in the password dialog to take a copy of the
object's instance data and place it in a structure that the dialog code may
access.
#
# Define new methods
#
methods:
BOOL QueryInfo(PPWF_INFO pPWFolderInfo), private;
--
-- METHOD: QueryInfo PRIVATE
--
-- PURPOSE: Copy the PWFolder instance data into
-- the PWF_INFO structure that pPWFolderInfo
-- points to.
--
The second example shows an overridden method. This method originates in the
WPObject class, which is a base class. It is used to set up the password string
when the folder object is created.
#
# Specify methods being overridden
#
override wpSetup;
--
-- OVERRIDE: wpSetup PUBLIC
--
-- PURPOSE: Here we can set the folder password
-- to that passed in from the object
-- create command.
--
More detailed information on class definition files and the OIDL is given in
the IBM SOM Programming Reference.
ΓòÉΓòÉΓòÉ 17.3.3. C Implementation of an Object Class ΓòÉΓòÉΓòÉ
When the SOM Precompiler has been run successfully against a class definition
file, it will produce all the source files necessary to build a Workplace Shell
DLL. The most important of these files for the C programmer is the C source
code file, which has an extension of .C. This file contains definitions and
"function stubs" for all the methods defined by the class. This file must be
edited by the programmer to add the actual application logic to each method.
Figure "A SOM Precompiler-generated Function Stub" shows the SOM
Precompiler-generated function stub for the QueryInfo method from the folder
example.
ΓòÉΓòÉΓòÉ 17.4. Object Behavior ΓòÉΓòÉΓòÉ
The behavior of an object in the Workplace Shell is very similar to that of a
window under Presentation Manager. An object must have its class registered
with the system, an instance of that class must be created ("instantiated") in
the system, and that instance (and any other instance) then receives messages
and uses its methods to process these messages. When processing is completed,
the instance may be destroyed.
One significant difference between a Workplace Shell object class and a window
class under Presentation Manager is that Workplace Shell object classes are
normally persistent; that is, while a Presentation Manager window class is
defined only for the duration of the application's execution, a Workplace Shell
object class remains defined to the system, and is useable by any application
until such time as it is explicitly deregistered from the system.
ΓòÉΓòÉΓòÉ 17.4.1. Creating an Object ΓòÉΓòÉΓòÉ
A new object class in the Workplace Shell is typically created by taking an
existing object class and subclassing it, introducing new data and methods, and
modifying existing behaviors where required. The new object class is then
registered with the Workplace Shell, and is available from that point on.
Registration
Once an object class has been defined, compiled and placed into a dynamic link
library, it must be registered with Workplace Shell before it can be used.
This may be accomplished in either of two ways:
The simplest method is to place the DLL for the object in a directory that is
included in the LIBPATH statement in CONFIG.SYS. Once this is done, opening
the the Templates folder on the Workplace Shell desktop will automatically
cause the DLL to be loaded and a template for the object class to appear in
the Templates folder.
An object class may also be registered with the Workplace Shell using the
WinRegisterObjectClass() function. This function records the name of the
object class, and the name of the DLL that contains the code to implement the
class.
An example of the WinRegisterObjectClass() function is given in Figure
"Registering a Workplace Shell Object Class".
Figure "Registering a Workplace Shell Object Class" provides a very simple
example; a useful technique for registering object classes is to build a simple
program that reads a set of strings from an ASCII data file and uses these
strings as parameters to the WinRegisterObjectClass() function. In this way, a
generic object-registraion routine can be built and used for multiple object
classes, without the need to modify and recompile source code.
Note that once an object class has been registered with the Workplace Shell, it
is permanently available until it is explicitly deleted by deregistering it.
See Deregistering an Object Class for information on deregistering an object
class.
Class Data
Class data is owned by the object class rather than by an instance of that
class. It is therefore available to all instances of the class, and must be
initialized prior to instantiating any objects within the class.
For this reason, class data is initialized when the object classes are loaded
from their DLLs, either during Workplace Shell initialization or dynamically
during execution. Class data initialization is performed by the _wpclsInitData
class method, which is called by the system when the class is loaded. If a new
object class has class data that must be initialized, it should override the
_wpclsInitData method and perform its class-specific processing.
An example of an overridden _wpclsInitData method from the password-protected
folder example is shown in Figure "Initializing Class Data".
In the example shown in Figure "Initializing Class Data", a global variable
hModule is used to contain the module handle for the DLL, which is required
when loading Presentation Manager resources such as strings, pointers or
dialogs. Since a global variable is used rather than a class data variable,
the first statement in the overridden method, which obtains a handle to the
class data, is not required and is therefore commented out.
Any class data items obtained or initialized by an object class from within the
_wpclsInitData method should also be freed by the object class, by overriding
the _wpclsUnInitData method. This method is invoked by the system when an
object class is deregistered (see Deregistering an Object Class), or when the
Workplace Shell process is terminated. An example of the _wpclsUnInitData
method is shown in Figure "Freeing Class Data Items".
The example shown in Figure "Freeing Class Data Items" assumes that the module
handle for the DLL has already been obtained and stored in the global variable
hModule, as shown in Figure "Initializing Class Data".
Instantiation
Once an object class has been registered with the Workplace Shell, an instance
of that class may be created; this is normally known as instantiation. This
may be done in one of two ways. The simplest method is to open the Templates
folder and drag the template for the object class to the required location.
Alternatively, an object may be created from within an application, using the
WinCreateObject() function, an example of which is given in Figure "Creating an
Object".
Note that the pszParams parameter shown in Figure "Creating an Object" is used
to contain a setup string, which can be used to pass one or more of a number of
parameters to the object class. In the example, it is used only to set the
icon for the object, but may also be used to specify other parameters for that
instance of the class. The keywords and values supported by the WPObject class
are documented in the IBM OS/2 Version 2.0 Presentation Manager Reference;
other object classes may add their own keywords and values.
The final parameter contains one or more flags which determine the behavior of
the WinCreateObject() call if the object being created clashes with an object
that already exists with the specified name and in the specified location.
Valid actions are for the call to fail, to update the existing object or to
replace the existing object. These flags are documented in the IBM OS/2
Version 2.0 Presentation Manager Reference.
The setup string is passed as a parameter to the _wpSetup method, which is
invoked when the object is instantiated. This method is defined by the
WPObject class, and may be overridden by a new object class in order to check
for its own keywords and take appropriate setup action.
The _wpSetup method accepts the setup string as a parameter, and may then parse
the setup string, extract any class-specific data and perform appropriate
processing on that data. However, since many of the keywords that may be
specified in the setup string are defined by the WPObject class and are handled
by the default _wpSetup method, the default processing must be carried out. In
this particular case, the default processing may be carried out before or after
the class-specific processing.
An example of an overridden _wpSetup method is shown in Figure "Object Setup";
this example shows the use of an additional parameter in the setup string
(PASSWORD=) to set an initial password for a password-protected folder upon
folder creation.
The setup string is parsed from within the object by calling the
_wpScanSetupString method. Both of these methods, along with the keywords
supported by the WPObject class, are described in the IBM OS/2 Version 2.0
Presentation Manager Reference.
After performing the class-specific processing in the _wpSetup method, an
object class should invoke its parent class's _wpSetup method to perform the
default processing for any other keywords in the setup string that are defined
by the parent class.
Before the _wpSetup method is invoked, the system invokes the object's
_wpInitData method, which allows an object to allocate resources and initialize
its instance data. See Instance Data below for further details.
Note that unlike a Presentation Manager window, which exists only for the
duration of an application's execution, an object remains in existence
permanently unless explicitly deleted from the system.
Instance Data
When an object is created or awakened from a dormant state, the _wpInitData
method is invoked by the system. This method allows an object to initialize
its instance data to a known state. Operating system resources should be
allocated at this stage, but Presentation Manager resources should not, since a
view of the object is not yet being opened. The allocation of Presentation
Manager resources is typically done during processing of the _wpOpen method
(see Using an Object (Opening an Object)).
If an object has its own instance data, which must be initialized to a known
state before processing may be carried out, the object should override the
_wpInitData method in its class definition file, and include the initialization
code. However, for any object class other than a base storage class, the
default initialization processing must be carried out in addition to the
class-specific processing. This allows the correct initialization of any
instance data items defined by the parent class, and ensures that the new
object class behaves in a manner consistent with its ancestors.
Figure "Initializing Instance Data" shows an overridden _wpInitData method,
which initializes the password information for a password-protected folder.
Note that during processing of the _wpInitData method, the instance data of the
object is not necessarily in a known state. The programmer must therefore take
great care when carrying out any processing during the execution of this
method, in order to avoid using data that may not yet have been initialized
correctly. Failure to follow this guideline may cause unpredictable results
for the object.
ΓòÉΓòÉΓòÉ 17.4.2. Using an Object ΓòÉΓòÉΓòÉ
A user typically accesses an object by opening a view of that object. For
example, to access the contents of a folder object, the user opens the default
view (usually an icon view) of the folder, which then displays its contents.
This is certainly true for container objects such as folders, and for the
password-protected folder class used as an example in this chapter, although
other "device" objects such as printers or the shredder may be used without a
view.
When no view of an object is open, and the folder within which the object
resides is not open, the object is said to be dormant; typically, no system
resources are allocated to the object and its instance data is in an unknown
state. Opening and closing views of an object therefore involve not only the
opening and closing of windows, but also allocating and freeing resources, and
saving and restoring the instance data of the object. Similarly, opening a
folder requires saving and restoring the instance data of the objects in that
folder.
Opening an Object
As mentioned above, a user typically interacts with an object using a view of
that object. An object may support various types of view; for example, the
WPFolder object class supports icon, tree, details and settings views. By
default, an object class supports the view types defined by its ancestors, and
a programmer may also define new view types for the object class.
When a view of an object is opened, a method named _wpOpen is invoked by the
Workplace Shell. This method is defined and implemented by the base storage
class WPObject, and may be overridden by a new object class to perform its own
class-specific processing. The supported views for each object class are
implemented as part of the _wpOpen method, using Presentation Manager windows.
When a view is opened by the user from a context menu, the _wpMenuItemSelected
method is invoked (see Methods (Attaching a Method to the Context Menu) for
more detailed discussion of this method). The _wpMenuItemSelected method
typically invokes the _wpOpen method, and passes the identifier of the
requested view as the third parameter. The _wpOpen method may then interrogate
this parameter to decide which view to open.
When the user opens a view by double-clicking the mouse on an object's icon,
the system invokes the _wpOpen method and passes an OPEN_DEFAULT value. The
default processing for the _wpOpen method invokes the _wpQueryDefaultView
method to determine the default view for the object, and immediately invokes
the _wpOpen method a second time with the identifier for that view.
An example of an overridden _wpOpen method is given in Figure "Opening an
Object". This example shows a password-protection facility being added to a
folder to prevent access by unauthorized users. Upon invocation of the _wpOpen
method, the password-protected folder object class displays a dialog box to
accept a password from the user. It then compares that password with the
correct password for that folder before actually opening the folder. Visual
cues such as the folder's icon and the word "Locked" on the folder's title are
modified or removed during the _wpOpen processing.
Since the view being opened in this case is the icon view defined by the
WPFolder class, the actual opening of the view and presentation of the folder's
contents is handled using the default processing supplied by the parent class,
which is called after the class-specific processing has completed.
If an object class wishes to create a new view, it must add the name of the
view to the Open submenu in the object's context menu, and include a case for
that view in the _wpMenuItemSelected method. This method then invokes _wpOpen
with a specific value in the ulView parameter, indicating the view to be
opened. The class-specific processing for _wpOpen must test for this value,
open a window and display the correct information using Presentation Manager
functions.
The example in Figure "Opening an Object" does not include the code to set the
folder's icon to the "unlocked" state. This code is identical to the code used
in Figure "Adding a New Method" to set the icon to the "locked" state; the
resource identifier of the "unlocked" icon is simply substituted in the _wpOpen
method for the identifier of the "locked" icon.
Note that in many cases, it is important for an object class to allow the
default processing for _wpOpen to occur before it attempts to carry out its own
processing. This allows instance data and control information to be
established and initialized before the object attempts any processing using
these items. In Figure "Opening an Object" however, the additional
class-specific processing determines whether the object should open at all; if
processing is allowed to proceed, no alteration to the default processing takes
place. The default processing may therefore be carried out after the
additional class-specific processing introduced by the password-protected
folder class.
The default processing for the _wpOpen method supports a number of views,
depending upon the parent class of the object; for example, the processing for
the WPFolder class supports ICON, TREE and DETAILS views. For new object
classes which support additional views, the _wpOpen method must be overridden
and the additional view types opened explicitly as windows using appropriate
Presentation Manager functions. Since a view of an object is essentially a
window, new views can be implemented as normal Presentation Manager windows and
the correct information displayed using text or graphical programming
functions, according to the requirements of the object class.
Note that upon opening a view using a Presentation Manager window, an object
should add itself to the "Use List" maintained by the Workplace Shell. If the
view is the first view of the object to be opened, this causes the Workplace
Shell to modify the object's icon to indicate the "in use" state. The object
should also register the view with the Workplace Shell, which will then
subclass the view's frame window, automatically attach the object's context
menu to the window's system menu icon, and add the view to the Workplace
Shell's Window List. These steps are done using the _wpAddToObjUseList and
_wpRegisterView methods, as shown in Figure "Opening a Custom View of an
Object".
The Workplace Shell makes use of a USEITEM and a VIEWITEM structure in the
_wpAddToObjUseList method. It assumes that these structures are contiguous in
memory; hence they should be allocated as part of a larger data structure such
as the OBJECTVIEW structure shown in Figure "Opening a Custom View of an
Object". A pointer to this structure is stored in the window words of the view
window, so that information such as the object's pointer can be accessed from
the view's window procedure.
Note that upon closing a view, the view's window procedure should invoke the
_wpDeleteFromObjUseList method to remove the view from the Use List. If the
view is the only open view of the object, the object's icon is modified to
remove the "in use" emphasis.
Automatic Opening Upon Instantiation
In many cases, it is desirable to automatically open a view of an object when
the object is created. This may be achieved by using the OPEN= keyword in the
setup string passed to the WinCreateObject() function. An example of this
technique is shown in Figure "Automatically Instantiating an Object".
The opening of the view specified in the OPEN= keyword is handled by the
default processing for the _wpSetup method, as defined by the WPObject class.
The default processing supports the icon, tree and details views, specified
using the ICON, TREE and DETAILS values for the OPEN= keyword respectively.
For new object classes that support additional views, the _wpSetup method must
be overridden and the additional view types opened explicitly as windows using
appropriate Presentation Manager functions.
Closing an Object
When all open views of an object are to be closed, the _wpClose method is
invoked. This method is normally invoked when the user selects the Close
option from a view's context menu.
The _wpClose method may be overridden to perform class-specific processing for
closing views, or to free system resources allocated during processing of the
_wpOpen method. For example, Figure "Closing an Object" shows the _wpClose
method being overridden to automatically lock a password-protected folder
whenever it is closed by the user.
When a view of an object is closed, the system sends a WM_DESTROY message to
the view's frame window. This allows the object to release any allocated
resources and save its instance data, so that the object may be reopened in its
current state at some future time.
Note that since the _wpClose method is defined by the parent class and is
overridden, the default processing performed by the parent is called after the
class-specific processing has completed.
Saving and Restoring the Object State
As already mentioned, an object is persistent; that is, it remains in existence
even when all views of the object are closed. In order to maintain its
instance data so that it may subsequently be opened in the same state in which
it was closed, the object must save this data when its views are closed and
restore it when a view is opened. The Workplace Shell provides methods that
handle the saving and restoration of instance data on behalf of object classes;
these methods are automatically invoked by the system at the appropriate times,
and are described below.
When an object is made dormant, the system invokes the object's _wpSaveState
method, which allows the object to save its instance data. A number of
predefined methods are available to the object to save its data, such as
_wpSaveString. These methods may be called by the object during the processing
of its _wpSaveState method, in order to save instance data. An example of the
_wpSaveState method for the password-protected folder example is given in
Figure "Saving an Object's State".
An object's instance data items are saved in different locations, depending
upon the class of the object. Object classes that are descendants of the
WPAbstract class store their instance data in the OS/2 initialization file
OS2.INI. Object classes that are descendants of the WPFileSystem class store
their instance data in extended attributes. Since the password-protected
folder class is descended from the WPFolder class defined by the Workplace
Shell, which in turn is a descendant of the WPFileSystem class, the instance
data of this object class is saved as extended attributes in the OS/2 file
system.
The class-defined key passed to the _wpSaveString method is used to save the
data item in a particular location, which can then be accessed, using the same
key, to restore the item. In addition to strings, numeric data may be saved
using the _wpSaveLong method, and other binary data such as application-defined
data structures may be saved using the _wpSaveData method.
Note that since the _wpSaveState method is defined by the object's class's
ancestors and overridden, it must invoke the default processing supplied by the
parent class in order to correctly save any instance data defined by ancestor
classes. Failure to do so may cause unpredictable results upon awakening the
object from its dormant state.
An object must retrieve its instance data and restore its state whenever it is
made awake. At this point, the system invokes an object's _wpRestoreState
method, which allows the object to restore its state. During the processing of
this method, the object can invoke other methods such as _wpRestoreString,
which restore specific instance data items. An example of the _wpRestoreState
method is given in Figure "Restoring an Object's State".
The class-defined key passed to the _wpRestoreString method is used to locate
the required data item, and the item is restored into the specified target
string variable. Numeric data can be restored using the _wpRestoreLong method,
and other binary data such as application-defined structures can be restored
using the _wpRestoreData method.
Since the _wpRestoreState method is an overridden method, it is important that
the default processing supplied by the parent class be invoked. Failure to do
so will result in any instance data defined by ancestor classes being in an
unknown state, with unpredictable results.
ΓòÉΓòÉΓòÉ 17.4.3. Destroying an Object ΓòÉΓòÉΓòÉ
A specific instance of an object class can be destroyed by the user, simply by
dragging it over the Shredder object on the Workplace Shell desktop. If an
object or application wishes to delete an object, it may do so using the
WinDestroyObject() function, as shown in Figure "Destroying an Object".
The WinDestroyObject() function uses the object handle that is returned by the
WinCreateObject() function. The object or application that creates the object
is responsible for storing this handle during the existence of the object.
When an object is destroyed, the system invokes the object's _wpUnInitData
method, which may be used to free any resources or instance data items that
were allocated to that particular object.
ΓòÉΓòÉΓòÉ 17.4.4. Deregistering an Object Class ΓòÉΓòÉΓòÉ
An entire object class can be deleted from the system by deregistering it from
the Workplace Shell This is achieved using the WinDeregisterObjectClass()
function, which is shown in Figure "Deregistering an Object Class".
The WinDeregisterObjectClass() function accepts a string containing the object
class name. Once a successful call is made to the WinDeregisterObjectClass()
function, the object class is deleted from the system and is no longer
available to other objects or applications. However, the DLL that contains the
code for the object class is not automatically deleted from the system; if the
Templates folder is subsequently opened with this DLL still resident in a
directory in the system's LIBPATH, a template for the class will still appear
in the folder. In order to prevent this, the DLL must be explicitly deleted
from the system.
During processing of the WinDeregisterObjectClass() call, the system invokes
the object's _wpclsUnInitData method, to free any instance data or resources
that were obtained when the object class was created. See Creating an Object
(Class Data) for an example of this method.
ΓòÉΓòÉΓòÉ 17.4.5. Accessing Presentation Manager Resources From a Workplace Shell Object ΓòÉΓòÉΓòÉ
A Workplace Shell object may access and make use of Presentation Manager
resources such as icons, bitmaps, strings and dialogs. These resources may
reside in the same DLL as the object's code, or in another DLL. However, since
the resources must reside in a DLL, the code that loads the resources must use
the DosLoadModule or DosGetModuleHandle() functions to obtain module handles,
as described in Loading Resources From a DLL. This is typically done by
obtaining the module handles as part of the _wpclsInitData method, and storing
them either in global variables or in class data until needed.
ΓòÉΓòÉΓòÉ 17.5. Transient Objects ΓòÉΓòÉΓòÉ
As mentioned earlier in this chapter, a Workplace Shell object differs from a
Presentation Manager window in that it is persistent; that is, it continues to
exist after a system restart. The exception to this rule is the transient
object, which only exists during the current execution of the system, and is
destroyed when the system is IPLed.
Transient objects are useful when a programmer wishes to represent and display
information such as records from a database. As each record is retrieved, a
transient object is created for that record and displayed in a folder on the
Workplace Shell desktop. These objects may be opened and manipulated by the
end user, but will cease to exist when the system is IPLed.
Figure "Creating a Transient Object" shows an object window in a requester
process which, upon receiving a completed database query from a server process,
invokes the _wpclsNew method to create a new instance of a transient object
class, representing the record retrieved from the database.
The SOM pointer to the transient object class is obtained using the
SOMIdFromString() macro and the _somFindClass method (see Communication Between
Objects for further information). This pointer is then used to invoke the
_wpclsNew method to create a new instance of the class. Once the new instance
is created, a method named _SetCustInfo, which is defined by the transient
object class, is invoked to insert the information retrieved from the database
into the object's instance data.
Note that the technique shown in Figure "Creating a Transient Object" may only
be used when an object is created from within the Workplace Shell process. If
an object must be created from another process in the system, the
WinCreateObject() function must be used.
ΓòÉΓòÉΓòÉ 17.6. Building a Workplace Shell Application ΓòÉΓòÉΓòÉ
As already mentioned, an application that exploits the Workplace Shell consists
of a number of objects on the desktop or in folders, which interact with one
another to carry out operations as requested by the user. The implementation
of the Workplace Shell under OS/2 V2.0 causes all Workplace Shell objects to
run in a single process, under the control of the Workplace Shell itself. It
is therefore possible for an error in a Workplace Shell to terminate the
Workplace Shell process, and all objects currently open under the control of
that process. While the Workplace Shell automatically restarts itself and its
open objects, it is recommended for reasons of performance that applications
carrying out lengthy processing such as database or remote system access should
be implemented using multiple processes. Other processes in the system are not
affected if the Workplace Shell process terminates, and become available to the
user as soon as the shell restarts itself, without the need to reload
application code, reinitialize communications links, etc.
For example, a database query application that searches a database for customer
records and displays these in a Workplace Shell folder may be composed of two
processes, each with multiple threads, as shown in Figure "Workplace Shell
Application Structure."
The requester portion of the application, which allows the user to enter a
query, and which displays the results on the screen, is implemented as a
Workplace Shell object, running under the control of the Workplace Shell
process. The primary thread in this process carries out the interaction with
the end user, while a secondary thread is created to handle communication
between processes.
The second process acts as a database server, and is created by the first
process when the application is started. The server process has a primary
thread that accepts requests from the requester in the Workplace Shell process,
and a number of secondary threads that actually perform the database access.
If an errant object or application were to cause the Workplace Shell to
terminate, the requester threads would be terminated. However, the server
process would not be terminated, and communication with the requester could be
re-established simply by having the requester initiate one of the standard
interprocess communication mechanisms described in Multitasking Considerations.
ΓòÉΓòÉΓòÉ 17.7. Communication Between Objects ΓòÉΓòÉΓòÉ
Objects communicate with one another in order to convey events and initiate
actions on the part of other objects. Such communication is typically
initiated in one of two ways:
By an object to convey information to another object with which it has an
application-defined relationship, such as a request. This is similar to the
application-initiated event discussed for Presentation Manager applications
in The Presentation Manager Application Model.
By the user directly manipulating the objects' icons. For example, dropping
one icon over another icon initiates a conversation between the two objects.
This is similar to the user-initiated event discussed for Presentation
Manager applications in The Presentation Manager Application Model.
Each of these types of communication is discussed in the following sections.
ΓòÉΓòÉΓòÉ 17.7.1. Application-Initiated Communication ΓòÉΓòÉΓòÉ
In the former case, the communication is quite simple since the initiator of
the communication typically has knowledge of the type of object to which the
communication is being passed, and can usually initiate the communication by
simply invoking a method in the receiving object, in a similar manner to that
discussed in Methods (Invoking Another Object's Methods).
However, it is often necessary to determine the identity of the object for
which a method must be invoked. The Workplace Shell provides access to objects
using the HOBJECT and the OBJECTID and, at a base level, system object model
provides pointers to objects and SOM IDs. Each of these is described in the
following sections, and some discussion is included on converting between
identifiers.
HOBJECT
This identifier is the object handle, which is allocated by the Workplace Shell
and passed as the return value from the WinCreateObject() function. It is a
persistent object handle that remains allocated to an object for the duration
of its existence. Object handles persist across system restarts, and may
therefore be used by one object to refer to another object at any time.
An object handle can be determined from the object's OBJECTID using the
WinQueryObject() function, as follows:
HOBJECT hObject; /* Object handle */
PSZ szObjectID = "<OBJECTID>"; /* OBJECTID string */
hObject = WinQueryObject(szObjectID); /* Query object handle */
Note that this function may be called from any process; its use is not
restricted to objects in the Workplace Shell process.
OBJECTID
The OBJECTID is provided by an application or object class as part of the setup
string parameter in the WinCreateObject() call, when an object is created. It
is persistent in the same way as an object handle, but provides a more
meaningful reference for an object, which can be used by other objects.
Figure "Referencing an Object Using OBJECTID"
Note that the angle brackets ("<" and ">") used within the OBJECTID are an
important part of the syntax.
Note also that the Workplace Shell provides a number of predefined OBJECTIDs
for system-defined objects. The first and third WinCreateObject() calls in
Figure "Referencing an Object Using OBJECTID" use the <WP_DESKTOP> OBJECTID to
place the objects on the desktop.
SOM Pointer
SOM pointers come in various forms, but can all be typecast to SOMAny *. From
a Workplace Shell perspective, a SOM pointer is the return value of the
_wpclsNew class method; this is the method used for creating objects within the
Workplace Shell process. An object's public methods and data can be accessed
using the object's SOM pointer.
A SOM pointer for an object may be obtained from an object handle using the
_wpclsQueryObject method provided by the WPObject class, as follows:
SOMAny *Asomptr; /* SOM pointers */
SOMAny *Bsomptr;
Asomptr = _wpclsQueryObject(_WPObject, /* Query SOM pointer */
hObject); /* Object handle */
A SOM pointer for a class may be obtained from the SOM ID for that class, using
the _somFindClass method shown below:
Asomptr = _somFindClass(SOMClassMgrObject,
AsomId,
1,
1);
A SOM pointer for a class may be obtained from the SOM pointer for any object
within that class, using the _somGetClass method as follows:
Asomptr = _somGetClass(Bsomptr);
The SOM pointer is typically used to invoke class methods from an object in
another class. The _SOMDispatchL() method shown in Figure "Invoking a Method
in Another Object Class" requires a SOM pointer as a parameter.
SOM ID
A SOM ID is simply a way of mapping a unique number to a string. This string
may represent the name of a method or class. SOM IDs are integers that are
managed by the Workplace Shell using the Atom Manager facility of Presentation
Manager. A SOM ID is obtained using the SOM_IdFromString() function as
follows:
somId AsomId;
AsomId = SOM_IdFromString("WPFolder");
The SOM ID is typically used to obtain a SOM pointer, which can then be used to
invoke a method.
ΓòÉΓòÉΓòÉ 17.7.2. User-Initiated Communication ΓòÉΓòÉΓòÉ
The latter case is somewhat more complex, since the two objects may have no
defined relationship. A conversation must be initiated between the two,
whereby each determines the nature of the other, and whether a drop operation
is valid at the present time. If so, each object passes the information
required to carry out the requested action.
Dragging an Object
When the user begins to drag an object, the object being dragged is notified by
the system, which invokes the object's _wpFormatDragItem method. This method is
used to build a DRAGITEM structure, which is passed to another object if the
current object is dragged over it or dropped upon it. The DRAGITEM structure
contains rendering information about the object, which is used by other objects
over which the object is dragged, in order to determine whether a drop
operation is valid at that point.
Default information for the DRAGITEM structure is inserted by the default
processing provided by the parent class, but an object class may override the
method and include its own class-specific processing. The DRAGITEM structure
is nested within a DRAGINFO structure, which is passed to any object over which
the current object is dragged. In a situation where more than one object is
being dragged simultaneously, a separate DRAGITEM structure is produced for
each object, and the entire set of structures is combined using a single
DRAGINFO structure.
When an object is dragged over another object, the system invokes the
_wpDragOver method in the object being dragged over. This method receives a
DRAGINFO structure, which contains a variety of information including pointers
to one or more DRAGITEM structures. The object may examine these structures
and determine whether any of the objects being dragged can be dropped over it.
If not, the object changes the mouse pointer to indicate that a drop operation
is not valid.
Dropping an Object
When a drop operation occurs, the object being dropped upon is notified by the
system, which invokes the _wpDrop method. This method accepts the DRAGINFO
structure, which may be examined by the object to determine the correct action
to be taken. The rendering information contained in the DRAGITEM structure may
be sufficient to allow the action to be completed, or the object being dropped
upon may initiate a conversation with the object being dragged over it, in
order to gain sufficient information to complete the action.
The rendering information provided in the DRAGITEM structure, and its use by a
Presentation Manager or Workplace Shell object, is described in detail in
Direct Manipulation.
ΓòÉΓòÉΓòÉ 17.8. Summary ΓòÉΓòÉΓòÉ
The OS/2 Version 2.0 Workplace Shell provides an object-oriented user interface
to the operating system, and provides an object-oriented application layer on
top of Presentation Manager, through its implementation of the system object
model. An application that exploits the facilities of the Workplace Shell
consists of a number of objects, which are manipulated on the Workplace Shell
desktop by the user, in order to carry out the required tasks.
Workplace Shell objects conform to "standard" object-oriented principles in
that they are grouped into object classes, have instance data, and contain
methods which perform the required tasks and operate upon the instance data.
Workplace Shell object classes may inherit data and methods from their parent
class, in accordance with the object-oriented concept of inheritance. A class
may add additional data items or new methods to perform actions not handled by
its parent class, or may override existing methods to handle actions in a
different manner.
An object class is defined using a class definition file, which defines the
parent hierarchy for the object, its data items and its methods. The class
definition file is used as input to the SOM Precompiler, which uses the file to
produce a number of source code files and header files. The source code is
edited by the programmer to add the application logic for each method. It is
then compiled using a normal C compiler, and link edited to produce a dynamic
link library that implements the object class. An object class may make use of
operating system and Presentation Manager resources during its execution.
Workplace Shell objects behave in a similar manner to windows under
Presentation Manager; object classes are registered to the Workplace Shell, and
individual instances of an object class are created, opened, closed and
destroyed by the user or by other objects in the system. The major difference
between a window under Presentation Manager and an object under the Workplace
Shell is that Workplace Shell objects are persistent; that is, they exist for
longer than a single application execution. Once created, a Workplace Shell
object remains in existence until it is explicitly destroyed.
ΓòÉΓòÉΓòÉ 18. Direct Manipulation ΓòÉΓòÉΓòÉ
Direct manipulation of icons on the Presentation Manager desktop in order to
carry out processing tasks has been possible since the first release of
Presentation Manager in OS/2 Version 1.1, but only in Version 1.3 was a
standard method introduced for implementing such function. Previously, each
programmer needed to devise a set of protocols, and write code in every
application to handle all the mouse messages and interaction between windows
that may have been needed.
OS/2 Version 1.3 introduced some standards for coding direct manipulation
operations, in the form of new message classes (the DM_xxxx messages), and
standard protocols known as rendering mechanisms, which are used to communicate
required information for commonly used direct manipulation operations. This
support is continued in OS/2 V2.0, and is of increased importance since the
Workplace Shell itself makes extensive use of direct manipulation.
Applications that use direct manipulation are therefore more likely to be
written under Version 2.0, either to interact with one another or to make use
of Workplace Shell facilities such as printer objects or the shredder.
This chapter discusses the use of direct manipulation in a program, covering
the major messages and data structures involved, and the use of the standard
rendering mechanisms. Examples of the use of these messages and data
structures are given, along with guidance on implementing a private rendering
mechanism to meet the needs of a particular application.
ΓòÉΓòÉΓòÉ 18.1. Direct Manipulation Basics ΓòÉΓòÉΓòÉ
It might appear that dragging an icon from one window and dropping it onto
another is straightforward, but on closer consideration it proves to be
somewhat more complex. Consider the simple action of dragging an icon
representing a customer from one container window to another, the intention
being to move the customer from one branch of the business (represented by the
first container) to another (the second container window). The following steps
are required:
1. The program owning the first container (hereafter called the source
program) must determine which customer the user wishes to move (hereafter
known as the dragitem).
2. The source program must decide on an icon or bitmap to represent the
customer as the user drags the customer around the screen.
3. The source program must package a number of items of information to travel
with the icon, so that potential target windows may decide whether or not
they will allow the item to be dropped on them.
4. As the icon passes outside the container to other areas, its appearance
must be constantly updated to indicate to the user whether a drop is
allowed.
5. When the icon reaches a potential target window, the program owning the
target window (hereafter known as the target) must access the information
about the dragged item to decide whether it will allow the item to be
dropped. At this point, the rendering mechanism used to convey this
information becomes significant, since both the source and target must be
able to understand the mechanism.
6. Once a drop has occurred, the target window must decide the form in which
it wishes to receive the dropped object (if more than one form is supported
by both source and target), and inform the source program accordingly.
7. The source program must make the data representing the customer available
to the target program. Since the source and target programs may not
necessarily run in the same process, this may not be trivial. Again, the
rendering mechanism to be used becomes significant.
8. The source must inform the target that the data is ready.
9. The target must access and retrieve the data.
10. The source must delete its own copy (since the operation is a "move"
operation).
11. The target must display the new customer object in its own container
window, in the location at which it was dropped.
While this appears extremely complex, much of the necessary work is done by
Presentation Manager for a Presentation Manager application; for a Workplace
Shell object, even more of the necessary function is automated by the Workplace
Shell. The remainder of this chapter will describe the steps necessary for a
Presentation Manager application and/or a Workplace Shell object to exploit
drag/drop functionality.
ΓòÉΓòÉΓòÉ 18.1.1. Significant Events ΓòÉΓòÉΓòÉ
There are a number of significant events that occur during a direct
manipulation operation, and which must be communicated to the source and/or
target of the operation. These are as follows:
Initiation of the drag operation, which must be communicated to the source so
that it can initialize data structures with information relating to the
dragitem.
Dragging the object over a potential target, which must be communicated to
the target so that the target can determine whether a drop operation is
valid.
Dropping the object over a target, which must be communicated to the target
so that it may decide the form in which it wishes the dragitem data to be
passed, and allocate any necessary resources to receive the data.
Transferring the information between the source and the target to complete
the overall direct manipulation sequence.
Presentation Manager carries out much of the required notification of drag/drop
events using messages, which are passed to the source or target windows as
necessary during the drag/drop operation. The required messages are described
in the OS/2 2.0 Programming Guide Volume II and their use is discussed in Using
Direct Manipulation.
In certain cases, the behavior of a Workplace Shell object participating in a
direct manipulation operation varies somewhat from that of a Presentation
Manager window. This is due to the fact that the Workplace Shell implements
much of the required message handling itself, and directly invokes the
appropriate methods in the object. Where the behavior of a Workplace Shell
object differs from that of a Presentation Manager window, this is noted in the
text.
ΓòÉΓòÉΓòÉ 18.1.2. Rendering Mechanisms ΓòÉΓòÉΓòÉ
Rendering mechanisms are the means by which the source and target of a
drag/drop operation determine the data type of the dragitem and the format of
the information to be exchanged.
While the precise sequence of events that takes place after a drop has occurred
is dependent upon the application, a number of standard rendering mechanisms
have been defined to enable diverse applications to engage in direct
manipulation with one another. These standard rendering mechanisms are used by
various components of OS/2, as well as being available for use by applications.
Three standard rendering mechanisms are provided by Presentation Manager and
are documented in the OS/2 2.0 Programming Guide Volume II:
DRM_PRINT This rendering mechanism is designed for applications that
wish to provide printing facilities via direct
manipulation, by allowing the user to drag items from the
application and drop them on one of the Workplace Shell
printer objects.
It is a very simple mechanism. When an object is dropped
on a printer object, the printer object sends a
DM_PRINTOBJECT message, one parameter of which gives the
name of the print queue represented by that printer object.
It is then the responsibility of the source window to print
the relevant data to the specified queue.
Note that in OS/2 Version 1.3, the DM_PRINT message was
used for this purpose, rather than the DM_PRINTOBJECT
message.
DRM_OS2FILE This rendering mechanism is intended for applications that
wish to allow the dragging and dropping of file objects
between windows or folders on the desktop. Such
applications include the File Manager in OS/2 Version 1.3,
or the Drives objects in OS/2 V2.0.
With this mechanism, all information about the source file
may be contained in the fields of the DRAGITEM structure,
so it is not necessary for a protracted conversation to
take place between source and target windows. In the
simplest case, the target can complete the operation using
only this information with no further involvement from the
source window, though this rendering mechanism does allow
for more interaction between the two windows should this be
useful.
DRM_DDE The DDE rendering mechanism is intended for applications in
which drag/drop actions will be used to set up DDE links
between windows. The DDE then proceeds according to
standard DDE protocols.
Further rendering mechanisms may be devised and documented for use by a
particular user's applications. The creation and use of rendering mechanisms
is discussed in Using Rendering Mechanisms.
ΓòÉΓòÉΓòÉ 18.2. Data Structures Used in Drag/Drop ΓòÉΓòÉΓòÉ
Three structures contain the data that travels with an item while it is being
dragged; these are the DRAGINFO, DRAGITEM and DRAGIMAGE structures. A further
structure, the DRAGTRANSFER structure, is used to transfer information between
source and target windows after a drop has occurred.
Details of the fields within these structures can be found in the IBM OS/2
Version 2.0 Presentation Manager Reference, and full descriptions will not be
given here. However, the following sections describe in general terms the kind
of data the structures contain, and particularly certain critical fields.
ΓòÉΓòÉΓòÉ 18.2.1. The DRAGINFO Structure ΓòÉΓòÉΓòÉ
The DRAGINFO structure contains information about the overall drag operation,
which may consist of one or more dragitems. Information in the DRAGINFO
structure determines the source and type of the drag operation, and provides
pointers to one or more DRAGITEM structures which identify individual
dragitems.
The handle of the source window for the drag operation is contained in the
DRAGINFO structure. This handle enables a target window which receives the
structure to initiate a conversation with the source window if necessary, in
order to exchange information.
The other item of note in the DRAGINFO structure is a field which identifies
the type of drag operation that the user has selected. For example, a value of
DO_COPY means that the user is holding the Ctrl key down, which by convention
means that a copy operation is required. The DO_DEFAULT value means that a
default drag operation is to be used because the user is not holding down any
modifier key.
The DRAGINFO structure contains a counter that specifies how many dragitems are
involved in the current operation. This counter is then used to access an
array of pointers, also contained within the DRAGINFO structure, which
reference individual DRAGITEM structures for each dragitem.
Note that the DRAGINFO structure must be accessible not only to the source
window that sets it up in the first place, but also to any potential target
windows. Since these windows may not be owned by the same process, the
DRAGINFO structure must be allocated in shared memory. In order that the
structure be correctly allocated and easily accessible by the system in order
to provide it to potential target windows, OS/2 allocates the DRAGINFO
structure on the application's behalf, using the DrgAllocDraginfo() function.
This function is called by the source window when it is notified of a drag
operation by receiving a WM_BEGINDRAG message.
For Workplace Shell objects, the Workplace Shell handles the allocation and
initialization of the DRAGINFO structure. The object itself is not required to
take any action with respect to this structure.
ΓòÉΓòÉΓòÉ 18.2.2. The DRAGITEM Structure ΓòÉΓòÉΓòÉ
The DRAGITEM structure contains information about an individual dragitem. A
drag operation may include one or more dragitems, and a separate DRAGITEM
structure is used for each. The number of dragitems, and an array of pointers
to the DRAGITEM structures, is contained in the DRAGINFO structure. In
conjunction with the information contained in the DRAGINFO structure, the
DRAGITEM structure provides the information required by a potential or actual
target window, to determine whether a drop operation is valid for the dragitem.
Several of the fields in the DRAGITEM structure are defined as being of type
HSTR. These fields refer to ordinary null-terminated character strings that
are given string handles by Presentation Manager when the DrgAddStrHandle()
function is called. It is the string handles that are stored in the DRAGITEM
structure; the strings themselves are stored by Presentation Manager and may be
accessed by any other process that has access to the string handle, using the
DrgQueryStrName() function.
For Presentation Manager windows, the DRAGITEM structure is normally allocated
by the source of the drag/drop operation as a local variable, since it only
persists for the duration of the operation. For Workplace Shell objects, the
structure is allocated by the Workplace Shell and a pointer to it is passed to
the object by the Workplace Shell when it invokes the object's
_wpFormatDragItem method when the drag is initiated.
A number of fields in the DRAGITEM structure are of primary importance; these
fields are described in the following sections.
lItemID
This field contains a value provided by the source window, which uniquely
identifies the dragitem. For example, the value might be a listbox index
value, a customer number, or any other value that is unique and meaningful to
the source window. The reason for having this identification is that later in
the drag/drop processing, the target window may need to ask the source window
for more information about the dragged item. The identifier can then be used
to identify the item concerned.
hstrType and hstrRMF
These values refer to character strings containing details of the type of data
represented by the dragitem, and the rendering mechanisms and formats that the
source is able support for the item. The types correspond to the file type
extended attribute, and are identified by names of the form DRT_xxxx; for
example, DRT_TEXT for plain text, or DRT_BITMAP for bitmap data.
The rendering mechanism is specified in the hstrRMF field, and may refer to any
of the standard mechanisms described in Rendering Mechanisms, identified by the
names DRM_PRINT, DRM_DISCARD, DRM_OS2FILE and DRM_DDE, or to any user-defined
rendering mechanism for which a similar name should be defined. More than one
rendering mechanism can be specified; for example, a program that allows the
dragging of files may allow the file to be moved or copied to another
directory, or to be printed by being dropped on a printer object. In this case
the program would include the names of both the Print and OS/2 File rendering
mechanisms in its hstrRMF string, allowing the target window to decide which is
more suitable.
The format specifications, which are also contained in the hstrRMF field,
inform a target window of the data formats supported by the dragitem for each
of its supported rendering mechanisms. Data format names use the convention
DRF_xxxx.
To illustrate the use of format specifications and rendering mechanisms,
consider a spreadsheet program that allows the user to drag an icon
representing a particular spreadsheet; the user may choose to drag the data
into a word-processor, into another spreadsheet, or onto a printer object for
printing. For dragging the file to another spreadsheet or to a word-processing
document, the DRM_OS2FILE rendering mechanism is appropriate but for dragging
to a printer object, the DRM_PRINT mechanism is required. In the case where
the target is the printer or the word-processing document, clearly the required
format for the data is text, but in the case of a drag to another spreadsheet
it would be more convenient to have the numerical data and the cell
relationships transferred too, so a different data format should be used,
perhaps SYLK.
The dragitem therefore needs to indicate that it supports the following
rendering mechanism/data format combinations:
DRM_OS2FILE with DRF_TEXT
DRM_PRINT with DRF_TEXT
DRM_OS2FILE with DRF_SYLK.
The hstrRMF string provides a syntax for defining this in a fairly
straightforward way. Complete details are given in the OS/2 2.0 Programming
Guide Volume II but, for the above example, the hstrRMF string is as follows:
<DRM_OS2FILE,DRF_TEXT>,<DRM_PRINT,DRF_TEXT>,<DRM_OS2FILE,DRF_SYLK>
This can be expressed slightly more concisely as:
(DRM_OS2FILE,DRM_PRINT)x(DRF_TEXT),<DRM_OS2FILE,DRF_SYLK>
Here the first two bracketed items, connected with an "x", indicate that all
possible pairs made up of one from the first bracket and one from the second,
are implied. This notation is very useful in more complex examples, where it
can save the programmer from having to enumerate all possible combinations in
the string.
hstrContainerName, hstrSourceName, hstrTargetName
The meaning of these three fields depends on the rendering mechanism to be
used; with some rendering mechanisms, certain fields are not needed. They
apply most directly to the DRM_OS2FILE mechanism where they are used to define
the source directory, source file name, and a suggested target filename (which
may be overridden by the target window if it so chooses).
ΓòÉΓòÉΓòÉ 18.2.3. The DRAGIMAGE Structure ΓòÉΓòÉΓòÉ
This structure, as its name suggests, contains information about the actual
image to be displayed on the screen as the user performs the drag operation.
In this structure, the source window specifies the icon or bitmap to be used,
whether it is to be rescaled, and the coordinates of the hot spot.
ΓòÉΓòÉΓòÉ 18.2.4. The DRAGTRANSFER Structure ΓòÉΓòÉΓòÉ
This structure is passed with a DM_RENDER message, from the target to the
source window, after a drop has occurred. It allows the target window to
inform the source of several important things. For example, where the source
supports several different rendering mechanisms and/or formats, the target can
specify which of these it wishes to use. Similarly, if the source supports
both copy and move operations, the target can specify which it will use by
means of the usOperation field of this structure.
Another important field is hstrRenderToName. This tells the source window
where to place the data, so that the target will know where to find it. The
precise interpretation of this depends on the rendering mechanism; for example,
in the case of the DRM_OS2FILE rendering mechanism, it contains the fully
qualified name that the file is to be given at its destination. Where the
transfer of information between source and target window is a simple memory
transfer, this field may be used to contain the name of a named shared memory
object into which the source is to place the data.
ΓòÉΓòÉΓòÉ 18.3. Using Direct Manipulation ΓòÉΓòÉΓòÉ
The following sections use an example to illustrate the way in which direct
manipulation can be used within a Presentation Manager application or a
Workplace Shell object. The example consists of a Customer program which reads
and displays customer details. Each customer is displayed as an object in a
container window.
The other component of the example is a Telephone program, which accepts
customer information from the Customer program via drag/drop, and automatically
dials the customer's telephone number. The Telephone program communicates with
the Customer program using a private rendering mechanism defined by the
application. This rendering mechanism uses shared memory, and is identified by
the name DRM_SHAREMEM. The rendering mechanism is explained in detail in
Implementing a Private Rendering Mechanism.
The example uses Presentation Manager windows as both the source and target for
the drag/drop operation, since this enables a description of the complete set
of steps required to complete the operation. For Workplace Shell objects,
certain steps are handled automatically by the Workplace Shell itself, and a
Workplace Shell object class is therefore not required to carry out these
steps. Where a particular step is automated by the Workplace Shell, this is
noted in the discussion.
ΓòÉΓòÉΓòÉ 18.3.1. Initiating a Drag Operation ΓòÉΓòÉΓòÉ
A drag operation is initiated by the source window or object. When the user
starts the drag operation by pressing and holding down mouse button 2,
Presentation Manager passes a WM_BEGINDRAG message to the window or object that
is currently under the mouse pointer. In the case of a Presentation Manager
window, the window procedure for that window may process the WM_BEGINDRAG
message in order to initialize the DRAGINFO and DRAGITEM structures, and start
the drag operation. A Workplace Shell object is notified of a drag initiation
by the Workplace Shell itself, which invokes the object's _wpFormatDragItem
method.
The initialization of a drag operation from a container window is shown in
Figure "Drag Initiation From a Container Window".
The code shown in Figure "Drag Initiation From a Container Window" would form
part of the window procedure for the owner of the container control, since it
is this window that would receive the WM_CONTROL message from the container.
Initializing Data Structures
When a WM_CONTROL message is received from a container window, a pointer to a
CNRDRAGINIT structure is passed in the second parameter to the WM_CONTROL
message. This structure contains a pointer to the item within the container
that the user is attempting to drag. If this pointer is NULL, the user has
attempted a drag operation while no item in the container was selected. In the
current example, the drag operation is ignored and control is immediately
returned to Presentation Manager.
The source window then allocates a DRAGINFO structure using the
DrgAllocDraginfo() function. The DRAGITEM structure is initialized with the
appropriate values, and its pointer is set in the DRAGINFO structure using the
DrgSetDragItem() function. All interaction with the DRAGINFO structure is
performed using Presentation Manager functions, avoiding the necessity for the
source window procedure to address the DRAGINFO structure directly.
The DRAGIMAGE structure is then initialized with the information relating to
the icon that will be displayed under the mouse pointer during the drag
operation.
For a Workplace Shell object, the Workplace Shell itself performs the
initialization of the DRAGINFO structure. The object may perform its own
initialization of the DRAGITEM structure during processing of the
_wpFormatDragItem method, if class-specific processing is required. For
example, if the object class implements a private rendering mechanism, the
appropriate information must be entered into the correct fields in the DRAGITEM
structure as part of the _wpFormatDragItem method.
Note that a Workplace Shell object need not allocate the DRAGITEM structure,
since the structure is already allocated by the Workplace Shell, and a pointer
to the structure is passed to the _wpFormatDragItem method upon invocation.
DrgDrag() Processing
Once all data structures are allocated and initialized, the drag operation is
initiated using the DrgDrag() function. This function is synchronous; it does
not return control to the source window procedure until the key or mouse button
specified in the fifth parameter (VK_ENDDRAG in the example above) is detected,
and any synchronous message passing has been completed.
At this point, the DrgDrag() function returns a window handle. If the dragitem
was dropped over a window or object that was able to accept the item, the
window handle of the target window is returned. If a drop occurred over an
object that was unable to accept the item, a NULL window handle is returned.
Upon return of control by the DrgDrag() function, the drag operation and the
drop operation (if any) is complete, and the DRAGINFO structure can be released
by the source window procedure.
A Workplace Shell object is not required to invoke the DrgDrag() function,
since this is performed automatically by the Workplace Shell when the object
completes the processing of its _wpFormatDragItem method.
Synchronous Message Processing During DrgDrag()
When the user drops the dragitem over another window or object that is able to
accept the item, a DM_DROP message is passed to the target, which then
processes the drop operation. Note that the target's DM_DROP message
processing must complete and return control to Presentation Manager before the
DrgDrag() function will return control to the source window procedure. Thus
any processing that is performed by the target window during its processing of
the DM_DROP message is synchronous.
The synchronous nature of this processing is necessary in order to ensure that
the drop operation, and the accompanying transfer of information, is completed
before the user performs any other operation. For this reason, it is
recommended that any messages passed by the target to the source window during
processing of the DM_DROP message should be passed synchronously using the
DrgSendTransferMsg() function. This is a departure from the normal Presentation
Manager guidelines, where messages are processed asynchronously, but is
required in order to ensure data integrity.
A number of synchronous messages may be sent to the source window at the
completion of a drop, prior to the DrgDrag() call returning control to the
source window. For example, if the user drops an object on a Workplace Shell
printer object with the DRM_PRINT rendering mechanism specified, the target
object sends a DM_PRINTOBJECT message to the source window. This message
contains sufficient information for the source window to direct a print data
stream to the print queue represented by the printer object. The first
parameter in the DM_PRINTOBJECT message contains a pointer to the DRAGITEM
structure that identifies the item being dropped, and the second parameter
contains the name of the print queue for the printer object.
An example of the way in which the source window procedure may process the
DM_PRINTOBJECT message is shown in Figure "Receiving a DM_PRINTOBJECT Message".
Note that the code that actually performs the printing operation has been
omitted from Figure "Receiving a DM_PRINTOBJECT Message". Printing under OS/2
Version 2.0 and Presentation Manager is discussed in detail in OS/2 Version 2.0
- Volume 5: Print Subsystem, and examples are also provided in the PRTSAMP
program included in the IBM Developer's Toolkit for OS/2 2.0.
ΓòÉΓòÉΓòÉ 18.3.2. Dragging Over a Window ΓòÉΓòÉΓòÉ
While the dragitem is being dragged, Presentation Manager sends a succession of
DM_DRAGOVER messages to the Presentation Manager window under the mouse
pointer; one message is sent for every mouse movement. The DM_DRAGOVER message
informs the target window that it is being dragged over, and allows it to
access sufficient information to allow the window to decide whether it is able
to accept a drop operation. The window procedure indicates this to
Presentation Manager by the value that it returns in response to the
DM_DRAGOVER message.
The information required by the window is contained in two data structures; the
DRAGINFO structure, which is referenced by one of the parameters in the
DM_DRAGOVER message, and the DRAGITEM structure, which can be accessed from the
DRAGINFO structure. Since multiple items may be dragged at the same time, the
DRAGINFO structure contains an array of pointers to DRAGITEM structures, one
for each dragitem. The DRAGINFO structure maintains a count of the number of
dragitems.
When a potential target is a Workplace Shell object, the Workplace Shell
notifies the object that a dragitem is being dragged over it, by invoking the
object's _wpDragOver method. The DRAGINFO structure is passed to the object as
a parameter to this method. Processing of the _wpDragOver method is very
similar to that described below for Presentation Manager window procedures. In
normal circumstances, however, the _wpDragOver method is not overridden by an
object class; the default processing supplied by the parent class is allowed to
occur unless the object class supports private rendering mechanisms that must
be explicitly checked against those supported by the dragitem.
An example of the way in which a window procedure may process the DM_DRAGOVER
message is shown in Figure "Handling the DM_DRAGOVER Message".
The code shown in Figure "Handling the DM_DRAGOVER Message" is quite simple;
the processing of the DM_DRAGOVER message is intended only to determine whether
a drop operation is valid for the specified dragitem and the target window.
First, access is gained to the DRAGINFO structure, which is referenced by the
first parameter to the DM_DRGOVER message. The DRAGINFO structure is then used
to access the DRAGITEM structure, by means of the DrgQueryDragitemPtr()
function. The window procedure then has access to all the information needed to
determine the validity of a drop operation.
In this particular case, the only type of dragitem that is acceptable to the
target window is one that represents a customer object, using the specially
defined DRM_SHAREMEM rendering mechanism. The window procedure therefore uses
the DrgVerifyRMF() function to check whether the dragitem supports this
rendering mechanism and the data type required by it.
According to the result returned by the DrgVerifyRMF() function, the window
procedure returns either DOR_DROP, indicating that a drop is acceptable, or
DOR_NEVERDROP, indicating that a drop is not acceptable and that there is no
point in sending any more DM_DRAGOVER messages to this window. A number of
other valid returns are possible for the DM_DRAGOVER message; these are
documented in the IBM OS/2 Version 2.0 Presentation Manager Reference.
Irrespective of the return code, the DRAGINFO structure is released.
If a window returns any return code other than DOR_DROP to this message, the
icon seen by the user is automatically modified to show that a drop is not
allowed, thereby providing instant visual feedback.
ΓòÉΓòÉΓòÉ 18.3.3. Dropping an Object ΓòÉΓòÉΓòÉ
When the user drops a dragitem over a Presentation Manager window, the target
receives a DM_DROP message. The window procedure for the target may process
that message in order to handle the drop operation, and may either complete the
operation or initiate a conversation with the source window or object in order
to do so, typically by sending it a DM_RENDER message, which ultimately will
result in the data being transferred.
When the user drops a dragitem over a Workplace Shell object, the Workplace
Shell invokes that object's _wpDrop method. The processing of this method is
very similar to that discussed below for the DM_DROP message. However, object
classes that do not implement private rendering mechanisms need not override
the _wpDrop method; the default processing provided by the parent class may be
allowed to occur.
In the customer/phone dialler example, the only type of dragitem that the order
program will accept is a customer object, which uses the application-defined
DRM_SHAREMEM rendering mechanism. The correct data type and rendering
mechanism is verified by the target window procedure during processing of the
DM_DRAGOVER message, so there is no need for further checking when the DM_DROP
is processed. Note however, that in a more sophisticated application, which
supports multiple data types and rendering mechanisms, it may be necessary to
perform more detailed checking.
In Figure "Handling the DM_DROP Message", access must first be gained to the
DRAGINFO and DRAGITEM structures. This is achieved in a similar manner to that
already described for the DM_DRAGOVER message. Having gained access to these
structures, a named shared memory object is then allocated, into which the
source window will be asked to place the customer details.
A DRAGTRANSFER structure is then allocated, in which information about the
target's requirements can be passed to the source window. This structure is
similar to the DRAGINFO structure, in that it must be accessible from multiple
processes. It is therefore allocated using the DrgAllocDragtransfer()
function, ensuring that the structure will be accessible to the source window,
which may be in another process and therefore not have direct access to the
target's private data areas.
There are several important fields in this structure. The target window
procedure places a pointer to the DRAGITEM structure into the pditem field,
thereby enabling the source to identify which item has been dropped. The
hstrSelectedRMF field is used to identify which rendering mechanism and data
format is to be used for this target, from the selection offered by the source
in the DRAGITEM structure. The hstrRenderToName field is used in the
DRM_SHAREMEM rendering mechanism to pass the name of the shared memory object
to the source window.
Once this structure has been completed with the necessary information, it is
sent to the source window as part of a DM_RENDER message. This message is
passed to the source window using the DrgSendTransferMsg() function. This
function should be used for drag/drop operations in preference to the
WinSendMsg() function since, for a DM_RENDER message, it also grants access to
the DRAGTRANSFER structure for the process that owns the window to which the
message is being sent.
In processing the DM_RENDER message, the source window copies the customer
details into the shared memory so that when DrgSendTransferMsg() returns, the
target window procedure may extract the data it needs. A detailed explanation
of the source window's processing of a DM_RENDER message is given in
Transferring Information.
Upon completion of the information transfer, the entire drag/drop operation is
complete and the data structures allocated during the operation may be
released. For the DRAGINFO and DRAGTRANSFER structures, this must be carried
out using the DrgFreeDraginfo() and DrgFreeDragtransfer() functions.
ΓòÉΓòÉΓòÉ 18.3.4. Transferring Information ΓòÉΓòÉΓòÉ
As explained in Dropping an Object, a target window may send a DM_RENDER
message to the source when it receives a DM_DROP message from Presentation
Manager. Similarly, a Workplace Shell object may send the same message when
its _wpDrop method is invoked by the Workplace Shell. This message is normally
sent to the source when the target requires the assistance of the source in
completing the transfer of data as part of the drop operation.
The source window processes this message in its window procedure, according to
the rendering mechanism requested by the target. If the source is a Workplace
Shell object, the Workplace Shell will directly invoke the object's _wpRender
method to perform the same function. In most cases, however, an object does
not need to override the _wpRender method unless it wishes to implement a
private rendering mechanism.
The DM_RENDER processing from the Customer program is shown in Figure "Handling
the DM_RENDER Message".
The first parameter to the DM_RENDER message contains a pointer to the
DRAGTRANSFER structure, which in turn contains a pointer to the DRAGITEM
structure in its pditem field. For a Workplace Shell object, a pointer to the
DRAGTRANSFER structure is passed as a parameter to the _wpRender method.
In the DRM_SHAREMEM rendering mechanism, the ulItemID field in the DRAGITEM
structure is used to hold a pointer to the customer container record (of type
CONTRECORD), in whch the cust field is a CUSTOMER structure containing details
of the customer object which was dragged.
Next, the name of the shared memory object previously allocated by the target
window is retrieved from the hstrRenderToName field of the DRAGTRANSFER
structure. This name is used to obtain access to the shared memory object.
The customer details are copied into this memory object, after which the memory
object is freed.
The operation code in the DRAGTRANSFER structure is then checked to establish
whether the target requires a copy or a move operation. If a move was
requested, the source program deletes the customer record from the contaiiner
by calling an application subroutine named RemoveCustomer().
The window procedure then returns the value TRUE, indicating that the data was
successfully rendered. This value is returned to the target window procedure
that issued the DrgSendTransferMsg() call. At this point, the target window
procedure has access to all information required to complete the drop
operation, and may do so without further communication.
At the completion of the rendering procedure, the source may pass a
DM_RENDERCOMPLETE message to the target, allowing the target to release any
resources still outstanding. A Presentation Manager window may process this
message in its window procedure, while a Workplace Shell object is notified of
the event by the Workplace Shell, which invokes the object's _wpRenderComplete
method. This is usually only required in cases where complex private rendering
mechanisms involve multiple transfers. It is not used in the above examples.
ΓòÉΓòÉΓòÉ 18.4. Using Rendering Mechanisms ΓòÉΓòÉΓòÉ
The rendering mechanism is essentially a protocol that determines the contents
of several fields in the DRAGITEM structure. These fields are:
ulItemID, which contains an application-specific value uniquely identifying
the item being dragged.
hstrType, which contains a handle to a string defining the data type of the
dragitem.
hstrRMF, which contains a handle to a string containing the names of all
rendering mechanisms supported by the dragitem, and the data formats
supported by those rendering mechanisms.
hstrContainerName, hstrSourceName and hstrTargetName, which contain handles
to strings used by the DRM_OS2FILE rendering mechanism, and may be used by
private rendering mechanisms to contain string data.
The content of the hstrRMF field should obey a set of syntactical rules that
are explained in the OS/2 2.0 Programming Guide Volume II. Other fields in the
DRAGITEM structure may also be used by particular rendering mechanisms; their
use is dependent upon the individual rendering mechanism in use at the time.
Applications may use one of the standard rendering mechanisms DRM_PRINT,
DRM_DISCARD, DRM_OS2FILE or DRM_DDE, or may define their own rendering
mechanisms to support dragging and dropping of particular dragitems.
ΓòÉΓòÉΓòÉ 18.4.1. Standard Rendering Mechanisms ΓòÉΓòÉΓòÉ
The following sections describe the use of two of the standard rendering
mechanisms, DRM_PRINT and DRM_OS2FILE. These mechanisms can be used by
Presentation Manager applications to interact with other applications and/or
Workplace Shell objects.
DRM_PRINT
For Presentation Manager applications running on the Workplace Shell desktop
under OS/2 Version 2.0, it may be desirable to allow the user to print from the
program by dragging the relevant item, such as a customer record, onto a
Workplace Shell printer object. Since all Workplace Shell printer objects are
written to understand the DRM_PRINT rendering mechanism, a Presentation Manager
may provide such function simply by adhering to this mechanism.
With the DRM_PRINT rendering mechanism, responsibility for actually carrying
out the printing rests within the source window. The source window must:
1. Detect the fact that a drag is being initiated by the user
2. Allocate and fill the DRAGINFO and DRAGITEM structures
3. Start the drag operation using the DrgDrag() function
4. Process the DM_PRINTOBJECT message which is returned by the target printer
object.
The first three steps are handled in exactly the same way as illustrated in
Figure "Drag Initiation From a Container Window". Note that a view of a
Workplace Shell object need not explicitly handle Presentation Manager messages
in the window procedures for its views. When the user initiates a drag from
within a Workplace Shell object such as a folder or work area, the object is
notified by the Workplace Shell, which invokes the object's _wpFormatDragItem
method. This method is processed in an identical manner to that shown for the
window procedure in Figure "Drag Initiation From a Container Window".
The final step is handled by processing the DM_PRINTOBJECT message in the
source window procedure. A simple example of such processing is shown in
Figure "Receiving a DM_PRINTOBJECT Message".
DRM_DISCARD
The DRM_DISCARD rendering mechanism operates in a similar fashion to the
DRM_PRINT mechanism, and is intended for use by applications which create their
own equivalent to the Workplace Shell Shredder object. In this rendering
mechanism, the target passes a DM_DISCARDOBJECT message to the source, which
may either accept responsibility for the discard operation, abort the
operation, or allow the system to perform the operation.
Note that the system may only discard objects which are capable of being
rendered with the DRM_OS2FILE rendering mechanism; that is, program files and
data files. Other objects not based upon files must be explicitly discarded by
the source.
When a Workplace Shell object is dropped on the Shredder object, the Workplace
Shell intercepts the DM_DISCARDOBJECT message and invokes the source object's
wpDelete method.
DRM_OS2FILE
The DRM_OS2FILE rendering mechanism is designed to support moving and copying
file objects between containers. This rendering mechanism is described in
detail in the OS/2 2.0 Programming Guide Volume II, and an extensive example is
provided in the IBM Developer's Toolkit for OS/2 2.0. The details of
programming for the DRM_OS2FILE mechanism will therefore not be described
further in this document.
Certain fields in the DRAGITEM structure are designed specifically for this
rendering mechanism; the hstrContainer, hstrSourceName and hstrTargetName
fields are ideally suited to holding the source directory name, source file
name, and fully qualified target file name respectively. This is how these
fields are used by the DRM_OS2FILE rendering mechanism.
An alternative, and even more straightforward way to implement this rendering
mechanism, is to use the DrgDragFiles() function. This function automatically
allocates and fills the required data structures for the source window,
avoiding the need for the application to perform these functions and reducing
the risk of error.
ΓòÉΓòÉΓòÉ 18.4.2. Implementing a Private Rendering Mechanism ΓòÉΓòÉΓòÉ
The OS/2 2.0 Programming Guide Volume II gives some advice on use of the
various messages available to implement a private rendering mechanism, and also
some guidelines on how such a rendering mechanism should be documented. This
section illustrates the implementation of a simple rendering mechanism, by
explaining the definition of the DRM_SHAREMEM rendering mechanism used by the
examples earlier in this chapter.
A rendering mechanism is necessary to pass the customer record data used in the
examples, since the CUSTOMER structure that contains this data is too large to
be contained within the DRAGITEM structure. It is therefore necessary, after a
drop has occurred, for the source program to make the relevant data available
to the target, in a format which is understood by and accessible to both the
source and the target. In the examples, a named shared memory object is used
to transfer the data; hence the name DRM_SHAREMEM used for the rendering
mechanism.
The DRM_SHAREMEM rendering mechanism operates as follows:
The source window stores a pointer to the customer record being dragged in
the ulItemID field of the DRAGITEM structure. This field is defined as
ULONG, but it can be used in any way that is meaningful to the source window
to identify the item being dragged. A pointer to the customer record is a
convenient way to do this.
The target window, on receiving a DM_DROP message, allocates a named shared
memory object with a name of its choice. It then sends a DM_RENDER message
to the source window, passing the name of the memory object in the
hstrRenderToName field of the DRAGTRANSFER structure, and indicating whether
it requires a copy (DO_COPY) or a move (DO_MOVE) to take place, using the
usOperation field of the DRAGTRANSFER structure.
When the source window receives the DM_RENDER message, it obtains access to
the shared memory object and places the customer record in that object. The
source window knows which customer record to copy, since the DRAGITEM
structure, which includes a pointer to the customer record, is passed along
with the DRAGTRANSFER structure.
Finally, if a move operation was requested by the target, the source window
deletes the customer record from its own data.
On receiving a TRUE return code from the DM_RENDER message, indicating that
the data was successfully rendered, the target window copies the data out of
the shared memory object, and uses it in whatever way it chooses.
It should be stressed that this is a very simple rendering mechanism. However,
it illustrates the general structure of such mechanisms, and their impact on
the contents of fields in the DRAGITEM and DRAGTRANSFER structures.
ΓòÉΓòÉΓòÉ 18.5. Summary ΓòÉΓòÉΓòÉ
Direct manipulation is likely to become considerably more important to
application designers than it has been in previous releases of OS/2, because of
its central role in the object-oriented user interface provided by the
Workplace Shell. Even applications that are not implemented as Workplace Shell
objects should provide, so far as is practical, a similar style of interface.
Direct manipulation forms an essential part of such an interface.
The programming facilities for direct manipulation in OS/2 V2.0 are essentially
the same as those introduced in OS/2 Version 1.3, and consist of a set of
message classes, functions and data structures, along with defined protocols
known as rendering mechanisms, which define standard techniques for using these
facilities to pass different types of information between diverse applications,
and between user-developed applications and Workplace Shell objects such as
printers and the shredder.
User-defined rendering mechanisms may also be defined for specific purposes
that are not covered by the standard ones. The OS/2 2.0 Programming Guide
Volume II gives guidance on this and on how such rendering mechanisms should be
documented.
ΓòÉΓòÉΓòÉ 19. Presentation Manager Resources ΓòÉΓòÉΓòÉ
The definition and use of Presentation Manager resources by applications was
mentioned in The Presentation Manager Application Model. The use of such
resources greatly simplifies the task of the application developer in creating
windows, menu bars, etc., and provides a powerful tool for the externalization
of the user interface properties of an application object, thereby enabling
easier modification of these properties during development or maintenance of
the application. This chapter will describe the definition of resources, and
the ways in which resources may be used within a Presentation Manager
application.
ΓòÉΓòÉΓòÉ 19.1. Types of Resources ΓòÉΓòÉΓòÉ
A number of different types of resources may be defined for use by Presentation
Manager applications. These include text items such as menu bars and window
templates, and graphical items such as graphics fonts, icons and bitmaps.
Textual items are defined in the resource script file, which is described in
Resource Script File. Non-textual items are defined and saved in other files,
and are referenced by statements in the resource script file. The various
types of Presentation Manager resource are described in the following sections.
ΓòÉΓòÉΓòÉ 19.1.1. Fonts ΓòÉΓòÉΓòÉ
A font is a set of alphanumeric characters and other symbols. Fonts may be
designed interactively using the Font Editor application provided as part of
the IBM Developer's Toolkit for OS/2 2.0. Once a font has been designed, the
Font Editor saves the font in a disk file with an extension .FNT. This font
file is referenced from the resource script file using the FONT keyword:
FONT 123 MYFONT.FNT
The integer following the FONT keyword is used to identify the font resource.
A symbolic name cannot be used to define a font resource.
A font file must be link-edited along with a resource script file containing a
FONT keyword referencing the .FNT file, and with the FONTS.OBJ and FONTS.DEF
files provided with the OS/2 Programmer's Toolkit, to produce a file with an
extension of .FON. Although a font cannot be stored in a dynamic link library,
the .FON file may be installed on the system by the user or installed
explicitly by an application. The font is then usable by any application in
the system. Alternatively, an application developer may choose not to install
the font, but merely to access it from a particular application using the
GpiLoadFonts() function.
ΓòÉΓòÉΓòÉ 19.1.2. Icons, Pointers and Bitmaps ΓòÉΓòÉΓòÉ
As already mentioned, an icon is a graphical representation of an object on the
screen. For the purposes of discussion, icons, pointers and bitmaps will be
grouped together; a pointer is a graphical image that is associated with a
pointing device such as a mouse, and which moves on the screen as the pointing
device is moved by the user, whereas a bitmap is a graphical image that
typically is used to represent a general item such as a logo. Icons, pointers
and bitmaps may be designed interactively using the Icon Editor application
supplied as part of the OS/2 Version 2.0 product. Depending on which resource
is being created, the Icon Editor saves the resulting icon, pointer or bitmap
in a file with an extension of ICO, PTR or BMP. These files are then
referenced from the resource script file using the ICON, POINTER or BITMAP
keywords:
ICON MAIN APPLIC.ICO
POINTER DRAW PENCIL.PTR
BITMAP INTRO LOGO.BMP
The keyword is followed in each case by a resource identifier, which is a
symbolic name used by the application to identify the resource. For an icon,
the identifier is used as a parameter to the WinCreateWindow() and
WinCreateStdWindow() calls, and identifies the icon resource to be used when
the FCF_ICON attribute is specified for the frame window. In all cases, the
symbolic name must be defined as an integer constant using a #define statement.
For a pointer or bitmap, the identifier is used as a parameter to the
WinLoadPointer() or GpiLoadBitmap() functions, which load the resource into
memory. WinLoadPointer() returns a pointer to the resource in memory, which
may then be used as a parameter to the WinSetPointer() function, in order to
set the desktop pointer to that resource.
A pointer may be set to one of the system-defined pointer styles (such as an
arrow or hourglass) using the WinSetPointer() function, by obtaining the handle
of the required system pointer using the WinQuerySysPointer() function as
follows:
rc = WinSetPointer(HWND_DESKTOP,
WinQuerySysPointer(HWND_DESKTOP,
SPTR_WAIT,
FALSE));
This call will set the pointer for the desktop to the hourglass pointer
(indicated by the symbolic name SPTR_WAIT). The handle of the hourglass
pointer is returned by the WinQuerySysPointer() call. The symbolic names of
the various system pointers are described along with the WinQuerySysPointer()
function in the IBM OS/2 Version 2.0 Presentation Manager Reference.
A bitmap is drawn within a window on the screen using the WinDrawBitmap()
function. The pointer to the bitmap, returned by GpiLoadBitmap() is passed as
a parameter to WinDrawBitmap() in order to identify the resource.
ΓòÉΓòÉΓòÉ 19.1.3. Menu Bars and Pulldown Menus ΓòÉΓòÉΓòÉ
Menu bars and their associated pulldown menus are defined within the resource
script file, using the MENU and SUBMENU keywords. A sample menu bar and
pulldown menu definition is shown in Figure "Menu Bar Resource Definition".
The symbolic name (MAIN in the example above) identifies the resource. This
name is passed as a parameter to the WinCreateWindow() and WinCreateStdWindow()
functions and identifies the menu bar resource when the FCF_MENU style frame
control flag is specified for the frame window. The PRELOAD option specifies
that the resource will be incorporated into the application's main .EXE file,
and is to be loaded immediately into memory, rather than being loaded when
called by the application.
The SUBMENU statement defines a menu bar entry that will be associated with a
pulldown menu. MENUITEM statements that are enclosed within the BEGIN and END
markers of a SUBMENU statement define the pulldown menu items. MENUITEM
statements that are not enclosed within the bounds of a SUBMENU statement
define menu bar entries that do not have an associated pulldown menu.
The text strings within quotation marks define the text for each menu bar or
pulldown menu item. The symbolic name following the text identifies the value
(placed in the first message parameter) of the WM_COMMAND message generated
when the item is selected. The symbolic names following the message identifier
define the style of the item. In the example above, all items are simple text
items and are defined with the style MIS_TEXT. The sole exception is the final
"Help" menu bar item, which is defined with the style attributes of MIS_HELP,
which causes the item to generate a WM_HELP message rather than a WM_COMMAND
message, and MIS_BUTTONSEPARATOR, which causes the item to be displayed on the
right-hand side of the menu bar separated by a vertical bar, in accordance with
SAA CUA guidelines. The various item styles and attributes are documented in
the IBM OS/2 Version 2.0 Presentation Manager Reference.
When groups of items within a single pulldown menu are logically separate, they
should be visually separated by a horizontal bar within the pulldown menu.
This may be achieved using the SEPARATOR keyword in the MENUITEM statement, as
follows:
MENUITEM SEPARATOR
The use of a separator bar in pulldown menus is particularly important when the
pulldown menu is used to display a list of entries, comprised of multiple sets
of mutually exclusive options, from which the user must select one option from
each set. In such a case, the separator bar is used to group the items within
each set, and to visually separate the sets from one another.
As already mentioned, menu bar resources are typically incorporated into a
window by specifying their resource identifier in a WinCreateWindow() or
WinCreateStdWindow() call, with the FCF_MENU frame creation flag set for the
frame window. A submenu within a menu bar resource may also be dynamically
created using the WinCreateMenu() function, which is described in The Menu Bar.
Mnemonics
Mnemonics may be specified for menu bar and pulldown menu items. A mnemonic is
a key which, when combined with the F10 key, results in selection of the item.
The character for the mnemonic must be part of the text for the item. For
example, the conventional mnemonic key for the "Exit" menu bar item is "x";
when the F10 key is pressed followed by the "x" key, a WM_COMMAND message with
value MI_EXIT is generated.
Mnemonics are indicated to the user by the appropriate character within the
item text being underlined. This is achieved by placing a tilde character (~)
within the item text, immediately prior to the required character; for example:
MENUITEM "E~xit", MI_EXIT, MIS_TEXT
When the resource script file is compiled using the resource compiler, the menu
bar item is created with the appropriate mnemonic.
Accelerator Keys
Accelerator keys or key sequences may be used to represent a pulldown menu item
and provide a "fast path" to a particular command. Note that accelerator keys
are not used to represent menu bar entries, since the use of an accelerator key
sequence is typically more complex than the use of a mouse or an F10 + single
character operation. The definition of accelerator keys is described in
Accelerator Tables. It is conventional to display an accelerator key sequence,
along with the command represented by that sequence, in the pulldown menu, thus
providing the user with a visual indication of the accelerator key sequence.
This may be achieved by the use of the "\t" or "\a" control codes within the
item text. The "\t" code causes text to the right of the code to be
left-justified in a new column, whereas the "\a" code causes text to the right
of the code to be right-justified in a new column.
To display an accelerator key sequence in a pulldown menu, it is conventional
to use the "\t" control code. For example:
MENUITEM "~Tile\tShift+F5", MI_TILE, MIS_TEXT
This would result in the item text "Tile" (with the "T" underscored to
represent the mnemonic) being displayed in the left of the pulldown menu with
the text "Shift+F5" being left-justified in a second column to the right of the
item text.
ΓòÉΓòÉΓòÉ 19.1.4. String Tables ΓòÉΓòÉΓòÉ
Tables of text strings may be defined within a resource script file for use by
an application. A string table is defined using the STRINGTABLE keyword, as
shown in Figure "String Table Resource Definition".
String tables may be used to contain titles, messages and other common text
used by an application. The external definition of these strings makes it easy
to change a title or message without modifying source code. String tables may
also be used to contain menu bar or pulldown menu text for dynamic insertion by
an application. Special characters such as mnemonic indicators and tab
characters for columnating display may be incorporated into the string
definition.
The symbolic name following the STRINGTABLE keyword identifies the string table
and is used as a parameter when loading strings from the resource into
application buffers using the WinLoadString() function. The PRELOAD keyword
specifies that the resource will be incorporated into the application's main
.EXE file, and is to be loaded into memory immediately rather than being loaded
when called by the application.
Multiple string tables may be defined by an application. Each string table
must have its own symbolic name (note that the same name may be used for a
string table and another type of resource such as a menu bar) and is enclosed
within the BEGIN and END keywords of a STRINGTABLE statement. Each string has
its own symbolic name within the string table.
As mentioned above, strings are loaded from the string table into application
buffers using the WinLoadString() function. For example, to load the string
STR_MAINTITLE from the string table MAIN into a buffer named szTitle, the
function shown in Figure "Loading a Text String Resource" is used.
The WinLoadString() function returns an unsigned integer representing the
number of characters loaded into the target buffer. Once loaded, the buffer
may then be manipulated using standard programming language functions, or used
as a parameter to other Presentation Manager function calls.
ΓòÉΓòÉΓòÉ 19.1.5. Accelerator Tables ΓòÉΓòÉΓòÉ
Accelerator keys are single keys or key sequences that are used to represent a
particular command (typically a pulldown menu item) within an application, and
provide a fast path for the entry of that command. Accelerators are defined
for an individual window and are active whenever that window is active.
According to Systems Application Architecture CUA conventions, accelerator keys
should be indicated to the user by placing the accelerator key sequence
alongside the command in the pulldown menu. Accelerator keys are defined in
the resource script file using the ACCELTABLE keyword, as shown in Figure
"Accelerator Table Resource Definition".
The symbolic name following the ACCELTABLE statement identifies the accelerator
resource, and is passed as a parameter to the WinCreateWindow() or
WinCreateStdWindow() functions when the FCF_ACCELTABLE style attribute is
specified for the frame window.
In the above example, the F3 key is defined as a virtual key that when pressed
will generate a WM_COMMAND message with the value MI_EXIT. This is equivalent
to the user having selected the "Exit" option from the menu bar. The Shift+F5
key sequence is also defined as a virtual key that will generate a WM_COMMAND
message with the value MI_TILE. Note that the shifted state of the key is
indicated by use of the SHIFT option. The Ctrl+D key sequence has also been
defined to generate a WM_COMMAND message with the value MI_DELETE. The Ctrl
state of the key is indicated by the use of the CONTROL option (in a similar
manner to the SHIFT option on the previous line). The various options for
defining accelerator keys are documented in the IBM OS/2 Version 2.0
Presentation Manager Reference.
As already mentioned, an accelerator table is associated with a particular
window by specifying the resource identifier as a parameter to the
WinCreateWindow() or WinCreateStdWindow() functions. In addition, the
WinLoadAccelTable() function may be used to dynamically load an accelerator
table into memory. The WinLoadAccelTable() function returns the handle of the
accelerator table in memory, which may then be passed as a parameter to the
WinSetAccelTable() function to activate the accelerator table for a particular
queue or window.
ΓòÉΓòÉΓòÉ 19.1.6. Help Tables ΓòÉΓòÉΓòÉ
Help tables are used by the IPF to relate each display window, dialog box or
control window to the help panel containing information about that window.
Help tables and their definition are described in detail in Adding Online Help
and Documentation.
ΓòÉΓòÉΓòÉ 19.1.7. Window and Dialog Templates ΓòÉΓòÉΓòÉ
Templates defining standard windows and dialog boxes may be defined within the
resource script file. Typically, a window or dialog template is designed using
the Dialog Box Editor application supplied with the IBM Developer's Toolkit for
OS/2 2.0, and is saved in a text file with an extension .DLG which is included
in the resource script file with an rcinclude statement. A window or dialog
template may also be defined directly into the resource script file. In either
case, the template is defined using the WINDOWTEMPLATE or DLGTEMPLATE keywords.
These keywords are actually synonymous, and the resource compiler interprets
either keyword in the same way.
Within a single window or dialog template, there may be multiple WINDOW or
DIALOG statements that define individual windows or dialog boxes. The nesting
of the statements defines the parent/child window hierarchy. Figure "Window
Template Resource Definition" shows an example of nested windows within a
window template.
The window template WCP_001 contains a frame window with the title "Window
Class X" and with size and positional coordinates as specified. The style
attributes of the frame window are specified using the CTLDATA statement. The
client window for this frame window is created using the WINDOW keyword nested
within the window template, with no window title, the identifier FID_CLIENT, no
size or positional coordinates (these are defined by the frame window), the
class "MyClass" and the default client style.
The use of the WINDOWTEMPLATE keyword and WINDOW statements is a useful way for
an application developer to predefine particular window types and styles for
use by one or more applications. The template definitions may be used to
create modal dialog boxes, which are loaded into memory and executed by the use
of WinLoadDlg() and WinProcessDlg() calls. Definitions may also be created for
standard windows or modeless dialog boxes, which are loaded into memory using
the WinLoadDlg() function and executed by making the window or dialog box
visible using the WinShowWindow() function.
Predefinition of windows is particularly useful when applied to dialog boxes.
Here, the number and complexity of control window definitions is often such
that creating such windows dynamically is a complicated task. A dialog box is
defined in the resource script file (or a .DLG file, which is incorporated into
the resource script file using the rcinclude statement) using the DLGTEMPLATE
keyword.
Within a dialog template, there may be multiple dialogs defined using the
DIALOG statement, and each dialog box may have multiple control windows defined
using CONTROL keywords. Figure "Dialog Template Resource Definition" shows an
example of a dialog template containing a dialog box with several control
windows:
The dialog template is equivalent to a frame window, and is named DC_CREATE.
This symbolic name is used to identify the dialog resource and is passed as a
parameter to the WinDlgBox() function, which loads and processes the dialog
box.
The dialog box is defined with a title bar and a dialog border, and is also
named using the symbolic name DC_CREATE. The dialog box contains a static text
control window providing instructions to the user, and an entry field into
which the user may enter text. It also contains an "Enter" and a "Cancel"
pushbutton.
Note that the resource identifier for the static text string does not use a
symbolic constant, but simply has the value "-1". This is done because there
is no need for the application to access the text string; it is merely present
as a prompt to the user. It is therefore conventional to omit the symbolic
constant and use "-1" as the value. Multiple text strings may have the same
value.
ΓòÉΓòÉΓòÉ 19.2. Resource Script File ΓòÉΓòÉΓòÉ
The resource script file is an ASCII text file in which Presentation Manager
resources are either defined or referenced. A sample resource script file is
given in Figure "Resource Script File".
Note that the dialog templates are not defined directly in the resource script
file, but are incorporated at the end of the resource script file using an
rcinclude statement for the file mydlg.dlg. This is the typical way to
incorporate dialog templates that are created by the Dialog Box Editor and
stored in a DLG file.
The resource script file has a number of #include statements at the start,
similar to those typically found in C programs. This is because the symbolic
names used throughout the resource script file represent integer constants, and
must be defined in the application's header file myappl.h. Other symbolic names
may be used in the .DLG file, and must also be defined; the header file
mydlg.h for these symbolic names is generated by the Dialog Box Editor.
Finally, a number of symbolic names such as DID_OK and DID_CANCEL are actually
defined by Presentation Manager rather than by the application, and therefore
the file os2.h is also required.
The resource script file is used as input to the resource compiler provided as
part of the IBM Developer's Toolkit for OS/2 2.0. For further information on
the resource compiler and its operation, see Resource Compilation.
ΓòÉΓòÉΓòÉ 19.3. Using Resources ΓòÉΓòÉΓòÉ
As mentioned throughout this chapter, resources are typically loaded and used
in an application by specifying the symbolic name of the resource as a
parameter to a function that requires the resource. The resource is then
loaded and used by that function in performing its task. However, there are
several ways in which the resource may be loaded, depending upon where it
resides. These are discussed in the following sections.
ΓòÉΓòÉΓòÉ 19.3.1. Loading From Within the Application ΓòÉΓòÉΓòÉ
In the typical case, resources are incorporated into an application by passing
the resource script file to the resource compiler. The resource compiler
compiles the resource definitions and incorporates them into an executable file
that has already been created.
Many of the functions that require a resource identifier, such as
WinLoadString() and WinLoadPointer(), also accept the identifier of a resource
file as one of their parameters. For resources that are incorporated into the
application's .EXE file, this parameter should be specified as NULL. For
example, to load a pointer from a resource defined within the .EXE file, the
following call is used:
hPointer = WinLoadPointer(hDesktop, /* Desktop handle */
NULL, /* Within .EXE file */
DRAW); /* Resource symbolic name */
Other Presentation Manager functions that use this convention include
WinLoadAccelTable(), WinLoadMenu() and WinCreateStdWindow().
ΓòÉΓòÉΓòÉ 19.3.2. Loading Resources From a DLL ΓòÉΓòÉΓòÉ
Presentation Manager resources may also be defined and stored in a dynamic link
library. The process of compiling and placing resources in a DLL is described
in Presentation Manager Resources in a DLL. Once a resource is located in a
DLL however, the DLL module must be loaded into memory by the application, and
a module handle obtained at run time before the resource may be accessed by a
Presentation Manager function. This is typically achieved using the
DosLoadModule() or DosGetModuleHandle() functions. Figure "Loading Resources
From a DLL" illustrates the necessary code to load a dynamic link library named
MYDLL from a directory identified in the LIBPATH statement in CONFIG.SYS, and
to load a string resource from this DLL.
The DosLoadModule() function call loads the dynamic link library with the name
"MYDLL" (the default extension of .DLL is assumed) into memory and returns a
handle hModule of type HMODULE. This handle is then passed as the resource
file identifier to the WinLoadString() function call, which accesses the
resources within the module. Other function calls such as WinLoadPointer()
work in a similar manner.
ΓòÉΓòÉΓòÉ 19.3.3. Loading Dialogs From a DLL ΓòÉΓòÉΓòÉ
The WinDlgBox() function also allows a DLL module handle to be specified, and
thus enables dialog template definitions to be loaded from a DLL. For instance,
to load and create a dialog box from a dialog template resource DC_001 defined
in a DLL module named WINDLL.DLL, the following call sequence is used:
rc = DosLoadModule(NULL, /* No object name */
0, /* No object length */
"MYDLL", /* DLL module name */
hModule); /* DLL handle (returned) */
rc = WinDlgBox(hDesktop, /* Desktop is parent */
hFrame, /* Frame is owner */
dpProc001, /* Dialog procedure address */
hModule, /* DLL module handle */
DC_001, /* Resource ID within DLL */
NULL); /* No create parameters */
Note that if the dialog procedure dpProc001 to be associated with this dialog
box is also defined within the DLL module, the address of this procedure must
be obtained by the application before the WinDlgBox() call is issued. This is
achieved using the DosGetProcAddr() function, which returns the address of the
required function, as shown in the following example:
rc = DosGetProcAddr(hModule,
"Proc1",
dpProc001);
In this case, Proc1 is the name of the required entry point in the DLL module,
and dpProc001 is a variable of type PFNWP which contains the address of the
procedure returned by the DosGetProcAddr() call. While the address of the
dialog procedure could have been supplied implicitly by using load-time rather
than run-time dynamic linking, run-time dynamic linking is necessary to load
the dialog box resource, and it is logical to place the resource and its
associated dialog procedure in the same DLL module. An example of the complete
procedure required to load a dialog box from a DLL is given in Figure "Loading
a Dialog Resource From a DLL".
When loading dialogs from DLL modules, it is recommended that a combination of
load-time and run-time dynamic linking techniques be used. A calling routine
should be placed in the DLL which, in response to an application request, loads
and obtains the appropriate module handle, obtains the required dialog
procedure address and executes the dialog. This relieves the application of
the responsibility for loading the dynamically-linked resources and routines.
An example of such a routine is given in Figure "Loading a Dialog Resource From
a DLL". The calling routine CustInfoDlg is defined as an entry point within
the DLL module, since it will be called from the application's main executable
module. An import library is then built for the DLL, and linked with the
application code using standard conventions for load-time dynamic linking.
When CustInfoDlg is invoked by the application, it obtains a module handle for
its own DLL module, which has already been loaded when the call to CustInfoDlg
was made, and uses this handle to obtain the address of the required dialog
procedure using standard run-time dynamic linking conventions. It then issues
a WinDlgBox() call to load and process the dialog box, and returns the result
to the application. This example illustrates the combination of load-time and
run-time dynamic linking conventions.
ΓòÉΓòÉΓòÉ 19.4. Resources and National Language Support ΓòÉΓòÉΓòÉ
Since Presentation Manager resources provide the ability to define all the user
interface properties of a Presentation Manager application, externally to the
application code, they provide a useful means for implementing national
language support within Presentation Manager applications. Resources may be
used to define:
Window titles
Menu bar and pulldown menu entries, including mnemonics and accelerator keys
Dialogs
Messages
Symbols such as icons and pointers.
In short, all of the language-specific properties of an application may be
defined using Presentation Manager resources. Icons and other graphical
symbols used by the user interface may also be tailored to suit different
cultures where such symbols may have different meanings.
The set of resources for each national language may be compiled and
incorporated into a separate dynamic link library, which may be accessed by the
application in order to load the required resources, as described in Loading
Dialogs From a DLL. The resource identifiers must, of course, be identical in
each DLL. Upon installation of the application on a workstation, an
installation procedure can prompt the user to determine the required language,
and install the appropriate DLL for that language.
Where multiple languages must be supported in the same system, an application
may query the codepage currently in use by its parent process using the
WinQueryCp() function, and load resources from a specific DLL, depending upon
the result of the function call. While this method is by no means foolproof,
it will suffice for many languages that use a single national codepage and
single-byte characters.
ΓòÉΓòÉΓòÉ 19.5. Summary ΓòÉΓòÉΓòÉ
It can be seen that Presentation Manager provides the mechanism by which an
application developer may externally define the user interface properties of
his/her application. This ability provides the benefit that these external
properties may be modified, or different versions substituted, without the need
to modify the application code itself. In addition, standard user interface
objects such as icons, pointers and dialog boxes, along with their associated
dialog routines, may be defined and stored in dynamic link libraries for use by
multiple applications.
Resources are defined using a resource script file, which is an ASCII text file
containing definitions for text-based resources and references to other files
that contain definitions for non-textual resources such as pointers and icons.
The resource script file is used as input to the resource compiler, which
compiles resource definitions and incorporates them into an executable module.
Resources may be incorporated into the application's main .EXE file, or may be
stored in a dynamic link library and loaded into memory using run-time dynamic
linking. Application procedures such as dialog procedures, which are
associated with such resources, may also be defined and stored in the same DLL
module, thus providing the opportunity to create libraries of standard
resources, including standard dialogs, which may be used by multiple
applications.
ΓòÉΓòÉΓòÉ 20. Multitasking Considerations ΓòÉΓòÉΓòÉ
Systems Application Architecture CUA guidelines recommend that an application
should complete the processing of a user- or system-initiated event within 0.1
seconds and be ready to continue interaction with the end user. The particular
implementation of the message handling concept under Presentation Manager means
that the application's primary thread must complete the processing of a
Presentation Manager message before any further messages can be passed to
applications; thus it is possible for the user to be "locked out" of the system
if an application does not complete its processing within a reasonable period
of time.
While the 0.1 second time period is adequate for the processing of most events,
it may be insufficient for those that result in lengthy processing such as
access to a remote system. It is therefore recommended that any window
procedure performing some processing that is likely to take longer than 0.1
seconds to complete should carry out this processing using a separate thread of
execution under OS/2. The application's primary thread may then initiate the
secondary thread and immediately return control to Presentation Manager,
thereby enabling the primary thread to continue with user interaction.
The separation of processing into a primary and one or more secondary threads
may occur in a number of ways:
Where the window procedure is an object window procedure, and the majority of
its methods may result in lengthy processing, the window procedure itself may
be implemented in a secondary thread.
Where only a single method results in lengthy processing, or where the
window procedure is concerned with a display object, a single subroutine
containing that method may be started in a secondary thread.
In certain circumstances where the different portions of an application's task
are entirely self-contained, and where it is desirable to isolate the portions
from one another, the application may be divided into separate processes.
Division of the application in this way means that each portion resides and
executes in its own address space, fully protected from other portions of the
application. This approach is particularly useful for applications that
exploit the Workplace Shell, since the implementation of the Workplace Shell
in OS/2 Version 2.0 causes Workplace Shell objects to execute, by default,
under the control of the Workplace Shell process. The use of multiple
processes within an application provides better protection for resources used
by Workplace Shell objects.
Note that for performance reasons, the use of multiple threads within the same
process is preferable to the use of multiple processes. This is because
switching between threads involves far less system overhead than switching
between processes.
Processes and threads may communicate with one another in a number of ways for
the purposes of exchanging information, and for synchronizing execution flow
and access to data objects. The techniques of communication between threads
and processes are described in Communicating With a Secondary Thread and
Communicating With Another Process.
Maintaining synchronization between threads and processes is discussed in
Maintaining Synchronization.
ΓòÉΓòÉΓòÉ 20.1. Creating a Secondary Thread ΓòÉΓòÉΓòÉ
In Application Structure, it is mentioned that an application must create its
own input message queue to process messages intended for its windows. The
Presentation Manager message-handling implementation creates message queues on
a per-thread basis, and thus requires that any thread that creates a window
(whether that window is a display window or an object window) and processes
messages must have its own message queue.
The primary thread of an application is typically a user interface thread that
handles processing for display windows on the screen; this thread creates the
application's main message queue and processes messages caused by user
interaction. The primary thread may also create a secondary thread to deal
with messages that cause lengthy processing to be carried out, leaving the
primary thread free to respond to user input. A secondary thread may be
created in one of two ways:
The _beginthread() function provided by the C compiler should be used to
create secondary threads that will contain object windows, or that contain
code which calls C run-time library functions. This function maintains
certain internal C library control data that is, by default, not maintained
by the DosCreateThread() function.
The DosCreateThread() function provided by OS/2 may be used to create
secondary threads that will not contain object windows, and that do not call
C run-time library functions. The DosCreateThread() function offers a
slight performance advantage over the _beginthread() function.
The _beginthread() function is used since it establishes internal semaphores
to serialize access to the run-time library's global data and non-reentrant
library functions, transparently to the calling application. The
_beginthread() function also maintains information for each thread, such as
the exception handling environment and the calling address for reentrant
functions. Since window procedures are reentrant, use of DosCreateThread() in
such situations may cause execution errors.
Whenever a thread is created, a thread information block (TIB) is created by
the operating system. The TIB contains information such as the thread ID,
priority and stack size. This information may be accessed by the application
using the DosGetInfoBlocks() function. This function also returns a pointer to
information on the thread's parent process, which resides in the process
information block (PIB). The DosGetInfoBlocks() function is described in the
IBM OS/2 Version 2.0 Control Program Reference.
ΓòÉΓòÉΓòÉ 20.1.1. Threads Containing Object Windows ΓòÉΓòÉΓòÉ
In the case where the processing of an event involves access to and
manipulation of another data object, the secondary thread should create its own
message queue and one or more object windows with window procedures to process
any messages passed by the primary thread. This technique preserves the
object-oriented nature of the application by isolating data objects from one
another.
The primary thread then passes messages to the secondary thread's object
windows, in an identical manner to that used when passing messages to a window
procedure in the primary thread; it is recommended that this be achieved using
the WinPostMsg() function, since this call allows asynchronous processing of
the message and preserves the correct serialization of messages in the system,
as described in Window Procedures (Invoking a Window Procedure).
Asynchronous threads with object windows are normally created by window
procedures in the application's primary thread issuing a _beginthread()
function call. This call is typically made by a window procedure during its
processing of the WM_CREATE message; the secondary thread and its object
window (or windows) are then initialized and able to accept any requests
passed to them. An example of the _beginthread() function is shown in Figure
"Creating a Thread With an Object Window".
Note that when using the IBM C Set/2 compiler, the second parameter in the
_beginthread() function call (the pointer to the stack) is ignored, since the
_beginthread() function automatically allocates memory for the stack. This
parameter is included merely to allow source code compatibility with
applications written for the earlier IBM C/2 and Microsoft C compilers, which
required the application to explicitly allocate stack space for a secondary
thread. Note that the minimum recommended stack size for a thread containing
object windows is 8192 bytes (8 KB).
The handle of the window from which the secondary thread is being created is
passed to the thread in the _beginthread() call. The secondary thread's main
routine may then pass this handle to the object window created in the thread.
Upon successful creation, the object window can then pass an acknowledgement
message back to the window that created it, containing the handle of the object
window, in order that the calling window may then post messages to the object
window. This acknowledgement message also ensures that the object window is
correctly created and initialized before any messages are posted to it.
The secondary thread's main routine is similar in structure to the main routine
of the primary thread in a Presentation Manager application. The main routine
registers the object window class, creates a window of that class and enters a
message processing loop.
It should be noted that the secondary thread's main routine is identical to
that of the application's primary thread, with the exception that a secondary
thread need not register itself to Presentation Manager, since this is
typically done once per application, by the primary thread. However, if
certain functions such as error processing are required on a per-thread basis,
a separate anchor block must be created for the secondary thread, and hence an
additional WinInitialize() call must be made.
Figure "Secondary Thread Creating an Object Window" shows a secondary thread
that registers an object window class and creates a window of that class.
An object window is created using the normal WinCreateWindow() call, as
illustrated in Figure "Secondary Thread Creating an Object Window". The
window's parent is specified as the conceptual object window, the handle of
which is obtained from the WinQueryObjectWindow() function, or using the
defined constant HWND_OBJECT. Note that the handle of the window that created
the thread is passed to the object window in the CtlData parameter of the
WinCreateWindow() call, in order that the object window may pass its handle
back to the calling window to indicate its readiness to receive messages.
The secondary thread retrieves messages from its input queue in the
conventional manner using WinGetMsg(), and invokes Presentation Manager using
WinDispatchMsg() to pass the message to its object window procedure. Thus a
secondary thread has a message processing loop similar to that of the
application's (primary thread's) main routine.
An object window procedure is identical in structure to a "normal" display
window procedure. An example of an object window procedure is illustrated in
Figure "Sample Object Window Procedure".
Upon creation, an object window receives a WM_CREATE message in the same way as
a standard window. The window may capture and explicitly process this message
in order to open or create data objects, initialize instance data, etc., as
illustrated in Figure "Sample Object Window Procedure". Once opened, however,
an object window typically only receives a number of application-defined
messages requesting certain actions on data objects owned by the window.
The object window procedure shown in Figure "Sample Object Window Procedure"
also extracts the handle of the window that issued the WinCreateWindow()
function call, which is normally passed to the object window as part of the
WM_CREATE message. The window procedure then uses this handle to send an
acknowledgement message back to this window, containing its own window handle
and thus enabling the two windows to communicate with one another. This is
necessary when object windows are created in secondary threads, as described in
Communicating With a Secondary Thread. Note that the object window procedure
must use the system linkage convention; this is achieved using the EXPENTRY
keyword.
The only other system-defined message class normally received by an object
window is the WM_DESTROY message class passed to the window by Presentation
Manager when a WinDestroyWindow() call is issued by the thread. An object
window should respond to the WM_DESTROY message by closing, destroying or
freeing any data objects to which it has obtained access, and backing out any
uncommitted units of work.
Figure "Sample Object Window Procedure" shows a number of application-defined
message classes being processed by the object window procedure. These message
classes are typically defined by the application during its initialization.
For message classes that will be processed by an object window procedure loaded
from a DLL module, the message classes should be defined in the include file
for that DLL module, rather than explicitly within the application that uses
the DLL module. This further enhances the isolation of the internal workings
of the object window from other components of the application, and facilitates
reusability of the code.
The window procedure in the primary thread must have some way of determining
when the object window has completed its processing, at which point it may
safely assume that the previous event has been processed successfully and allow
the user to continue operating upon the data object, or take appropriate error
action. This indication may be provided in a number of ways, which are
discussed in Maintaining Synchronization.
ΓòÉΓòÉΓòÉ 20.1.2. Threads Without Object Windows ΓòÉΓòÉΓòÉ
When the processing to be performed within a secondary thread is limited in
scope to the data objects "owned" by the current application object, an object
window is not warranted. A secondary thread without an object window is
similar in both appearance and behavior to a normal subroutine. However, the
routine executing in the secondary thread performs its tasks asynchronously to
the primary thread, although it still has access to the same data objects.
Such a thread is typically started when required by issuing a DosCreateThread()
call from within a window procedure in the primary thread. A sample invocation
of such a thread is illustrated in Figure "Creating a Thread Without an Object
Window".
Two considerations arise when processing asynchronous threads without the use
of object windows:
The primary thread must not attempt to access a data object at the same time
as a secondary thread is updating that data object, since the state of the
data during the update is undetermined and unpredictable results could occur.
The primary thread must have some way of determining when the secondary
thread has completed its processing, at which point it may then access the
data objects that were manipulated by the secondary thread.
These two conditions may be achieved by adopting a convention whereby a
secondary thread has exclusive access to its data object(s) for the duration of
its execution. It is therefore only necessary for the primary thread to
determine when the secondary thread has completed processing, at which point
it may access the data objects.
Where this is not possible, mutex semaphores may be used to serialize access
to resources such as data objects. Each thread that requires access must bid
for the semaphore. If the semaphore is already held by another thread, the
requesting thread must wait for that thread to release the semaphore before
attempting to access the resource.
A number of mechanisms for synchronizing execution and/or access to resources
are described in Maintaining Synchronization.
ΓòÉΓòÉΓòÉ 20.2. Creating Another Process ΓòÉΓòÉΓòÉ
Each application running under OS/2 typically resides in its own process, and
therefore has its own address space. Resources created by or allocated to a
process are normally private to that process. If required for application
purposes, this process may in turn create one or more additional processes to
perform part of the application's processing. Additional processes may be
created in either of two ways:
As a child process of the creating process, in which case the child process
will automatically terminate upon termination of the creating process. Such
processes are started using the DosExecPgm() function.
As a separate process, in which case the process will not automatically
terminate when its creator terminates, and must be explicitly terminated
either by its creator or by another process in the system. Such a process is
started using the DosStartSession() function.
When an application uses multiple processes, it is usual for the first process
to be regarded as the "primary" process for the application, and for other
processes to be started as children of this process. This is conceptually
similar to the use of primary and secondary threads.
It is therefore conventional to use the DosExecPgm() function to start a child
process. This function is illustrated in Figure "Starting a Child Process".
The window handle of the window from which the DosExecPgm() call is made, is
passed to the child process as an argument, using the the fourth parameter of
the DosExecPgm() function. This enables the child process to post a message
to its parent upon completing its initialization, indicating the window handle
of its own window. In this way, communication via Presentation Manager
messages may be established in both directions.
Note that since the fourth parameter to the DosExecPgm() function is defined
as an ASCII string, the window handle is converted to its ASCII equivalent
before the call is issued. The main routine of the child process subsequently
converts the handle back to its true form.
Use of the EXEC_ASYNCRESULT flag in the DosExecPgm() call causes the operating
system to save the termination codes of the child process so that they may be
examined at a later point by the parent process, using a DosWaitChild()
function call for synchronization purposes (see Figure "DosWaitChild()
Function" for further information).
The process ID of the child process is returned by the DosExecPgm() function
as part of the RESULTCODES structure in the sixth parameter. This value should
be stored by the parent process, since it is used if and when the parent
process needs to terminate the child at some later point during execution.
ΓòÉΓòÉΓòÉ 20.3. Destroying a Secondary Thread ΓòÉΓòÉΓòÉ
Secondary threads should be terminated when they are no longer required, to
reduce the context-switching overhead of the operating system. The method of
termination depends upon how the secondary thread was created, and whether or
not it has created object windows.
ΓòÉΓòÉΓòÉ 20.3.1. Threads Containing Object Windows ΓòÉΓòÉΓòÉ
A secondary thread with an object window should be terminated by the window
procedure in the primary thread that initially created the secondary thread.
This is achieved simply by posting a WM_QUIT message to the object window,
which will cause the message processing loop for the secondary thread to
terminate.
The thread's main routine then issues WinDestroyWindow() calls for its object
windows. These calls cause WM_DESTROY messages to be posted to the object
windows, which will process these messages in order to close data objects,
release any resources, etc., in accordance with established conventions.
Once all data objects and other resources have been released or destroyed, the
thread should terminate itself using the _endthread() function. The use of this
function will ensure that the semaphores and control structures used by the
_beginthread() function are correctly reset.
ΓòÉΓòÉΓòÉ 20.3.2. Threads Without Object Windows ΓòÉΓòÉΓòÉ
Secondary threads without object windows are typically created to perform a
lengthy processing operation within the scope of a single event. A window
procedure under the control of the primary thread creates the secondary thread
to process a particular subroutine, and the secondary thread terminates
automatically when this subroutine reaches an exit point. However, the
DosExit() function should be called as the last action in the secondary thread,
in order to ensure that the memory allocated for the thread's stack is
correctly released by the operating system.
However, some checks may be necessary to ensure orderly termination of a
secondary thread, particularly where access to data objects is involved. Upon
termination of an application's primary thread, all secondary threads that
have not already been terminated by the application are forcibly terminated by
OS/2. Where the secondary thread's processing involves a critical data
operation such as the update of a database, the primary thread should ensure
that the secondary thread has completed its processing before allowing itself
to terminate.
It is recommended that before creating a secondary thread without an object
window, a window procedure should set an event semaphore, and pass the handle
of this semaphore to the secondary thread. The event semaphore is then cleared
by the secondary thread as the last action before it terminates.
Upon receiving a WM_DESTROY message, the window procedure in the primary thread
should test the state of the event semaphore and wait for the semaphore to
clear before completing the WM_DESTROY message processing (which should include
releasing the semaphore) and returning control to Presentation Manager. This
will ensure that the secondary thread terminates in an orderly manner before
the primary thread is terminated.
The use of event semaphores is described in more detail in Maintaining
Synchronization.
ΓòÉΓòÉΓòÉ 20.3.3. Forcing Termination of a Thread ΓòÉΓòÉΓòÉ
In certain circumstances, it may be necessary to terminate a secondary thread
without waiting for the thread to complete its processing; for example, the
user may decide to exit from the application. This capability is provided
under OS/2 Version 2.0 using the DosKillThread() function. This function is
illustrated in Figure "DosKillThread() Function".
Note that the DosKillThread() function cannot be used to terminate the current
thread; if the application attempts to issue a DosKillThread() function call
for the current thread, the function will return an error. To terminate a
secondary thread from within that thread, the _endthread() function should be
used if the thread was created with the _beginthread() function, or the
DosExit() function may be used if the thread was created using the
DosCreateThread() function.
ΓòÉΓòÉΓòÉ 20.4. Terminating a Process ΓòÉΓòÉΓòÉ
A process may terminate another process running in the system, provided it has
access to the process ID of the process it wishes to terminate. This process
ID is returned by the DosExecPgm() function when the process is created and
since, in the majority of cases, a process is terminated by the process that
created it, this presents no particular problem since the process ID can be
stored as a global variable or as instance data in window words, until it is
needed to terminate the process.
A process is terminated using the DosKillProcess() function. This function
may be used to terminate a single process, or to terminate a process and all
its descendants (that is, its children, along with their children, and so on).
An example of the DosKillProcess() function is given in Figure "Terminating a
Process".
The value of "1" specified for the first parameter in the DosKillProcess()
call causes the function to terminate only the specified process and not its
descendants (if any).
ΓòÉΓòÉΓòÉ 20.5. Communicating With a Secondary Thread ΓòÉΓòÉΓòÉ
The primary thread may wish to communicate with the secondary thread in order
to initiate an event or transfer data. The methods available for such
communication differ, depending upon whether the secondary thread contains an
object window.
ΓòÉΓòÉΓòÉ 20.5.1. Threads Containing Object Windows ΓòÉΓòÉΓòÉ
When a secondary thread is created, and in turn creates an object window as
shown in Figure "Secondary Thread Creating an Object Window", the handle of the
calling window may be passed to the object window as part of the WM_CREATE
message, and the object window procedure uses this handle to pass its own
window handle back to the calling window as part of an acknowledgement
message. This technique is illustrated in the sample object window procedure
shown in Figure "Sample Object Window Procedure".
Once the calling window receives this message and extracts the object window's
handle, it should store the handle in its own instance data. It may then use
the handle at any time to pass a Presentation Manager message to the object
window, in order to initiate an event in the object window.
By convention, messages passed to an object window should contain the window
handle of the calling window, within the message parameters. The object
window procedure may then use this handle to pass an acknowledgement message or
return data to the calling window in the primary thread. This technique allows
the same object window to process messages from multiple sources. See
Client-Server Applications for additional considerations.
Note that messages passed to object windows in secondary threads should be
posted using the WinPostMsg() function, rather than being sent using the
WinSendMsg() function. This causes asynchronous processing of the message, and
allows the primary thread to return to Presentation Manager and continue
interaction with the end user.
In situations where the user must be prevented from carrying out certain
actions while the object window processes an event, the calling window
procedure should disable those actions in the action bar immediately before
posting the message to the object window, and re-enable those actions only
after a completion message has been received from the object window. This
prevents the user from carrying out such actions, but does not prohibit other
actions within the application, or interaction with other applications on the
desktop.
ΓòÉΓòÉΓòÉ 20.5.2. Threads Without Object Windows ΓòÉΓòÉΓòÉ
Where a secondary thread is created only to process a specific event, and
where the thread terminates upon completion of that event, communication
between the primary and secondary threads is usually not required. Necessary
data is communicated to the secondary thread as part of the DosCreateThread()
function, including pointers to the data objects upon which the thread must
operate. The secondary thread then proceeds to process the event,
independently of the primary thread.
The only communication from the secondary thread to the primary thread occurs
upon completion of the event, when the secondary thread signals this
completion to the primary thread. Completion may be signalled by Presentation
Manager messages or via semaphores; see Maintaining Synchronization for further
discussion.
ΓòÉΓòÉΓòÉ 20.6. Communicating With Another Process ΓòÉΓòÉΓòÉ
Communication between processes must use one of the architected methods
provided by OS/2, since the operating system by default prohibits different
processes from accessing the same resources. For this reason, communication
between processes is slightly more complex than communication between threads,
but requires less care on the part of the programmer to ensure synchronization
and data integrity.
The mechanisms provided by OS/2 for interprocess communication are:
Presentation Manager messages
Shared memory
Queues
Pipes (both named and anonymous)
Atoms
Dynamic data exchange (DDE).
Each of these mechanisms is explained in detail in the IBM OS/2 Version 2.0
Application Design Guide, and simple examples are given in the following
sections.
ΓòÉΓòÉΓòÉ 20.6.1. Presentation Manager Messages ΓòÉΓòÉΓòÉ
When a child process creates its own windows, Presentation Manager messages can
be used to signal events and/or pass information between the parent and child
processes, provided the windows' handles are known to one another. One
technique for passing window handles during process creation is described in
Creating Another Process. Even where the child process does not create its
own windows, it may use Presentation Manager messages to indicate events and
pass information to its parent process.
The amount of information which can be passed in a Presentation Manager message
is somewhat limited, due to the four-byte size of each message parameter. The
use of Presentation Manager messages for passing information is therefore
typically combined with other mechanisms such as shared memory or atoms. The
message parameters are then used to carry pointers to shared memory objects, or
string handles that are then used by the child process to access the required
information.
ΓòÉΓòÉΓòÉ 20.6.2. Shared Memory ΓòÉΓòÉΓòÉ
Shared memory objects may be allocated and used to pass information between
specific processes. Such memory objects may be named or anonymous.
The example that follows assumes that two processes are created in the system:
a client process that accepts user input and displays results, and a server
process that accepts requests from the client, accesses data objects and
returns the requested data to the client. Both of these processes create
windows.
In order to communicate a request to the server, the client must first
allocate a shared memory object, using the DosAllocSharedMem() function as
described in The Flat Memory Model. Since the process ID of the server
process is known to the client, the client can provide access to the shared
memory object for the server process, using the DosGiveSharedMem() function,
which is also described in The Flat Memory Model. This technique is shown in
Figure "Interprocess Communication Using Shared Memory (Part 1)".
If the technique described in Creating Another Process is followed, and the
server process has posted a message to the client at the completion of server
initialization, containing the window handle of the server's object window,
the client can dispatch the request as an application-defined Presentation
Manager message to the server's object window, with a pointer to the memory
object as a message parameter. The server process then obtains access to the
object using the DosGetSharedMem() function, as shown in Figure "Interprocess
Communication Using Shared Memory (Part 2)".
In the simplest case where the client process has only one window, the handle
of this window is passed to the server process when it is created, as part of
the DosExecPgm() call, as shown in Figure "Starting a Child Process". Hence
the server has access to the client's window handle and can pass the return
data to the client. In a more complex situation where the client process has
several windows and where a request can come from any of these, the handle can
be passed as part of the request structure, as shown in Figure "Interprocess
Communication Using Shared Memory (Part 1)" and Figure "Interprocess
Communication Using Shared Memory (Part 2)".
Another issue that arises when using shared memory to communicate between
processes is that of freeing the shared memory object. When a process issues
a DosGiveSharedMem() or DosGetSharedMem() call, the operating system increments
a usage counter for the shared memory object, and will not release the memory
until all processes using the object have issued a DosFreeMem() call.
For the server process that receives access to the shared memory object, the
DosFreeMem() call is simply made whenever the server process has finished with
the contents of the memory object. For the client process that initially
creates the memory object, the DosFreeMem() call can be made at either of two
points:
If the client process does not care whether the request is correctly
received by the server process, the DosFreeMem() call can be made
immediately after passing the message to the server, as shown in Figure
"Interprocess Communication Using Shared Memory (Part 1)".
If the client wishes to guarantee delivery of the request, it must pass the
message, wait for an acknowledgement of receipt from the server, and then
issue the DosFreeMem() call. This acknowledgement may simply be an
indication of receipt, prior to the server processing the request, or may be
the returned data from the request.
Note that it is common for returned data from a request to be passed using the
same memory object as was used to contain the original request. In such
cases, the memory object cannot be freed by the client process until the
returned data is received and processed.
ΓòÉΓòÉΓòÉ 20.6.3. Atoms ΓòÉΓòÉΓòÉ
This example assumes that the two processes described in the previous example
require only to pass character strings, perhaps containing the request and the
returned information. In this case, the requester obtains the handle to the
system atom table using the WinQuerySystemAtomTable() function. It may then add
the request string to this table using the WinAddAtom() function, and obtain
an atom that represents the string in the table. This atom may then be passed
to the server process in an application-defined Presentation Manager message.
An example of this technique is shown in Figure "Interprocess Communication
Using Atoms (Part 1)".
When the server process receives this message, it may also obtain the handle to
the system atom table, and retrieve the string using the atom supplied in the
message. If the string is of a predefined length, the server may simply
retrieve the string using the WinQueryAtomName() function. If the string is of
variable length, the server may need to obtain the length of the string using
the WinQueryAtomLength() function, and allocate a buffer for the string. This
is illustrated in Figure "Interprocess Communication Using Atoms (Part 2)".
The server may return information to the requester using the system atom
table. The WinAddAtom() function is used by the server to add the result
string to the atom table, and the WinQueryAtomLength() and WinQueryAtomName()
functions are used by the requester to retrieve the string. In the example
shown in Figure "Interprocess Communication Using Atoms (Part 1)", it is
assumed that the reply string returned to the requester is of a predefined
length, and the WinQueryAtomLength() function is thus not required.
Note that the request string is not removed from the atom table until the
server process has returned the result to the requester. Once the result is
obtained and verified, the requester removes both the request and the result
using the WinDeleteAtom() function.
The functions used to manipulate atoms and atom tables are described in detail
in the IBM OS/2 Version 2.0 Presentation Manager Reference.
ΓòÉΓòÉΓòÉ 20.6.4. Queues ΓòÉΓòÉΓòÉ
A queue can be used to pass information between the process that created it and
other processes in the system. The process that creates the queue is known as
the owner of the queue, and is the only process that can read and remove
elements from the queue. Other processes may only add elements to the queue.
In a client-server environment, a queue is typically created by the server
process. If a requester wishes to receive returned data from the server
process, it must therefore create its own queue. Figure "Interprocess
Communication Using Queues (Part 1)" shows a requester process using the
DosCreateQueue() function to create its own queue, as well as using a queue
owned by a server process.
Queues may be created with a number of different ordering mechanisms. The
order of elements in a queue is determined when the queue is created, and may
be specified as FIFO, LIFO, or priority-based. When adding an element to a
priority-based queue, a process must specify a priority (from 0 to 15 with 0
being lowest and 15 being highest) for the element.
Processes other than a queue's owner may gain write access to the queue using
the DosOpenQueue() function to obtain a queue handle. Once this handle is
obtained, the process may use the DosWriteQueue() function to add elements to
the queue. The example in Figure "Interprocess Communication Using Queues
(Part 1)" shows a requester process that passes a request to a server process
using a queue created by that server process.
The requester process first creates its own queue for returned data, using the
DosCreateQueue() function. This queue will be accessed by the server to write
the returned data from the completed request, which can then be read by the
requester. The example shown in Figure "Interprocess Communication Using
Queues (Part 2)" creates a FIFO queue with the name specified in the string
constant REQQUENAME, and specifies that the addresses of any elements placed
in the queue by 16-bit processes are to be automatically converted to 32-bit
addresses by the operating system. This conversion, specified using the
QUE_CONVERT_ADDRESS flag, is used by 32-bit queue owners to avoid the need for
the queue owner to explicitly convert addresses.
The requester obtains access to the server's queue using the DosOpenQueue()
function, passing the queue name as a parameter. This function returns both a
queue handle and the process identifier of the server process that owns the
queue.
The requester must allocate a shared memory object to contain the request; the
actual queue element contains only a pointer to that memory object. The
requester then invokes the DosGiveSharedMem() function to provide read-only
access (by specifying only the PAG_READ flag) to that object for the server
process, using the process identifier returned by the DosOpenQueue() function.
The requester adds its request as a element in the queue, using the
DosWriteQueue() function. Note that the second parameter to the function is
an unsigned long integer, which may be used to pass application-specific
information. The value specified in this parameter is passed to the queue
owner as the ulData field of a REQUESTDATA structure, which is returned by the
DosReadQueue() function. In this example, the parameter is used to pass the
window handle of the requester's object window to the server process, so that
a notification message can be passed to the requester when the request has
been completed.
Once the element has been written to the queue, the requester immediately
relinquishes access to the server's queue by issuing a DosCloseQueue()
function call. The shared memory object allocated for the request buffer is
then released by the requester using the DosFreeMem() function.
The server process is very similar in structure to the requester, in that it
creates its own queue, then awaits and services requests. The server process
is illustrated in Figure "Interprocess Communication Using Queues (Part 2)".
Note that the server process does not use an object window. It simply accepts
requests from its own queue, using the DCWW_WAIT flag to suspend itself in the
DosReadQueue() call until an element becomes available in the queue. Once a
request is complete, the server places the returned data on the requester's
queue, extracts the window handle of the requester from the REQUESTDATA
structure provided by the DosReadQueue() call, and posts a message to the
requester indicating that the request is complete. This message is processed by
the requester to retrieve the returned data from the queue. Continue on the
next page of this chapter.
ΓòÉΓòÉΓòÉ 20.6.5. Queues (continued) ΓòÉΓòÉΓòÉ
After adding the request to the server's queue, the requester is notified by
the server when the request has been serviced. This is done using a
Presentation Manager message, since the requester's window handle is passed to
the server in the second parameter to the DosWriteQueue() function. The
operating system imbeds this value as the second doubleword of a REQUESTDATA
structure which is passed to the server by the DosReadQueue() function.
Once notification is received from the server process, the requester uses the
DosReadQueue() function to retrieve the returned data from its own queue, as
shown in Figure "Interprocess Communication Using Queues (Part 3)".
The DCWW_WAIT flag causes the DosReadQueue() function to wait until an element
is available in the queue before returning control to the application. If the
process merely wishes to check whether a queue element is available, the
DCWW_NOWAIT flag may be specified, in which case an event semaphore must be
created and its handle passed to the DosReadQueue() function. This semaphore
is immediately set by the operating system, and is posted when an element is
added to the queue. If the queue is shared between processes (as in the
examples given herein), the semaphore must be shared, either by creating it as
a named semaphore or by setting the DC_SEM_SHARED flag in the
DosCreateEventSem() call.
It will be noted that the use of queues is very similar to that of shared
memory, except that the queue is used to pass a pointer to a shared memory
object, rather than a Presentation Manager message. However, queues have an
advantage in that they may be FIFO, LIFO or priority-based, without the need
for the application to handle the querying and sorting of elements.
ΓòÉΓòÉΓòÉ 20.6.6. Pipes ΓòÉΓòÉΓòÉ
While a queue may only be read by its owner, a pipe may be used for either read
access, write access or both. Pipes function in a similar way to files, and
once created, are accessed using the OS/2 file system programming functions
such as the DosRead() and DosWrite() functions. This means that pipes can be
accessed by other applications in the system that support file system
operations, including applications executing in virtual DOS machines. In this
way, interprocess communication can be supported between an OS/2 application
and a DOS or Windows application.
Pipes may be either named or anonymous. Communication via an anonymous pipe
requires that the read and write handles for the pipe are known to both
processes involved in the communication. Since these handles are not shared
by default, another means of passing the handles, such as Presentation Manager
messages or shared memory, must be used. For this reason, anonymous pipes are
typically less useful than named pipes for interprocess communication, and are
therefore used mainly for "streaming" communication between threads in the
same process.
Named pipes are even more similar to files than anonymous pipes, since they
are initially accessed using predefined names rather than requiring handles.
Hence a process may easily obtain access to a named pipe, provided it knows
the name of the pipe. Once the pipe has been created or opened, the process
uses a pipe handle, which is similar to a file handle, to access the pipe via
DosRead() and DosWrite() function calls.
OS/2 V2.0 introduces a number of new functions for accessing named pipes,
which simplify programming in the client-server environment. These are the
DosCallNPipe() function and the DosTransactNPipe() function, both of which are
explained in the following text.
Note that while queues allow many processes to access and write to the queue,
a named pipe is typically a one-to-one connection; the creator of the pipe may
interact with only one other process at a time, and that process must
relinquish access to the pipe before another process may gain access. For
this reason, pipes have some limitations when used in a client-server
environment with many requesters being serviced by a single server, as will
become evident from the following examples.
A named pipe is normally created by the server process, using the
DosCreateNPipe() function. During creation of the pipe, the server specifies
the type of access that is allowed for the pipe. The following types of
access are valid:
Inbound access (client to server)
Outbound access (server to client)
Duplex (both).
Since only one client process may have access to a named pipe at any given
time, the requester must wait for the named pipe to become available, using
the DosWaitNPipe() function.
Figure "Interprocess Communication Using Named Pipes (Part 1)" shows a
secondary thread routine in a requester process, which is dispatched to make a
request to a server process.
In the example shown in Figure "Interprocess Communication Using Named Pipes
(Part 1)", the requester dispatches a secondary thread that waits
synchronously for the named pipe to become available. This thread accepts a
pointer to a data structure that contains the request and reply buffers along
with the window handle of the window that initiated the thread. This window
handle is included so that a notification message can be posted to the window
when the request is complete. Since a separate thread is dispatched for each
request, the thread terminates when the reply is returned by the server. Hence
no object window is necessary.
When the pipe becomes available, the requester opens the pipe, writes the
request, reads the reply and then closes the pipe. These functions are all
performed by a single call to the DosCallNPipe() function. This function
actually opens the pipe using a DosOpen() function call, and writes the request
to the pipe using the DosWrite() function. The reply is read using the
DosRead() function and the pipe is closed using the DosClose() function. Use of
the DosCallNPipe() function simplifies the application code by allowing the
programmer to combine these operations into a single function call.
Once the reply is received from the server and the DosCallNPipe() function
returns, the requester thread notifies the window from which the request was
made, by posting a Presentation Manager message to it. The pointer to the
transaction data structure initially passed to the thread is returned with the
message, enabling the window procedure to easily differentiate this request
from any others that may currently be active.
The server process creates the named pipe, as shown in Figure "Interprocess
Communication Using Named Pipes (Part 2)", using the DosCreateNPipe() function.
Once the pipe is created, the server process makes the pipe available to a
requester process by issuing a DosConnectNPipe() function call. This enables
any requester processes currently waiting for the pipe to contend for
ownership. The requester that claims ownership returns from its DosWaitNPipe()
call, while other requesters continue to wait.
The server then uses the DosRead() function to retrieve a request from the
pipe. Since blocking mode is selected in the DosCreateNPipe() call by
specifying the NP_WAIT flag, the DosRead() call does not return until a request
becomes available.
Once the read operation completes, the server process services the request and
writes the returned data back to the pipe using the DosWrite() function. It
then informs the requester that the request has completed, using a
Presentation Manager message, and obtaining the window handle of the requester
from the Request structure.
Note that the server process cannot make the pipe available to other requesters
by issuing a DosDisconnectNPipe() call, until the current requester has
completed retrieval of the information from the pipe. If this call is issued
before the requester retrieves its returned data, the requester's DosRead()
call will fail. The server ensures that correct synchronization is maintained
by passing the completion message synchronously using the WinSendMsg()
function. For this reason, and in order to ensure that user responsiveness is
maintained, it is recommended that requesters interacting with named pipes
should do so from within object windows created in secondary threads under the
control of the application's primary process.
Once the pipe is made available once more, this cycle of operations continues
for each request issued to the server. The server process is suspended within
the DosConnectNPipe() call until a request is issued by a requester process.
Note that where a one-to-one relationship exists between the server and
requester processes, the requester need not relinquish access to the named pipe
between requests. In such situations, the named pipe would be opened by the
requester using the DosOpen() function directly, and accessed using the
DosTransactNPipe() function. This function combines the DosWrite() and
DosRead() functions. When the secondary thread is terminated, it can
relinquish access to the pipe using the DosClose() function.
ΓòÉΓòÉΓòÉ 20.7. Maintaining Synchronization ΓòÉΓòÉΓòÉ
It is the responsibility of the application to ensure the appropriate level of
synchronization between threads or process accessing resources. Assuming the
convention suggested in Threads Without Object Windows, it is only necessary to
indicate when a secondary thread or process has completed processing a
particular unit of work. This may be achieved in a number of ways:
By having the secondary thread or process post a completion message to the
calling window procedure before terminating
By using an event semaphore in conjunction with the Presentation Manager
timer facility
By using the DosWaitThread() function in the case of threads
By using the DosWaitChild() function in the case of processes.
While it is possible, when using object windows in secondary threads or
separate processes, to ensure synchronization by using the WinSendMsg() call
for synchronous processing of the target window procedure, this method is not
recommended since it prevents the calling window procedure from processing
additional user input, and is thus potentially in violation of SAA CUA
guidelines. In addition, immediate invocation of a window procedure in this
way may disturb the natural sequence of message processing and compromise the
user's intention.
ΓòÉΓòÉΓòÉ 20.7.1. Presentation Manager Messages ΓòÉΓòÉΓòÉ
Since a process in OS/2 owns data resources, window handles are available to
any threads under the control of that process. It is therefore possible for a
secondary thread to post a message to the window procedure that invoked it,
advising that the secondary thread has completed its processing. The window
procedure may then process the message and take appropriate action.
This technique may be used by secondary threads that use object windows and
those which do not. It requires only that the secondary thread have
addressability to the window handle of the window procedure that invoked it.
This handle may be obtained directly from Presentation Manager, but it is
recommended that the handle of the invoking window procedure is passed to the
secondary thread upon invocation. This may be done in one of two ways:
By including the handle in the CtrlData parameter of the WinCreateWindow()
call if the secondary thread is using an object window. This also requires
passing the handle as a parameter to the _beginthread() call used to create
the secondary thread's main processing routine.
By including the handle as a parameter to the DosCreateThread() call if
using a secondary thread without an object window.
The second method described above is illustrated in Figure "Synchronization
Using Presentation Manager Messages".
Where the two communicating windows are under the control of different
processes, the window handles must be explicitly communicated from one to the
other since by default, the window handle of a window in one process is not
available to a window in another process. One technique for achieving this
communication involves passing the window handle of the first window when the
second process is created, and having the second window return a message to
the first window after initialization, containing the window handle of the
second window. This technique allows both communication and synchronization
between windows. An example is given in Creating Another Process.
ΓòÉΓòÉΓòÉ 20.7.2. Timers and Semaphores ΓòÉΓòÉΓòÉ
Another method of achieving synchronization between threads or processes
involves the use of an event semaphore and the Presentation Manager timer
facility. The timer facility may be used from within a window procedure to
create and start a timer that periodically sends messages of class WM_TIMER to
the window, at intervals specified by the window procedure when the timer is
created.
In this case, the WM_TIMER message is used by the window procedure in the
primary thread or process, to periodically check the state of an event
semaphore that indicates whether the secondary thread or process has completed
its processing. The secondary thread or process sets the event semaphore upon
commencing its processing, and releases (posts) it upon completion. The
primary thread or process queries the state of the semaphore to determine when
the secondary thread or process has completed its processing.
Note that when using this technique for synchronization between processes
(rather than between threads within the same process), the event semaphore
must be created as a shared semaphore, either by giving it a name or by
specifying the DC_SEM_SHARED flag when invoking the DosCreateEventSem()
function.
An example of a secondary thread using this technique is shown in Figure
"Synchronization Using an Event Semaphore (Part 1)".
Note that the event semaphore is created as a shared semaphore and named. A
named semaphore is recommended since, if the secondary thread routine is placed
in a dynamic link library for subsequent use by other applications, or the
secondary thread executes in a separate process, the name of the semaphore may
be included in the documentation for that library, enabling calling window
procedures to access the semaphore using the DosOpenEventSem() function (see
Figure "Synchronization Using an Event Semaphore (Part 2)"). Using this
technique promotes code reusability.
Figure "Synchronization Using an Event Semaphore (Part 2)" shows a window
procedure using the WinStartTimer() function to start a timer, immediately
after dispatching a secondary thread such as the one shown in Figure
"Synchronization Using an Event Semaphore (Part 1)". This timer in this
example will cause a WM_TIMER message to be passed to the window every 0.5
seconds (500 milliseconds).
Since the primary thread or process must remain responsive to the end user and
thus cannot wait indefinitely for the semaphore to be released, the
Presentation Manager timer facility is used to generate periodic WM_TIMER
messages to the invoking window procedure in the primary thread or process.
Upon receipt of each WM_TIMER message, the window procedure checks the state of
the semaphore, timing out immediately if the semaphore has not yet been
released by the secondary thread or process. This technique is illustrated in
Figure "Synchronization Using an Event Semaphore (Part 2)".
Note once again the use of a named shared semaphore, in order to reduce the
level of interdependence between the primary and secondary threads/processes,
thus facilitating the inclusion of the secondary routine into a dynamic link
library for subsequent use by other applications.
ΓòÉΓòÉΓòÉ 20.7.3. DosWaitThread() Function ΓòÉΓòÉΓòÉ
Where a secondary thread must complete its processing and terminate before the
primary thread can continue, the primary thread may use the DosWaitThread()
function to determine whether the secondary thread has terminated. This
function is used in conjunction with the Presentation Manager timer facility,
to periodically check whether the secondary thread has issued a DosExit()
function call. An example of a secondary thread using this technique is given
in Figure "Synchronization Using the DosWaitThread() Function (Part 1)".
When the secondary thread has been started, the window procedure in the primary
thread stores the thread identifier in its instance data area (typically using
window words), and uses the Presentation Manager timer facility to send
periodic WM_TIMER messages to itself, as shown in Figure "Synchronization Using
the DosWaitThread() Function (Part 2)".
Whenever it receives a WM_TIMER message, the window procedure retrieves the
thread identifier from its instance data area and uses the DosWaitThread()
function to determine whether the thread has terminated. If so, it performs
the required processing. If the thread has not yet terminated, it immediately
returns control to Presentation Manager. Note the use of the DosExit()
function in Figure "Synchronization Using the DosWaitThread() Function (Part
1)". This assumes that the processing performed by the routine does not use
an object window, and does not call C run-time library functions. As mentioned
earlier in this chapter, secondary threads without object windows are
typically used to perform a single, lengthy task, and terminate upon
completion of this task. Since they are able to use the DosExit() function
and the completion of their task causes the termination of the thread, such
threads are ideal candidates for use of the DosWaitThread() function. For
situations where the progress of execution must be indicated to the primary
thread, an event semaphore is more suitable.
As already mentioned, there is very little difference between the use of the
DosWaitThread() function and the use of an event semaphore. Both are used in
conjunction with the Presentation Manager timer facility and in fact, both use
an event semaphore. The DosWaitThread() function avoids the need for the
application to explicitly open and check the semaphore, since the
DosWaitThread() function performs these operations transparently. However,
while an event semaphore may be used to indicate any significant event during
execution of a secondary thread, while the DosWaitThread() function can only
signal termination of the thread. Hence the DosWaitThread() function is
slightly less flexible than the explicit use of an event semaphore with the
Presentation Manager timer facility.
ΓòÉΓòÉΓòÉ 20.7.4. DosWaitChild() Function ΓòÉΓòÉΓòÉ
The DosWaitChild() function allows a thread within a process to wait upon the
termination of an asynchronous child process, in a similar manner to the
DosWaitThread() function. The DosWaitChild() function allows a thread to wait
for the termination of a single child process, or the termination of an entire
process tree (that is, a process and all of its descendants).
Note that only the calling thread in the parent process is suspended during a
DosWaitChild() call. If the parent process has other threads, they will
continue to be dispatched.
The DosWaitChild() function can also be used to check the termination status
of a child process that has already terminated, provided that process was
started with the EXEC_ASYNCRESULT flag specified in the DosExecPgm() call.
The use of this flag causes OS/2 to store the result code from the child
process, for future reference by a DosWaitChild() call.
An example of the DosWaitChild() function is given in Figure "DosWaitChild()
Function". Specifying the DCWA_PROCESS flag in the first parameter of the
DosWaitChild() call causes the calling thread to wait only upon the specified
process, and not upon its children (if any). If a thread is to wait upon the
entire process tree, the DCWA_PROCESSTREE flag must be specified.
The DCWW_WAIT flag in the second parameter causes the calling thread to wait
until the specified process has terminated. The DCWW_NOWAIT flag would cause
the DosWaitChild() call to return immediately, without waiting for a child
process to end. The DCWW_NOWAIT flag is typically used when checking the
termination status of a child process that has already ended.
ΓòÉΓòÉΓòÉ 20.8. Preserving Data Integrity ΓòÉΓòÉΓòÉ
Since data resources are owned by a process, rather than by threads within the
process, multiple threads may have addressability to the same static data
storage areas, and potential problems arise with regard to serialization of
data access and maintenance of data integrity. Similarly when multiple
processes have access to a shared memory object, it is the responsibility of
the application to ensure the integrity of shared resources; neither OS/2 nor
Presentation Manager provide any automatic methods of avoiding such problems.
However, mechanisms are provided whereby the application developer may prevent
problems from occurring. Some suggested techniques for private data are as
follows:
1. For any data that is private to a thread, use local variables defined
within the thread, or automatic storage assigned from the stack (because
each thread has its own stack memory object, this data is automatically
protected since no other thread has addressability to this area of memory).
2. For any data that is private a particular window (as distinct from the
window class), create a memory object to store this data and place a
pointer in the window words, as described in Instance Data and Window
Words.
3. Specific data areas may be used to contain data that is passed between
threads or processes. If this data is only accessed in response to
particular messages passed between the threads or processes, and if these
messages are only generated at predefined points in the application's
execution (such as on entry to and exit from a window procedure), it is
relatively simple for an application to control access to these data areas.
Static allocation of such data areas is permissible where the accessing
routines reside and execute solely under the control of a single
application. However, where such routines are placed in a library and
accessed by multiple applications, the potential for data corruption
through application error increases significantly, and dynamic data
allocation prior to invoking a secondary thread or passing a request to
another process should be considered to ensure the integrity of data areas.
4. For any code that will be placed in a DLL, it is important that a separate
set of memory objects is created for the data of each process that will
access the DLL. In order to ensure this, a DATA NONSHARED statement should
be specified in the module definition file (see Module Definition File).
Note that the above techniques apply to data shared between threads within a
process; OS/2 provides a variety of mechanisms for dealing with data and
memory areas that are shared between processes. These techniques are
described in the IBM OS/2 Version 2.0 Control Program Reference.
ΓòÉΓòÉΓòÉ 20.9. Client-Server Applications ΓòÉΓòÉΓòÉ
In situations where an object window is created in a secondary thread to
manipulate a data object such as a database, or to handle access to a remote
device or system, it is often desirable to have a single object window
performing the requested actions, in response to requests from multiple
display windows. This follows the basic architecture of a client-server
application, in accordance with the object-oriented rule of allowing access to
a data object only from a single application object, and therefore implements
the concept of encapsulation.
For example, a user may use different display windows to access different
views of the same database. However, for reasons of efficiency and data
integrity, the actual database access should be coordinated by a single object
window, preferably in a secondary thread in case a database access request
causes a lengthy search.
The question then arises of how the handle of the object window may be made
available to multiple display windows. A number of options are available:
The handle may be stored as a global variable. This is not recommended
however, since global variables are open to inadvertent modification, and
their use imposes programming restrictions with respect to variable names.
Immediately after the object window is created, its handle may be passed to
all display windows that require communication with the object window.
However, if subsequent modification of the application introduces a new
display window, additional modifications would be required to the module that
created the object window. This increases the interdependence between
application objects, and is therefore not recommended.
The handle of the object window may be stored in the window words of the
application's main window. The handle of this window is available to all
windows in the application, by querying the application's switch entry (as
shown in Identifying the Destination Window). If the window words of the
application's main window are used to store a pointer to a data structure,
which in turn contains the handles of object windows and other items of a
global nature, these items may be retrieved by window procedures when
required.
The final method described above is therefore the recommended solution. Object
windows that will perform "server" tasks on behalf of a number of display
window "clients" should be created by the window procedure for the
application's main window, immediately upon creation of the main window, and
the handles of the object windows stored in a data structure accessed via the
window words of the main window.
ΓòÉΓòÉΓòÉ 20.10. Summary ΓòÉΓòÉΓòÉ
OS/2 allows multiple threads of execution to be initiated within an
application. Each thread is regarded as a distinct unit by the operating
system, and is scheduled independently of other threads and processes in the
system. Each application has a primary thread, created when the application
is started. An application may optionally create one or more additional
threads, known as secondary threads.
In certain circumstances, an application may also create additional processes
to perform some portion of the application's processing. The use of additional
processes may be necessary where different portions of the application's
processing must be isolated from one another. It is also useful for
applications that exploit the Workplace Shell since by default, all Workplace
Shell objects share the same process and are hence unprotected from one
another. The use of multiple processes has performance implications due to
additional system overhead and should thus be implemented with care.
Secondary threads and processes may contain object windows, which do not
appear on the display screen but act as addresses to which messages may be
sent in order to initiate application processing. An object window typically
"owns" a data object such as a database or controls access to an external
entity such as a remote system. Where the processing in response to an
application event requires access to another data object, the use of object
windows in a secondary thread is recommended.
Communication with an object window is performed in the normal way using
Presentation Manager messages. With suitable programming conventions, the
handle of the object window may easily be made available to the calling window
in order for such messages to be posted.
A single object window may receive messages from multiple windows, and perform
actions on its data object on behalf of those windows. This approach allows
easy coordination of requests for access to a data object, enhancing data
integrity and efficiency of access. Applications that use this technique
follow the basic client-server architecture, within the boundaries of the
Presentation Manager application model.
Where the scope of a long-running event is restricted to a single method
within the current application object, a secondary thread or process may be
initiated without an object window. In such cases, a subroutine is initiated
in the secondary thread, and the thread terminates immediately upon exiting
that subroutine.
Presentation Manager provides a number of methods by which an application can
synchronize access to data objects and determine whether a secondary thread or
process has completed processing an event. These methods involve the use of
functions such as DosWaitThread() or DosWaitChild(), Presentation Manager
messages and/or event semaphores.
The multitasking capabilities of OS/2 allow greater application responsiveness
since lengthy application processing may be performed in an asynchronous
manner, leaving the application's primary thread free to continue interaction
with the end user. This also facilitates conformance with the Systems
Application Architecture CUA guideline stipulating that an application should
complete the processing of an event and be ready to handle further user input
within 0.1 seconds.
ΓòÉΓòÉΓòÉ 21. Systems Application Architecture CUA Considerations ΓòÉΓòÉΓòÉ
The Presentation Manager environment provides the application developer with a
rich set of functions that enable tasks to be performed in a variety of ways.
However, within the general Presentation Manager application model, there are a
number of considerations which, if observed, enable the design and development
of applications that comply more closely with the guidelines and emerging
conventions of the Systems Application Architecture CUA component. This
chapter will discuss some of the considerations involved in designing an
object-oriented, CUA-conforming Presentation Manager application.
The Presentation Manager programming interface enables the creation and
manipulation of windows in a variety of ways by an application developer.
However, there is considerable value in adopting a series of standard practices
for developing Presentation Manager applications, from the viewpoint of
consistency and ease of maintenance, and to enhance the degree of conformance
to SAA CUA guidelines. The following points provide some guidelines on the
interpretation of CUA specifications, and outline some emerging trends in the
development of applications that use the Presentation Manager user interface.
ΓòÉΓòÉΓòÉ 21.1. Standard Windows ΓòÉΓòÉΓòÉ
Standard windows are used to display the contents of data objects. The contents
of a data object may, in turn, be comprised of other objects. For example, if
the data object is a directory on a workstation's fixed disk, its contents are
files, which are themselves objects. Alternatively, a data object may contain
information in the form of text or formatted data. Note that an object may be
defined by the user during execution; for example, if the user is editing a
text file and selects a block of text to be operated upon, then that block of
text becomes the scope of the following series of actions, and is thus defined
as an object.
By convention, the nature of a user's interaction with a standard window should
be unformatted and modeless; a standard window is used to display objects or
their contents, from which the user selects an object upon which to perform one
or more actions. The exact sequence of actions performed by the user in the
window should not be of concern to the application. If a modal or otherwise
structured dialog with the user is required, the application developer should
implement this dialog as a dialog box. For this reason, it is recommended
that the use of control windows be confined wherever possible to dialog boxes
only. An allowable exception to this rule is the instance where a standard
window displays a list of objects; in this case, the client window may be
created as a container window or listbox.
This is relatively simple for normal listboxes; however, for a listbox with
special display requirements and which is therefore created with the style
LS_OWNERDRAW, the application must subclass the frame window in order to
intercept and process the WM_DRAWITEM messages which are sent to the listbox's
owner (the frame) whenever a listbox item must be redrawn on the screen.
A standard window should normally be both sizable and movable on the screen,
allowing the user to configure the visual appearance of the desktop to suit the
tasks being performed. A standard window should therefore be created with the
FCF_SIZEBORDER style attribute in order to generate a sizing border for the
window. Similarly, the user should be able to maximize and minimize the window
in order to more clearly display information, unless the logical requirements
of the application scenario dictate otherwise; the standard window should thus
also be created with the FCF_MINMAX style attribute. A window that is neither
sizable nor able to be minimized or maximized is by definition an optimized
window, and should be implemented using a dialog box.
A standard window should always possess a title bar, to indicate the nature of
the window's contents, and to provide a "handle" for moving the window on the
screen; the frame window should therefore be created with the FCF_TITLEBAR
style attribute. For an application's main window, the text displayed in the
title bar should be the same as that displayed in the OS/2 Window List entry
for the application, and should follow the convention "Object Name - View".
For child windows containing objects or their contents, the window title should
be the same as the name or identifier of the item in the parent window that
caused the child window to be created. For instance, the selection of a
"Customer List" entry in the main window of an "Address Book" application might
cause the display of a child window containing a list of customers' names; the
title of this window would be "Customer List - Details View". Since a
standard window represents an object or group of objects, the title should
always be a noun rather than a verb.
A standard window is created using the WinCreateWindow() or
WinCreateStdWindow() functions. WinCreateWindow() creates the frame and client
windows in separate steps, whereas WinCreateStdWindow() creates both in a
single step. A standard window is typically created with the FCF_SIZEBORDER,
FCF_SYSMENU, FCF_TITLEBAR, FCF_MINMAX and FCF_MENU style attributes specified
for the frame window. See Figure "Sample Application Main Routine (Part 2) -
Window Creation" for an illustration of the use of these style attributes.
If an icon and/or accelerator table will be associated with the window, the
FCF_ICON and FCF_ACCELTABLE style attributes should be specified. The icon and
accelerator table definitions will then be loaded from the specified resource
file when the window is created.
If the application does not wish to explicitly size and position a frame window
on the desktop, the FCF_SHELLPOSITION style attribute may be specified.
Presentation Manager will then determine a default size and position for the
window.
As an alternative to specifying all of the above attributes, the FCF_STANDARD
attribute may be specified. This attribute is assumed if the
WinCreateStdWindow() call or the WinCreateWindow() call for a frame window
contains no control data.
ΓòÉΓòÉΓòÉ 21.2. The Menu Bar ΓòÉΓòÉΓòÉ
The menu bar is a menu which, in conjunction with its associated pulldown
menus, enables the user to select an action from a list of valid actions, to
be applied to a selected object or group of objects displayed in a window. The
following guidelines should be followed in the design and layout of the menu
bar, for the purpose of consistency and ergonomic behavior:
A menu bar is not required for fewer than six actions, unless these are
actions specifically defined by CUA.
The number of entries within an menu bar should be kept to a minimum; it is
better to have a "deep" pulldown menu with many choices than to have a
"broad" menu bar. This reduces the number of options displayed to the user
at any one time.
A menu bar must have a pulldown menu associated with it.
A pulldown menu item always represents an action, and therefore should always
be a verb.
Where selection of a menu bar entry results in the display of a pulldown
menu, the menu bar entry should indicate the generic nature of the group of
actions contained in the pulldown menu. If these actions pertain to a
particular object or object class, the name of the object or class may be
used as part of the menu bar entry. In such a case, the menu bar entry may
be either a verb or a noun.
If multiple distinct groups of actions, pertaining to a single object or
class, are contained within the same pulldown menu, they should be separated
by a horizontal separator bar within the pulldown menu.
A pulldown menu item that when selected, results in the display of a dialog
box, should have its text succeeded in the pulldown menu by an ellipsis (...)
to indicate that the dialog continues.
The SAA CUA guidelines stipulate that each standard window has a menu bar,
which contains actions specific to the object represented by that window.
However, certain actions may be inapplicable at certain points during
application execution. If an action is not necessarily applicable at all
stages of processing or for all data objects displayed within a window, that
action should remain in the menu bar or pulldown menu, but should be disabled
(that is, made non-selectable) until the point at which the action is valid.
Selection of a valid menu bar or pulldown menu item should result in the
immediate performance of the action, or the display of a dialog box to obtain
necessary information before performance of the requested action may take
place. Selection of an invalid menu bar or pulldown menu item will result in
a "beep" and the continued display of the pulldown. The menu bar and pulldown
menus are discussed in the IBM Systems Application Architecture CUA Advanced
Guide to User Interface Design and the IBM Systems Application Architecture CUA
Advanced Interface Design Reference.
Presentation Manager provides mechanisms to achieve the insertion/deletion and
enabling/disabling of menu bar items, as explained in the following sections.
ΓòÉΓòÉΓòÉ 21.2.1. Inserting/Deleting Menu Bar Items ΓòÉΓòÉΓòÉ
The insertion of an item is achieved by sending a message of class
MM_INSERTITEM to the system menu (or to the menu bar or appropriate pulldown
menu) using the WinSendDlgItemMsg() function. The menu item information is
placed into a data structure of type MENUITEM, as shown in Figure "Dynamically
Inserting a Menu Bar Item".
In the example shown above, an item is to be inserted into a standard "File"
pulldown menu. The menu item information is placed into the data structure
MenuItem, and the text to appear in the pulldown menu is contained in the
string variable szItemText.
Note however, that the menu bar is a child of the frame window, and the
pulldown menu is a child of the menu bar. In order to successfully pass the
message, the handle of the frame window must be obtained, and used to obtain
the handle of the menu bar window. This handle is then used in the
WinSendDlgItemMsg() call, along with the window identifier MN_FILE, to send
the MM_INSERTITEM message to the pulldown menu. The frame window handle is
obtained using the WinQueryWindow() function, and the QW_PARENT attribute
causes the function to return the handle of the client's parent (that is, the
frame window).
Once the frame window's handle is obtained, the various attributes of the
MenuItem structure are initialized. An MM_INSERTITEM message is then sent
directly to the pulldown menu.
Deletion of an item is accomplished in a similar fashion using a message of
class MM_DELETEITEM. Both message classes and the MENUITEM data structure are
described in the IBM OS/2 Version 2.0 Presentation Manager Reference.
Inserting/Deleting Separators
Where more than one logical group of items is contained within a single
pulldown menu, these groups should be divided by a separator, which is a
horizontal bar appearing between the last item of one group and the first item
of the next, in order to provide a visual indication of the group's distinct
identities. A separator may be defined within the resource script file (see
Presentation Manager Resources) or may be inserted and deleted dynamically by
the application. This dynamic insertion/deletion is carried out in a similar
manner to that already described for "normal" pulldown menu items. However,
the afStyle field in the MENUITEM structure is specified as MIS_SEPARATOR, and
the text of the item is set to NULL. In such cases, an item identifier is not
required for the separator, although it is recommended since an identifier
must be specified in order to delete the separator from the pulldown menu
should this be necessary at a later time.
Deletion of a separator is achieved in exactly the same manner as that
described for a normal pulldown menu item, using a message of class
MM_DELETEITEM and specifying the identifier of the separator to be deleted.
Inserting/Deleting Pulldown Menus
The technique for dynamically inserting a pulldown menu or cascade pulldown
into the menu bar is basically similar to that already described for inserting
a menu bar or pulldown menu item. An example is given in Figure "Dynamically
Inserting a Pulldown Menu".
The difference lies in the fact that a pulldown menu or cascade pulldown
requires a menu template to be reserved in memory in order to contain the items
that will subsequently be inserted into the pulldown. This template is created
using the WinCreateMenu() function, which returns a handle to the menu
template. This handle is then used in the hwndSubmenu field of the MENUITEM
structure.
ΓòÉΓòÉΓòÉ 21.2.2. Enabling/Disabling Items ΓòÉΓòÉΓòÉ
Disabling an item is achieved using the WinEnableMenuItem() function. Figure
"Disabling an Menu Bar/Pulldown Menu Item" shows how to disable the menu bar
item MI_VIEW.
Enabling an item is achieved with the same message class, but FALSE is
specified as the last attribute in the WinEnableMenuItem() function call.
Note that the WinEnableMenuItem() function is new in OS/2 Version 2.0; previous
versions of OS/2 required use of the WinSendDlgItemMsg() function to send an
MM_SETITEMATTR message to the menu.
ΓòÉΓòÉΓòÉ 21.2.3. Indicating Selected Items ΓòÉΓòÉΓòÉ
A pulldown menu may be used to display a list of options from which one or more
items may currently be selected; for example, a pulldown menu might provide a
list of fonts to be used by a word-processing or desktop publishing
application. SAA CUA guidelines stipulate that in such a case, the currently
selected item or items within the pulldown menu should be indicated by a check
mark next to the item. Presentation Manager provides support for this
convention by allowing a check mark to be displayed within the pulldown menu.
This is achieved using the WinCheckMenuItem() function; Figure "Placing a Check
Mark on a Pulldown Menu Item" shows how to place a check mark next to the item
MI_OPTION1.
Note that the WinCheckMenuItem() function is new in OS/2 Version 2.0; previous
versions of OS/2 required the use of a WinSendDlgItemMsg() function call to
send an MM_SETITEMATTR message to the menu.
If a checked item is selected for a second time, the check mark should be
removed by the application. This is achieved by sending the same message to
the menu bar, with FALSE specified for the last attribute in the function call.
Note that the use of a check mark in a pulldown menu provides an alternative to
the use of radio buttons or check boxes in simple dialogs. See Use of Control
Windows for further information. When a pulldown menu with a check mark is
used to display more than one set of mutually exclusive items, each set should
be separated by a horizontal bar in the pulldown menu. See Presentation
Manager Resources.
ΓòÉΓòÉΓòÉ 21.3. Action Windows ΓòÉΓòÉΓòÉ
Under the guidelines provided by CUA'91, a dialog box is known as an action
window. Since this chapter discusses CUA guidelines, this term will be used
herein when referring to the provisions made by CUA. The term "dialog box"
will be used when referring to the implementation of these concepts under
Presentation Manager.
Action windows used by an application may be either modal or modeless, although
modeless windows are preferred under CUA. Both types of action window are
defined as optimized windows; that is, they are created at a predefined optimal
size for their function, and may not be resized by the user. However, the use
of each type of action window is different, as explained below.
A dialog box is typically created using the Dialog Box Editor application
supplied as part of the IBM Developer's Toolkit for OS/2 2.0, and is defined in
a dialog template which is stored in a .DLG file and referenced from the
application's resource script file. Dialog templates are fully described in
the IBM OS/2 Version 2.0 Application Design Guide.
It is recommended that wherever possible, action windows should be created with
a title bar. Since action windows typically appear as the result of a menu bar
item being selected, the title bar should contain the name of the parent
object, plus the same text as the menu bar item. This provides the user with a
visual indication of the action which led to the action window being displayed.
As already mentioned, an action window should not be sizable by the user,
although it may be movable. Similarly, a modal action window should not
include minimize or maximize icons, since the user must complete the
interaction with the action window at its optimal size prior to continuing with
execution. In the case of a modeless action window, there is no point in
providing a maximize icon since the window is created at an optimal size for
the information it will contain. However, since a user may wish to suspend the
dialog in order to interact with other windows, the user may wish to remove the
action window from the desktop. In such cases, a modeless action window should
include a minimize icon.
ΓòÉΓòÉΓòÉ 21.3.1. Modeless Action Windows ΓòÉΓòÉΓòÉ
A modeless action window is preferred in situations where the dialog with the
user need not be completed before other user interaction with the application
may occur. For instance, in an application object that performs an
administrative procedure, data entry would typically be performed by the use of
control windows. Since the control windows should remain displayed at all
times, their parent window should not be sizable. By definition, the parent
window is an optimized window, and should therefore be created as a dialog
box. However, it may not be mandatory for the user to complete the dialog
before interacting with other windows, and the dialog box should therefore be
modeless.
Since the WinDlgBox() function automatically creates and executes a modal
dialog box, a modeless dialog box must be created in one of two alternative
ways:
Using the standard WinCreateWindow() function, with the FCF_BORDER frame
creation flag set. Control windows such as entry fields and buttons may then
be created as children of the dialog box window.
Using a WinLoadDlg() call to load the dialog template from a resource into
memory, and then using the WinShowWindow() or WinSetWindowPos() functions to
make the dialog box visible. The dialog template should have the FCF_BORDER
attribute set. Control windows within the dialog box are defined in the
dialog template.
The latter method is recommended for reasons of simplicity, since the dialog
box and its control windows may be defined and stored in a resource file (see
Presentation Manager Resources), making the definition of the dialog box
easier for the application developer.
The dialog box may be explicitly positioned on the screen, regardless of the
method used. With the former method using the WinCreateWindow() function, the
dialog box is positioned at the time it is created. With the latter method,
the dialog box is positioned during its processing of the WM_INITDLG message.
The FCF_BORDER attribute results in the dialog box being displayed with a thin
blue line as the dialog border. This is in accordance with the SAA CUA
guidelines for modeless action windows.
Note that the two methods described above will result in different
initialization messages being received. When created with the
WinCreateWindow() function, the dialog box is regarded as a "normal" window,
and a WM_CREATE message is passed to it. When created with the WinLoadDlg()
function however, a WM_INITDLG message is passed instead. The application
developer must bear this in mind when creating the dialog procedures for such
dialog boxes.
ΓòÉΓòÉΓòÉ 21.3.2. Modal Action Windows ΓòÉΓòÉΓòÉ
Modal action windows are used to carry out a dialog with the user in order to
define or qualify the properties of a data object upon which the user is
operating or wishes to operate. It is important to differentiate the
properties of a data object from its contents; for instance, the properties of
a text file might be its name, parent directory, archive/hidden/read-only
attributes etc, whereas its contents would be the text within the file. Under
Presentation Manager, manipulation of an object's contents is typically carried
out in a standard window, whereas definition or alteration of attributes is
done using a dialog box.
Note that where the dialog with the user is limited to a simple decision, a
Presentation Manager message box should be used in preference to a dialog box
for the implementation of an action window, since the coding effort and
processing overhead associated with a message box is much less than that
associated with loading and processing a dialog box. See Message Boxes for
more information on the use of message boxes.
A modal dialog box is typically loaded and processed in a single step using the
WinDlgBox() call. The modal nature of the dialog box is indicated to the user
by a double blue line as the border for the dialog box, rather than the
standard window border. The different border indicates that the dialog box is
modal, and also indicates that it may not be sized by the user. This border is
specified in the dialog template using the FCF_DLGBORDER attribute.
By default, a modal dialog box is application-modal; that is, the user must
complete interaction with the dialog box before any further interaction may
take place with windows in the current application. A dialog box may also be
system-modal, in which case the user must complete interaction with the dialog
box before interacting with any other window in the system. A system-modal
dialog box is created in the same way as an application-modal dialog box, but
with the additional attribute FS_SYSMODAL specified in the dialog template.
ΓòÉΓòÉΓòÉ 21.3.3. Standard Dialogs ΓòÉΓòÉΓòÉ
OS/2 Version 2.0 provides standard dialog boxes for handling the selection of
files and fonts. These dialogs conform to SAA CUA guidelines, and are
implemented within Presentation Manager. Applications are therefore not
required to explicitly design and code such dialog functions, nor to modify
them should the CUA guidelines change in the future.
The standard dialogs are displayed using two Presentation Manager functions new
to OS/2 Version 2.0; these are the WinFileDlg() and WinFontDlg() functions.
File Dialog
The standard file dialog enables a user to specify a file to be opened or a
file name under which current work is to be saved, including the ability to
switch directories and logical drives. The file dialog provides basic
capabilities, and is designed in such a way that it may be modified if
additional function is required.
The file dialog is displayed using the WinFileDlg() function. The dialog may
be displayed as either an "Open" dialog or a "Save as" dialog, depending upon
the value of control flags specified in a FILEDLG structure passed as a
parameter to the function call. The WinFileDlg() function is shown in Figure
"Standard Dialogs - WinFileDlg() Function".
The appearance of the file dialog is controlled by the FDS_* style flags
specified in the fl field in the FILEDLG structure. The fields in this
structure are:
Field Usage
cbSize Defines the size of the FILEDLG structure, and should be
initialized using the sizeof() function.
fl Style flags of the form FDS_*, which control the attributes
of the dialog. These flags are described in the IBM OS/2
Version 2.0 Presentation Manager Reference.
IUser Used by applications to store their own state information
if subclassing the dialog in order to modify its appearance
or behavior.
IReturn Identifier of the button used to dismiss the dialog. This
is typically DID_OK or DID_CANCEL, unless the application
has subclassed the dialog and added its own buttons.
ISRC System return code which indicates the reason for dialog
failure, if a failure has occurred. This field is used to
assist in debugging.
pszTitle Dialog title text. If set to NULL, the text will default
to "Open" or "Save As", depending upon the FDS_* flags
selected.
pszOKButton Text used for the OK pushbutton on the dialog. If set to
NULL, the text defaults to "OK".
pfnDlgProc Pointer to custom dialog procedure, for custom dialogs with
the FDS_CUSTOM style flag set.
pszIType String pointer to a string defining the initial Extended
Attribute type filter to be applied to the file name field
in the dialog.
pszITypeList Pointer to a table of string pointers. Each points to a
null terminated string defining an Extended Attribute type
filter. The filters are displayed in ascending order in
the Type pull-down box.
pszIDrive Pointer to a string specifying the initial logical drive to
be applied in the dialog.
ppszIDriveList Pointer to a table of string pointers. Each points to a
null terminated string defining a valid logical drive.
hMod If the FDS_CUSTOM style flag is set, this field defines the
DLL module handle that contains the file dialog template to
be used. If set to NULL, the dialog template is loaded
from the application's EXE file.
szFullFile On initialization, this field contains the initial fully
qualified path and file name, and on completion of the
dialog, contains the selected or user-specified fully
qualified file name. Upon invocation of the dialog, all
drive and path data is stripped from the name, and moved to
the appropriate fields in the dialog box.
ppszFQFilename Pointer to a table of pointers. Each points to a null
terminated string containing a fully qualified file name.
This table is used by applications that require multiple
files to be selected from within the file dialog (indicated
by specifying FDS_MULTIPLESEL). The storage is allocated
by the file dialog procedure, and must be freed after
dialog completion using the WinFileFreeFileList() function.
IFQFCount Number of file names selected in the file dialog, for
dialogs with multiple selection enabled.
idDlg Window identifier of the dialog window. If the FDS_CUSTOM
style flag is set, this is also the resource identifier of
the dialog template.
x,y Position of the dialog, relative to its parent. These
fields are automatically updated by the dialog procedure
when the dialog is moved by the user, so that if the same
FILEDLG procedure is used on subsequent invocations, the
dialog will appear in the same location. The FDS_CENTER
style flag overrides any settings specified.
sEAType Extended Attribute file type to be be assigned to the file.
This field contains the returned value specified in the
Type field in the dialog. This field is valid only for a
"Save As" dialog; the value -1 is returned for an "Open"
dialog.
For applications with specialized file handling requirements, the standard file
dialog may be subclassed, allowing these requirements to be handled while
retaining standard processing for the majority of events. This subclassing is
invoked by specifying the address of an application-defined dialog procedure in
the pfnDlgProc field in the FILEDLG structure, and by specifying the resource
identifier of an application-defined dialog template if controls are to be
added or removed from the dialog.
Note that application-defined dialog procedures should invoke the
WinFileDlgProc() function as their default case for message processing, to
ensure that messages not explicitly processed by the application are passed to
the standard file dialog procedure for correct default processing.
Font Dialog
The standard font dialog enables a user to specify a choice of font names,
styles, and sizes from the range available within a given application. The
font dialog is intended to fit basic application needs, and is designed in such
a way that additional function may be added by subclassing the dialog
procedure.
The font dialog is displayed using the WinFontDlg() function, specifying the
owner window for the dialog box, and a FONTDLG control structure. The use of
the WinFontDlg() function is shown in Figure "WinFontDlg() Function - Sample
Code".
The appearance of the dialog is determined by the FNTS_* flags specified in the
fl field of the FONTDLG structure, and by the other fields in this structure.
The fields in the FONTDLG structure are:
Field Usage
cbSize Defines the size of the structure, and should be
initialized using the sizeof() function.
hpsScreen If not NULL, this field specifies the screen presentation
space, which the dialog procedure queries for available
fonts.
hpsPrinter If not NULL, this field specifies the printer presentation
space, which the dialog procedure queries for available
fonts.
pszTitle Title text for the dialog box. If set to NULL, the default
text "Font" is used.
pszPreview Text to be displayed in the Preview field in the dialog
box. If set to NULL, the default text "abcdABCD" is used.
pszPtSizeList String containing a list of numeric point sizes, to be
displayed in the Point Size drop-down list in the dialog
box. Point sizes within the string must be separated by
spaces. If set to NULL, the defaults of 8, 10, 12, 14, 18,
and 24 are used.
pfnDlgProc Pointer to custom dialog procedure, for dialogs with the
FNTS_CUSTOM flag set.
szFamilyname Font family name to be used by an application to select a
font. If set to NULL, the system default is used.
fxPointSize Vertical point size of the font.
fl Flags which specify the characteristics of the dialog box;
these may be any combination of FNTS_CENTERED, FNTS_CUSTOM,
FNTS_HELPBUTTON, FNTS_MULTIFONTSELECTION, and
FNTS_MODELESS. Flags are combined using the "or"
operator.
flFlags Flags; specifying FNTF_VIEWPRINTERFONTS specifies whether
printer fonts should be included if both hpsScreen and
hpsPrinter are non-NULL. FNTF_PRINTERFONTSELECTED is set
upon return, if the user selects a printer font.
flType Specifies additional font attributes specified by the user,
and may be used as the options field in a QFSATTRS
structure for the GpiQueryFaceString() function.
flTypeMask Specifies which flags in the flType field are required to
change. This is only relevant where selections may be for
different types and styles when multiple fonts are being
selected.
flStyle Specifies any additional selections, and may be used for
the selection indicators in a FATTRS structure supplied to
the GpiCreateLogFont() function.
flStyleMask Specifies which flags in the flStyle field are required to
change. This is only relevant where selections may be for
different types and styles when multiple fonts are being
selected.
flCHSOptions These are equivalent to the CHS_* option flags used by the
GpiCharStringPos() and GpiCharStringPosAt() functions.
flCHSMask Similar to flStyleMask.
clrFore Foreground color for the font.
clrBack Background color for the font.
lUser May be used by applications to pass information if
subclassing the font dialog.
lReturn Identifier of the button used to dismiss the dialog. This
is typically DID_OK or DID_CANCEL, unless the application
has subclassed the dialog and added its own buttons.
ISRC System return code that indicates the reason for dialog
failure, if a failure has occurred. This field is used to
assist in debugging.
lEmHeight Value that may be used within a FONTMETRICS structure by
applications.
IXHeight As above.
iExternalLeading As above.
fAttrs Complete font attribute (FATTRS) structure for the selected
font. Only the codepage field may be modified by the
application prior to invoking the dialog.
sNominalPointSize Nominal point size of selected font.
usWeight Character thickness (for example, normal or bold). The
returned value may be used in the weightclass field in the
QFSATTRS structure for the GpiQueryFaceString() function.
usWidth Character width. The returned value may be used in the
widthclass field in the QFSATTRS structure for the
GpiQueryFaceString() function.
x,y Position of the dialog relative to its parent. These
fields are automatically updated by the dialog procedure
when the dialog is moved by the user, so that if the same
FONTDLG structure is used on subsequent invocations, the
dialog will appear in the same location. The FNTS_CENTERED
style flag overrides any settings specified.
idDlg Window identifier of the dialog window. If the FNTS_CUSTOM
style flag is set, this is also the resource identifier of
the dialog template.
hmod If the FNTS_CUSTOM style flag is set, this field defines
the DLL module handle that contains the file dialog
template to be used. If set to NULL, the dialog template
is loaded from the application's EXE file.
Applications may customize the font dialog through subclassing, by specifying
the FNTS_CUSTOM style flag, giving the resource identifier and module handle of
the application's customized font dialog template, and the address of an
application-defined dialog procedure, in the FONTDLG structure. The
WinFontDlg() function then performs the subclassing operation on the
application's behalf.
Note that application-defined dialog procedures should invoke the
WinFontDlgProc() function as their default case for message processing, to
ensure that messages not explicitly processed by the application are passed to
the standard font dialog procedure for correct default processing.
An application that uses its own dialog template must include all of the
standard controls within the dialog box, in addition to its own customized
controls. Those controls, which are not required, may be rendered invisible
in order to provide the correct appearance.
Control window identifiers in the range 0x0000 to 0x0FFF are reserved for use
by standard controls. The application's own controls should therefore use
window identifiers greater than 0x0FFF.
ΓòÉΓòÉΓòÉ 21.3.4. Use of Control Windows ΓòÉΓòÉΓòÉ
A number of control window classes are provided by Presentation Manager. Under
CUA guidelines, these control windows should be displayed in standard windows,
although their use is more typically in dialog boxes. This is in accordance
with the convention that windows display objects or the contents of objects,
and other more structured information such as object attributes is displayed in
a dialog box. See also the proviso regarding listboxes under Standard Windows.
The use of control windows is defined in the IBM Systems Application
Architecture CUA Advanced Guide to User Interface Design. However, there are
some emerging conventions as to the exact interpretation of the CUA
guidelines, and these are discussed in the following sections.
Entry Field
Entry fields are used where textual or numeric data is required from the user,
and where the set of possible entries is open-ended. Examples of such data
items include file names, object descriptions etc.
List Box
A listbox is used to display a list of objects, where the contents of that list
may change from one execution to the next, based upon various external or
user-specified criteria. One or more items may be selected from a listbox. The
listbox is typically created with a size sufficient to display a certain number
of items, and a scroll bar is provided if the number of items increases such
that not all items may be displayed at once.
Note that a listbox should not be used to display a set of choices where that
set is finite and unchanging. In such a case, radio buttons may be used where
the choices are mutually exclusive, or check boxes used where more than one
choice may be made concurrently.
Combo Box
A combo box, also known as a prompted entry field is a combination of the
entry field and listbox control window styles, and is supported by
Presentation Manager in OS/2 Version 1.2 and above. A combo box is used where
textual or numeric data is required from a user, where the set of possible
entries is finite, and where the application wishes to prompt the user for a
valid entry. A combo box may be of three distinct types:
A simple combo box is displayed as an entry field with a listbox directly
below it. The user may enter textual or numeric data into the entry field
in the same way as for a normal entry field, or may select an item from the
listbox. The selected item will then appear in the entry field. The simple
combo box provides a similar function to that of a single-selection listbox.
A drop-down combo box is displayed as an entry field with an icon to its
immediate right. The user may enter textual or numeric data into the entry
field, or may select the icon. When selected, the icon causes a listbox to
appear below the entry field, containing a list of valid entries for the
entry field. When selected, an item appears in the listbox. The drop-down
combo box is recommended where the set of valid entries is finite and
limited, but where the user may already know the required entry and may wish
to save time by entering it him/herself.
A drop-down list combo box is displayed in a similar manner to a drop-down
combo box, as an entry field with an icon to its immediate right. However,
the user may not enter data directly into the entry field, but must select an
item from the listbox. A drop-down list combo box is recommended in
situations where a number of control windows are located in a dialog box,
where the optimization of space is of primary importance, and where the
default entry is likely to be used.
The use of a combo box is typically recommended in place of a listbox in order
to save room within a dialog box, or in place of an entry field where the
application wishes to prompt a user with a list of valid entries.
Radio Button
Radio buttons are used to indicate a group of mutually exclusive options; that
is, only one of the items in the group is selectable at any one time, and
selecting one item automatically deselects any previously selected item.
Selecting a radio button does not complete the dialog; a user may revise
his/her selection any number of times during the dialog. Once a final decision
is made, the user completes the dialog using a push button (see below).
Radio buttons are always displayed in groups; it makes no sense to have a
single mutually exclusive selection item. Text is displayed along with the
buttons to indicate the choice represented by each button. If multiple groups
of radio buttons are present within a dialog box or window, or if radio buttons
are combined with other types of control window, it is recommended for reasons
of clarity that the radio buttons be placed within a group box, and that this
group box be named to indicate the nature or purpose of the group as a whole.
As described above, radio buttons should be used to denote a set of mutually
exclusive options in the creation or manipulation of an object, as part of a
more complex dialog. They should not be used to present a set of options in
response to an application or system event, where this set of options is the
sole purpose of the dialog. In such cases, a message box is the preferred
mechanism to achieve this type of communication with the user, since the
processing overhead associated with a message box is less than that associated
with a dialog box. For example, a warning that the user is about to exit the
application without saving his/her latest set of changes would be presented
using a message box rather than a dialog box with radio buttons.
The equivalent function of a group of radio buttons may also be provided by a
pulldown menu displaying a set of options, only one of which may be selected at
any one time, with the selected item indicated by a check mark. The use of a
pulldown menu is the recommended option in situations where the selection of an
option is the only action to be performed. The use of radio buttons is
recommended where the selection of an option indicated by the radio buttons is
part of a more complex dialog.
Note that from a programming viewpoint, "auto" radio buttons should be used in
preference to standard radio buttons since these buttons are drawn and
maintained by Presentation Manager. The application need not concern itself
with redrawing the buttons when their state changes, thereby allowing simpler
programming.
Check Box
A check box is used to indicate a single option that may be toggled on or off
by the user. Multiple check boxes may appear in a single dialog box or window,
and may refer to different attributes of the same object. However, these
attributes are related to each other only by their application to that same
object, and should not be mutually exclusive.
A 3-state button is a special type of check box that, in addition to being
marked selected or non-selected, may be "grayed out" to indicate that a choice
is non-selectable in the current dialog. A 3-state button should be used
whenever a dialog box is applicable to a range of objects, but where certain
options within the dialog box are not valid for all objects dealt with by that
dialog box. A 3-state button may be enabled or disabled using the
WinEnableWindow() function, obtaining the window handle of the button from a
WinWindowFromID() call.
The equivalent function to a check box may be provided by a pulldown menu
displaying a list of options, from which multiple items may be selected at any
one time, with the selected items indicated by check marks. The use of a
pulldown menu is recommended where the selection of such an option is the only
action to be performed. The use of a check box or 3-state button is the
preferred solution where the selection is part of a more complex dialog.
Note that the "auto" versions of check boxes and 3-state buttons should be used
in preference to the standard versions, since the auto versions are maintained
by Presentation Manager, and the application need not concern itself with
redrawing these buttons when their state changes.
Push Button
Push buttons are used to initiate an immediate action by the application. If
desired, push buttons can be used in conjunction with the menu bar and context
menu, to provide easy access to commonly used functions in both primary windows
and action windows.
Push buttons should not be used to form menus of selectable options that cause
child windows to appear when a push button is selected. Such a practice
effectively forms a hierarchical user interface, which is in violation of
object-oriented user interface principles.
An exception to this rule is a "Help" push button, which immediately displays a
window containing help information, while maintaining the previous window or
dialog on the screen. Dismissing the help window returns the user to the
original window in which the "Help" push button was displayed.
Slider
The slider is used where a single value must be selected from a continuous
range of options. For example, the brightness of the screen, the saturation of
a color or the speed of the mouse cursor on the screen are all values selected
from a continuous, though finite, range of options.
Under previous versions of OS/2, scroll bars were often used to provide a
portion of the slider's functionality. The provision of the slider control
under OS/2 Version 2.0 allows the scroll bar to be used only for its intended
purpose of scrolling information within a window; this improves the consistency
of the user interface and removes a potential source of user confusion.
Value Set
The value set control is used in a similar way to a set of radio buttons, to
indicate a group of mutually exclusive options. Many of the comments made for
radio buttons apply equally to value sets.
However, while the use of radio buttons is effectively limited to text items, a
value set allows the use of text or graphical items, as well as color patches.
Thus a value set provides additional flexibility where a selection must be made
from a set of mutually exclusive options, providing a mechanism for the display
of those options to the user, and allowing the user to directly select the
required choice.
ΓòÉΓòÉΓòÉ 21.3.5. Message Boxes ΓòÉΓòÉΓòÉ
By convention, message boxes are used to inform the user of an event, and to
carry out a dialog with the user in the following circumstances:
Where the information to be conveyed to the user is simple and limited to no
more than a few lines of text
Where the input to be gained from the user is limited to a single decision
from a limited list of mutually exclusive options.
The type of decision available to the user from a message box is also limited
to simple choices such as "Yes/No", "OK/Cancel", or "Yes/No/Help". Since the
buttons displayed in the message box are push buttons, selecting any button
will result in the removal of the message box from the screen and immediate
action on the part of the application. An exception to this rule is the
"Help" button, which should result in the message box being left on the screen,
and the simultaneous display of a window containing help information. This
help window should be a child of the message box, so that it is dismissed when
the message box is closed, and the input focus should return to the message box
when the help window is dismissed.
A message box is created and processed using the WinMessageBox() function as
follows:
rc = WinMessageBox(hDesktop, /* Desktop is parent */
hwnd, /* Curr. window is owner */
szMessageText, /* Message text */
"Warning", /* Title of message box */
0, /* No message box ident. */
MB_YESNO | /* Yes/No choices */
MB_DEFBUTTON1 | /* Yes is default choice */
MB_CUAWARNING); /* Warning style */
Message boxes may be of three types:
Notification message boxes inform the user of a system event that requires
his/her attention, but does not signify an error or potential error
condition. Such message boxes are created with the message style
MB_CUANOTIFICATION.
Warning message boxes inform the user of a potential error condition that may
affect the integrity of the application or its data; for example, the user
may try to exit the application without saving the latest set of changes to
a data object. Such message boxes are created with the message style
MB_CUAWARNING.
Critical message boxes inform the user of an error condition that requires
his/her immediate attention; for example, a diskette may be unreadable. Such
message boxes are created with the message style MB_CUACRITICAL.
These message box styles may be combined with other style identifiers that
determine the buttons to be displayed in the message box, the default action
and the modality of the message box (that is, system- or application-modal).
These identifiers are described, along with the WinMessageBox() function, in
the IBM OS/2 Version 2.0 Presentation Manager Reference.
A message box should always be created with a title; while Presentation Manager
provides a default message title if a null title string is specified in the
WinMessageBox() function, the use of this feature is not recommended. A
message box title should identify the object or action from which the message
originated; for example, a message originating from a "Parts List" object
would have the title "Parts List", whereas a message occurring as a result of
an incorrectly completed dialog during an "Open File" action would have a title
of "Open File".
A message box is created as an optimized window, and by default is neither
moveable nor sizable. However, the situation may arise where the message is
related to some information displayed in a window, and the decision to be made
by the user is dependent upon the nature and context of that information. The
user must therefore be able to view the information in order to make the
decision required by the message box, and the information may be hidden by the
message box itself. To avoid this situation, a message box may be specified
with the style identifier MB_MOVEABLE, which allows the message box to be moved
(although not sized) by clicking the mouse on its title in a similar fashion to
that used for a standard window.
ΓòÉΓòÉΓòÉ 21.4. Maintaining User Responsiveness ΓòÉΓòÉΓòÉ
The particular implementation of the message handling concept under
Presentation Manager means that it is possible for a user to be "locked out" of
the system if a window procedure does not return from processing a message
within a reasonable period of time, since Presentation Manager only dispatches
messages from the system queue to other applications when the currently active
application attempts to retrieve a message from its queue.
The "reasonable" period of time is defined under Presentation Manager
guidelines to be 0.1 seconds; a window procedure should complete the processing
of a message within this period and return control to the application's main
routine in order that the main routine may issue its next WinGetMsg() call.
While this time period is adequate for processing of most messages, it may be
insufficient for some messages; for examples, those that involve lengthy
operations such as access to a remote system.
In order to avoid the situation where an application or the entire Presentation
Manager environment is unresponsive to the end user, OS/2 allows applications
to create secondary threads of execution to handle lengthy processing, thus
enabling the application's primary thread to continue responding to user
interaction. Presentation Manager also provides a number of methods by which
synchronization between threads may be achieved in order to ensure the
integrity of the user's intention and of data resources manipulated by the
application. The use of secondary threads, and techniques for synchronizing
execution between threads and processes, are discussed in Multitasking
Considerations.
ΓòÉΓòÉΓòÉ 21.5. Summary ΓòÉΓòÉΓòÉ
It can be seen that there are emergent programming conventions governing the
use of Presentation Manager and operating system constructs to implement
CUA-conforming, object-oriented applications under the Presentation Manager
application architecture. These principles facilitate the achievement of the
many benefits attributable to the use of an object-oriented design approach,
while remaining within the framework of Systems Application Architecture.
Guidelines have been established, in accordance with emerging conventions, with
regard to the use of standard and control windows, dialog boxes and message
boxes, and the nature of their interaction with the user. Each type of window
has its own particular role in the interaction between the application and the
end user; adherence to these conventions will provide a greater level of
consistency between applications, within the parameters of the CUA
specifications.
The CUA guidelines specify that an application should have a response time of
no more than 0.1 seconds, after which time the application should be ready to
process the next user interaction. However, the situation may arise where a
unit of processing takes longer than the allowed time period. A number of ways
exist by which the application may overcome this problem, typically involving
the use of asynchronous threads, either with or without object windows.
The embodiment of these principles into Presentation Manager applications at
the design stage results in closer conformance to Systems Application
Architecture guidelines. The enterprise may thereby achieve the benefits of a
consistent and intuitive approach to the human-machine interface between users
and applications.
ΓòÉΓòÉΓòÉ 22. Application Migration ΓòÉΓòÉΓòÉ
OS/2 Version 2.0 provides application compatibility at the executable code
level for applications written to run under previous versions of OS/2. Hence
no modification is necessary to enable such applications to run under Version
2.0. However, in order to take full advantage of the enhanced capabilities of
OS/2 Version 2.0, such as the 32-bit flat memory model and the additional
features implemented by Presentation Manager, applications will require
modification of their source code.
Application developers who wish to migrate their code to the 32-bit programming
environment under OS/2 Version 2.0 should experience little difficulty. Changes
between the OS/2 Version 2.0 programming environment and that provided under
previous versions of OS/2 fall into the following basic categories:
Data types
Function name changes
Function enhancements
Memory management
New Presentation Manager functions.
The remainder of this chapter will describe each of these categories in detail,
and suggest methods by which the required changes may be made.
Note that it is not mandatory for an application to migrate all its modules and
resources to the 32-bit programming environment. OS/2 Version 2.0 allows mixed
model programming, where 32-bit applications may make use of existing 16-bit
modules and resources. The subject of mixed model programming is discussed in
Mixing 16-Bit and 32-Bit Application Modules.
ΓòÉΓòÉΓòÉ 22.1. Data Types ΓòÉΓòÉΓòÉ
A number of the function type declarations and data type definitions used by
Presentation Manager map into different "standard" C language type definitions
under OS/2 Version 2.0. This is due to the differences between the 16-bit
architecture of previous versions and the 32-bit architecture of Version 2.0.
For example, the Presentation Manager data type EXPENTRY, used to declare
exportable entry points, is defined under OS/2 Version 1.3 in the following
way:
#define EXPENTRY pascal far
However, the pascal linkage convention is not used in the 32-bit OS/2 Version
2.0 programming environment, since all function calls use the standard C
calling convention. The only exception is when creating applications that
access 16-bit functions; see Mixing 16-Bit and 32-Bit Application Modules.
In addition, far memory references are not used, since the 32-bit flat memory
model allows addressability to all locations in the process address space. In
the 32-bit programming environment therefore, the EXPENTRY type is defined as
blanks; 32-bit applications are not required to use the EXPENTRY keyword.
The OS/2 header file os2.h provided with the IBM Developer's Toolkit for OS/2
2.0 provides transparent remapping of the Presentation Manager type definitions
to their new C language equivalents, and thus no modification is required to
existing functions and data definitions that use the Presentation Manager
types. However, applications that have used standard C language type
definitions in place of the Presentation Manager types will require
modification. For this reason, it is recommended that all Presentation Manager
applications should use the Presentation Manager function and data type
definitions.
ΓòÉΓòÉΓòÉ 22.2. Function Name Changes ΓòÉΓòÉΓòÉ
Under OS/2 Version 2.0, certain function names for operating system kernel
functions and Presentation Manager functions have been changed to provide
improved consistency. These changes obey the following rules:
The use of the terms Create, Get, Set and Query in function names is in
accordance with SAA conventions, as follows:
- Create implies that a new resource is created as the result of a function
call.
- Get implies that a resource is made available to the application as the
result of a function call.
- Set implies that a system value is changed as a result of a function call.
- Query implies that a system value or handle to an existing function is
returned as the result of a function call.
Verbs are placed before nouns in function calls.
Similar actions have similar semantics, although they may operate on
different types of resources.
These changes have been made in order to provide improved consistency in
function names, simplifying the task of learning the various function names.
Applications that use operating system functions should be checked and function
names altered where necessary. A list of corresponding function names in OS/2
Version 1.3 and OS/2 Version 2.0 is given in OS/2 Version 2.0 - Volume 1:
Control Program.
ΓòÉΓòÉΓòÉ 22.3. 32-Bit Interface Constraints ΓòÉΓòÉΓòÉ
The following subsystems, present in OS/2 Version 1.3, have no 32-bit
equivalents, since they are not portable and are device-dependent.
VIO Video subsystem; these function calls should be replaced with
Presentation Manager GPI calls or AVIO (advanced video) calls.
KBD Keyboard subsystem; these function calls should be replaced by
processing WM_CHAR messages from a Presentation Manager
application.
MOU Mouse subsystem; these function calls should be replaced by
processing WM_MOUSEMOVE and WM_BUTTON messages.
MON Device monitor subsystem; these function calls should be replaced
by using appropriate message queue hooks in a Presentation Manager
application.
Note that these subsystems are supported under OS/2 Version 2.0 as 16-bit
service layers, for access by existing applications. However, OS/2 Version 2.0
does not provide thunk layers to enable 32-bit applications to access these
service layers. 32-bit applications that use these subsystems must employ
mixed model programming techniques to access the 16-bit services; see Mixing
16-Bit and 32-Bit Application Modules for further discussion.
Only two forms of input/output are supported in the 32-bit environment; the
stdin/stdout C interface (producing command line-based applications that can be
run in a text window) and Presentation Manager applications. Programs wishing
to perform graphics, handle keyboard or mouse input, or intercept and modify
device information should do so using Presentation Manager functions.
Certain other functions have also been removed from the 32-bit programming
interface. These are primarily concerned with the management of memory in the
segmented memory model. Therefore functions such as DosSizeSeg(), DosLockSeg()
and DosUnlockSeg(), DosR2StackRealloc() etc are not implemented in the 32-bit
programming interface, although the 16-bit entry points are still supported for
compatibility purposes.
ΓòÉΓòÉΓòÉ 22.4. Function Enhancements ΓòÉΓòÉΓòÉ
A number of enhancements have been made to existing operating system functions
in OS/2 Version 2.0. These include the semaphore functions for synchronization
between threads and processes, and the DosCreateThread() function for
initiating secondary threads.
ΓòÉΓòÉΓòÉ 22.4.1. Semaphore Functions ΓòÉΓòÉΓòÉ
The enhanced semaphore functions available under OS/2 Version 2.0 were
described in Operating System/2. Previous versions of OS/2 provided only basic
semaphore facilities with limited capability to handle multiple events. Where
these semaphores were used in applications under previous versions of OS/2,
they may be updated to the new OS/2 Version 2.0 semaphore facilities using the
following guidelines:
Where a semaphore is used to serialize the access to a particular data object
or system resource from multiple threads, a mutex semaphore should be used.
Where a semaphore is used to signal an event occurring in one thread to other
threads having an interest in this event, an event semaphore should be used.
Where an application waits upon the clearing of one semaphore from a range of
semaphores using the DosMuxWaitSem() function, this function may be replaced
by the use of a muxwait semaphore.
The muxwait semaphore has additional flexibility over the use of the
DosMuxWaitSem() function with normal semaphores under previous versions of
OS/2, since with a muxwait semaphore, a thread may wait for any one of a list
of mutex semaphores or event semaphores to be cleared (as with previous
versions), or may wait for all of the semaphores to be cleared. This latter
capability is not available under OS/2 Version 1.3.
The enhanced semaphore functions available under OS/2 Version 2.0 are described
in the IBM OS/2 Version 2.0 Control Program Reference.
ΓòÉΓòÉΓòÉ 22.4.2. Thread Management ΓòÉΓòÉΓòÉ
The DosCreateThread() function has been enhanced in OS/2 Version 2.0 to
facilitate the creation of secondary threads. Under previous versions of OS/2,
an application was required to explicitly allocate a memory segment for the
stack to be used by a secondary thread. Under OS/2 Version 2.0 however, stack
allocation is performed as a built-in part of the DosCreateThread() function,
and deallocation is performed automatically by the operating system upon
termination of a thread.
Applications that use the DosCreateThread() function should be modified to use
the new form of the function call, as shown in Figure "DosCreateThread()
Function".
Note that the DosCreateThread() function under OS/2 Version 2.0 also allows
parameters to be passed to the thread as part of the DosCreateThread()
function. The third parameter to the function is a 32-bit pointer, which may
be used to pass the address of an application-defined data structure containing
the required parameter data.
The DosCreateThread() function and its implementation under OS/2 Version 2.0
are described in greater detail in IBM OS/2 Version 2.0 Control Program
Reference.
OS/2 Version 2.0 also allows an application to forcibly terminate a thread
using the DosKillThread() function. This function allows an application's
primary thread to terminate any secondary threads prior to its own shutdown, in
a more elegant manner than was possible under previous versions of OS/2.
ΓòÉΓòÉΓòÉ 22.5. Memory Management ΓòÉΓòÉΓòÉ
The 64KB segment size limitation imposed by the Intel 80286 processor
architecture has been eliminated in OS/2 Version 2.0, avoiding the need for
applications to allocate large data structures in individual units of 64KB. The
flat memory model implemented under OS/2 Version 2.0 allows applications to
request the allocation of individual memory objects up to 512MB in size, using
the DosAllocMem() function, an example of which is shown in Figure
"DosAllocMem() Function".
The above example shows the allocation of 73KB of memory as a single memory
object, with read and write access permitted. The PAG_COMMIT flag is set in
the DosAllocMem() function call, in order to commit the storage immediately.
ΓòÉΓòÉΓòÉ 22.6. New Presentation Manager Functions ΓòÉΓòÉΓòÉ
A number of new functions have been added to Presentation Manager under OS/2
Version 2.0. While these functions do not add new capabilities to the
Presentation Manager interface, they simplify application development by
combining operations that previously required multiple steps into a single
Presentation Manager function call.
Table "New Presentation Manager Functions in OS/2 Version 2.0"
A number of other functions are also added in OS/2 Version 2.0, and are used to
deal with the passing of messages between 16-bit and 32-bit modules in
Presentation Manager applications. These functions are discussed in Mixing
16-Bit and 32-Bit Application Modules.
These functions are described in more detail in the IBM OS/2 Version 2.0
Presentation Manager Reference.
ΓòÉΓòÉΓòÉ 22.7. Summary ΓòÉΓòÉΓòÉ
Existing 16-bit applications written for OS/2 Version 1.3 may execute under
OS/2 Version 2.0 without modification. However, significant enhancements to
performance and functionality are possible by taking advantage of additional
features provided by the 32-bit OS/2 Version 2.0 environment. In order to take
full advantage of the 32-bit environment, applications must be modified to use
the new features.
In addition, a number of changes have been made in the 32-bit programming
environment to provide improved consistency and ease of use, simplifying the
task of learning the operating system interfaces and reducing the amount of
coding required by application developers. The incorporation of these changes
into applications will also require source code modification.
It is not necessary for applications to migrate all their modules and resources
to the 32-bit environment, since OS/2 Version 2.0 allows mixing of 16-bit and
32-bit code and resources within the same application. However, 32-bit modules
that make calls to 16-bit modules or resources must be aware of the differences
in addressing schemes between the the 16-bit and 32-bit environments.
ΓòÉΓòÉΓòÉ 23. Mixing 16-Bit and 32-Bit Application Modules ΓòÉΓòÉΓòÉ
Under OS/2 Version 2.0, 32-bit applications may make use of existing 16-bit
application code and resources; this practice is known as mixed model
programming. For example, a 32-bit Presentation Manager application may access
an object window procedure contained in a 16-bit DLL created for OS/2 Version
1.3. This capability allows 32-bit applications to make use of existing
application objects, avoiding the necessity to rewrite existing object
libraries to accommodate the 32-bit programming environment.
Applications that make use of 16-bit modules and resources must be aware of the
particular characteristics of the 16-bit environment, which affect the way that
application modules interface with one another and pass parameters or messages.
Such characteristics include:
Pointers in the 16-bit environment are made up of a segment selector and an
offset; this addressing scheme is therefore known as 16. Pointers in the
32-bit environment are composed of a linear offset only; hence the addressing
scheme is known as 0:32. Note that this difference in representation applies
not only to memory pointers, but also to window and resource handles under
Presentation Manager.
Memory objects passed as parameters between 16-bit and 32-bit routines must
not be greater than 64KB in size, in order to avoid problems with the 16-bit
segmented memory model.
Memory objects passed as parameters from 32-bit applications to 16-bit
routines must not lie across a segment boundary.
Obviously, conversion of pointers and possible realignment of memory objects is
required when passing control between 16-bit and 32-bit modules. This
conversion between addressing schemes is known under OS/2 Version 2.0 as
thunking. Thunking is performed using a simple algorithm known as the
Compatibility Region Mapping Algorithm (CRMA). This algorithm, along with
sample code, is described in OS/2 Version 2.0 - Volume 1: Control Program.
ΓòÉΓòÉΓòÉ 23.1. Function Calls to 16-Bit Modules ΓòÉΓòÉΓòÉ
Thunking considerations affect the way in which a 16-bit function must be
declared within the 32-bit module, and the way in which parameters to be passed
to the 16-bit function are defined. Such functions and parameters must be
declared using the #pragma linkage directive and the far16 keyword, as shown in
Figure "Declaring a 16-Bit Function in 32-Bit Code".
Note the use of the #pragma stack16 directive to set the stack size for all
16-bit function calls made from the 32-bit module.
Declaring a 16-bit function in this manner will cause the operating system to
automatically perform thunking for all "value" parameters (that is, those other
than pointers). Pointers passed as parameters must be explicitly defined using
the _Seg16 keyword, as shown in Figure "Declaring a 16-Bit Function in 32-Bit
Code".
The #pragma linkage and #pragma stack16 directives are discussed in more detail
in the IBM C Set/2 User's Guide.
ΓòÉΓòÉΓòÉ 23.2. Using 16-Bit Window Procedures ΓòÉΓòÉΓòÉ
A 32-bit application may access window procedures that reside in 16-bit
modules, either statically linked or as DLLs. However, the differences between
addressing schemes require some consideration on the part of the developer,
since both the window handles and any pointers passed as message parameters
will differ in their representation.
ΓòÉΓòÉΓòÉ 23.2.1. Creating a Window ΓòÉΓòÉΓòÉ
When a 32-bit application module creates a window, and the window procedure for
that window resides in a 16-bit module (either statically linked or in a DLL),
the calling routine must explicitly declare the 16-bit nature of the window
procedure's entry point when registering the window class. This may become
rather complex, since it involves invoking a 32-bit entry point from a 32-bit
module, but passing a 16-bit entry point as a parameter.
A simpler solution is to build a registration routine within the 16-bit module,
which registers the window class and creates the window. The 32-bit module
then need only invoke this routine, and allow for the resulting 16-bit window
handle. This technique has the added advantage that Presentation Manager
records the fact that the window was registered from a 16-bit module, and will
automatically perform thunking for system-defined message classes. The
technique is illustrated in Figure "Creating a 16-bit Window From Within a
32-bit Module".
Since the 16-bit module would typically be a DLL, the registration routine is
declared in the 16-bit module as an exportable entry point using the EXPENTRY
keyword.
The 32-bit module declares the registration routine MakeMyWindow() as a 16-bit
function using the #pragma linkage directive with the far16 keyword. Since in
16-bit code, the EXPENTRY keyword forces use of the pascal calling convention,
the directive also specifies this calling convention. Note that if the
registration routine and the window procedure were to reside in a DLL, this
declaration would typically take place within a header file provided by the
developer of the DLL.
The 32-bit module invokes the registration routine that registers the window
class and creates the window. The registration routine then returns the window
handle to the 32-bit module, which stores it in 16:16 format. Note that the
registration routine in the 16-bit module is not aware that it is being called
from a 32-bit module.
This approach allows the same DLL to be accessed by both 16-bit and 32-bit
applications concurrently. The developer of the DLL simply provides two
separate header files containing declarations of the DLL's entry points, in the
appropriate format for each programming environment.
ΓòÉΓòÉΓòÉ 23.2.2. Passing Messages to 16-Bit Windows ΓòÉΓòÉΓòÉ
Passing data between 16-bit and 32-bit window procedures via message parameters
also requires consideration of the internal representations of the data types
passed within the parameter. For system-defined message classes, this is
handled automatically by OS/2 Version 2.0, but for application-defined message
classes the conversion between addressing schemes must be handled by the
application, since the operating system has no way of determining the intended
contents of each parameter.
Simple "value" parameters (such as integers, characters, etc.) may be passed
without the need for translation. It is recommended that message parameters be
constructed using the standard Presentation Manager macros described in
Creating Message Parameters.
When a pointer or handle is passed in a message parameter to a 16-bit window
procedure, the pointer or handle must be translated to the 16:16 addressing
scheme by the application. Since the 16-bit module is unlikely to have been
written with code to achieve this conversion, it is the responsibility of the
32-bit module.
Conversion may be achieved using the _Seg16 keyword to explicitly define a
16:16 pointer or handle, which is then placed in a message parameter using the
MPFROMP macro. This is illustrated in Figure "Passing a 16:16 Pointer as a
Message Parameter".
The resulting message parameter may then be passed to a window in a 16-bit
module using the normal WinPostMsg() or WinSendMsg() functions, using a 16:16
window handle obtained in the manner shown in Figure "Creating a 16-bit Window
From Within a 32-bit Module". Note that the data structure referenced by the
pointer may not be greater than 64 KB in size, and must not cross a segment
boundary. This is ensured in Figure "Passing a 16:16 Pointer as a Message
Parameter" by using the #pragma seg16 directive, since a structure defined
using this pragma will automatically be aligned on a segment boundary by the C
Set/2 compiler.
Note also that defining a structure with the #pragma seg16 directive does not
implicitly qualify pointers within the structure with the _Seg16 keyword. Such
pointers must be explicitly qualified, as shown in Figure "Creating a 16-bit
Window From Within a 32-bit Module". Further information on the #pragma seg16
directive can be found in the IBM C Set/2 User's Guide.
A 0:32 pointer may also be converted to a 16:16 pointer using the
DosFlattoSel() function provided by OS/2 Version 2.0. This function provides
the correct remapping of pointer formats from the 32-bit flat memory model to
the 16-bit segmented memory model.
ΓòÉΓòÉΓòÉ 23.2.3. Passing Messages to 32-Bit Windows ΓòÉΓòÉΓòÉ
The technique described above handles messages passed to a window in a 16-bit
module. However, messages passed from that window to the 32-bit module may
also require thunking. In order to perform this thunking, the 32-bit
application may define a thunk procedure and register this procedure to
Presentation Manager, which then invokes the thunk procedure whenever a message
is passed from within the window.
This registration is achieved using the WinSetWindowThunkProc() function, which
is illustrated in Figure "Mixed Model Programming - WinSetWindowThunkProc()
Function".
The WinSetWindowThunkProc() function call is made from the 32-bit module. Since
the window class for the window has been registered in the 16-bit module,
Presentation Manager recognizes that the thunk procedure is to handle 16-bit to
32-bit conversion.
A thunk procedure may be deregistered, by issuing a WinSetWindowThunkProc()
function call with the thunk procedure entry point address set to NULL.
Whenever Presentation Manager invokes a thunk procedure for a message, it
passes the normal four parameters accepted by a window procedure, along with
the entry point address of the window procedure to which the message was to be
passed. This may be the window procedure defined for the destination window
when its class was registered, or a subclass window procedure defined by the
application. Thus thunking may take place, irrespective of whether a window
has been subclassed.
A sample thunk procedure is shown in Figure "Mixed Model Programming - Thunk
Procedure".
The thunk procedure is invoked whenever a message is passed by the window in
the 16-bit module to a window in the 32-bit module. The thunk procedure is
similar in structure to a "normal" window procedure, but need contain cases
only for application-defined message classes, since thunking for system-defined
message classes is performed by Presentation Manager.
Note that since the thunk procedure is invoked by Presentation Manager, it must
use the system linkage convention, and is thus declared using the EXPENTRY
keyword.
In Figure "Mixed Model Programming - Thunk Procedure", the 16-bit window
contains two application-defined message classes, WMP_MSG1 and WMP_MSG2. The
first of these contains pointers in both parameters, and thus both parameters
are thunked by the thunk procedure. The second message class contains a
pointer in the first message paramater only; the second may contain an integer
or some simple value parameter which does not require explicit thunking.
Thunking is performed using the DosSeltoFlat() function provided by OS/2
Version 2.0.
After performing the necessary thunking, the thunk procedure directly calls the
window procedure entry point supplied by Presentation Manager when the thunk
procedure is invoked. Note that this is one of the few instances where direct
invocation of a window procedure should be used. The correct sequence of
message processing is preserved in this case because the thunk procedure itself
is invoked either synchronously or asynchronously by Presentation Manager,
depending upon whether the message was sent or posted by the 16-bit window.
An alternative to the use of the DosSeltoFlat() function is the explicit use of
the Compability Region Mapping Algorithm discussed in OS/2 Version 2.0 - Volume
1: Control Program. This algorithm is implemented in the subroutine CRMA16to32
shown in Figure "16:16 to 0:32 Address Conversion".
The use of the DosSeltoFlat() function should be the preferred option, since
the CRMA routines may fail under certain circumstances. Explicit use of CRMA
should be restricted to those situations where special processing must be
performed on the parameters being passed.
ΓòÉΓòÉΓòÉ 23.3. Summary ΓòÉΓòÉΓòÉ
OS/2 Version 2.0 allows applications and resources from both 16-bit and 32-bit
environments to coexist and communicate. A 32-bit application may make
function calls to 16-bit code, and 16-bit and 32-bit window procedures may pass
messages between one another.
Conversion between the 16:16 and 0:32 addressing schemes is achieved using
thunks, which implement an algorithm known as the Compatibility Region Mapping
Algorithm. The IBM C Set/2 compiler provides transparent thunking for most
function calls and parameters, using the #pragma linkage directive in
conjunction with the _Seg16 keyword.
For threads that will make calls to 16-bit code, the stack must also be aligned
on a 64KB segment boundary, to avoid possible problems with stack overflow in
the 16-bit code. Again, the IBM C Set/2 compiler facilitates this alignment
through use of the #pragma stack16 directive, which causes the thread's stack
to be automatically aligned on a 64KB boundary.
Thunking becomes slightly more complex when communicating between 16-bit and
32-bit window procedures, since pointers passed in message parameters must be
thunked. While Presentation Manager provides transparent thunking for all
system-defined message classes, application-defined messages must be thunked
explicitly by the application.
Presentation Manager provides some assistance to the application developer by
allowing thunk procedures to be registered for a window. Presentation Manager
automatically invokes the thunk procedure whenever a message to passed to that
window from a window of another memory model.
The ability to mix 16-bit and 32-bit code in the same application provides
considerable flexibility and protects investment in existing application
functions and resources. This in turn eases the task of migrating the
organizational development environment from the 16-bit to the 32-bit
environment, since the transition need not be accomplished in a single step.
ΓòÉΓòÉΓòÉ 24. Compiling and Link Editing an Application ΓòÉΓòÉΓòÉ
A Presentation Manager application, written in a high-level language such as C,
is compiled and link-edited in a similar fashion to a regular OS/2 or DOS
application. System Object Model object classes are created in a similar way.
However, additional steps are required for the creation of a Workplace Shell
object class, prior to compilation of the C source code.
This chapter describes the process of creating an executable Presentation
Manager application or system object model object class. The chapter describes
the process of precompilation for system object model object classes, and the
compilation, link edit and resource compilation stages for both system object
model object classes and Presentation Manager applications.
Figure "Development Process for New WPS Classes" shows the overall process used
to create a new class in the Workplace Shell:
The starting point for a system object model class is the class definition file
which, for classes written using the C language, has an extension of .CSC. The
class definition file is used as input to the SOM Precompiler, which will
generate a number of files from the class definition file:
.H A public header file for programs that use the class.
.PH A private header file, which provides usage bindings to any private
methods implemented by the class.
.IH An implementation header file, which provides macros, etc., to support
the implementation of the class.
.C A template C file, to which code may be added to implement the class.
.SC A language-neutral class definition.
.PSC A private language-neutral core file, which contains private parts of
the interface for the class.
.DEF An OS/2 DLL module definition file containing the relevant exports
needed to implement the class.
ΓòÉΓòÉΓòÉ 24.1. Running the SOM Precompiler ΓòÉΓòÉΓòÉ
Once the class definition file has been created, the SOM Precompiler is used to
generate the source files for the class. The options for the SOM Precompiler
are described in detail in the IBM SOM Programming Reference; however, a brief
description of the options used to create the folder example is given below.
ΓòÉΓòÉΓòÉ 24.1.1. The Makefile ΓòÉΓòÉΓòÉ
The instructions to be used are placed into a makefile. The new make facility
NMAKE, provided with the IBM Developer's Toolkit for OS/2 2.0 is extremely
flexible and rich in function. It is recommended that programmers read the
NMAKE section of the IBM OS/2 Version 2.0 Programming Tools Reference if
unfamiliar with makefiles.
The SOM Precompiler environment variables are set as follows:
!if [set SMINCLUDE=.;$(SCPATH);] || \
[set SMTMP=$(SOMTEMP)] || \
[set SMEMIT=ih;h;ph;psc;sc;c;def]
!endif
The use of the !if directive is somewhat confusing, as the statement has
nothing to do with a conditional command. In fact, the OS/2 SET command is
being executed to initialize the environment variables. The NMAKE utility
executes any OS/2 command placed within square brackets in a !if directive.
The SMEMIT environment variable tells the SOM Precompiler which C source files
are to be generated; the suffixes correspond to the file types described
earlier in this chapter.
The SMINCLUDE and SMTMP environment variables are set from two NMAKE macros,
which are defined at the top of the makefile:
SCPATH = D:\toolkt20\sc
SOMTEMP = .\somtemp
The SMINCLUDE variable tells the SOM Precompiler where to find the class
definition (.SC) include files.
The SMTMP variable locates the SOM Precompiler temporary workspace directory.
This brings us to the next part of the makefile that is responsible for
ensuring the existence of the temporary directory.
!if [cd $(SOMTEMP)]
! if [md $(SOMTEMP)]
! error Error creating $(SOMTEMP) directory
! endif
!else
! if [cd ..]
! error Error could not cd .. from $(SOMTEMP) directory
! endif
!endif
This code checks for the existence of the directory and if it cannot be found,
attempts to create it.
ΓòÉΓòÉΓòÉ 24.1.2. SOM Precompiler Invocation ΓòÉΓòÉΓòÉ
The SOM Precompiler is invoked as a consequence of the following NMAKE
inference rule:
.csc.c:
sc $<
This infers that to go from a .CSC file to a ".C" file the SOM Precompiler
(sc.exe) will be invoked on the .CSC file ("$<").
Note that for the folder example, many default SOM Precompiler options are
used. Readers may wish to investigate some of the other options that are
available, by checking the IBM SOM Programming Reference.
ΓòÉΓòÉΓòÉ 24.2. Compiling C Source Code ΓòÉΓòÉΓòÉ
The following files are required to generate a system object model object class
or Presentation Manager application from "C" source code:
Source An application may contain one or more source modules; multiple
source modules are normally bound at link-edit time. However,
application routines may be compiled and placed in a DLL for
binding at execution time.
H An application may use a header file that contains data type
definitions, constants and macro definitions for use by the
application.
DEF A module definition file, while not required for all
Presentation Manager applications, is definitely recommended.
This file contains information for input to the link editor, as
described in Module Definition File.
RC A resource script file contains definitions for Presentation
Manager resources, and/or statements that include resources from
other files.
DLG If an application uses a dialog box, a dialog file is normally
created containing a definition for the dialog box and its
control windows. This file is normally included into the
resource script file using an appropriate statement.
The role of these files in the development of a Presentation Manager
application is illustrated in Figure "Compiling and Linking an OS/2
Presentation Manager Application".
Note that certain additional header files are generated by the SOM Precompiler
and used in compiling a system object model object class. These files are
typically header files used to link the class with its parent, and have no
direct bearing on the compilation process.
The following steps are required to compile and link-edit a Presentation
Manager application:
1. Compile the source file using a high-level language compiler, to produce an
object file (usually with an extension of .OBJ).
2. Link-edit the object file with any other required object files, and
possibly one or more run-time libraries, to create an executable file
(usually with an extension of .EXE).
3. Compile any Presentation Manager resources using the resource compiler, and
incorporate these resources into the application's executable code or place
them in a DLL module.
A number of compiler and link editor options are specified for Presentation
Manager applications; these are shown in the example below. The executable
file may then be run as a Presentation Manager application under OS/2.
Note that the third step above is not required if Presentation Manager
resources are not used by the application. However, it is envisaged that
virtually all Presentation Manager applications will make some use of
resources, due to the benefits to be gained through externalization of
logic-independent or language-specific application components.
Note that the command sequences for compiling and link editing an application
may be combined and placed in a parameterized OS/2 command file for automated
execution. Alternatively, a makefile may be created and the NMAKE utility used
to compile and link edit the application.
ΓòÉΓòÉΓòÉ 24.2.1. Module Definition File ΓòÉΓòÉΓòÉ
The module definition file is a simple text file required by most Presentation
Manager applications. Module definition files are used when link editing both
programs and dynamic link libraries. By convention, the module definition file
has the same name as the program or library source file, but with an extension
of DEF.
A sample module definition file for a simple Presentation Manager application
is shown in Figure "Sample Module Definition File for Presentation Manager."
A module definition file normally begins with a NAME or LIBRARY statement,
which identifies the module as a program or DLL respectively, and assigns it a
module name. The keyword WINDOWCOMPAT may be used to specify a full-screen
application that may be run in a Presentation Manager text window, or WINDOWAPI
may be used to specify a full Presentation Manager application.
The module definition file also contains a DESCRIPTION entry, containing text
that is embedded by the link editor into the header of the executable module.
This text may contain information such as a copyright notice or author
information concerning the module.
The PROTMODE keyword should be used to indicate that the application will be
run only in protect mode under OS/2 (note that this is a standard provision;
all Presentation Manager applications must run in protect mode). This allows
the link editor to shorten the header in the executable module.
The STUB keyword instructs the link editor to set up a stub file that generates
an error message if the user attempts to execute the application in a DOS
environment. OS2STUB.EXE is a DOS executable file that performs this function,
and is provided with the IBM Developer's Toolkit for OS/2 2.0.
A DATA statement may be used in the module definition file to indicate the
disposition of data segments created by the module. Data segments may be
specified as SHARED, NONSHARED or NONE. If SHARED is specified, different
processes using the code segments of a dynamic link library will share the same
data segments; if NONSHARED is specified, the operating system will create a
new set of data segments for each process using a DLL. NONSHARED is
recommended.
The STACKSIZE and HEAPSIZE statements specify the size of the memory areas to
be reserved for the application's stack and for the local heap in the program's
automatic data segment. Note that the recommended minimum stack size for
Presentation Manager applications is 8 KB. Note also that STACKSIZE is not
used for dynamic link library modules, since a DLL has no stack (see Creating a
DLL).
The module definition file may also contain an EXPORTS statement for all
exportable entry points (such as window procedures) window procedures contained
in the module. This statement causes the entry points for window procedures to
be defined in the header of an executable module, so that they may later be
called from outside the current executable module (since window procedures are
actually invoked by Presentation Manager on behalf of the application, rather
than directly by the application itself).
An IMPORTS statement may be used to define the entry points for those functions
and/or resource definitions that will be imported from a dynamic link library.
However, an IMPORTS statement is not required if an import library is being
link edited with the application (see Using a DLL).
The module definition file, and the statements it may contain, are described
fully in the IBM OS/2 Version 2.0 Application Design Guide.
ΓòÉΓòÉΓòÉ 24.2.2. Compiler Options ΓòÉΓòÉΓòÉ
Using the IBM C Set/2 compiler, the following command sequence is recommended:
cc /C+ /L+ /G3 /Ti+ MYPROG
The /C+ option indicates that only the compile step should be run, and not the
link-edit step, which is then performed explicitly at a later point using the
LINK386 utility. The /L+ option causes the compiler to produce a source
listing file.
The /G3 option optimizes the code for execution on an Intel 80386 processor.
The code will also execute on an 80486 processor. However, for code that will
mainly be executed on 80486 hardware, use of the /G4 option is recommended.
See the IBM C Set/2 User's Guide for further information.
The /Ti+ option instructs the compiler to generate symbolic debugging
information which may then be used when debugging the application with the IBM
C Set/2 debugging tool.
ΓòÉΓòÉΓòÉ 24.3. Link Edit ΓòÉΓòÉΓòÉ
When using the IBM C Set/2 compiler, an application may be compiled and
link-edited in a single operation. The following command sequence is used to
compile and link edit a program for Presentation Manager under OS/2 Version
2.0:
CC /L- /G3 /Ti+ /Gm+ MYPROG OS2386.LIB MYPROG.DEF
This command sequence directs the linkage editor to compile the file MYPROG.C
to produce an object file named MYPROG.OBJ, and to link this file to produce an
executable file named MYPROG.EXE, without creating a list file, to use the
run-time library named OS2386.LIB and the module definition file named
MYPROG.DEF.
Note the use of the /Gm+ option. This option causes the multithreading "C"
run-time libraries to be used in linking, thereby enabling multithreadingin the
resulting application code.
ΓòÉΓòÉΓòÉ 24.4. Resource Compilation ΓòÉΓòÉΓòÉ
Presentation Manager resources used by the application and defined in a
resource script file are compiled using the resource compiler provided in the
IBM Developer's Toolkit for OS/2 2.0. The command sequence used to invoke the
resource compiler is as follows:
rc MYPROG.RC MYPROG.EXE
This command sequence causes the resource compiler to read the resource
definitions from the resource script file MYPROG.RC and compile them to produce
an intermediate resource file MYPROG.RES, which is then incorporated into the
executable module MYPROG.EXE.
Resources may also be compiled and incorporated into dynamic link libraries,
simply by specifying the name of the DLL rather than the EXE file when invoking
the resource compiler. Note that certain additional considerations may apply;
see Presentation Manager Resources in a DLL for further information.
Note that under OS/2 Version 2.0, 32-bit applications may use existing 16-bit
application modules and resources. This concept is known as mixed model
programming, and is discussed in Mixing 16-Bit and 32-Bit Application Modules.
ΓòÉΓòÉΓòÉ 24.5. Dynamic Link Libraries ΓòÉΓòÉΓòÉ
Since window procedures that communicate using the standard Presentation
Manager message conventions have no exterior interfaces aside from these
messages, window procedures are essentially "black boxes" and are invisible to
the application. It is thus possible to produce a number of window procedures
to perform standard or often-used functions, and to store these window
procedures in a library from which they may be accessed by a number of
applications.
The recommended way to achieve this capability is to place such window
procedures in an OS/2 dynamic link library. [See Dynamic Linking for an
explanation of the concept of dynamic linking. ] Applications using these
window procedures then reap the benefits of DLLs; namely that changes to window
procedures contained in the DLLs do not require the applications to be
re-linked and that multiple applications may use the same memory-resident copy
of the window procedure code, since DLLs are re-entrant. The use of DLLs
therefore maximizes the potential for code reuse, and facilitates the
containment of change within a single application module.
Note that where existing 16-bit DLLs contain application objects, functions or
resources required by 32-bit applications under OS/2 Version 2.0, these
applications may access the 16-bit DLLs. This technique, known as mixed model
programming, is discussed in Mixing 16-Bit and 32-Bit Application Modules.
ΓòÉΓòÉΓòÉ 24.5.1. Creating a DLL ΓòÉΓòÉΓòÉ
To build a DLL from a particular source code module, the code is compiled in a
similar manner to that used for any other Presentation Manager application
code. However, use of the /Ge- option will cause the C Set/2 compiler to
produce a DLL module.
CC /L- /G3 /Ti+ /Gm+ /Ge- MYDLL OS2386.LIB MYDLL.DEF
This command sequence instructs the compiler to take the file MYPROG.C, to
compile and link edit it to produce a dynamic link library named MYPROG.DLL,
and to use the file named MYPROG.DEF as input to the linking process. Use of
the /Gm+ option enables multithreading, and use of the /Ge- option directs C
Set/2 to produce a DLL module.
A sample module definition file for use when creating a DLL is shown in Figure
"Sample Module Definition File to Create a DLL":
The following rules apply to module definition files when used to create
dynamic link libraries:
The LIBRARY statement must be used, and the module name declared must be the
same as the file name of the DLL. The keywords INITINSTANCE and TERMINSTANCE
may be used to indicate that any initialization code should be executed for
each process which accesses the DLL.
If the DLL will be accessed by separate processes within the system, separate
data segments should be created for each process; this is achieved by
specifying DATA MULTIPLE in the module definition file
The STACKSIZE statement must not be used since a DLL does not use a stack.
An EXPORTS statement must be included, defining each function that will be
exported from the DLL.
The DLL module must be copied to a directory referenced by the LIBPATH
statement in CONFIG.SYS. This is typically the C:\OS2\DLL directory, although
another directory may be used if so desired.
ΓòÉΓòÉΓòÉ 24.5.2. Using a DLL ΓòÉΓòÉΓòÉ
When an application is to use functions contained in a DLL, these functions
must first be declared at compilation time. This is typically achieved by the
use of an include file containing function prototypes for all exportable entry
points within the DLL; such an include file is normally created along with the
DLL and supplied to all application developers who will use the DLL.
Once the functions are declared within the application's source code, the
external references must be resolved at the time the program is link edited.
This may be performed in one of two ways:
The functions may be identified in the application's module definition file
using an IMPORTS statement, as described in Module Definition File. For
example, the statement:
IMPORTS MYPROG.func1
defines the function func1, which will be imported from a DLL named
MYPROG.DLL.
The functions may be included in an import library, which is a library
specified at link edit time. An import library is created using the IMPLIB
utility provided with the IBM Developer's Toolkit for OS/2 2.0. For example,
the command:
implib MYLIB.LIB MYLIB.DEF
causes IMPLIB to create an import library named MYLIB.LIB, using information
contained in a module definition file named MYLIB.DEF. The import library
file should be placed in a directory referenced by the INCLUDE environment
variable.
Note that the file OS2.LIB, used when link editing OS/2 application programs,
is in fact an import library containing definitions for OS/2 system functions
that are themselves implemented using DLLs.
ΓòÉΓòÉΓòÉ 24.5.3. Presentation Manager Resources in a DLL ΓòÉΓòÉΓòÉ
As noted in Dynamic Linking, Presentation Manager resources may be defined and
stored in a DLL for use by multiple applications. However, the implementation
of dynamic linking under OS/2 requires that each DLL must contain an executable
module, and resources are not executable modules in their own right. If a DLL
will contain only resources and will not contain an executable routine such as
a dialog procedure, a dummy executable module must be provided for the DLL by
the application developer, as shown below:
int ARCTUSED = 1;
void EXPENTRY dummy()
{
}
The declaration for the variable ARCTUSED is provided in order to avoid an
error generated by the IBM C/2 compiler when it cannot find a module named main
within the source file.
Editor's Note: The above statement may not be true for the C Set/2 compiler.
This must be determined.
This dummy module is compiled and link-edited into an executable file in the
normal way. The resource compiler is then used to compile and incorporate the
resource definitions into the executable file.
ΓòÉΓòÉΓòÉ 24.5.4. Using Dialogs in System Object Model Objects ΓòÉΓòÉΓòÉ
In the folder example, a dialog box is used to prompt the user for the folder's
password, and for the user to enter the password. Creating and invoking the
dialog is done in the normal way. However, invoking an object's methods from
within a dialog procedure requires that the dialog procedure know the pointer
to the object that invokes the method (that is, somSelf). This is done through
the use of the pCreateParams parameter of the WinDialogBox() function. In this
way, the pointer to somSelf is passed to the dialog procedure as follows:
pCreateParams = (PVOID)somSelf;
The dialog procedure may then store the pointer in the reserved window word
QWL_USER:
case WM_INITDLG:
WinSetWindowULong(hwndDlg, /* Set window word */
QWL_USER, /* Offset of window word */
(ULONG) mp2); /* Value to be stored */
break;
When an instance method must be invoked from the dialog procedure, the object
pointer may easily be retrieved from the window words and used to invoke the
method.
{
PWFolder *aPWF; /* Object pointer */
PWF_INFO pwfolderInfo; /* Folder info struct */
aPWF = (PWFolder *)WinQueryWindowULong( /* Get object pointer */
hwndDlg, /* Dialog box handle */
QWL_USER); /* Offset of win word */
_QueryInfo( /* Invoke method */
aPWF, /* Object pointer */
&pwfolderInfo); /* Folder info struct */
}
In the above example, a WinQueryWindowULong() call is used to retrieve the
object pointer from the window word, and store it in aPWF. This variable is
then used as the first parameter when invoking the method _QueryInfo.
Note that the method name _QueryInfo is in fact fully defined as
pwfolder_QueryInfo. However, as noted in C Implementation of an Object Class,
the SOM Precompiler automatically generates a macro to define the abbreviated
form of the function name, in order to avoid the necessity for the programmer
to type the full name.
ΓòÉΓòÉΓòÉ 24.6. Summary ΓòÉΓòÉΓòÉ
The steps required in compiling and link-editing a Presentation Manager
application are generally similar to those required to generate any other OS/2
application. Some files are required in addition to those used by a
"conventional" application, due to Presentation Manager's use of externalized
definitions for application resources such as menus, string tables and dialog
boxes.
The module definition file provides a mechanism whereby various attributes of
an application or dynamic link library may be specified. The module definition
file also allows the developer to specify copyright information that is
imbedded in the executable code.
The creation of dynamic link libraries, while essentially similar to that of
normal application code, requires certain special considerations, notably with
regard to the module definition file and the options that are specified at
link-edit time. Code modules and Presentation Manager resources that are
likely to be subject to change, or are of a potentially reusable nature may be
placed in dynamic link libraries and thus isolated from the remainder of the
application. The remainder of the application code is thus protected from
changes that may be necessary to these dynamic link libraries in order to
accommodate changes in such areas as organizational procedures or government
legislation. Dynamic link libraries may also be used by multiple applications
concurrently, by virtue of their reentrant nature.
ΓòÉΓòÉΓòÉ 25. Adding Online Help and Documentation ΓòÉΓòÉΓòÉ
In line with the philosophy of making applications easy to use through the
provision of an intuitive, graphical user interface, it is extremely useful to
have an application provide online, context-sensitive help and tutorial
facilities to the end user. Such facilities further encourage learning by
exploration.
Presentation Manager provides such capabilities in the form of the Information
Presentation Facility (IPF), which allows help panels to be generated and
displayed in help windows under Presentation Manager. These help windows are
linked with the normal application windows in such a way that when the user
presses the "Help" key, selects a "Help" item from the menu bar or presses a
"Help" button in a dialog box, the appropriate help window is displayed.
In addition to providing online help for Presentation Manager applications, IPF
can also be used in a stand-alone mode, to provide online documentation for
applications, or for business procedures that are independent of any single
application. Using capabilities provided by IPF, an online procedure manual
may initiate appropriate applications, thus providing a "real-life" tutorial
capability for new or inexperienced users.
This chapter will describe the use of IPF for creating help libraries and
online documents, and examine some ways in which IPF may improve the
ease-of-use of Presentation Manager applications.
ΓòÉΓòÉΓòÉ 25.1. Creating Help Information ΓòÉΓòÉΓòÉ
Help information is created in ASCII source files using an IPF tag language,
which embeds formatting tags in the text. These tags define the formatting
characteristics of the text which appears in help windows, and the appearance
of the windows themselves. Once the source files are created, the IPF compiler
is then used to translate the source files into an IPF library format. The IPF
compiler can generate a table of contents and an index for help information.
ΓòÉΓòÉΓòÉ 25.1.1. IPF Tag Language ΓòÉΓòÉΓòÉ
The IPF tag language is similar in structure and syntax to the Generalized
Markup Language (GML) used by IBM's Document Composition Facility* (DCF*)
product. Source files are simple ASCII text files, and can be created using
any normal text editor.
Tags are embedded in the files simply by inserting the tag into the text at the
required point. For example, this document was created and formatted using GML
tags, and the opening sentences of this chapter were created using the format
shown in Figure "IPF Tag Language Example".
Note that the chapter heading is preceded by a "header level 1" tag which
causes the header text to be formatted in a particular manner. Similarly, the
header is followed by a "paragraph" tag which caused a new paragraph to begin.
The formatting of the text within the source file is not significant; there is
no requirement for a tag to begin at the left margin, or for each tag to begin
on a separate line. A developer may organize the source files in the most
appropriate manner for readability.
The first statement in a source file must be a :userdoc tag, and the last
statement must be a :euserdoc tag. These tags are required by IPF. Comments
may also be imbedded within a source file using the :* tag; comments are
ignored by the IPF compiler, and do not appear in the formatted text.
A complete description of the formatting tags available under the IPF tag
language is beyond the scope of this document. Some examples are given in the
remainder of this chapter, and each tag is described in detail in the IBM OS/2
Version 2.0 Information Presentation Reference.
ΓòÉΓòÉΓòÉ 25.1.2. Defining Help Panels ΓòÉΓòÉΓòÉ
The IPF tag language contains "header" tags with levels from 1 to 6; by
default, levels 1 to 3 define the start of a new help panel, and are
automatically included in the table of contents for online documentation. Each
help panel therefore begins with one of these header tags, followed by the help
text to be displayed within that panel.
Figure "Simple Help Panel Source"
The res= attribute specified in the :h1 through :h6 tags is used by IPF to
uniquely identify the help panel, and to enable an application to link to that
panel when the user requests help. See Linking Help Windows With Applications
for further information.
The x=, y=, cx= and cy= attributes define the position and size of the window
within its parent. In the case of a help window, the parent is the application
window from which the help window was invoked.
The header levels 1 to 3 are used when organizing help panels within the table
of contents. Panels defined with header level 3 are grouped under the last
defined header level 2, and those defined with header level 2 are similarly
grouped under the last defined header level 1. Thus the order of definition
within the source file is significant.
Note that multiple help panels may be placed within a single source file,
simply by including additional header tags. By default, header levels 4 to 6
will not cause the display of a new help window, but will appear as formatted
subject headings within a help panel.
ΓòÉΓòÉΓòÉ 25.1.3. Displaying Graphics ΓòÉΓòÉΓòÉ
In addition to text information, graphics may also be displayed in help panels.
Either character graphics or bitmaps may be used. Character graphics are
embedded directly within the help text, using the :xmp tag to ensure correct
formatting. Bitmaps are referenced from within the help text using the
:artwork tag. An example of this tag is shown in Figure "Displaying a Bitmap
in a Help Window".
The align= attribute on the :artwork tag allows a bitmap to be aligned either
left-justified, right-justified or centered in the window. In situations where
the bitmap must fill the entire window, the fit attribute may be specified,
which causes the bitmap to be scaled to fit the window size.
ΓòÉΓòÉΓòÉ 25.1.4. Hypertext and Hypergraphics ΓòÉΓòÉΓòÉ
Help windows may be nested through the use of links embedded within the help
information. Both text and graphics may be defined as selectable; selection of
these items can then be used to trigger events such as:
Display of another help window with supporting help text
Dispatch of message to the application window which invoked the help window
Initiation of a new application.
Selectable items are known as links; text items are hypertext links, and
graphical items are hypergraphic links. Each of these link types is described
in the following sections.
Hypertext Links
Text items are defined using the :link tag, which defines the type of event
triggered by the link operation, and details of the target object activated by
the link. An example of a :link tag is shown in Figure "Hypertext Link".
The :link tag shown in the example above uses the reftype= attribute to
identify the type of event to be triggered (in this case, the display of
another help window). The res= attribute identifies the help window to be
displayed when the hypertext item is selected.
Different values for the reftype= attribute will trigger different types of
events:
Specifying reftype=hd causes the display of another help window, as shown in
Figure "Hypertext Link". The res= attribute must also be specified in order
to identify the help window to be displayed.
Specifying reftype=fn causes the display of a popup window containing a
footnote. The refid= attribute must also be specified in order to identify
the footnote.
Specifying reftype=inform causes a message to be sent to the application
window which invoked the help window. The res= attribute must also be
specified, and its value is passed back to the application.
Specifying reftype=launch causes another application to be started by the
operating system. The name of the program to be started is specified in the
object= attribute, and parameters may be passed to the program in the data=
attribute.
The use of hypertext links provides a powerful means to develop sophisticated
help text and online documentation, and to implement tutorials and
"self-teaching" applications. This subject is discussed further in
Self-Teaching Applications.
Hypergraphic Links
Bitmapped graphic items are defined in a slightly different manner to text
items, using the :artlink tag. The :artlink tag is specified on the line
immediately following the :artwork tag in the source file.
Multiple :artlink tags may be defined for the same bitmap, in order that the
user may select different portions of the bitmap to trigger different events.
If multiple :artlink tags are specified however, they must be placed in a link
file, which is referenced using the linkfile= attribute to the :artwork tag.
Both techniques are illustrated in Figure "Hypergraphic Link".
The use of a link file is mandatory where multiple hypergraphic links exist for
the same bitmap. The format of a link file is shown in Figure "Link File With
Multiple Hypergraphic Links".
Multiple :link tags are nested within a single :artlink tag, and define various
selectable areas of the bitmap, each of which triggers a specific event when
selected by the user. Any of the types of events normally triggered by a :link
tag may be initiated from a hypergraphic link.
ΓòÉΓòÉΓòÉ 25.1.5. Viewports ΓòÉΓòÉΓòÉ
Information within help windows is displayed in viewports. In the default case,
a single viewport is defined that occupies the entire help window and contains
the text. This is known as a simple viewport. However, multiple viewports may
be defined within the same help window, and handled separately. For example,
two viewports may be defined in a help window; the first may be used to
display a graphical diagram, while the second may contain a text narrative
relating to the diagram. The user may scroll the text in the window, but the
diagram remains displayed since it lies in a separate viewport. This type of
definition is known as a complex viewport.
Multiple viewports are normally defined within a help window using :link tags
which are known as automatic links. These operate in a similar manner to
hypertext links, but are invoked automatically when the help window is
displayed. An example of a help window containing such links is shown in
Figure "Multiple Viewports Using Automatic Links".
The auto attribute specifies that the viewport is to be opened automatically
when its parent help window is opened. The dependent attribute specifies that
the viewport is to be closed when its parent is closed. The vpx=, vpy=, vpcx=
and vpcy= attributes specify the position and size of the viewport within the
parent window. In Figure "Multiple Viewports Using Automatic Links", two
viewports are opened, positioned side-by-side within the parent window.
The scroll=, titlebar= and rules= attributes determine whether each viewport
possesses its own scroll bars, title bar and sizing borders. In Figure
"Multiple Viewports Using Automatic Links", neither viewport contains a title
bar or sizing border (both make use of the parent's title bar and border), but
the right-hand viewport contains its own scroll bar. This allows the
right-hand viewport to be scrolled while the left-hand viewport remains
unchanged.
IPF-Controlled Viewports
By default, the presentation of information in viewports is under the control
of IPF, using instructions defined in the source files. Such viewports are
known as IPF-controlled viewports. When an IPF-controlled viewport is used,
text is automatically formatted within the viewport by IPF, and presented in
the help window.
Application-Controlled Viewports
A viewport may also be defined as an application-controlled viewport, using the
:acviewport tag. This tag allows an application to take direct control of a
viewport, and to present information in this viewport in a manner determined by
that application. For example, a full-motion video application could be used
to display information in video format.
The :acviewport tag is shown in Figure "Application-Controlled Viewport".
The :acviewport tag causes IPF to load a dynamic link library as specified in
the dll= attribute, and to pass control to the entry point identified by the
objectname= attribute.
ΓòÉΓòÉΓòÉ 25.2. Compiling Source Files ΓòÉΓòÉΓòÉ
Once the text has been generated in source files, it must be compiled in order
to produce a help library. By default, source files have an extension of IPF.
The IPF compiler does not require this extension, but if the compiler finds two
files with the same name, the file with the IPF extension is used in the
compilation.
For source files that will be used to produce online documents rather than help
libraries, the extension INF should be used. See Stand-Alone Online
Documentation for further information.
ΓòÉΓòÉΓòÉ 25.2.1. The IPFC Command ΓòÉΓòÉΓòÉ
The IPF compiler is invoked using the IPFC command, as follows:
IPFC SOURCE.IPF /X /W3 >ERRORS.TXT
The above command invokes the IPF compiler with the input file SOURCE.IPF. The
/X parameter instructs the compiler to produce a cross-reference listing for
all headings, diagrams, etc. The /Wn command specifies the level of
error-reporting to be performed; valid levels are 1 (/W1) to 3 (/W3). The
final parameter pipes any error messages to the file ERRORS.TXT in order that
they may be examined later. The IPFC command is fully documented in the IBM
OS/2 Version 2.0 Information Presentation Reference.
When creating online documentation that will function in a stand-alone format
rather than as help associated with an application, the /INF parameter is
specified. This causes the IPF compiler to search for source files with the
INF extension, and to format the output for use with the online viewing utility
VIEW.EXE.
ΓòÉΓòÉΓòÉ 25.2.2. National Language Support ΓòÉΓòÉΓòÉ
Support for languages other than U.S. English may be provided in help files by
specifying the /COUNTRY, /CODEPAGE and /LANGUAGE parameters in the IPFC
command. These parameters affect the collating sequence used when creating a
table of contents or index, and the titles displayed for note (:nt), warning
(:warning) and caution (:caution) tags.
These parameters and the use of national languages in help windows and online
documentation is described in more detail in the IBM OS/2 Version 2.0
Information Presentation Reference.
ΓòÉΓòÉΓòÉ 25.3. Linking Help Windows With Applications ΓòÉΓòÉΓòÉ
In order for an application to display help information using IPF, a number of
steps must be performed to link the application's windows with the
corresponding help windows. Each of these steps is described in the following
sections.
ΓòÉΓòÉΓòÉ 25.3.1. Creating a Help Table ΓòÉΓòÉΓòÉ
A help table is a Presentation Manager resource, and is defined in a resource
script file using the HELPTABLE resource. An example of a help table is shown
in Figure "Help Table Resource Definition".
The HELPITEM resources within the help table define each application window for
which help is to be provided, and point to a HELPSUBTABLE resource. Each
HELPITEM resource also defines the panel identifier of the optional extended
help panel for that window.
A HELPSUBTABLE resource is defined for each window, and contains HELPSUBITEM
resources that identify each item within the window for which help is to be
provided, and the panel identifier of the help panel for that item.
For example, Figure "Help Table Resource Definition" shows a main window with
the window identifier MAIN, and a dialog box with the identifier DIALOG1. A
subtable is defined for MAIN, which defines the menu bar items within that
window, and identifies a help panel for each of these items. For DIALOG1, the
subtable specifies the identifiers of the control windows within the dialog
box, and identifies a help panel for each control window. The identifiers of
the help panels must correspond to the identifiers specified in the res=
attribute of the header tags.
ΓòÉΓòÉΓòÉ 25.3.2. Creating a Help Instance ΓòÉΓòÉΓòÉ
Once the help table for an application has been created, the application must
pass this help table to IPF and create a help instance, using the
WinCreateHelpInstance() function. This function is shown in Figure
"WinCreateHelpInstance() Function".
The WinCreateHelpInstance() function is normally called from an application's
main routine, immediately after creating the application's main window, but
before entering the message processing loop.
The WinCreateHelpInstance() function creates the application's main help
window, which is initially invisible, and passes appropriate information to
that window to enable the specified help library to be loaded and access to be
obtained to required resources. See Main Help Window.
ΓòÉΓòÉΓòÉ 25.3.3. Associating a Help Instance ΓòÉΓòÉΓòÉ
Once the help instance has been created, it must be associated with an
application window. The help instance is normally associated with the
application's main frame window, and help may therefore be provided for any
children of the frame window, including the menu bar and client window. The
WinAssociateHelpInstance() function is used to associate a help instance with
an application window; an example of this function is shown in Figure
"WinAssociateHelpInstance() Function".
The WinAssociateHelpInstance() function is normally called from the
application's main routine, immediately following the WinCreateHelpInstance()
function call.
ΓòÉΓòÉΓòÉ 25.3.4. Ending a Help Instance ΓòÉΓòÉΓòÉ
Upon termination of the application, the help instance should be ended using a
WinDestroyHelpInstance() function call, as shown in Figure
"WinDestroyHelpInstance() Function".
This function is invoked immediately after termination of the application's
message processing routine, and prior to destroying the application's main
window.
ΓòÉΓòÉΓòÉ 25.4. Displaying Help Panels ΓòÉΓòÉΓòÉ
Help panels are displayed in help windows by IPF as a result of user
interaction. A user may cause a help panel to be displayed in one of three
ways:
Hitting the F1 key
Selecting a "Help" item on the menu bar or a pulldown menu
Pressing a Help pushbutton in a dialog box.
Each of these actions normally results in a WM_HELP message being generated.
This message is trapped by IPF, which then determines the active application
window and uses the current help table to identify the help panel for that
window.
ΓòÉΓòÉΓòÉ 25.4.1. F1 Key ΓòÉΓòÉΓòÉ
Under the default accelerator table maintained by Presentation Manager for all
windows, the F1 key causes a WM_HELP message to be generated and posted to the
queue for the window that possessed the input focus when the key was pressed.
Explicit definition of the accelerator key by the application is not required.
ΓòÉΓòÉΓòÉ 25.4.2. Help Menu Bar Item ΓòÉΓòÉΓòÉ
A "Help" menu bar item, whether it is defined on the menu bar or in a "Help"
pulldown menu, should be defined using the MIS_HELP style. This will cause the
item to generate a WM_HELP message, rather than a WM_COMMAND message. The
definition of such an item is shown in Figure "Resource Script File".
ΓòÉΓòÉΓòÉ 25.4.3. Help Pushbutton ΓòÉΓòÉΓòÉ
A "Help" pushbutton in a dialog box should be defined using the BS_HELP and
BS_NOPOINTERFOCUS styles. The WM_HELP message is passed to IPF, which then
determines the control window within the dialog box that currently possesses
the input focus, and displays the help panel for that control window.
ΓòÉΓòÉΓòÉ 25.5. Main Help Window ΓòÉΓòÉΓòÉ
The WinCreateHelpInstance() function returns a window handle. This is the
handle of the application's main help window. The main help window is created
by IPF, with a standard format and with a window procedure supplied by
Presentation Manager. Whenever a help panel is displayed, it appears as a
child window of the main help window.
The main help window has a title bar, which contains a title specified by the
application. The application passes this title in the pszHelpWindowTitle
parameter to the WinCreateHelpInstance() function.
The main help window contains a menu bar with several pulldown menus allowing
the user to perform text searches, view the index, etc. An application
developer may modify this menu bar using the resource definitions contained in
the hmtailor.rc file provided with IPF. This file includes an hmtailor.h file,
which contains the integer constant definitions for the menu bar and pulldown
menu items. Additional items may be defined within the help pulldown menu, but
their resource identifiers should be between 7F00 and 7FFF to avoid conflicts
with identifiers already defined.
When the menu bar of the main help window has been modified, it must be
resource-compiled in the normal way, and combined with the application's
executable file or with a DLL. Its resource identifier must then be specified
in the idActionBar parameter of the WinCreateHelpInstance() function call. If
additional accelerator keys have been defined, the identifier of the
accelerator table must also be defined in the idAccelTable parameter.
If the menu bar and accelerator table definitions have been combined with a
DLL, the module handle of this DLL must be specified in the
hmodAccellActionBarModule parameter. The module handle must first be obtained
using the DosLoadModule() or DosGetModuleHandle() functions. These functions
are described in Loading Resources From a DLL.
ΓòÉΓòÉΓòÉ 25.5.1. The Help Pulldown Menu ΓòÉΓòÉΓòÉ
The menu bar of the main help window contains a "Help" pulldown menu which in
turn contains a number of options. The resource definition for this pulldown
menu is included in the hmtailor.rc file provided with IPF, and illustrated in
Figure "Help Pulldown Menu Definition".
When the user selects an item from the help pulldown menu, a message is
generated, and is trapped by IPF and processed. Typically, this message causes
IPF to query the application for the correct help panel. The message generated
is dependent upon the pulldown menu item selected by the user.
Help For Help
When the user selects this item, IPF sends a WM_COMMAND message to the active
application window, with the first parameter containing the ID_HELP_FOR_HELP
identifier. The application's window procedure should process this message by
sending an HM_REPLACE_HELP_FOR_HELP message containing the panel identifier of
its own "Help for help" panel if one exists, or by sending an HM_DISPLAY_PANEL
message with both parameters set to zero in order to display the default panel.
Extended Help
When the user selects this item, IPF responds by displaying the "Extended help"
panel defined for the active application window in the help table. If no such
help panel is defined for that window, IPF sends an HM_EXT_HELP_UNDEFINED
message to the application (see Communication Between IPF and Applications
(HM_EXT_HELP_UNDEFINED)).
Keys Help
When the user selects this item, IPF sends an HM_QUERY_KEYS_HELP message to the
active application window. The application's window procedure should process
this message by returning the panel identifier of its own "Keys help" panel in
the return code to Presentation Manager.
Help Index
Selecting this item causes IPF to display the index of the current help
library.
ΓòÉΓòÉΓòÉ 25.5.2. Communication Between IPF and Applications ΓòÉΓòÉΓòÉ
Information may be communicated from IPF to an application in response to user
interaction in a help window. This information may be in the form of
application events or errors, and is communicated to the application in the
form of a message passed to the application window specified in the
WinCreateHelpInstance() function. Such messages originate from the main help
window, as part of the window procedure supplied by Presentation Manager for
that window.
HM_INFORM Message
This message is passed to the application when the user selects a hypertext or
hypergraphic item in a help window, for which the reftype=inform attribute has
been specified. The first parameter of the HM_INFORM message contains the
identifier specified by the res= attribute in the hypertext or hypergraphic
link definition.
An application window typically processes the HM_INFORM message by examining
the identifier in the first message parameter, and dispatching a message of the
appropriate class to itself or another application window, in order to initiate
the action requested by the HM_INFORM message.
HM_ERROR
This message is passed to the application when an error occurs during a user
interaction with a help window. This message allows the application to display
its own error message in such cases, thereby providing a consistent appearance
for error messages. The first parameter of the message indicates the reason
for the error. These reasons are documented in the IBM OS/2 Version 2.0
Information Presentation Reference.
An application typically processes the HM_ERROR message by displaying an
appropriate message box and returning zero to Presentation Manager. If the
application does not process the message, Presentation Manager takes no action.
HM_EXT_HELP_UNDEFINED
This message indicates that the user selected the "Extended help" item on the
"Help" pulldown menu, and that no such help panel was defined for the active
application window.
An application may process this message in one of three ways:
Display a message box indicating that no help is available
Display its own help window by explicitly creating and displaying the window
on the screen
Pass a HM_DISPLAY_HELP message back to IPF, instructing IPF to display a
particular help panel.
If the application does not process this message, no panel is displayed and the
user's request is simply ignored.
HM_SUBITEM_NOT_FOUND
This message indicates that the user issued a help request on an item for which
no help panel is defined in the current help table. The application may
process this message in one of three ways, as described in
HM_EXT_HELP_UNDEFINED above. The application should then return TRUE to
Presentation Manager.
If the application does not process this message, the extended help panel for
the currently active window is displayed by IPF.
ΓòÉΓòÉΓòÉ 25.6. Stand-Alone Online Documentation ΓòÉΓòÉΓòÉ
Panels containing text produced using IPF need not be called from an
application; IPF can be used to produce "stand-alone" online documentation,
which is viewed using the VIEW.EXE utility provided with OS/2 Version 2.0.
Online documents have similar capabilities to help libraries; both text and
graphics may be included, and hypertext and hypergraphic links are supported.
Online documents also have a number of differences from help libraries:
In an online document, a panel may be identified by using the name= or id=
attributes in the heading, rather than the res= attribute. These attributes
allow the use of alphanumeric characters, where the res= attribute must
specify an integer identifier. Links are then defined using the refid=
attribute in the :link tag.
Note that the name= or id= attributes may not be used if files will be
concatenated and hypertext or hypergraphic links are required between files.
Online documents may not use hypertext or hypergraphic links with
reftype=inform, since there is no associated application for the help
instance, and IPF cannot determine the window to which the message should be
directed.
An online document has a main window created by IPF, which contains the table
of contents for the document. The title of this main window is determined by
a :title tag.
Note that the :title tag may only be used for online documents, and not for
help libraries. The title of an application's main help window is specified
in the WinCreateHelpInstance() function call.
The ability to include hypertext and hypergraphics in online documents allows
the creation of online procedure manuals that automatically invoke the
appropriate application or applications for each step of the procedure. This is
achieved by defining the hypertext or hypergraphic items with reftype=launch,
specifying the name of the executable file for the required application. See
Self-Teaching Applications for further discussion of such applications.
ΓòÉΓòÉΓòÉ 25.6.1. Compiling Online Documents ΓòÉΓòÉΓòÉ
Source files that will be used for online documents are created in an identical
manner to those used for help text. When the IPFC command is invoked to
compile the source files, the /INF parameter should be specified, as follows:
IPFC SOURCE.IPF /X /W3 /INF >ERRORS.TXT
The IPF compiler will then include the necessary hooks to enable VIEW.EXE to
display the online document. Note that online documents compiled with the /INF
parameter have a default extension of .INF, rather than the normal extension of
.HLP for help libraries.
ΓòÉΓòÉΓòÉ 25.6.2. Concatenating Source Files ΓòÉΓòÉΓòÉ
Multiple document files may be concatenated to produce a single online
document. Concatenation is achieved by creating an OS/2 environment variable
that contains the names of the concatenated files. For example:
SET BIGDOC=DOC1.INF+DOC2.INF+DOC3.INF+DOC4.INF
This environment variable is typically set from within a batch file, which also
contains the command VIEW BIGDOC to view the resulting concatenated document.
Hypertext links are permitted between panels in different files, but a panel
must use the res= attribute in the heading tag to identify itself, rather than
the name= or id= attributes. The global attribute must also be specified in
the panel heading.
ΓòÉΓòÉΓòÉ 25.7. Application Tutorials ΓòÉΓòÉΓòÉ
For any application, the developer or developers may supply a tutorial, which
is effectively another Presentation Manager program which provides step-by-step
guidance to the user. IPF enables tutorials to be started from within help
windows, in a number of ways:
Within a help panel, a hypertext or hypergraphic link may be defined with
reftype=launch, and with the objectname= attribute specifying the name of the
tutorial program. When the user selects the hypertext or hypergraphic item,
the tutorial is started automatically.
A "Tutorial" item may be included in the "Help" pulldown menu in the
application's main help window. This is done automatically by IPF if any
help panel heading tag (:h1 through :h6) contains the tutorial attribute.
In this case, the name of a tutorial program must be specified in the
pszTutorialName parameter of the WinCreateHelpInstance() function call.
When the user selects the "Tutorial" item from the "Help" pulldown menu, an
HM_TUTORIAL message is sent to the active application window, with the first
parameter containing the name of the tutorial program. The application
typically processes this message by calling the DosExecPgm() function to start
the tutorial program.
ΓòÉΓòÉΓòÉ 25.8. Self-Teaching Applications ΓòÉΓòÉΓòÉ
An extension of the tutorial concept is possible, where the user invokes an
online procedure manual that describes a business process; hypertext and
hypergraphic links can be imbedded in this manual to start the application or
applications that support the business process. This can be performed in
either of two ways:
Where the steps in the business process are largely independent of one
another, a separate application may be used for each step.
Where the steps are interdependent, a single application can be used, with
links triggering application events by way of messages.
Note that this is an extension of the procedural entity concept originally
discussed in Object-Oriented Applications.
ΓòÉΓòÉΓòÉ 25.8.1. Loosely Coupled Applications ΓòÉΓòÉΓòÉ
Where the steps in a business process are independent of one another and do not
require any great coordination between supporting application functions,
separate programs may be used to carry out each step. In this case, the
procedure manual is created as an online document with links for each step.
Each link is specified with reftype=launch.
ΓòÉΓòÉΓòÉ 25.8.2. Tightly Coupled Applications ΓòÉΓòÉΓòÉ
Where interdependencies exist between the steps in a business process, and
where the application functions that support these steps must therefore
interact closely with one another, a single application is used. In this case,
the procedure manual is created as a help library, and execution is handled as
follows:
1. The application creates a help instance for the help library in the normal
manner, creates its own main window but does not make this window visible.
2. The application's main window makes itself the active window, and sends an
HM_DISPLAY_HELP message to the main help window to cause the initial help
panel to be displayed.
3. Each step in the business is defined using hypertext or hypergraphic links
with reftype=inform. When such an item is selected, it causes an HM_INFORM
message to be posted to the application's main window (the active window).
4. When the application's main window receives the HM_INFORM message, it
examines the message parameters to determine the required action, then
creates one or more additional display windows or dialog boxes and makes
these visible, allowing the user to complete the required step.
5. When the current step is complete, the user selects an appropriate menu bar
item or pushbutton, and returns to the procedure manual.
Using this technique, the application's main window retains overall control of
the application, and can ensure coordination between steps and impose a
sequence of execution if this is required.
ΓòÉΓòÉΓòÉ 25.9. Summary ΓòÉΓòÉΓòÉ
The Information Presentation Facility allows an application developer to create
online context-sensitive help panels and stand-alone online documentation for
Presentation Manager applications. The ability to link between panels and
between a panel and applications provides a flexible and powerful tool for
developing:
Presentation Manager applications that contain comprehensive help information
Online manuals both for applications and for business processes
Interactive tutorials for applications and business processes
"Self-teaching" business processes where the online manual automatically
starts the required applications and leads the novice user through the
process.
The flexibility of IPF and the high level of interaction between a help
instance and its controlling application allows the application to exercise
significant control over the way in which help information is displayed to the
end user. The ability to combine multiple viewports in a single help window
allows the simultaneous use of text, graphics and other technologies such as
image or full-motion video to provide help, documentation and tutorial
information.
ΓòÉΓòÉΓòÉ 26. Problem Determination ΓòÉΓòÉΓòÉ
The steps required for identification and resolution of application errors and
"bugs" in the Presentation Manager application environment are basically
similar to those required for conventional programming environments. However,
the event-driven nature of the Presentation Manager application model often
causes unnecessary confusion when developers attempt to test and debug their
applications. This chapter describes a simple approach to problem
determination and resolution under Presentation Manager, which will help in
locating and removing the majority of application problems.
Successful problem determination in the Presentation Manager environment, as in
any programming environment, requires some basic ingredients:
Effective problem documentation
A methodical approach to problem resolution
Knowledge and experience of the application environment
A symbolic debugging tool such as CodeView or Multiscope**
A measure of luck (!)
When these requirements are satisfied, problem determination may proceed
through the following three phases:
1. Documentation
2. Isolation
3. Diagnosis and resolution.
The remainder of this chapter describes each of these phases in detail,
discussing each step in the resolution process, and also describes the symptoms
and likely solutions for some common application problems.
ΓòÉΓòÉΓòÉ 26.1. Problem Documentation ΓòÉΓòÉΓòÉ
Problems in Presentation Manager applications typically occur within window
procedures, or in subroutines invoked from within window procedures. This is
not surprising, since all processing within a Presentation Manager application
takes place as a result of messages, which are received and processed by window
procedures. However, the event-driven nature of the Presentation Manager
application model provides a built-in means of narrowing down the location of a
problem, provided the event that caused the problem can be determined.
The initial documentation of an error may be performed by whoever is
responsible for application testing, since no great level of technical
expertise is required at this stage. It is important that the error is
effectively documented in writing, at the time it occurs, along with relevant
supporting information. Effective documentation greatly eases the task of
recreating the error and identifying the underlying problem.
A worksheet that may be used for problem documentation, and that records the
information required by the guidelines given in this chapter, is contained in
Problem Reporting Worksheet.
ΓòÉΓòÉΓòÉ 26.1.1. Window ΓòÉΓòÉΓòÉ
In order to narrow down the location of the problem, it is first necessary to
identify the window that was active when the error occurred. This is usually
self-evident when the window is a display window, but may be less so if the
window is an object window. However, an object window is activated upon
receiving a message that typically originates from a display window, and
therefore the problem may be effectively tracked down by beginning the search
with the display window.
The first step is therefore to determine the display window with which the user
was interacting when the error occurred. For documentation purposes, the
window's title may be used to identify the window.
Step #1: Identify the window with which the user was interacting when the
error occurred, and note its title.
Identification of the active window allows the search for the problem to be
focused on the window procedure for that window. It is likely that the problem
lies within that window procedure or a subroutine invoked from that window
procedure. If not, the active window usually passes a message to another
window which in turn causes the problem; this may be determined in the
isolation phase (see Problem Isolation).
ΓòÉΓòÉΓòÉ 26.1.2. Event/Action ΓòÉΓòÉΓòÉ
Once the active window has been identified, it is necessary to determine the
last user action before the error occurred. The name of the last menu bar or
pulldown menu item, button or icon selected should be noted for documentation
of the problem.
Step #2: Identify the last user action before the error occurred, and record
the name of the menu bar or pulldown menu item, button or icon.
Identification of the last user action provides the initial location, within
the window procedure for the active window, at which to begin searching for the
problem. The problem is likely to be within the scope of processing for the
message resulting from this action, or within that of another message generated
during the processing of this action.
ΓòÉΓòÉΓòÉ 26.1.3. First Time vs Repetitive Actions ΓòÉΓòÉΓòÉ
The third important step in documenting a problem is to determine whether the
error occurs every time a particular action is performed, or if it only occurs
after the action has been performed a number of times.
Step #3: Note whether the problem occurred when the action was performed for
the first time, or only when the action had been repeated a number of
times.
Problems that occur after a number of repetitions of an action typically
indicate a resource limitation being exceeded, and provide a short-cut to
problem resolution; see Repetitive Action Problems.
ΓòÉΓòÉΓòÉ 26.2. Problem Isolation ΓòÉΓòÉΓòÉ
Once the problem has been documented and narrowed down to a specific event
within a particular window, the developer must determine the Presentation
Manager message that results from that event, or the first such message if
multiple messages are generated.
A symbolic debugging tool is then applied to the application code, and a
breakpoint is set at the commencement of processing for that message class. The
program is then single-stepped to determine the operation or function call at
which the error occurs.
Step #4: Single-step with a symbolic debugging tool to determine the code
statement at which the error occurs.
It is important during this stage to note any WinPostMsg(), WinSendMsg() or
WinBroadcastMsg() function calls performed by the program, which will generate
additional Presentation Manager messages in the system. If the initial pass
through the processing for the current message does not reveal the error, the
same process must be performed for each of these messages and the window
procedures that process them.
Note that this single-stepping process is most useful in situations where the
error occurs every time a particular action is performed. In cases where the
error only appears after a large number of repetitions, single-stepping will be
time-consuming and unproductive. In such cases, the problem resolution process
may be expedited by omitting the isolation phase and immediately checking the
logic of the processing for the failing message, to ensure that all resources
allocated during processing are subsequently released. See Repetitive Action
Problems for more details.
ΓòÉΓòÉΓòÉ 26.3. Problem Diagnosis ΓòÉΓòÉΓòÉ
Once the cause of the error is narrowed down to a single statement within the
source code, the problem with that statement must then be identified.
Syntactical errors can generally be ruled out as a cause of failure during run
time, since such errors are almost always identified during compilation of the
application code. However, the items listed below are common causes of
run-time errors, and should be checked for failing program statements:
Logic: is the sequence of operations performed during the processing of a
message in accordance with the application design? Have any steps been
accidentally omitted?
Parameters: are the correct variable names being used for parameters in the
program statement? Do the parameter definitions in the program statement
directly match those given in the function declaration?
Pointers: do they contain valid references, and/or have they been correctly
initialized prior to the program statement?
Operating system or Presentation Manager resources: have they been
successfully allocated prior to the program statement? Are resources
released at the completion of processing for the event and if not, is there a
valid reason for retaining them?
Step #5: Diagnose the cause of the problem by carefully checking the program
statement, and correct the error.
The following sections provide descriptions of some common application problems
against which failing programs may be checked.
ΓòÉΓòÉΓòÉ 26.3.1. First Time Problems ΓòÉΓòÉΓòÉ
Problems that occur whenever a program statement is executed indicate an error
in that statement or in a parameter used by that statement. These errors may
often be indicated by the nature of the error. Some common errors are given
below.
Trap 000D
This error indicates that the program attempted to access a location in memory
that was not within the area allocated to its parent process. Since such
access might violate the integrity of other applications or of the operating
system itself, OS/2 disallows the access. Note that the pointer may directly
reference a memory location, or may be the handle to a resource such as a
window, presentation space etc.
The usual cause of such an error is that a pointer passed as a parameter in a
function call is incorrect. The pointer may not have been initialized, or may
have been set to an incorrect value as a result of a failed allocation request
or incorrect pointer arithmetic.
Resolution actions are typically as follows:
Check that the function call which allocated the resource referenced by the
pointer completed without error, and that a valid pointer was returned.
Ensure that any pointer arithmetic carried out on the pointer between
allocation and the failing program statement is error-free.
If the pointer is stored in an instance data area (that is, a data block
normally stored in the window words), ensure that the pointer to the instance
data area itself has been correctly read from the window words at the start
of processing for the current message.
The allocation of a Presentation Manager resource may also fail for reasons
associated with its parent window. See Failure to Allocate Resources below.
One additional cause of this error is the application releasing an instance
data block too early in the processing of a WM_DESTROY message. If the memory
object containing this data block is released, and the application then
attempts to release other resources whose handles are contained within the data
block, OS/2 will not allow access to the memory. This problem is easily
resolved by releasing the instance data block after other resources.
Trap 000E
This error indicates that an application under OS/2 Version 2.0 attempted to
access an area in memory for which an address range had been allocated, but no
storage committed. This error typically occurs when writing data objects into
application data areas, since most operating system and Presentation Manager
resources are automatically committed upon allocation.
The usual cause of such an error is that the application failed to include the
PAG_COMMIT flag in the DosAllocMem() function call that allocated the resource,
or failed to issue a DosSetMem() call when increasing the size of a memory
object. The problem may be easily resolved simply by including the PAG_COMMIT
flag or including a DosSetMem() call to ensure that sufficient storage is
available before writing to a memory object.
Failure to Allocate Resources
A common error shows itself when Presentation Manager resources cannot be
allocated correctly by an application. This occurs most frequently with
resources allocated upon creation of a window, during processing of the
WM_CREATE message.
The cause of the error is a failure, on the part of the application, to
complete the default processing of the WM_CREATE message, before carrying out
application-specific processing. Part of this default processing involves the
allocation of a Presentation Manager control block for the window, allocation
of a window handle etc. If this processing is not performed, via a
WinDefWindowProc() function call, at the commencement of processing for the
WM_CREATE message, function calls which use parameters such as the window
handle will fail.
The problem may be easily resolved by placing a WinDefWindowProc() function
call as the first statement in the processing for the WM_CREATE message.
Stack Space Exceeded
This error may appear in either of two places:
If it appears during a call to an application subroutine, it usually
indicates that the space reserved for the application's stack is insufficient
for the number of nested function calls, local variables, etc., being used by
the application.
If it appears during a call to an operating system or Presentation Manager
function, it may indicate the same cause as above, or that the limit of the
application's Ring 2 stack, used by system-level code invoked by the
application, has been exceeded.
The application's stack size may be exceeded in situations where the
application makes a large number of nested subroutine calls, particularly where
extensive recursion is used, and/or where large numbers of local variables are
defined. In such cases, the stack may be need to be increased beyond the
recommended minimum of 8KB, using the STACKSIZE statement in application's
module definition file.
The Ring 2 stack limit is normally exceeded only in situations where a
system-level function attempts to retrieve more items from the stack than were
originally placed there. This can occur where an application passes an
incorrect parameter to a function; for example, if a parameter is declared by
the function as an array of eight elements, but the application passes an array
containing only seven elements, an error may occur when the function attempts
to retrieve eight elements from the Ring 2 stack for processing.
While such an error may reveal itself during compilation, certain C typecasting
conventions may mask the problem until run time. Where this error occurs
during execution, careful checking of parameters is recommended.
Window Fails to Appear
This error occurs when an application issues a WinCreateWindow() or
WinCreateStdWindow() function call to create a display window, but the window
fails to appear on the desktop, even though the function returns a valid window
handle. This error may result from either of two causes:
The WS_VISIBLE flag may not be set in the frame creation flags for the
window.
The application may include the FCF_ICON or FCF_ACCELTABLE frame creation
flags, but no icon or accelerator table resources are defined with resource
identifiers which match the window identifier.
In both cases, the WinCreateWindow or WinCreateStdWindow() function will return
a valid window handle, since the window has been created.
In the first case, the problem may be rectified by including the WS_VISIBLE
flag in the frame creation flags, or by using the WinShowWindow() function to
explicitly make the window visible.
In the second case, resources should be defined in the application's resource
script file to match the FCF_ICON and FCF_ACCELTABLE frame creation flags.
These resources must have identifiers that match the window identifier given in
the WinCreateWindow() or WinCreateStdWindow() calls, since Presentation Manager
uses this identifier to load the resources.
ΓòÉΓòÉΓòÉ 26.3.2. Repetitive Action Problems ΓòÉΓòÉΓòÉ
Application errors that only reveal themselves after an action has been
performed many times typically result from the application exceeding an
operating system or Presentation Manager resource constraint. Resources such
as window handles, presentation spaces, memory objects and so on, have finite
limits. If an application repeatedly requests allocation of such resources
without releasing them, these limits may be exceeded, in which case the
resource will not be allocated and the application may fail when attempting to
use the resource.
Such problems may manifest themselves as Trap 000D errors that will result in
application termination, or may simply corrupt execution of the application.
The effect is dependent upon the (invalid) contents of the resource handle when
the application issues a function call that uses the resources. In certain
cases, a function call may cause the application to enter an endless loop
within the processing of one message, in which case the entire Presentation
Manager desktop may "lock up".
This problem may be avoided by ensuring that all resource requests (DosGet...()
and WinGet...() function calls) in the code are matched by corresponding
DosRelease...() and WinRelease() function calls. In accordance with the
principle of encapsulating function, resources required for processing a
particular message should be allocated, used and released during the processing
of that message.
An exception to this rule occurs in the case of resources such as control
blocks, presentation spaces for display windows, etc. These are typically
allocated during processing of the WM_CREATE message, and persist throughout
the life of the window, until released during processing of the WM_DESTROY
message.
ΓòÉΓòÉΓòÉ 26.4. Post-Resolution Action ΓòÉΓòÉΓòÉ
Once a problem has been identified and corrections made to the application, the
resolution of the problem should be documented and placed, along with the
original problem documentation, in some form of log. In this way, similar
problems encountered at a later date may be more easily identified and resolved
by reference to the log.
Step #6: After resolving the problem, document the resolution for future
reference.
Logging systems for such information may range widely in complexity and
sophistication, from simple paper files to automated database systems with
keyword search capabilities. The level of system implemented by a development
organization is dependent upon cost and the perceived productivity benefit to
be gained from such information; organizations with an ongoing involvement in
the development of complex Presentation Manager applications will derive
greater benefits than those with only a single development project.
ΓòÉΓòÉΓòÉ 26.5. Summary ΓòÉΓòÉΓòÉ
Problem determination in the Presentation Manager environment is similar to
that for other application environments, and proceeds through a number of
phases:
1. Documentation
a) Failing window
b) User action which caused the failure
c) Whether the failure occurs upon first performing the action, or only
upon repetitive actions
2. Isolation
3. Identification and resolution.
The documentation phase is normally part of the application testing cycle, and
is performed by those responsible for such testing. No particular technical or
programming skills are required for this phase.
Proper documentation of the failure usually allows a developer to determine the
window procedure and message which caused the failure. This provides a useful
starting point at which to search for the underlying problem.
The isolation phase is normally employed only for those failures that occur
every time a particular action is performed, and involves the use of a symbolic
debugging tool to single-step through the processing of the failing message, in
order to determine the statement in the source code at which the error occurs.
Problems that occur only after many repetitions of a particular user action
normally indicate that an operating system or Presentation Manager resource
limit has been exceeded. This is usually the result of an application
acquiring resources and failing to release them. In such cases, the resolution
process may be expedited by immediately checking the processing of the
offending message for resource allocation statements, and ensuring that each of
these is matched by a corresponding statement that releases the resource.
Once the problem is narrowed down to a single application statement, the
identification phase determines the cause of the problem and makes appropriate
corrections to the source code. This phase requires familiarity with the OS/2
and Presentation Manager environments.
When the application has been corrected and submitted once more for testing,
the problem and its resolution should be documented and this information made
available for future problem determination activities. The availability of such
information may be used to more quickly determine likely causes of similar
problems in the future.
ΓòÉΓòÉΓòÉ 27. Generic Application Modules ΓòÉΓòÉΓòÉ
As mentioned throughout this document, the Presentation Manager application
model promotes the reuse of application objects, by facilitating code
modularity through data abstraction and encapsulation. With correct design
procedures, it is possible to create generic application objects that may be
used by multiple applications. Should subsequent applications require
modification to allow different processing of particular message classes, this
may be achieved through subclassing. The Workplace Shell application model
introduced in OS/2 Version 2.0 provides even more potential for reuse, due to
its enhanced support of inheritance and subsequently enhanced provision for
object reuse.
Standardization and reuse of application code promotes consistency between
applications in terms of processing techniques and user interfaces, and helps
to enforce organizational programming and interface design standards. It also
reduces the amount of new code required for applications, potentially
shortening development time, and the use of previously developed and tested
code may also decrease application testing time.
In situations where reusability at the application object level is either not
possible or impractical, common application functions may still be developed as
subroutines, and placed in libraries for access by multiple applications. The
use of such subroutines reduces application development time.
This chapter examines the creation of such generic objects and subroutines
within the Presentation Manager application model, and their placement in
dynamic link libraries for subsequent use by applications. Since Workplace
Shell objects are by definition placed in DLLs and available for reuse, they
are not explicitly discussed in this chapter.
ΓòÉΓòÉΓòÉ 27.1. Generic Application Objects ΓòÉΓòÉΓòÉ
Within the Presentation Manager application model, a window procedure provides
both the definition of a data object and the methods that operate upon that
data object. A window procedure may therefore be considered as a complete
application object in its own right.
Where the data object to be manipulated by a window will be accessed by a
number of applications, it makes sense to define the data object and its
methods once, in a single window procedure, and to make that window procedure
available to any application that needs to manipulate the data object. Any
changes to the data object's characteristics or processing requirements can
then be contained within the application object, avoiding the need to modify
and recompile multiple applications. The dynamic linking capabilities of OS/2
facilitate such a technique, enabling such modifications to be automatically
incorporated into applications at load time or run time.
ΓòÉΓòÉΓòÉ 27.1.1. Display Windows ΓòÉΓòÉΓòÉ
A display window may be created as a generic application object, and its window
procedure placed in a dynamic link library. The following steps are typically
followed in creating such a window procedure:
1. Both the window procedure and a calling routine to create the window are
written in the normal manner.
2. The routine containing the code to create the window is declared as an
exportable entry point, and may thus be called by applications.
3. This routine returns the handle of the newly created window to the calling
application, along with a success or failure code.
4. The source code is compiled and link edited as described in Creating a DLL.
The calling application then simply issues a single function call, such as:
usSuccess = CreateEditWindow(hEdit);
The CreateEditWindow() function within the DLL handles all necessary operations
including registration of the window class and creation of the window, places
the resulting window handle in the address indicated by the hEdit parameter,
and returns a success or failure code (usSuccess) to the calling application.
Note, however, that the above example assumes that the window is created with a
predetermined title, size and position on the desktop. Should this not be the
case, additional parameters to the CreateWindow() function would be required.
The definition of the CreateEditWindow() function as the only entry point in
the DLL enforces the consistency of using this function. The calling
application is still provided with the window handle, which allows it to
communicate with the window and to subclass the window if required.
ΓòÉΓòÉΓòÉ 27.1.2. Object Windows ΓòÉΓòÉΓòÉ
Object windows may be created and placed into dynamic link libraries in a
similar manner to that already explained for display windows. However, object
windows have an additional complication in that they are frequently created in
secondary threads in order to handle long-running application tasks.
The steps in creating an object window for inclusion in a DLL are therefore as
follows:
1. The window procedure, the calling routine to create the window and a
routine to start the secondary thread from which the window is created, are
written in the normal manner, as described in Threads Containing Object
Windows.
2. The routine containing the code to start the secondary thread is declared
as an exportable entry point, and may thus be called by applications.
3. The source code is compiled and link edited as described in Creating a DLL.
Note that the routine called by the application does not return the handle of
the newly created window. Indeed, it cannot do so, since the creation of the
window takes place asynchronously, in a secondary thread.
This obstacle is overcome by having the calling application (typically a window
procedure) pass its own window handle as a parameter. This is passed to the
object window, which then passes an acknowledgement message to the calling
window procedure, containing its window handle. The calling window procedure
may subsequently communicate with or subclass the object window as required.
This technique is described, along with an example, in Threads Containing
Object Windows.
ΓòÉΓòÉΓòÉ 27.1.3. Subclassing ΓòÉΓòÉΓòÉ
When a generic application object (that is, window class) does not quite meet
the requirements of an application, a developer may choose to use the generic
object and modify its behavior, through subclassing, to meet the specific
requirements. This may be easily achieved in conjunction with the methods
described above, since the handle of the newly created window is either
returned directly by the called routine or indirectly by the window itself.
This handle can then be used in the WinSubclassWindow() function call.
The subject of subclassing is described in detail in Subclassing a Window,
along with examples of both the WinSubclassWindow() function and a subclass
window procedure.
ΓòÉΓòÉΓòÉ 27.2. Dialog Boxes ΓòÉΓòÉΓòÉ
Standard dialog boxes to handle commonly performed user dialogs may also be
generated and placed in dynamic link libraries. The inclusion of a dialog box
in a DLL however, is slightly more complicated than the inclusion of a "normal"
display or object window, due to the definition of the dialog template as a
Presentation Manager resource. The DLL must therefore include not only the
dialog procedure and the invoking routine, but also the dialog template
definition.
This necessitates the invoking routine within the DLL not only executing the
WinDlgBox() function call, but also obtaining a module handle for the DLL and
an entry point address for the dialog procedure. The necessary steps are as
follows:
1. The dialog procedure and the invoking routine are developed and placed in a
dynamic link library.
2. The invoking routine is declared as an exportable entry point and may thus
be called by applications.
3. The dialog template is created using the Dialog Box Editor, resource
compiled and combined with the DLL.
The invoking routine for a dialog box loaded from a DLL is described, along
with an example, in Figure "Loading a Dialog Resource From a DLL".
ΓòÉΓòÉΓòÉ 27.3. Generic Subroutines ΓòÉΓòÉΓòÉ
In addition to code reuse at the application object level, significant
productivity gains can be achieved by the reuse of application code at the
subroutine level, to carry out common operating system and Presentation Manager
functions.
For example, initialization functions are required to perform tasks related to
initializing the Presentation Manager environment and any data areas to be used
by utility routines. Functions required to be performed include:
Registration of the application to Presentation Manager
Creation of a message queue
Creation of an entry in the Workplace Shell Window List.
These functions may be combined into one or more standard initialization
routines, which may be invoked upon entry to an application or thread. Examples
of the necessary code are given in Figure "Sample Application Main Routine
(Part 1) - Registration", Figure "Sample Application Main Routine (Part 2) -
Window Creation" and Figure "WinAddSwitchEntry() Function".
Termination functions required by Presentation Manager applications could also
be standardized; these functions include:
Removing the application from the Workplace Shell Window List
Destroying the application's main window
Destroying the primary thread's message queue
Deregistration of the application from the Presentation Manager environment.
These operations are performed by Presentation Manager upon termination of the
application if the application does not perform them explicitly. However, it
is recommended that the application carries out these actions, since they may
then be achieved in a controlled manner. Examples of the necessary code are
given in Figure "Sample Application Main Routine (Part 2) - Window Creation".
Other functions may often be required during the execution of an application,
such as:
Obtaining the window handle of the application's main client window. An
example of this procedure is given in Identifying the Destination Window.
Passing a message from a subclass window procedure to the original window
procedure for that window class. An example is given in Figure "Subclass
Window Procedure".
These functions may also be combined into standard subroutines and placed in a
library, thereby avoiding the need for application developers to repetitively
code such functions.
A final function often used in the stepwise development of object-oriented
Presentation Manager applications is a small routine to display a message box
with the message "Action Not Yet Implemented", invoked when the user selects a
menu bar or pulldown entry for which a method has not yet been coded. This
function is typically invoked as the default case for the WM_COMMAND message
class. In this way, methods within a window procedure may be implemented in a
stepwise manner, and testing of existing methods may occur while new ones are
being added. Selecting an action for which no method has yet been implemented
will always result in the same message box being displayed.
ΓòÉΓòÉΓòÉ 27.4. Granularity ΓòÉΓòÉΓòÉ
When placing generic code in a dynamic link library, whether that code is at
the application object level or at the functional level, the question arises as
to the way in which the code should be partitioned into individual DLL modules,
and thus the level of granularity that will be achieved within the reusable
code.
This decision must be made on the basis of interdependence; where routines are
interdependent and are required or likely to be used together, it is advisable
to place them in a single dynamic link library. For example, a group of
standard window manipulation routines would typically reside in single DLL.
However, generic application objects should bear no predefined relationship to
one another, and generic window classes may therefore be used independently.
In such a case, the window procedure and invoking routine for each window class
should be placed in a separate DLL, along with any subroutines specific to that
window procedure. Applications that desire to use more than one such
application object may then access multiple DLLs.
ΓòÉΓòÉΓòÉ 27.5. Packaging ΓòÉΓòÉΓòÉ
When a set of application objects and/or subroutines has been created and
placed into a dynamic link library, the following items will have been
generated:
The dynamic link library containing the application objects and/or
subroutines
A header file containing declarations for the routines that will be called by
applications in order to create the application objects or invoke the
subroutines
An import library file, containing entry point definitions for those routines
that will be called by applications.
These items must be stored in a location from which application developers may
access them. The use of a local area network to provide and manage access to
such items is discussed in Managing Development.
In addition, appropriate entries must be included in an interface control
document, which defines all common application objects and subroutines along
with their external interfaces, and acts as a reference for application
developers who wish to use such objects or routines.
ΓòÉΓòÉΓòÉ 27.6. Summary ΓòÉΓòÉΓòÉ
The Presentation Manager application model affords the opportunity for
significant standardization and reuse of application code, at both the
application object and function levels. The dynamic linking facilities
provided by OS/2 allow this capability to be carried over to executable code as
well as source code. Such reusability reduces the amount of new code required
for applications, thereby reducing the development time and cost of new
applications.
Common application elements such as windows and dialogs may be defined and
stored in dynamic link libraries for access by one or more applications, thus
implementing reusability at the application object or dialog level. At a lower
level, a large number of common Presentation Manager application tasks may be
identified, which may also be placed in standard routines for purposes of
enhancing programmer productivity.
A further benefit of using standardized routines is the improvement in the
consistency of both the application code and the user interface. Such
standardization provides an easy means of enforcing Systems Application
Architecture CUA standards without the need for programmers to repetitively
code definitions for an CUA-conforming user interface. In addition, the
standardized implementation of various functions and techniques eases the task
of application maintenance, since all applications will behave in a similar
manner through the use of common code.
Although the functions mentioned in this chapter are restricted to Presentation
Manager functions, the same principles may be applied to other functions,
dialogs etc., which are common to multiple applications within the
organization. The creation of standard routines for such functions, and the
incorporation of these routines into dynamically linked modules under OS/2, may
enhance the modularity and granularity of applications and bring additional
benefits through reduced development time for new applications, and through
easier application maintenance and change management.
ΓòÉΓòÉΓòÉ 28. Managing Development ΓòÉΓòÉΓòÉ
In order to enable the implementation of large-scale applications in the
programmable workstation environment, with multiple application developers
participating in design, coding and testing, it is important not only to have
an appropriate technological and architectural base for development, but also
to provide appropriate and effective management of and control over the
development process and development resources. Established techniques exist in
the host-based application development environment for addressing such issues,
but historically, the considerations of large-scale management and control have
been overlooked in the workstation environment due to the relatively minor
nature of workstation-based development projects in the past.
Two areas worthy of note in the workstation-based development environment are
the management of developmental risk, and the management and control of
development resources that are used and created during the application
development process. This chapter will briefly describe these issues and offer
some suggestions as to how they may be effectively resolved. Much of the
discussion in this chapter will deal with Presentation Manager applications
written using the C programming language, but the techniques described may be
adapted to suit other environments and programming languages.
ΓòÉΓòÉΓòÉ 28.1. Risk Management ΓòÉΓòÉΓòÉ
In any application development project, there are risks imposed by the use of
new technologies and methods. These risks may be divided into two basic types:
Technological risk; that which is imposed by new or unfamiliar technologies
which will be used in an application or during the creation of the
application.
Managerial risk; that which arises from the lack of established management
techniques to support new technologies and methods.
These two elements of risk are closely related, and affect one another in a
variety of ways. The following sections discuss both elements and suggest some
mechanisms for their mitigation.
ΓòÉΓòÉΓòÉ 28.1.1. Technological Risk ΓòÉΓòÉΓòÉ
Technological risks may take a wide variety of forms, and vary from simple
risks to highly complex instances involving the interrelationship of many
divergent technologies. Some relatively simple examples of technological risk
are:
Use of a new prototyping tool
Use of a programming language other than that which is normally used by the
particular development organization
Use of a new programming interface
Incorporation of new analysis techniques for the gathering of requirements.
The element of risk in the incorporation of new technologies arises from the
simple fact that they are new, and likely to be unfamiliar to the majority of
development personnel. A period of learning will be necessary, and the
probable length of this period must be assessed in the light of required
development schedules. Technological risk is always greater where new
techniques and procedures must be evolved in order to support and exercise the
new technologies, since elements of managerial risk are then involved. Simple
technological tools are relatively easy to learn and use, but techniques for
their effective employment are often learned over a longer period.
The decision as to whether to utilize new technologies in a development project
must be based upon the question of whether the development organization
possesses the requisite skills to effectively exercise the new technologies, or
can acquire such skills within the timeframe of the development project,
without adversely affecting the schedule and budget of the project. If the
first question can be answered in the positive, there is no risk involved; if
not, then it is the second question that constitutes the element of risk.
Technological risk may be mitigated by ensuring that development personnel
possess the necessary skills to effectively utilize the new technologies,
through the provision of relevant education. The potential benefit to be
gained from the use of these technologies must be identified and quantified, in
terms of enhanced application functionality, reduced development time and cost,
etc. This benefit must be weighed against the time and cost involved in
training personnel to a sufficient skill level in order to effectively mitigate
the risk, and against the schedule and budget imposed upon the development
organization.
Technological risk may also be mitigated by minimizing the managerial risk
involved in the use of new technologies. If established managerial techniques
can be adapted and applied to the implementation of new technologies, the use
of these mechanisms may provide a greater degree of control over the
development process, and help to control and reduce the associated
technological risk. Thus it can be seen that technological and managerial risk
are closely related and complimentary to one another.
ΓòÉΓòÉΓòÉ 28.1.2. Managerial Risk ΓòÉΓòÉΓòÉ
Managerial risk is somewhat more complex than technological risk, since it
involves the effective administration of and control over the use of new
technologies. While it is possible to train or employ development personnel in
order to gain the required skills in the use of new technologies, it is less
easy to obtain the managerial skills necessary to ensure the maximum benefit is
gained from their use.
Like technological risk, managerial risk may also vary from the relatively
simple to the highly complex. Some examples of managerial risk are:
Transformation of new analysis techniques into application design
specifications
Establishment of effective control procedures for a new development
environment
Measurement of programmer productivity when using a new programming tool or
language.
The managerial risk arises not from the question of whether sufficient skills
are present to utilize new technologies, but from the question of whether
managerial personnel are sufficiently well-versed in the concepts underlying
these technologies to provide effective administration and control over the use
of the technologies, in order to ensure that maximum benefit is gained from
their use.
Managerial risk may be mitigated by ensuring that managerial personnel possess
a sufficient grounding in the principles underlying new technologies, in order
that they may successfully adapt existing managerial techniques to the
administration and control of the new technologies. These skills may be
acquired in a similar manner to the technological skills required by
programmers, through training and familiarity with the technologies involved.
The decision must be made as to whether the benefit to be gained from the use
of these technologies is sufficient to offset the time and effort involved in
acquiring the necessary skills and establishing the managerial techniques to
effectively control their use.
Managerial risk may also be mitigated by reducing the associated technological
risk. For example, a new technology such as object-oriented programming
principles can be implemented using tools such as the C programming language
and Presentation Manager. There is likely to be a higher degree of familiarity
with such tools in the development organization than with tools such as C++ or
Smalltalk V. Therefore, implementation of object-oriented principles may be
more effectively controlled by the application of established managerial
techniques for C application development. While this will not eliminate the
element of risk altogether, it will significantly reduce the managerial risk
involved, and also help to mitigate the technological risk by facilitating
effective control over the development process.
ΓòÉΓòÉΓòÉ 28.2. Configuration/Library Management ΓòÉΓòÉΓòÉ
While the same techniques of management are valid in both host and workstation
environments, the distributed nature of the workstation environment presents
difficulties for the centralized control and administration of development
resources. This section provides some suggestions as to the ways in which a
local area network (LAN) may be used to provide centralized control and
administration to a workstation-based application development environment.
In the case of C language applications developed for the Presentation Manager
environment, development resources include:
Application source modules. An application source module is defined to
comprise not only the source code itself, but also the local and external
interface include files that accompany the source code (see Application
Program Construction).
Existing code libraries; these may need to be modified or additional routines
generated in order to meet the requirements of the application.
Presentation Manager resources such as icons, fonts, bitmaps and dialog
definitions.
Test data sets or databases.
Compilers, link-editors, run-time libraries and other development tools; in
an evolving development environment, it is crucial to ensure that all
development personnel use the same version and modification level of compiler
and linkage editor software, and that programming language runtime libraries
are consistent in their version.
These resources must be created, tested and placed in locations from which they
may be accessed easily and concurrently by a number of application developers,
while at the same time maintaining adequate control over their access and
particularly over any modifications made to individual modules.
A LAN provides a useful means of enabling access by multiple developers to a
common repository of application resources. The ways in which a LAN may be
used to address the configuration management issues arising from the PWS
development environment are described in the following sections.
ΓòÉΓòÉΓòÉ 28.2.1. Terminology ΓòÉΓòÉΓòÉ
In the subsequent discussion of configuration and library management, the
following terminology will be used. The term application resource will be used
to indicate a particular development resource such as a source module (along
with its supporting include file), a custom-developed dynamic link library
(that is, a dynamic link library not taken from a group of generic library
modules), a Presentation Manager resource such as an icon or dialog definition
etc., which is specific to the current application. Other development
resources such as compilers, link-editors, programmers' toolkits, generic code
libraries and so on, may be used in the development of an application, but are
not considered to be application resources.
The term production level will be used to indicate a version of an application
resource that has been created, tested and approved for placement in a
production library. The process of testing and subsequent approval for
placement in a production library is called baselining.
The term user level will be used to indicate a version of an application
resource that is currently undergoing modification, and has not been either
tested or placed in a production library. The actual transfer of an
application resource from a developer's local work library to a production
library is called promotion.
ΓòÉΓòÉΓòÉ 28.2.2. Network Organization ΓòÉΓòÉΓòÉ
The topology of a local area network is very much determined by the structure
of the development organization, and by the size and nature of the projects
undertaken by that organization. The techniques of LAN installation,
configuration and management are beyond the scope of this document. However,
it is possible to formulate some simple guidelines which facilitate management
of the development process.
Local area networks are typically divided into logical partitions known as
domains. A domain is defined as a logical subgroup of a network, which contains
a defined group of network nodes (machines), a defined set of network resources
such as shared disks, directories and printers, and a defined set of authorized
users. Each domain thus forms a logical network in its own right, and multiple
domains may exist on a single physical network. A domain may include resources
residing on multiple network server nodes, and multiple domains may access the
resources of any particular server. Each user on the network is provided with
a unique user ID and password. An application developer may be defined as an
authorized user of multiple domains within the same physical network; the same
or different user IDs and passwords may be used. Figure "Network Domains"
illustrates a network with three domains, each containing a number of network
nodes. Each domain has one or more server nodes (marked S) upon which reside
shared resources accessible by users on other nodes. Note that the servers may
be accessed from within a single domain or from multiple domains, and that
other network nodes may also belong to multiple domains. Note also that there
is no direct mapping between a network node and a network user; a user may, in
principle, sign on and access server resources from any network node in the
domain.
Assuming a project-team orientation in the development organization, it is
expedient to logically group the members of a particular project team, in order
that they may be treated as a distinct group and separated from other project
teams for purposes of resource access and administration.
In the simplest case, a number of project teams in the same physical location
would use the same physical network, partitioned into separate domains for each
project team. Each domain would possess its own set of production libraries
for application resources; other development resources such as compilers and
generic code libraries, which are common across the entire development
organization, would be stored in a production library on a single server, and
defined within all domains. This technique provides isolation of application
resources while also allowing common access to other development resources, and
eases the task of maintaining and updating these common resources since only
one copy need exist on the network.
The principle of one domain per project team is obviously a "rule of thumb" and
must be evaluated in light of the individual development organization. In the
case of very large projects, it may be necessary to subdivide the project team
into manageable subgroups. This would probably be necessary purely for
managerial purposes, irrespective of whether a LAN were to be used.
Conversely, very small project teams may not warrant the effort of establishing
a separate domain, and several such small teams may be combined in a single
management unit with a single network domain.
ΓòÉΓòÉΓòÉ 28.2.3. Common Access to Resources ΓòÉΓòÉΓòÉ
On a local area network server node, directories may be created that act as
production libraries. Production libraries for a particular development
project may exist on one or more network server nodes, depending upon the size
and organization of the LAN.
These libraries serve as repositories for the current production-level versions
of all development resources. The exact number and type of libraries created
is highly dependent upon the structure of the development organization and the
application under development, but the following skeleton structure is
recommended.
Figure "Production Libraries on a LAN Server"
All application developers should be given read-only access to production
libraries. This will enable those developers to access compilers, link-editors
and programming language run-time libraries, and to access the current
production-level versions of application source modules, Presentation Manager
resources and test data, but not to update those production versions.
Application resources currently undergoing modification (that is, user level
resources) are held in a work directory on the developer's own workstation,
from which only that developer may access them. This restriction of access is
implicit since only appropriately declared and configured server nodes may
share their disks and directories on the network.
Production level application resources may be transparently accessed at compile
or link-edit time by ensuring that each developer's compiler search path
specifies the production libraries. The search path should first specify an
application developer's local work directory, in order to pick up any user
level resources currently being worked upon by that developer, and then search
the appropriate production libraries in order to pick up production level
copies of other resources not currently subject to modification by that
developer. This technique ensures that each application build accesses the
latest tested and baselined versions of all application resources, except for
those resources that exist in the developer's local work directory, and that
are therefore likely to be under test.
Each application resource should have an owner appointed at the start of
development. This owner may be the application developer primarily responsible
for the creation of a source module, or in the case of larger and more complex
development projects, may be a developer responsible for the testing of a
number of modules that together comprise a coherent code unit. In either case,
the owner is given update access to the files in the production libraries that
comprise the module or modules under his/her jurisdiction, and only to those
files. The updating of each application resource may then be achieved in a
controlled manner.
This assumes that the name of the file or files containing each application
resource is known at the outset of development. This in turn requires a sound
approach to application design and to the correct partitioning of the
application at the design stage. It also requires the adoption of a set of
file or data set naming conventions across the development organization.
ΓòÉΓòÉΓòÉ 28.2.4. Update/Modification of Resources ΓòÉΓòÉΓòÉ
When an application developer wishes to make a modification to an application's
resources, those resources should be copied from the production library to the
developer's local work directory. This is known as drawdown, and must be
recorded, including the date, time, the identity of the developer and the name
of the module being copied. This recording process is known as checkout. Only
one developer at any time must be allowed to check out and draw down a
particular module, in order to avoid the problems inherent in the well-known
simultaneous update situation. Control over checkouts may be achieved in a
number of ways. However, it is recommended that the drawdown process be
achieved by way of a simple utility application that performs the following
steps:
1. Accesses a central database that contains the name of each application
resource under development, and determines whether that resource is
currently checked out.
2. If the resource has been checked out, the utility application returns the
identity of the developer by whom the resource has been checked out
3. If the resource has not been checked out, the utility application performs
a checkout operation, recording the identity of the application developer
and that of the application resource in the central database, and draws
down the application resource into the developer's local work directory,
ready for modification.
When modification of a resource is complete and the resource has been
adequately tested, the user level version should be passed to the resource's
owner who, after determining that appropriate testing has been satisfactorily
carried out, should then promote the new version to production level, ready for
access by other developers.
When a user level version of an application resource is consigned to the
resource owner, that version must be deleted from the developer's local work
directory, in order to ensure that only the latest production level version is
accessed by the compiler or link editor during the next build. This operation
may be automated as part of the promotion process, or may be left as an
explicit task for the developer.
ΓòÉΓòÉΓòÉ 28.2.5. Administration ΓòÉΓòÉΓòÉ
As in any multi-user environment, some degree of system administration is
necessary in a LAN environment. When a LAN is used to provide a workstation
application development platform, the LAN administrator must perform the
following duties:
At the outset of development for a particular application, create a network
domain for that development project. This is optional, and it may be
considered expedient to combine a number of smaller projects into a single
network domain.
Create the production libraries for the project's network domain.
Register each developer as a user of the project's network domain, and define
each developer to have read-only access to production libraries.
Provide the appointed owner of each application resource with write access to
the resource or resources under his/her jurisdiction.
In the case where an application resource has been checked out and remains
checked out for an unnecessary length of time (for example, a developer
checks out a resource and then goes on vacation without first submitting the
new version for promotion), provide an override capability to cancel the
checkout.
It is recommended that the LAN administrator be the same person responsible for
administration of the production libraries that contain system software such as
compilers and link-editors, in order to place all such system administration
responsibilities with the same person.
ΓòÉΓòÉΓòÉ 28.3. Summary ΓòÉΓòÉΓòÉ
The management and mitigation of risk during the application development
process is an important aspect of managing application development,
particularly where new or unfamiliar technologies are to be used. There are
two closely related elements of risk that arise from the incorporation of new
technologies. These are technological risk, which arises from the need for
adequate skills to exercise the technologies, and managerial risk, which arises
from the need for adequate administration and control mechanisms to ensure that
maximum benefit is gained from the use of the technologies. It is the
responsibility of a development manager to assess, quantify and weigh the
potential benefits of new technologies against the risk involved in their use,
and to provide adequate mitigation of these risks.
The issue of configuration management in a distributed, workstation-based
development environment is another issue that must be addressed in order to
support the large-scale development of workstation-based applications. The use
of a local area network as a development platform for such applications has a
number of benefits, particularly from the viewpoint of configuration management
and control over application resources such as source code, Presentation
Manager resources, test data and the like. The use of a LAN provides:
Common access by all developers to production level versions of application
resources
The ability to directly access these production level versions during the
build process
The ability to combine production level versions with user level versions of
application resources during the build process
The ability to manage and regulate the modification and update of production
level application resources.
The proper use of a LAN in the workstation-based development environment, and
the achievement of the aforementioned benefits, requires the adoption of and
adherence to a consistent set of standards in the areas of module naming,
access and testing, and a measure of discipline on the part of application
developers. However, it is considered that the increased time and effort
expended in maintaining these standards is more than offset by the reduced
incidence of error and wastage of development time and effort imposed by the
lack of adequate coordination and control in a multi-developer project.
The issues of management and control in the workstation-based development
environment are of increasing importance as organizations begin to develop and
deploy line-of-business applications on workstation platforms. These issues
may be adequately addressed by the use of appropriate tools and the adaptation
and application of existing management techniques. With the proper care and
planning, the maximum benefit may be obtained from the use of the workstation
as a development and delivery platform for business applications.
ΓòÉΓòÉΓòÉ 29. Naming Conventions ΓòÉΓòÉΓòÉ
It is often a desirable practice to implement common naming conventions for
application routines and for symbolic constant and variable names. The
adoption of such techniques facilitates application readability and code
maintenance, since the nature and role of various routines and data items used
by an application may be more easily understood. This chapter proposes some
naming conventions; it is not suggested that application developers should use
these conventions slavishly, but that they should use the suggestions provided
as guidelines in developing their own consistent set of organizational
standards.
The conventions proposed herein will cover the following areas:
Symbolic names and constants
Subroutine names
Window and dialog procedure names
Variable names.
The conventions proposed will adhere to most "standard" C programming
conventions, in that lowercase characters will be used for routine and variable
names, with uppercase characters used for symbolic names and constants.
Application developers wishing to use standardized naming conventions for
applications written in other languages will obviously need to adapt these
conventions to suit their particular language implementation.
The conventions proposed herein will also use a notational concept known as
Hungarian notation, named for its inventor, Charles Simyoni. Under this
notational system each variable, symbolic name or procedure name is prefixed by
a one-, two- or three-character mnemonic that indicates its type or function.
ΓòÉΓòÉΓòÉ 29.1. Symbolic Names and Constants ΓòÉΓòÉΓòÉ
In a PM application, symbolic names are typically used within an application to
represent numeric values such as message classes or control window identifiers
by a meaningful name rather than a less meaningful numeric representation. A
list of suggested prefixes is given in Table "Type Prefixes for Symbolic
Constants", to give an indication of type when using a symbolic name or
constant.
These one-, two- or three-letter prefixes may be concatenated with the actual
symbolic names of control windows, window classes etc., in order to provide a
more meaningful representation of the symbolic name in the source code.
ΓòÉΓòÉΓòÉ 29.2. Subroutine Names ΓòÉΓòÉΓòÉ
For the purpose of discussion, a distinction will be made between subroutines
invoked using normal programming language calling mechanisms, and window or
dialog procedures invoked by Presentation Manager in response to the
application issuing a WinDispatchMsg(), WinPostMsg() or WinSendMsg() call.
Window and dialog procedures are discussed in the following section.
When examining application code, it is useful to know the type of event handled
or processing carried out by a particular function or subroutine, without the
need for detailed examination of the code for that subroutine. This capability
can be facilitated by the use of a prefix to the function or subroutine name,
which indicates the type of the function or subroutine to the reader.
Since the types of functions carried out within applications may be extremely
diverse, no standards will be suggested here. However, readers should note the
potential benefits of such a practice, and may wish to adopt a suitable
convention for their own applications.
ΓòÉΓòÉΓòÉ 29.3. Window and Dialog Procedure Names ΓòÉΓòÉΓòÉ
In order to indicate that a particular subroutine within an application is a
window procedure, it is suggested that all window procedure names should be
prefixed with wp in lowercase letters. Similarly, dialog procedures for
processing modal dialog boxes, should be prefixed with "dp" to identify the
nature of their processing and to differentiate them from normal window
procedures.
ΓòÉΓòÉΓòÉ 29.4. Variable Names ΓòÉΓòÉΓòÉ
It is far easier to determine the nature and usage of a variable if its data
type is known to the reader. Variable names may be prefixed with mnemonics
indicating their data type, in a similar way to that proposed for symbolic
names and constants. A list of suggested prefixes for various data types is
given in Table "Type Prefixes for Variables".
For example, a character string variable (a zero- or null-terminated string)
named WindowTitle might have an attached mnemonic prefix of sz to indicate the
data type, making the variable name szWindowTitle. This is a simple example;
to take a more complex instance, a handle to a window might have a variable
name hMainWindow, which would differentiate it in the source code from a window
procedure wpMainWindow or other data items relating to the window, while
maintaining an indication of the relationship between the items by the
similarity in their names.
Prefixing variable names in this way has the additional advantage that a
compiler cross-reference listing will group together all variables of the same
data type. Any redundancies may thus be seen at a glance.
A pointer to a variable is indicated by using an additional prefix p before the
prefix indicating the data type of the variable. Some examples are shown in
Table "Type Prefixes for Pointers".
As a further example, an unsigned integer UserResponse might have a prefix of
us making the variable name usUserResponse. A pointer to this variable would
have the name pusUserResponse. The name thus indicates both the data type of
the pointer and its relationship with the variable to which it points.
ΓòÉΓòÉΓòÉ 30. Application Program Construction ΓòÉΓòÉΓòÉ
This section of the document presents guidelines for the structuring of
applications and their component modules, in order to achieve the optimum level
of modularity and granularity within an application. The guidelines contained
herein are particularly applicable to the C programming language, although they
may also apply to other languages with similar structures.
ΓòÉΓòÉΓòÉ 30.1. Modularization ΓòÉΓòÉΓòÉ
Within a Presentation Manager application, it is recommended that the
application code be separated into distinct source modules, as follows:
Each window procedure (that is, application object) should be placed in its
own separate source module, along with functions and subroutines created for
and exclusively called by that window procedure. This creates the situation
where a single window is contained per source module, which preserves
isolation and facilitates independence of application objects.
Type definitions, variable and constant declarations (including private
message classes) and function prototypes that are local to a particular
source module should be placed in a private header file or alternatively,
included in the source module itself.
Function prototypes for those window procedures or subroutines that will
become the entry points to the source module should be placed in a separate
header file, along with type definitions, variable and constant declarations
that will be required by other source modules calling those procedures or
subroutines. This header file may then be referenced by each source module
that requires access to these procedures or routines. This header file is
known as the public header file.
Global type definitions, variable and constant declarations should be placed
in a global header file that may be referenced by each source module. In the
ideal case, global variables and constants should not be used by an
application, and this header file would therefore not be required.
Generic functions and subroutines accessed by more than one window procedure
should be placed in a separate source module with its own header file (known
as a generic routines header file), which may be referenced by each module
requiring access to the generic routines. This includes "functions" such as
dialog definitions and dialog procedures that are accessed from multiple
window procedures, and message handling routines.
Presentation Manager resources used by modules within an application should
be placed in a resource script file, and their associated identifiers defined
in the application's public header file.
Note that a Workplace Shell object's source code is automatically partitioned
in a similar manner to that described above, since the various files are
created by the SOM Precompiler from the object's class definition file.
Separation of the application code into its constituent application objects in
this manner facilitates the isolation and independence of application objects,
and enhances the potential for their subsequent reuse. It also eases the task
of application maintenance and change management, by effectively modularizing
an application and therefore helping to contain the scope of change within a
single source module and its dependent header files.
The separation of header files into private, public and global definitions in
the manner described above further enhances the independence of application
objects and facilitates change management, in the following ways:
The separation of an application object's public interfaces means that other
application objects are aware only of those interfaces, and not of the
internal definitions and operations of the application object. Changes within
an application object, to local type, variable or constant definitions, do
not impact other application objects with which the changed object
communicates
The separation of the private and public interfaces explicitly defines each
of these interfaces, so that a maintenance programmer is clearly aware of
changes that will or will not impact other application objects. Other
applications that do require modification as a result may be easily
identified, since their source modules will contain a reference to the
changed object's external interface header file.
When managing the development of large projects, an "owner" should be appointed
for each source module. This owner is typically a member of the development
team who bears responsibility for that module. A module's owner should also
have the responsibility for that module's private and public header files.
ΓòÉΓòÉΓòÉ 30.2. Header Files ΓòÉΓòÉΓòÉ
Header files should be used wherever possible in order to isolate data and
function declarations from the application code, thereby enhancing modularity
and improving readability.
For management purposes and to facilitate subsequent maintenance of the
application code, a header file should include a prolog identifying the
application and source module with which it is associated, its author and
owner, and whether the header file is a private, public, global or generic
header file (see below for definitions of these terms).
ΓòÉΓòÉΓòÉ 30.2.1. Private Header File ΓòÉΓòÉΓòÉ
Each source module should have its own private header file, or have the
contents of such a file included in the source module itself. The private
header file should itself include:
Declarations for all local constants used within the source module; that is,
those constants that are not accessed or referenced from outside the source
module. This includes those application-defined message classes used by a
window procedure in indicating events to itself, or by dependent functions
and/or subroutines to indicate messages to their parent window procedure.
Declarations for all non-local variables used within the source module; that
is, those variables that are accessed from more than one routine within the
source module, but are not accessed from outside the source module.
Prototypes for all functions and subroutines that are accessed only from
within the source module.
A private header file should be referenced, using an appropriate #include
statement, only by its own source module.
ΓòÉΓòÉΓòÉ 30.2.2. External Interface Header File ΓòÉΓòÉΓòÉ
Each source module should possess its own public header file. The public
header file should contain:
Function prototypes for the entry-point functions or subroutines within the
source module, and only for those routines. This preserves the isolation of
the source module's internal workings from the calling application.
Type definitions for any application-defined data types required by the
entry-point functions or subroutines.
Message class definitions for application-defined message classes that will
be used to signal events to a window procedure within the source module.
A public header file should be referenced by its own source module and by any
other source module which requires access to the entry points of the module.
In an ideal case, where optimum isolation is achieved by relating all
processing within the source module to a single window, access to these entry
points would be achieved by:
A single "conventional" subroutine call to create the window, with the caller
specifying appropriate parameters and the called routine returning a handle
to the window. The public header file must therefore contain definitions for
any application-defined data types to be passed as parameters to this call.
Passing a series of messages to the window in order to indicate events and
request actions. The public header file must therefore also contain
definitions for any application-defined message classes used by the window.
Since the public header file contains the interfaces to its parent window (that
is, application object) it should be carefully documented, and the entry points
and their means of access should be placed in the application's design
documentation. Interfaces to those application objects that are identified as
having potential for reuse should also be placed in an Interface Control
Document from which they may be accessed for future reuse of the application
object (see Packaging).
ΓòÉΓòÉΓòÉ 30.2.3. Global Header File ΓòÉΓòÉΓòÉ
An application may contain a global header file, which itself should contain:
Declarations for all global constants used by the application; that is, those
constants that are accessed from more than one source module within the
application.
Declarations for all global variables used by the application; that is, those
variables that are accessed from more than one source module within the
application. Note that this does not include those variables that are used
by multiple routines within the same source module.
The global header file should be referenced, using an appropriate #include
statement, by all source modules within the application, other than the
module(s) containing generic routines.
ΓòÉΓòÉΓòÉ 30.2.4. Generic Routines Header File ΓòÉΓòÉΓòÉ
One or more source modules in an application may contain generic routines that
are accessed from multiple source modules within the application. These source
modules may possess their own local header files to define data and functions
accessed only from within their own module. In addition, such source modules
should possess a single generic routines header file per application, which
should contain:
Prototypes for all generic functions and subroutines that will be accessed
from other source modules within the application
Declarations for data types and constants necessary to the invocation of
these generic routines.
The generic routines header file should be referenced, via an appropriate
#include statement, by its own source modules and by each source module within
the application that requires access to generic routines.
ΓòÉΓòÉΓòÉ 30.2.5. System-Supplied Header Files ΓòÉΓòÉΓòÉ
Source modules in an application will typically require access to operating
system or C language functions. Prototypes for these functions and
declarations for their associated data types and constants are provided in
system-supplied header files. Examples of system-supplied header files are the
OS/2 system functions file os2.h and the C language run-time library files such
as stlib.h and string.h.
ΓòÉΓòÉΓòÉ 30.3. Data Abstraction and Encapsulation ΓòÉΓòÉΓòÉ
In order to enhance reusability and to facilitate the containment (and
therefore the management) of change, data definition and initialization should,
wherever possible, be encapsulated within source modules as follows:
Local variables should be used wherever possible. Where the value of a
variable must be held between invocations of the same function or subroutine,
the static keyword may be used in declaring the variable.
For window procedures where the values of variables must be held beyond the
scope of processing a single message, a memory object may be allocated for
the variable(s) and a pointer to that object stored in the window words of
the window.
External data objects such as files, databases, etc., should be defined and
accessed only from within a single window procedure and its dependent
functions and subroutines. Definition of and/or establishment of access to
such data objects should be performed upon window creation as part of the
WM_CREATE message processing, and termination of access should be performed
upon window closure as part of the WM_CLOSE message processing.
The use of global variables should be avoided wherever possible, although it
is recognized that global variables are necessary in certain circumstances
within a Presentation Manager application. Where global variables are to be
used, they should be declared in the application's main source module (that
is, the module that contains the application's main routine) and referenced
from the application's global header file using the extern keyword.
Except in the case noted above, the use of external variable declarations
using the extern keyword should be avoided wherever possible, since this
creates an interdependence between source modules (and therefore between
application objects) that may subsequently limit the potential for reuse of
those objects. Variables should preferably be defined locally within a
source module or alternatively, defined globally and referenced in the
application's global header file.
Where non-local variables and/or constants (that is, variables and/or
constants that are accessed only from within a particular source module, but
are not local to any routine within that module) are declared, they should be
placed in that source module's private header file or, if the module does not
possess its own header file, placed at the beginning of the source module.
The practice of maximizing the use of local and encapsulated data, and of
minimizing and simplifying the external interfaces of application objects, will
achieve the maximum level of isolation and therefore of independence between
application objects, thus enhancing the potential for their reuse and
facilitating their future maintenance by isolating their internal workings from
those of other application objects.
ΓòÉΓòÉΓòÉ 30.4. Packaging ΓòÉΓòÉΓòÉ
As already mentioned in Modularization, application code should be separated
into distinct source modules. These source modules are then compiled to
produce individual object modules, which in turn are link-edited to produce
executable code. However, the executable application code may itself consist of
more than one executable module, by virtue of the dynamic linking capabilities
of the OS/2 operating system.
ΓòÉΓòÉΓòÉ 30.4.1. Application Object Modules ΓòÉΓòÉΓòÉ
If the foregoing guidelines are followed, each object module produced by the C
language compiler will contain the following:
Definitions for all locally defined data types, variables and constants
required by routines within the module, obtained from the module's private
header file at compile time
Prototypes for all local window procedures, functions and subroutines
accessed only by routines within the module, obtained from the application's
private header file at compile time
Definitions for all external data structures, variables and constants
required to communicate with other source modules, obtained from one or more
public header files at compile time
Prototypes for all external window procedures, functions and subroutines
accessed by routines within the module, other than those that constitute
generic routines, obtained from one or more public header files at compile
time
Declarations for all global variables and constants required by routines
within the module, obtained from the application's global header file at
compile time
Prototypes for all generic routines, obtained from the application's generic
routines header file at compile time
Code for those routines contained within the module.
Each object module therefore exists as a coherent identity in its own right,
and ideally has no dependence upon other object modules, other than the need to
communicate with and make use of window procedures, functions and subroutines
contained within those modules, which is achieved through public interfaces
that are clearly defined and documented. The separation of source modules is
now carried over to the object code, in that each object module represents a
separate application object.
It is therefore possible to assemble a number of object modules in various ways
to achieve an executable application. The following guidelines are offered for
the construction of the executable application.
ΓòÉΓòÉΓòÉ 30.4.2. Application Executable File ΓòÉΓòÉΓòÉ
The application's main executable file (that is, the file that is invoked to
start the application) should contain those object modules which are required
to execute the application, and that do not contain generic routines or generic
Presentation Manager resources.
Where it is envisaged that an application object is usable only by the current
application, and has no possible potential for future reuse, it may be bound
with the application's main executable file. However, if such potential for
reuse exists, the application object should be placed in a dynamic link
library.
ΓòÉΓòÉΓòÉ 30.4.3. Dynamic Link Libraries ΓòÉΓòÉΓòÉ
The following routines and objects should, wherever possible, be placed in
dynamic link libraries:
Those application objects that have been identified as having potential for
future reuse by other applications
Those routines identified as generic routines, which will be accessed from
more than one window procedure
Those Presentation Manager resources (for example, dialog definitions, along
with their associated dialog procedures) that are accessed from multiple
window procedures within the application.
The placement of such items in dynamic link libraries enhances their
independence from the application's code, enabling changes to be made without
affecting the code or requiring application maintenance. In addition,
placement in dynamic link libraries facilitates reuse of such items by multiple
applications. It is thus possible to achieve object code reuse at both the
application object and at the subroutine level.
To this end, all items placed in dynamic link libraries should have their
external interfaces documented, baselined and included in an Interface Control
Document, for subsequent use as development library routines. It is the
responsibility of the development organization to establish procedures for the
testing and acceptance of reusable code modules into libraries from which they
may subsequently be accessed by application developers, and the creation of a
repository of documentation detailing the application objects that are
available, their behavior and external interfaces.
ΓòÉΓòÉΓòÉ 31. OS/2 Kernel API Functions ΓòÉΓòÉΓòÉ
This section of the document describes the functions that are available to
application programs for accessing operating system services. Note that only
the operating system kernel functions are described in this section, since the
Presentation Manager programming interface has not significantly changed,
although a number of new Presentation Manager functions have been added.
The following tables list the kernel functions available under OS/2 Version 1.3
and their equivalent function under OS/2 Version 2.0, categorized by function
area.
ΓòÉΓòÉΓòÉ 31.1. Memory Allocation and Management ΓòÉΓòÉΓòÉ
Memory management under OS/2 Version 2.0 is greatly simplified through use of
the 32-bit flat memory model, eliminating the need for applications to create
and manipulate separate memory segments.
Table "Memory Management Functions"
ΓòÉΓòÉΓòÉ 31.2. Session Management ΓòÉΓòÉΓòÉ
There are few changes in session management functions between OS/2 Version 1.3
and OS/2 Version 2.0. Only the DosSMRegisterDD() function has been removed
from OS/2 Version 2.0.
Table "Session Management Functions"
ΓòÉΓòÉΓòÉ 31.3. Task Management ΓòÉΓòÉΓòÉ
A number of function names have changed in the task management area. These
changes are primarily due to the simplified 32-bit programming environment.
Table "Task Management Functions"
The following comments apply to the functions described in Table "Task
Management Functions":
The DosCreateThread() function is enhanced in Version 2.0 to allow dynamic
stack growth, operating system management of stacks for secondary threads,
and the ability to create a suspended thread.
The InfoSeg architecture of 16-bit OS/2 versions is redefined for the flat
memory model. The equivalent per thread and per process data is obtained
under Version 2.0 using the DosGetInfoBlocks() function, whereas the
non-changing values can be obtained using the DosQuerySysInfo() function.
The DosGetPrty(), DosGetPID(), and DosGetPPID() functions are not implemented
since this information is available through the DosGetInfoBlocks() function.
DosPTrace() support is provided under OS/2 Version 2.0 for 16-bit debugging
tools such as CodeView. For 32-bit debugging tools, the DosPTrace() function
is replaced by the DosDebug() function.
DosWaitThread() is a new function allowing a thread to suspend itself,
waiting for other threads within a process to terminate.
DosKillThread() is a new function allowing a thread to forcibly terminate
another thread within the current process.
The DosR2StackRealloc(), DosCallBack(), and DosRetForward() functions are not
applicable in the 32-bit flat memory model environment.
ΓòÉΓòÉΓòÉ 31.4. Signal and Exception Handling ΓòÉΓòÉΓòÉ
OS/2 Version 2.0 removes the function handling signals and combines signal
handling with hardware exception handling, providing a more unified approach
that allows greater flexibility.
Table "Exception Handling Functions"
The DosSetKBDSigFocus() function is used to allow 32-bit programs to inform the
operating system that they are "primed for signals", although the signals are
dispatched as exceptions.
Note the following:
16-bit DosSetVec() exceptions are supported under OS/2 Version 2.0.
The 32-bit OS/2 Version 2.0 exception manager allows per-thread exception
handling.
OS/2 Version 2.0 does not allow an exception handler to be registeed for the
numeric processor exception (NPX).
ΓòÉΓòÉΓòÉ 31.5. Interprocess Communication ΓòÉΓòÉΓòÉ
OS/2 Version 2.0 provides the same interprocess communication and
synchronization facilities as OS/2 Version 1.3. Differences in functions used
to invoke these facilities are shown in the following tables.
ΓòÉΓòÉΓòÉ 31.5.1. Anonymous Pipes ΓòÉΓòÉΓòÉ
The name of the DosMakePipe() function has been changed to DosCreatePipe() to
conform with the consistent naming rules introduced in OS/2 Version 2.0.
Table "Anonymous Pipe Functions"
Other functions used to access anonymous pipes are basic file I/O functions,
and are described in File I/O.
ΓòÉΓòÉΓòÉ 31.5.2. Named Pipes ΓòÉΓòÉΓòÉ
Changes to the functions used to create and manipulate named pipes have been
made in order to conform to the consistent naming rules introduced in OS/2
Version 2.0.
Table "Named Pipe Functions"
ΓòÉΓòÉΓòÉ 31.5.3. Queues ΓòÉΓòÉΓòÉ
No changes have been made to function names for queue manipulation between the
OS/2 Version 1.3 and OS/2 Version 2.0 implementations.
Table "Queue Functions"
The queueing functions for the 16-bit and 32-bit environments are virtually
identical; the only difference is that the 32-bit API uses 0:32 addressing and
may use element sizes greater than 64KB. Note that a a 32-bit application may
not open a queue created by a 16-bit application using the 16-bit
DosCreateQueue() function.
ΓòÉΓòÉΓòÉ 31.5.4. Semaphores ΓòÉΓòÉΓòÉ
Significant changes have been made to semaphore functions under OS/2 Version
2.0, in order to provide additional flexibility and enhance the architectural
independence of applications using semaphores.
Table "Semaphore Functions"
OS/2 Version 2.0 provides 16-bit entry points allowing compatibility with
16-bit applications that use the old system semaphores, RAM semaphores and Fast
Safe RAM (FSR) semaphores.
ΓòÉΓòÉΓòÉ 31.6. Message Retrieval ΓòÉΓòÉΓòÉ
Few changes have been made to the kernel message retrieval functions. Only the
name of the DosInsMessage() function has been changed to DosInsertMessage() in
order to conform with the consistent naming rules introduced in OS/2 Version
2.0.
Table "Message Retrieval Functions"
ΓòÉΓòÉΓòÉ 31.7. Timer Services ΓòÉΓòÉΓòÉ
A number of timer function names have changed under OS/2 Version 2.0, in order
to conform to the consistent naming rules introduced in OS/2 Version 2.0.
Table "Timer Services Functions"
ΓòÉΓòÉΓòÉ 31.8. Dynamic Linking ΓòÉΓòÉΓòÉ
A number of dynamic linking function names have been changed in order to
conform to the consistent naming rules introduced in OS/2 Version 2.0.
Table "Dynamic Linking Functions"
ΓòÉΓòÉΓòÉ 31.9. Device I/O ΓòÉΓòÉΓòÉ
No changes have been made to device I/O functions under OS/2 Version 2.0.
Table "Device I/O Functions"
ΓòÉΓòÉΓòÉ 31.10. File I/O ΓòÉΓòÉΓòÉ
A number of changes have been made to file I/O functions, in order to conform
to the consistent naming rules introduced in OS/2 Version 2.0.
Table "File I/O Functions"
ΓòÉΓòÉΓòÉ 31.11. Code Page Support ΓòÉΓòÉΓòÉ
Code page support has been simplified under OS/2 Version 2.0, and a number of
function names have been changed to conform to the consistent naming rules
introduced in Version 2.0.
Table "Code Page Functions"
The DosSetCp() function is no longer implemented, since under OS/2 Version 2.0
an application may only set the code page for its own process, using the
DosSetProcessCp() function.
The DosCaseMap() function is no longer implemented since the same task is
performed by the WinUpper() function.
ΓòÉΓòÉΓòÉ 31.12. Error Management ΓòÉΓòÉΓòÉ
No changes have been made to error management functions under OS/2 Version 2.0.
Table "Error Management Functions"
ΓòÉΓòÉΓòÉ 32. Problem Reporting Worksheet ΓòÉΓòÉΓòÉ
The following section contains a worksheet that may be used for reporting
problems encountered during application testing. This worksheet follows the
guidelines given in Problem Determination, and requires the application user to
complete the following information:
The name of the application. This is necessary in order that developers may
search for the error in the correct program.
The title of the active window when the error occurred. This is necessary in
order to identify the window procedure in which the problem most likely
resides.
The title of the last user action prior to the error occurring. This is
required in order to identify the Presentation Manager message that is likely
to have caused the error; it is probable that the problem lies in the
processing for this message.
Whether the action was attempted for the first time, or whether the action
had already been successfully completed one or more times during the current
execution of the application. This indicates whether the problem is probably
a resource allocation error, or whether another cause is more likely.
A description of the error, including an error message if one was provided by
the application, Presentation Manager or the operating system.
The name of the user who discovered the error, along with a telephone number
for future contact if any clarification is required.
The date and time at which the error occurred. While not necessary from a
problem determination viewpoint, this information allows a problem management
coordinator to monitor the amount of time necessary to respond to and rectify
application problems, and therefore allows management to determine the
effectiveness of the testing and debugging process.
The worksheet also contains a space at the foot of the page, into which readers
may insert the name of the person responsible for coordinating problem
determination and resolution activities, and to whom completed worksheets
should be sent. This person would then typically allocate the isolation,
diagnosis and resolution of problems to specific developers.
For a more complete description of Presentation Manager problem determination
procedures, readers should refer to Problem Determination.
Readers may photocopy the worksheet on the following page, insert the name of
the appropriate coordinator, and distribute the worksheet within their
organizations for problem-reporting purposes.
ΓòÉΓòÉΓòÉ 32.1. Problem Reporting Worksheet. ΓòÉΓòÉΓòÉ
ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
Γöé PROBLEM REPORTING WORKSHEET Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé This worksheet is to be completed by application testers, for all problems Γöé
Γöé encountered during testing of Presentation Manager applications. Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé APPLICATION: What was the name of the application you were running Γöé
Γöé when the error occurred? Γöé
Γöé Γöé
Γöé Γöé
Γöé Γöé
Γöé Γöé
Γöé Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé WINDOW: What was the title of the window you were accessing when the Γöé
Γöé error occurred? Γöé
Γöé Γöé
Γöé Γöé
Γöé Γöé
Γöé Γöé
Γöé Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé ACTION: What was the last action bar entry or accelerator key Γöé
Γöé combination you selected? Γöé
Γöé Γöé
Γöé Γöé
Γöé Γöé
Γöé Γöé
Γöé Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé [ ] First time action was attempted Γöé [_] Action was repeated multiple Γöé
Γöé Γöé times Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé ERROR DESCRIPTION: Provide a description of the error, including the Γöé
Γöé error message if one was displayed. Γöé
Γöé Γöé
Γöé Γöé
Γöé Γöé
Γöé Γöé
Γöé Γöé
Γöé Γöé
Γöé Γöé
Γöé Γöé
Γöé Γöé
Γöé Γöé
Γöé Γöé
Γöé Γöé
Γöé Γöé
Γöé Γöé
Γöé Γöé
Γöé Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé REPORTED BY Γöé Name: Γöé Ext: Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé Include the date/time at which the error Γöé Date: Γöé Time: Γöé
Γöé occurred Γöé Γöé Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
Γöé When completed, please forward this worksheet to: Γöé
Γöé Γöé
Γöé Γöé
Γöé Γöé
Γöé Γöé
Γöé Γöé
ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
ΓòÉΓòÉΓòÉ 33. Glossary ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 33.1. ACDI ΓòÉΓòÉΓòÉ
ACDI
Asynchronous Communication Device Interface; programming interface which
supports device-independent communication between devices on an asynchronous
communications link. ACDI is supported by OS/2 Extended Edition Version 1.x,
OS/2 Extended Services, and by a number of other hardware and software vendors.
ΓòÉΓòÉΓòÉ 33.2. action ΓòÉΓòÉΓòÉ
action
A user-specified operation that is applied to an object.
ΓòÉΓòÉΓòÉ 33.3. action window ΓòÉΓòÉΓòÉ
action window
Term used in SAA CUA'91 documentation to refer to a short-lived window used to
display information and receive input from the user in a structured dialog
format. The information is typically related to a particular action being
performed by the application. Implemented in Presentation Manager using a
dialog box.
ΓòÉΓòÉΓòÉ 33.4. address conversion ΓòÉΓòÉΓòÉ
address conversion
The process of converting a 0:32 memory reference to a 16:16 memory reference,
and vice versa. Part of thunking.
ΓòÉΓòÉΓòÉ 33.5. address translation ΓòÉΓòÉΓòÉ
address translation
(1) The process of resolving a 0:32 memory reference into a physical memory
address. When using the paged memory option in the 80386 processor, a memory
pointer passed by an application consists of Page Directory and Page Table
entries, and an offset within a physical page. This is resolved by the
processor into a 32-bit physical memory address. The validity and legality of
the memory reference is also checked during the translation process, and a
general protection exception is generated if necessary. (2) The process of
resolving a 16:16 memory reference into a physical memory address using a
process's local descriptor table. The validity and legality of the memory
reference is also checked during the translation process, and a general
protection exception is generated if necessary.
ΓòÉΓòÉΓòÉ 33.6. ancestor ΓòÉΓòÉΓòÉ
ancestor
Term used in Workplace Shell programming to refer to any object class from
which a new object class inherits methods and/or data. An ancestor may be the
parent of the new object class, a parent of the parent, etc. See also
descendant.
ΓòÉΓòÉΓòÉ 33.7. API ΓòÉΓòÉΓòÉ
API
Application Programming Interface; term used to described the set of functions
provided by which an application may gain access to operating system services.
ΓòÉΓòÉΓòÉ 33.8. APPC ΓòÉΓòÉΓòÉ
APPC
Advanced Program-to-Program Communication; programming interface for peer-level
communication between applications over an SNA LU6.2 communications link. APPC
is supported in the PWS under DOS (using the APPC/PC product), and under OS/2
Extended Edition Version 1.x and OS/2 Extended Services using the
Communications Manager. It is also supported in AS/400 systems and in
System/370 hosts running VM/CMS and CICS.
ΓòÉΓòÉΓòÉ 33.9. application-controlled viewport ΓòÉΓòÉΓòÉ
application-controlled viewport
Viewport within a help window or online document window, where the display of
information within that viewport is controlled by an application, which is
specified by the developer of the source information. Application-controlled
viewports may be used to display image, video or other types of information
under the control of the Information Presentation Facility. See also
IPF-controlled viewport.
ΓòÉΓòÉΓòÉ 33.10. application-modal ΓòÉΓòÉΓòÉ
application-modal
Term used to describe a message box or dialog box for which processing must be
completed before further interaction with any other window owned by the same
application may take place. Interaction with windows owned by other
applications is unaffected.
ΓòÉΓòÉΓòÉ 33.11. application object ΓòÉΓòÉΓòÉ
application object
An object consisting of a particular representation of a data entity, along
with its associated methods; the term is used in this document for clarity, in
order to differentiate the concept from that of a data object.
ΓòÉΓòÉΓòÉ 33.12. application resource ΓòÉΓòÉΓòÉ
application resource
Term used to describe a development resource that is application-specific.
Such resources include source code modules and dynamic link libraries that will
be used by only a single application.
ΓòÉΓòÉΓòÉ 33.13. ASCII ΓòÉΓòÉΓòÉ
ASCII
American Standard Code for Information Interchange; system which defines a
standard for the representation of alphanumeric information within computer
systems.
ΓòÉΓòÉΓòÉ 33.14. asynchronous processing ΓòÉΓòÉΓòÉ
asynchronous processing
Invocation of another procedure whereby that procedure is dispatched as a
separate thread of execution, independent of the caller. Control returns to
the caller as soon as dispatching is complete; the caller may then continue
execution without waiting for the dispatched procedure to complete its
processing. Asynchronous processing enables a Presentation Manager application
to preserve the user responsiveness goals laid down by Common User Access
guidelines, by executing lengthy operations as separate threads of execution.
ΓòÉΓòÉΓòÉ 33.15. baselining ΓòÉΓòÉΓòÉ
baselining
Process of establishing that a user-level application resource passes defined
unit testing criteria before being promoted to production level. See also
promotion and production-level.
ΓòÉΓòÉΓòÉ 33.16. base storage class ΓòÉΓòÉΓòÉ
base storage class
Term used to describe the three System Object Model object classes that form
the basis of the inheritance hierarchy implemented by the Workplace Shell.
ΓòÉΓòÉΓòÉ 33.17. bit ΓòÉΓòÉΓòÉ
bit
A binary digit, which may have a value of either zero or one. Bits are
represented within a computing device by the presence or absence of an
electrical or magnetic pulse at a particular point, indicating a one or zero
respectively.
ΓòÉΓòÉΓòÉ 33.18. byte ΓòÉΓòÉΓòÉ
byte
A logical data unit composed on eight binary digits (bits).
ΓòÉΓòÉΓòÉ 33.19. CASE ΓòÉΓòÉΓòÉ
CASE
Computer Aided Software Engineering; term used to describe the concept of
automated application design and code generation, based upon a set of
requirements entered by a user. Products that implement CASE concepts are
known as CASE tools.
ΓòÉΓòÉΓòÉ 33.20. cdecl ΓòÉΓòÉΓòÉ
cdecl
Linkage convention used in 16-bit "C" language programming under the IBM C/2
compiler, which causes the compiler to generate object code for a function or
subroutine, such that parameters are placed on the stack in right-to-left order
when the subroutine is called, and the calling routine clears the stack after
control is returned. This is the default for "C" programs. Contrast with
pascal linkage convention.
ΓòÉΓòÉΓòÉ 33.21. checkout ΓòÉΓòÉΓòÉ
checkout
Process of recording the drawdown of an application resource by a developer for
modification.
ΓòÉΓòÉΓòÉ 33.22. child window ΓòÉΓòÉΓòÉ
child window
A window that resides wholly within another window, known as its parent window,
and that is restricted to the boundaries of the parent window.
ΓòÉΓòÉΓòÉ 33.23. class-based ΓòÉΓòÉΓòÉ
class-based
Term used to describe an implementation of object-oriented programming, whereby
object classes are defined in terms of other, previously-defined object
classes; the new class takes on the properties and methods of the existing
class or classes, in accordance with the principle of inheritance. The various
dependencies thus formed constitute an inheritance hierarchy. Such an approach
facilitates the creation of new object classes with minimal effort, but at the
expense of increased interdependence and reduced object granularity. Compare
with module-based approach.
ΓòÉΓòÉΓòÉ 33.24. class data ΓòÉΓòÉΓòÉ
class data
Data item for which the definition and contents are determined for an entire
object class rather than an individual instance of that class; contrast with
instance data.
ΓòÉΓòÉΓòÉ 33.25. class definition file ΓòÉΓòÉΓòÉ
class definition file
ASCII file that defines the characteristics of a Workplace Shell object class;
used as input to the SOM Precompiler.
ΓòÉΓòÉΓòÉ 33.26. client area ΓòÉΓòÉΓòÉ
client area
See client window.
ΓòÉΓòÉΓòÉ 33.27. client-server ΓòÉΓòÉΓòÉ
client-server
Term used to describe an application architecture whereby an application module
(the server) accepts requests from a number of other application modules (the
clients) and performs actions on behalf of these clients. Presentation Manager
applications may be designed in such a way as to embody a client-server
architecture.
ΓòÉΓòÉΓòÉ 33.28. client window ΓòÉΓòÉΓòÉ
client window
The area within a window that is used by an application to display information.
The client window is actually a child window of the frame window within which
it resides.
ΓòÉΓòÉΓòÉ 33.29. Common Programming Interface ΓòÉΓòÉΓòÉ
Common Programming Interface
Component of Systems Application Architecture that defines a set of programming
languages and interfaces.
ΓòÉΓòÉΓòÉ 33.30. Common User Access ΓòÉΓòÉΓòÉ
Common User Access
Common User Access; component of Systems Application Architecture that
comprises a set of guidelines for defining user interface elements of an
application. CUA includes such items as screen layout, PF key usage, etc.
ΓòÉΓòÉΓòÉ 33.31. compatability region ΓòÉΓòÉΓòÉ
compatability region
In the OS/2 Version 2.0 flat memory model, the address region below 512 MB,
which may be addressed by a 16-bit application using the 16:16 addressing
scheme. Under OS/2 Version 2.0, this region is equivalent in size to the
process address space.
ΓòÉΓòÉΓòÉ 33.32. compatability region mapping algorithm ΓòÉΓòÉΓòÉ
compatability region mapping algorithm
Algorithm used to perform address translation between 16:16 and 0:32 addressing
schemes. See also thunking.
ΓòÉΓòÉΓòÉ 33.33. complex viewport ΓòÉΓòÉΓòÉ
complex viewport
Term used to describe the creation of multiple viewports within the same help
window or online document window, with separate formatting and scrolling
characteristics. For example, one viewport may contain a bitmap, while another
contains supporting text. The text viewport may be scrolled, while the other
viewport containing the bitmap remains constant in the window. See also simple
viewport.
ΓòÉΓòÉΓòÉ 33.34. context switching ΓòÉΓòÉΓòÉ
context switching
In a multitasking operating system, the act of halting a currently executing
task, saving its task state, and loading and dispatching a new task. Note that
OS/2 undertakes context switching on the basis of threads rather than
hardware-defined tasks.
ΓòÉΓòÉΓòÉ 33.35. control ΓòÉΓòÉΓòÉ
control
See control window.
ΓòÉΓòÉΓòÉ 33.36. Control Panel ΓòÉΓòÉΓòÉ
Control Panel
Application provided by the OS/2 Presentation Manager user shell, which allows
a user to set and customize various system parameters and attributes such as
screen colors, default printer settings, etc.
ΓòÉΓòÉΓòÉ 33.37. control window ΓòÉΓòÉΓòÉ
control window
A specialized window created for a specific purpose, such as a text entry
field, a push button or a list box. The general concept of control windows
also includes children of the frame window such as the title bar, menu bar and
system, minimize and maximize icons. Also known simply as a control.
ΓòÉΓòÉΓòÉ 33.38. cooperative multitasking ΓòÉΓòÉΓòÉ
cooperative multitasking
Multitasking implementation whereby applications executing in the system must
voluntarily relinquish control of the processor in order to allow another task
to execute. Cooperative multitasking is typically less reliable than
pre-emptive multitasking, and results in lower system throughput.
ΓòÉΓòÉΓòÉ 33.39. CPI ΓòÉΓòÉΓòÉ
CPI
See Common Programming Interface.
ΓòÉΓòÉΓòÉ 33.40. CRMA ΓòÉΓòÉΓòÉ
CRMA
See compatability region mapping algorithm.
ΓòÉΓòÉΓòÉ 33.41. CUA ΓòÉΓòÉΓòÉ
CUA
See Common User Access.
ΓòÉΓòÉΓòÉ 33.42. DASD ΓòÉΓòÉΓòÉ
DASD
Direct Access Storage Device; in traditional personal computer parlance, a
fixed disk drive.
ΓòÉΓòÉΓòÉ 33.43. data object ΓòÉΓòÉΓòÉ
data object
A specific representation of a logical data entity; for example, the same
logical data entity may exist both in memory and on a disk file. These
representations are considered to be distinct data objects. See also
application object.
ΓòÉΓòÉΓòÉ 33.44. descendant ΓòÉΓòÉΓòÉ
descendant
Term used in Workplace Shell programming to denote any object class which
inherits methods and/or data from the current object class. See also ancestor.
ΓòÉΓòÉΓòÉ 33.45. desktop ΓòÉΓòÉΓòÉ
desktop
The screen background in the OS/2 Presentation Manager environment, upon which
windows are displayed.
ΓòÉΓòÉΓòÉ 33.46. development resource ΓòÉΓòÉΓòÉ
development resource
Identifiable component of an application, such as a source code module, dynamic
link library, Presentation Manager icon, etc; alternatively, a utility or tool
used to develop an application, such as a compiler, link-editor or programmers'
toolkit.
ΓòÉΓòÉΓòÉ 33.47. dialog ΓòÉΓòÉΓòÉ
dialog
An interaction between an application and a user, based upon the need to
achieve a single logical task, such as the opening of a file.
ΓòÉΓòÉΓòÉ 33.48. dialog box ΓòÉΓòÉΓòÉ
dialog box
A special, short-lived window created by an OS/2 Presentation Manager
application to display information and receive input from the user in a
structured dialog format. The information is typically related to a particular
action being performed by the application.
ΓòÉΓòÉΓòÉ 33.49. Dialog Box Editor ΓòÉΓòÉΓòÉ
Dialog Box Editor
Utility application provided with the IBM Developer's Toolkit for OS/2 2.0,
which allows the design and creation of templates for dialog boxes.
ΓòÉΓòÉΓòÉ 33.50. dialog procedure ΓòÉΓòÉΓòÉ
dialog procedure
Special case of a window procedure; associated with a dialog box rather than a
standard window.
ΓòÉΓòÉΓòÉ 33.51. direct manipulation ΓòÉΓòÉΓòÉ
direct manipulation
User interface technique whereby application functions are initiated by the
user manipulating objects, represented by icons, on the Presentation Manager or
Workplace Shell desktop. The user typically initiates an action by selecting
an icon, pressing and holding down a mouse button while "dragging" the icon
over another object's icon on the desktop. The user then "drops" the icon over
the target object by releasing the mouse button. For this reason, the
technique is also known as "drag and drop" manipulation.
ΓòÉΓòÉΓòÉ 33.52. DLL ΓòÉΓòÉΓòÉ
DLL
See dynamic link library.
ΓòÉΓòÉΓòÉ 33.53. domain ΓòÉΓòÉΓòÉ
domain
Logical grouping of users, applications and devices in a network, which is
treated as a coherent unit for network administration purposes.
ΓòÉΓòÉΓòÉ 33.54. dormant ΓòÉΓòÉΓòÉ
dormant
Term used to denote the state of a Workplace Shell object when no views of that
object are currently open. Dormant objects typically do not "own" system
resources, and their instance data is in an unknown state.
ΓòÉΓòÉΓòÉ 33.55. DOS ΓòÉΓòÉΓòÉ
DOS
Disk Operating System; operating system for programmable workstations,
originally developed by Microsoft Corporation as MS DOS, and marketed under
license by IBM. Later versions were developed jointly by Microsoft and IBM.
ΓòÉΓòÉΓòÉ 33.56. DOS Compatibility Box ΓòÉΓòÉΓòÉ
DOS Compatibility Box
Facility provided by OS/2 Version 1.3 that allows a single real mode (DOS)
application to execute under control of OS/2, occupying the lowest 640 KB of
physical memory. A real mode application executing in this way may coexist
with other protected mode applications in the same system. Certain restrictions
are imposed on applications executing in the DOS Compatibility Box; an
application may not be a TSR application, nor should it be a time-dependent
application (such as a terminal emulator). These limitations are overcome by
the Multiple Virtual DOS Machines feature implemented by OS/2 Version 2.0.
ΓòÉΓòÉΓòÉ 33.57. DOS settings ΓòÉΓòÉΓòÉ
DOS settings
Feature implemented within the Multiple Virtual DOS Machines component of OS/2
Version 2.0, enabling a virtual DOS machine to be customized to suit the
requirements of an application running within it. This feature enables greater
application compatibility for virtual DOS machines.
ΓòÉΓòÉΓòÉ 33.58. drag and drop ΓòÉΓòÉΓòÉ
drag and drop
See direct manipulation.
ΓòÉΓòÉΓòÉ 33.59. dragitem ΓòÉΓòÉΓòÉ
dragitem
In the context of direct manipulation, an item that is currently being dragged
on the desktop by the user.
ΓòÉΓòÉΓòÉ 33.60. drawdown ΓòÉΓòÉΓòÉ
drawdown
Process of copying an application resource from a master-level library to a
developer's own working library.
ΓòÉΓòÉΓòÉ 33.61. dynamic linking ΓòÉΓòÉΓòÉ
dynamic linking
Process under OS/2, whereby resolution of external references within an
application to modules in dynamic link libraries (DLLs) is deferred until load
time or run time. This allows modification of modules contained in DLLs
without the need to link-edit an application once more. Since DLLs are
normally written as reentrant code, dynamic linking also allows multiple
applications to use the same copy of a DLL in memory, thus reducing the storage
requirements of OS/2 applications.
ΓòÉΓòÉΓòÉ 33.62. dynamic link library ΓòÉΓòÉΓòÉ
dynamic link library
Library containing OS/2 application code and/or resources, which may be linked
by one or more applications using the OS/2 dynamic linking process.
ΓòÉΓòÉΓòÉ 33.63. EHLLAPI ΓòÉΓòÉΓòÉ
EHLLAPI
Emulator High-Level Language Application Programming Interface; programming
interface provided by OS/2 Extended Edition Version 1.x and OS/2 Extended
Services, which enables PWS applications to emulate keystroking for host
terminal emulation sessions.
ΓòÉΓòÉΓòÉ 33.64. encapsulation ΓòÉΓòÉΓòÉ
encapsulation
Concept whereby the definition of a data object is included as part of the
application object that owns and manipulates the data object.
ΓòÉΓòÉΓòÉ 33.65. entity ΓòÉΓòÉΓòÉ
entity
Data item that must be manipulated by an application. See also logical data
entity, data object and application object.
ΓòÉΓòÉΓòÉ 33.66. event-driven ΓòÉΓòÉΓòÉ
event-driven
Term used to describe an application environment where the sequence of
processing is determined primarily by the application's response to external
events, which may be initiated by the user, the operating system or other
applications.
ΓòÉΓòÉΓòÉ 33.67. event semaphore ΓòÉΓòÉΓòÉ
event semaphore
Semaphore used by applications to signal an event such as the termination of a
thread.
ΓòÉΓòÉΓòÉ 33.68. exception handler ΓòÉΓòÉΓòÉ
exception handler
Application-supplied routine that is registered with OS/2 Version 2.0 on a
per-thread basis, and invoked by the operating system whenever an exception
condition occurs for that thread. Multiple exception handlers may be chained
for each thread, and a handler may process an exception or allow it to pass on
down the chain. OS/2 Version 2.0 itself provides default exception handlers
for all exception conditions.
ΓòÉΓòÉΓòÉ 33.69. execution instance ΓòÉΓòÉΓòÉ
execution instance
An individual process executing a reentrant code module. Such a module may
have multiple execution instances in existence at any one time; under OS/2, the
operating system maintains a separate task state for each execution instance.
ΓòÉΓòÉΓòÉ 33.70. exportable entry point ΓòÉΓòÉΓòÉ
exportable entry point
Entry point for an application function that is invoked from outside the
current executable module; for example, window procedures, which are invoked by
Presentation Manager on the application's behalf, rather than by the
application itself.
ΓòÉΓòÉΓòÉ 33.71. external entity ΓòÉΓòÉΓòÉ
external entity
An entity such as a remote system or data entry device which exists outside the
application, and interacts with the application. Such an entity and the
methods to manipulate it may be encapsulated in an application object.
ΓòÉΓòÉΓòÉ 33.72. external reference ΓòÉΓòÉΓòÉ
external reference
Program call to a memory address outside the current executable module; the
target of the call is typically a library routine. Examples of external
references are OS/2 system service calls.
ΓòÉΓòÉΓòÉ 33.73. EXPORTS statement ΓòÉΓòÉΓòÉ
EXPORTS statement
Statement used in a module definition file to define exportable entry points.
Required by all OS/2 Presentation Manager applications under OS/2 Version 1.3
unless the -Alfu option is specified at compile time.
ΓòÉΓòÉΓòÉ 33.74. far call ΓòÉΓòÉΓòÉ
far call
When using the segmented memory model, a program call to a routine located in a
different memory segment; such a call must use both a segment address and an
offset in the branch instruction, rather than just the offset as is the case
with a near call. By default, C programs compiled with the medium or large
memory models generate far calls.
ΓòÉΓòÉΓòÉ 33.75. FIFO ΓòÉΓòÉΓòÉ
FIFO
First In, First Out; term used to describe a queueing algorithm whereby items
are serially inserted into and removed from a queue structure, and where the
first item placed into a queue structure is the first item to be removed.
ΓòÉΓòÉΓòÉ 33.76. flat memory model ΓòÉΓòÉΓòÉ
flat memory model
Conceptual view of real memory implemented by OS/2 Version 2.0, where the
operating system regards memory as a single linear address range of up to 4 GB.
ΓòÉΓòÉΓòÉ 33.77. focus ΓòÉΓòÉΓòÉ
focus
See input focus.
ΓòÉΓòÉΓòÉ 33.78. Font Editor ΓòÉΓòÉΓòÉ
Font Editor
Utility provided with the IBM Developer's Toolkit for OS/2 2.0. which enables
the design and creation of new fonts.
ΓòÉΓòÉΓòÉ 33.79. frame area ΓòÉΓòÉΓòÉ
frame area
See frame window.
ΓòÉΓòÉΓòÉ 33.80. frame window ΓòÉΓòÉΓòÉ
frame window
A window that contains the border visible on the screen; various control
windows such as the title bar, menu bar and icons are children of the frame
window. The client window, used by the application to display information, is
also a child of the frame window.
ΓòÉΓòÉΓòÉ 33.81. functional decomposition ΓòÉΓòÉΓòÉ
functional decomposition
Application design technique also known as structured programming, whereby
procedures become the focus of the application design and are progressively
divided into smaller units of work until an atomic level is reached that may be
implemented by a series of operations in a conventional programming language.
ΓòÉΓòÉΓòÉ 33.82. GB ΓòÉΓòÉΓòÉ
GB
Gigabyte; 1024 Megabytes, or 1024 x 1024 x 1024 bytes.
ΓòÉΓòÉΓòÉ 33.83. graphical model ΓòÉΓòÉΓòÉ
graphical model
Object-action, event-driven user interface model defined in the IBM Systems
Application Architecture CUA Advanced Guide to User Interface Design. The
graphical model makes extensive use of windows and graphical visual cues, and
is supported by Presentation Manager.
ΓòÉΓòÉΓòÉ 33.84. GRE ΓòÉΓòÉΓòÉ
GRE
Graphical Rendering Engine; component of the OS/2 Version 2.0 operating system
responsible for drawing graphical items on the display.
ΓòÉΓòÉΓòÉ 33.85. guard page ΓòÉΓòÉΓòÉ
guard page
Uppermost committed page of a private memory object, or lowermost committed
page of a shared memory object, set using the PAG_GUARD flag. A write
operation into a guard page generates a guard page exception, which may be
trapped by an application-registered exception handler, which may then commit
additional pages of storage. See exception handler.
ΓòÉΓòÉΓòÉ 33.86. guard page exception ΓòÉΓòÉΓòÉ
guard page exception
Exception condition generated by OS/2 Version 2.0 when an application writes
into a guard page. Like other exception conditions, the guard page exception
may be trapped by an exception handler registered by the application. See
exception handler.
ΓòÉΓòÉΓòÉ 33.87. help instance ΓòÉΓòÉΓòÉ
help instance
A link between an application and the Information Presentation Facility, which
allows information to be passed between the two, in order to display help
panels and enable the application to be informed of events occurring within
help windows.
ΓòÉΓòÉΓòÉ 33.88. help library ΓòÉΓòÉΓòÉ
help library
A file produced by the IPF compiler, which contains a collection of help panels
related to a particular application, and which is used by the Information
Presentation Facility to display help information for that application.
ΓòÉΓòÉΓòÉ 33.89. help panel ΓòÉΓòÉΓòÉ
help panel
A unit of help information, displayed in a help window under the control of the
Information Presentation Facility.
ΓòÉΓòÉΓòÉ 33.90. help window ΓòÉΓòÉΓòÉ
help window
A window displayed by the Information Presentation Facility at the request of
an application, containing a help panel with information pertaining to the
active application window.
ΓòÉΓòÉΓòÉ 33.91. Hungarian notation ΓòÉΓòÉΓòÉ
Hungarian notation
Technique for including data typing in variable and procedure names within
application source code; devised by Charles Simonyi of Microsoft.
ΓòÉΓòÉΓòÉ 33.92. hypergraphics ΓòÉΓòÉΓòÉ
hypergraphics
Under the Information Presentation Facility, a portion of a bitmap displayed in
a help panel or online document, which may be selected by the end user.
Selecting such an item causes an event to occur, such as the display of another
help panel, a popup window, the dispatch of a message to the parent application
or the start of a new application. See also hypertext.
ΓòÉΓòÉΓòÉ 33.93. hypertext ΓòÉΓòÉΓòÉ
hypertext
Under the Information Presentation Facility, a word or phrase in a help panel
or online document, which may be selected by the end user. Selecting such an
item causes an event to occur, such as the display of another help panel, a
popup window, the dispatch of a message to the parent application or the start
of a new application. See also hypergraphics.
ΓòÉΓòÉΓòÉ 33.94. icon ΓòÉΓòÉΓòÉ
icon
In the Presentation Manager user interface, a small graphical image that
represents an application, window or other object such as a file or device.
The user may directly manipulate icons on the desktop to perform work tasks.
ΓòÉΓòÉΓòÉ 33.95. Icon Editor ΓòÉΓòÉΓòÉ
Icon Editor
Utility application provided with OS/2 Version 2.0, which may be used to design
and create icons.
ΓòÉΓòÉΓòÉ 33.96. import library ΓòÉΓòÉΓòÉ
import library
Library file containing information on functions and resources contained in a
dynamic link library. Used as input to the OS/2 linkage editor. Use of an
import library negates the need for an IMPORTS statement in an application's
module definition file.
ΓòÉΓòÉΓòÉ 33.97. IMPORTS statement ΓòÉΓòÉΓòÉ
IMPORTS statement
Statement used in a module definition file to denote functions that will be
imported from a dynamic link library. Required for any application that uses a
DLL, unless an import library containing information on the DLL functions is
specified at link-edit time.
ΓòÉΓòÉΓòÉ 33.98. Information Presentation Facility ΓòÉΓòÉΓòÉ
Information Presentation Facility
Facility provided by OS/2 Version 1.2 and above (including OS/2 Version 2.0),
by which application developers may produce online documentation and
context-sensitive online help panels for their applications, using an IPF tag
language and an IPF compiler.
ΓòÉΓòÉΓòÉ 33.99. inheritance ΓòÉΓòÉΓòÉ
inheritance
Concept whereby an application object takes on the properties of the object
class to which it belongs; such properties may include the definition of
instance variables and data objects. Object classes may also be defined in
terms of other, previously defined object classes; the new object class then
takes on the properties and methods of its parent class or classes (which
themselves may be defined in terms of other classes).
ΓòÉΓòÉΓòÉ 33.100. inheritance hierarchy ΓòÉΓòÉΓòÉ
inheritance hierarchy
Term used to describe the chain of interdependence formed when object classes
are defined in terms of other currently existing classes, and where the
definition of an object class is thus dependent upon the presence of its parent
class or classes.
ΓòÉΓòÉΓòÉ 33.101. input focus ΓòÉΓòÉΓòÉ
input focus
In the Presentation Manager environment, the user interacts with a single
window at any given moment; that window is said to have the input focus.
ΓòÉΓòÉΓòÉ 33.102. instance ΓòÉΓòÉΓòÉ
instance
An individual application object (or Workplace Shell object) that belongs to a
particular object class. See also execution instance.
ΓòÉΓòÉΓòÉ 33.103. instance data ΓòÉΓòÉΓòÉ
instance data
A data item that is created and owned by a single instance of an application
object class. An instance variable is typically defined by the class, and the
definition is thus common to all instances of that class, but a separate data
item is maintained for each instance.
ΓòÉΓòÉΓòÉ 33.104. Interface Control Document ΓòÉΓòÉΓòÉ
Interface Control Document
Document that contains descriptions of all generic library objects and
functions, along with their external interfaces including both input and output
data. The interface control document is used by application developers who
wish to utilize library objects and functions in their applications.
ΓòÉΓòÉΓòÉ 33.105. IPF ΓòÉΓòÉΓòÉ
IPF
See Information Presentation Facility.
ΓòÉΓòÉΓòÉ 33.106. IPF compiler ΓòÉΓòÉΓòÉ
IPF compiler
Compiler provided with the IBM Developer's Toolkit for OS/2 2.0, which allows
the compilation of source files into help libraries or online documents that
may be displayed using the Information Presentation Facility.
ΓòÉΓòÉΓòÉ 33.107. IPF-controlled viewport ΓòÉΓòÉΓòÉ
IPF-controlled viewport
Viewport within a help window or online document window, where the formatting
and display of information within that window is controlled by the Information
Presentation Facility. This is the default case for information displayed
using the Information Presentation Facility. See also application-controlled
viewport.
ΓòÉΓòÉΓòÉ 33.108. IPF tag language ΓòÉΓòÉΓòÉ
IPF tag language
Text formatting language used by the Information Presentation Facility, whereby
tags are inserted into the ASCII source text to cause formatting to occur. The
tags and syntax of the IPF tag language are similar to IBM's Generalized Markup
Language (GML).
ΓòÉΓòÉΓòÉ 33.109. KB ΓòÉΓòÉΓòÉ
KB
Kilobyte; 1024 bytes.
ΓòÉΓòÉΓòÉ 33.110. LAN ΓòÉΓòÉΓòÉ
LAN
See local area network.
ΓòÉΓòÉΓòÉ 33.111. LIFO ΓòÉΓòÉΓòÉ
LIFO
Last In, First Out; term used to describe a queueing algorithm whereby items
are serially inserted into and removed from the queue structure, and where the
most recently inserted item is the first item to be removed.
ΓòÉΓòÉΓòÉ 33.112. load-time dynamic linking ΓòÉΓòÉΓòÉ
load-time dynamic linking
Form of dynamic linking where resolution of external references takes place
during loading of the application into memory. Load-time dynamic linking is
typically used to share a single memory-resident copy of common application
service routines, or to isolate portions of application code from the remainder
of the application, thereby facilitating any future change management. See
also run-time dynamic linking.
ΓòÉΓòÉΓòÉ 33.113. local area network ΓòÉΓòÉΓòÉ
local area network
A network, typically composed of programmable workstations, in which the
constituent nodes are situated in direct geographical proximity to one another,
usually within the same property boundary. A number of local area networks may
be "bridged" together to form a wide area network that may extend across
multiple geographical locations.
ΓòÉΓòÉΓòÉ 33.114. logical data entity ΓòÉΓòÉΓòÉ
logical data entity
Term used to describe a coherent unit of logical data, such as a block of text.
This data may simultaneously exist in numerous representations within the
system, either in memory or on secondary storage devices. See also data object
and application object.
ΓòÉΓòÉΓòÉ 33.115. MB ΓòÉΓòÉΓòÉ
MB
Megabyte; 1024 kilobytes, or 1024 x 1024 bytes.
ΓòÉΓòÉΓòÉ 33.116. memory object ΓòÉΓòÉΓòÉ
memory object
Logical unit of memory requested by an application, which forms the granular
unit of memory manipulation from the application viewpoint. A memory object may
be up to 512 MB in size under OS/2 Version 2.0.
ΓòÉΓòÉΓòÉ 33.117. menu bar ΓòÉΓòÉΓòÉ
menu bar
Area near the top of a CUA-conforming window, which contains a horizontally
oriented list of actions that relate to the data object being manipulated in
the window.
ΓòÉΓòÉΓòÉ 33.118. message ΓòÉΓòÉΓòÉ
message
Data structure used by OS/2 Presentation Manager for communication between
window procedures, or between Presentation Manager and a window procedure.
Messages may be system-defined or user-defined. See also message class.
ΓòÉΓòÉΓòÉ 33.119. message box ΓòÉΓòÉΓòÉ
message box
Within Presentation Manager, a specialized type of dialog box that carries out
a simple structured dialog with the user. This dialog is limited to the
display of some textual information, and the input of a single choice from a
limited, finite set of mutually exclusive options. A message box is simpler to
process than a dialog box, and is useful in circumstances where the
sophistication of a dialog box is unnecessary.
ΓòÉΓòÉΓòÉ 33.120. message class ΓòÉΓòÉΓòÉ
message class
Logical grouping of messages with common properties. Under Presentation
Manager, messages are grouped into classes with the name of the message class
and the definitions of message parameters being common to all instances of that
class. Individual instances differ in their destination window and in the
contents of their message parameters.
ΓòÉΓòÉΓòÉ 33.121. metaclass ΓòÉΓòÉΓòÉ
metaclass
Term used to describe the conjunction of an object and its class information;
that is, the information pertaining to the class as a whole, rather than to a
single instance of the class. Each class is itself an object, which is an
instance of the metaclass.
ΓòÉΓòÉΓòÉ 33.122. method ΓòÉΓòÉΓòÉ
method
In object-oriented terms, a routine or procedure used to manipulate a data
object. A group of methods, together with a definition of the data object
itself, constitute an application object.
ΓòÉΓòÉΓòÉ 33.123. mixed model programming ΓòÉΓòÉΓòÉ
mixed model programming
Technique of combining 16-bit and 32-bit modules and resources within the same
application under OS/2 Version 2.0. Mixed model programming requires some
special considerations when passing control and parameters between 16-bit and
32-bit modules and resources.
ΓòÉΓòÉΓòÉ 33.124. modal ΓòÉΓòÉΓòÉ
modal
Term used to describe a message box or dialog box for which processing must be
completed before user interaction may continue. Two types of modal dialog are
possible: application-modal and system-modal. See also modeless.
ΓòÉΓòÉΓòÉ 33.125. modeless ΓòÉΓòÉΓòÉ
modeless
Term used to describe a dialog box which is displayed on the screen, but which
does not require immediate interaction with the user, who may continue to
interact with other windows while the dialog box is displayed.
ΓòÉΓòÉΓòÉ 33.126. module-based ΓòÉΓòÉΓòÉ
module-based
Term used to describe an implementation of object-oriented programming, whereby
an object class is completely defined in its own right, and does not depend
upon the definitions of other classes. Such an approach provides increased
levels of granularity and thus enhances object reusability, albeit at the
expense of additional complexity during creation of the object. Compare with
class-based approach.
ΓòÉΓòÉΓòÉ 33.127. module definition file ΓòÉΓòÉΓòÉ
module definition file
ASCII text file typically used with OS/2 Presentation Manager applications to
define information such as module names, stack and heap sizes and exportable
entry points. Used as input to the OS/2 link-editor.
ΓòÉΓòÉΓòÉ 33.128. Multiple Virtual DOS Machines ΓòÉΓòÉΓòÉ
Multiple Virtual DOS Machines
Feature of OS/2 Version 2.0 that enables multiple DOS applications to execute
concurrently in full-screen or windowed mode under OS/2 Version 2.0, in
conjunction with other 16-bit or 32-bit applications, with full pre-emptive
multitasking and memory protection between tasks.
ΓòÉΓòÉΓòÉ 33.129. multiprogramming ΓòÉΓòÉΓòÉ
multiprogramming
Term used to describe an operating system environment that allows the
concurrent execution of multiple applications in the same system.
ΓòÉΓòÉΓòÉ 33.130. multitasking ΓòÉΓòÉΓòÉ
multitasking
Extension of the multiprogramming concept, whereby processor time is
distributed among multiple applications by giving each application access to
the processor for short periods of time. Multitasking may be cooperative or
pre-emptive in nature.
ΓòÉΓòÉΓòÉ 33.131. multithreading ΓòÉΓòÉΓòÉ
multithreading
Extension of the multitasking concept, whereby multiple "tasks" may exist
within a single application, allowing different portions of the application to
execute asynchronously to one another. Multithreading allows an application to
continue to respond to user input while lengthy processing takes place in the
background.
ΓòÉΓòÉΓòÉ 33.132. Mutex semaphore ΓòÉΓòÉΓòÉ
Mutex semaphore
Semaphore used to control access to a resource that may be safely accessed only
by a single application thread at any time.
ΓòÉΓòÉΓòÉ 33.133. MuxWait semaphore ΓòÉΓòÉΓòÉ
MuxWait semaphore
Semaphore used when waiting for multiple events to occur or for multiple
resources to be freed.
ΓòÉΓòÉΓòÉ 33.134. near call ΓòÉΓòÉΓòÉ
near call
Under the segmented memory model, a program call to a routine located within
the same memory segment. Such a call provides only the offset of the routine
within the segment; a segment address is not needed since all application code
is assumed to reside in the same memory segment. By default, C programs
compiled using the small or compact memory models generate near calls. See
also far call.
ΓòÉΓòÉΓòÉ 33.135. NPX ΓòÉΓòÉΓòÉ
NPX
Numeric Processor Extension; term used in reference to the exception condition
generated by the 80386 processor when an application issues a numeric
coprocessor instruction in a machine with no coprocessor installed. Note that
OS/2 Version 2.0 will trap the NPX exception and emulate the numeric
coprocessor function within the operating system, returning the result to the
application exactly as if a physical coprocessor were installed.
ΓòÉΓòÉΓòÉ 33.136. object ΓòÉΓòÉΓòÉ
object
A collection of data and methods (procedures) that operate on that data, which
together represent a logical entity in the system. In object-oriented
programming, objects are grouped into classes that share common data
definitions and methods. Each object in the class is said to be an instance of
the class. See also instance, object class, data object, application object.
ΓòÉΓòÉΓòÉ 33.137. object class ΓòÉΓòÉΓòÉ
object class
Logical grouping of application objects with similar properties; methods are
normally associated with an object class, rather than with individual instances
of that class. Under the Workplace Shell, an object class is defined using a
class definition file.
ΓòÉΓòÉΓòÉ 33.138. object window ΓòÉΓòÉΓòÉ
object window
A conceptual window that does not appear on the screen, and is associated with
a data object such as a file or database. In effect, an object window is
merely an address to which messages may be sent to cause manipulation of a
particular data object.
ΓòÉΓòÉΓòÉ 33.139. online document ΓòÉΓòÉΓòÉ
online document
A set of information relating to an application or a business process, which is
developed using the IPF tag language, compiled and viewed using the Information
Presentation Facility. An online document, unlike a help library, is not
necessarily related to a single application, and exists in a "standalone"
environment.
ΓòÉΓòÉΓòÉ 33.140. online document window ΓòÉΓòÉΓòÉ
online document window
A window displayed by the Information Presentation Facility, using the VIEW.EXE
utility, and which contains information from an online document.
ΓòÉΓòÉΓòÉ 33.141. Operating System/2 ΓòÉΓòÉΓòÉ
Operating System/2
Operating system for programmable workstations, offering more sophisticated
multiprogramming and multitasking capabilities and larger memory support than
DOS.
ΓòÉΓòÉΓòÉ 33.142. optimized window ΓòÉΓòÉΓòÉ
optimized window
Term used to describe a dialog box; such a window is created for a specific
purpose, containing a number of control windows, and is deemed to have been
created at the optimum size to display those control windows. Thus an
optimized window may not be resized by the user, nor may it be minimized or
maximized.
ΓòÉΓòÉΓòÉ 33.143. optlink ΓòÉΓòÉΓòÉ
optlink
Default linkage convention using in C programming under the IBM C Set/2
compiler, which causes the compiler to generate object code for a function or
subroutine, such that parameters are placed on the stack in right-to-left
order, and the stack is cleared by the calling function when control is
returned. The optlink linkage convention differs from the system linkage
convention in the preservation of register values and the handling of return
values.
ΓòÉΓòÉΓòÉ 33.144. OS/2 ΓòÉΓòÉΓòÉ
OS/2
See Operating System/2.
ΓòÉΓòÉΓòÉ 33.145. page ΓòÉΓòÉΓòÉ
page
Granular unit for memory management using the 80386 or 80486 processors with
the paging feature enabled. A page is a 4 KB contiguous unit of memory, which
the processor manipulates as a single entity for the purpose of memory
manipulation and swapping.
ΓòÉΓòÉΓòÉ 33.146. parent ΓòÉΓòÉΓòÉ
parent
Immediate ancestor of a Workplace Shell object class; the object class from
which the current object class was created by subclassing. See also ancestor,
descendant.
ΓòÉΓòÉΓòÉ 33.147. pascal ΓòÉΓòÉΓòÉ
pascal
Linkage convention used in C programming that causes the compiler to generate
object code for a function or subroutine, such that parameters are placed on
the stack in left-to-right order when the subroutine is called, and the stack
is cleared by the called subroutine when control is returned. Originally
introduced by Microsoft with early versions of Microsoft Windows, when this
convention saved several hundred bytes of system memory, and adopted by
Presentation Manager under OS/2 Version 1.3. Contrast with cdecl linkage
convention.
ΓòÉΓòÉΓòÉ 33.148. PC DOS ΓòÉΓòÉΓòÉ
PC DOS
Personal Computer Disk Operating System; see DOS.
ΓòÉΓòÉΓòÉ 33.149. persistent ΓòÉΓòÉΓòÉ
persistent
Term used to describe Workplace Shell objects that are registered with the
operating system and that continue to exist in the Workplace Shell after the
system is re-IPLed.
ΓòÉΓòÉΓòÉ 33.150. pipe ΓòÉΓòÉΓòÉ
pipe
Facility provided by OS/2 for communication between threads and/or processes.
Pipes may be named or unnamed.
ΓòÉΓòÉΓòÉ 33.151. polymorphism ΓòÉΓòÉΓòÉ
polymorphism
Concept whereby the behavior of an application object is dependent solely upon
the class and contents of the messages received by that object, and is not
affected by any other external factor. Similarly, the effect of the same
message class is dependent upon the application object to which it is passed,
and that object's interpretation of the message.
ΓòÉΓòÉΓòÉ 33.152. pre-emptive multitasking ΓòÉΓòÉΓòÉ
pre-emptive multitasking
Multitasking implementation whereby the operating system provides a scheduler
that periodically interrupts an executing task, saves its current state
information and dispatches another task, thereby sharing system resources
across multiple applications.
ΓòÉΓòÉΓòÉ 33.153. Presentation Interface ΓòÉΓòÉΓòÉ
Presentation Interface
Component of Systems Application Architecture Common Programming Interface,
which defines an application programming interface for presentation services.
ΓòÉΓòÉΓòÉ 33.154. Presentation Manager ΓòÉΓòÉΓòÉ
Presentation Manager
Windowed, graphics-oriented user interface provided by OS/2 Version 1.1 and
above; allows object-oriented applications to be written in conformance with
Common User Access guidelines. The Presentation Manager programming interface
conforms to the Systems Application Architecture Common Programming Interface
Presentation Interface specifications.
ΓòÉΓòÉΓòÉ 33.155. presentation space ΓòÉΓòÉΓòÉ
presentation space
In the context of Presentation Manager, a conceptual display surface onto which
information is written. A presentation space is a data object normally
associated with a window.
ΓòÉΓòÉΓòÉ 33.156. primary thread ΓòÉΓòÉΓòÉ
primary thread
The first thread of execution created by an OS/2 application upon application
startup. In a Presentation Manager application, the primary thread typically
provides processing for user interaction and short-lived application functions.
Lengthy processing is typically carried out by a secondary thread, to preserve
user responsiveness goals as defined in Common User Access guidelines.
ΓòÉΓòÉΓòÉ 33.157. private semaphore ΓòÉΓòÉΓòÉ
private semaphore
See semaphore.
ΓòÉΓòÉΓòÉ 33.158. procedural entity ΓòÉΓòÉΓòÉ
procedural entity
An entity, such as an administrative procedure, that interacts with other
logical entities within an object-oriented application, and that itself may be
encapsulated within an application object.
ΓòÉΓòÉΓòÉ 33.159. process ΓòÉΓòÉΓòÉ
process
In the context of OS/2, an instance of a particular program, which owns system
resources such as threads, file handles and a memory map described by the
process' local descriptor table. A process may consist of one or more threads.
ΓòÉΓòÉΓòÉ 33.160. process address space ΓòÉΓòÉΓòÉ
process address space
Region of memory addressable by a single process under OS/2 Version 2.0. Each
process address space may be up to 512 MB in size.
ΓòÉΓòÉΓòÉ 33.161. production-level ΓòÉΓòÉΓòÉ
production-level
Term used to describe an application resource that has been unit-tested and
baselined, and is placed in a production library from which multiple
application developers may access it.
ΓòÉΓòÉΓòÉ 33.162. programmable workstation ΓòÉΓòÉΓòÉ
programmable workstation
An intelligent workstation device, containing its own processor, memory and
possibly its own storage devices; for example, the IBM Personal System/2
family.
ΓòÉΓòÉΓòÉ 33.163. promotion ΓòÉΓòÉΓòÉ
promotion
Process of migrating a user-level application resource to production level
after baselining.
ΓòÉΓòÉΓòÉ 33.164. protect mode ΓòÉΓòÉΓòÉ
protect mode
Native mode of execution for the Intel 80286 processor, whereby memory
addresses are made by segment and offset, and a separate set of descriptors is
maintained for memory addressable by each application, thereby providing memory
isolation in a multiprogramming environment.
ΓòÉΓòÉΓòÉ 33.165. PTDA ΓòÉΓòÉΓòÉ
PTDA
Per Task Data Area; storage area maintained by OS/2 for each process executing
in the system, containing process-specific execution data.
ΓòÉΓòÉΓòÉ 33.166. pulldown menu ΓòÉΓòÉΓòÉ
pulldown menu
A menu that appears when the user selects an item in a window's menu bar. The
pulldown menu acts as a "submenu", and contains a list of entries from which
the user may select the required action. Pulldown menus may be nested.
ΓòÉΓòÉΓòÉ 33.167. PWS ΓòÉΓòÉΓòÉ
PWS
See programmable workstation.
ΓòÉΓòÉΓòÉ 33.168. queue ΓòÉΓòÉΓòÉ
queue
Facility provided by OS/2 for communication between threads and/or processes.
ΓòÉΓòÉΓòÉ 33.169. real mode ΓòÉΓòÉΓòÉ
real mode
Mode of execution for the Intel 80286 processor, whereby the processor emulates
the operation of an 8086/8088 processor. In this mode, memory addresses are
made to physical locations in memory, and addressability is limited to 1 MB.
Real mode is the mode used by the DOS operating system; the design of this
operating system further restricts applications' memory addressability to 640
KB.
ΓòÉΓòÉΓòÉ 33.170. rendering mechanism ΓòÉΓòÉΓòÉ
rendering mechanism
Protocol that defines the communication between two windows or objects during a
drag/drop operation. Presentation Manager provides three standard rendering
mechanisms for commonly used data types, and application developers may define
their own rendering mechanisms to meet specific requirements.
ΓòÉΓòÉΓòÉ 33.171. resource ΓòÉΓòÉΓòÉ
resource
Item such as a window or dialog template, string table, menu table, etc., which
may be defined externally and used by one or more Presentation Manager or
Workplace Shell applications.
ΓòÉΓòÉΓòÉ 33.172. resource compiler ΓòÉΓòÉΓòÉ
resource compiler
Utility provided with IBM Developer's Toolkit for OS/2 2.0, which takes a
resource script file and produces a precompiled resource or group resources
that may be incorporated into an executable code module.
ΓòÉΓòÉΓòÉ 33.173. resource script file ΓòÉΓòÉΓòÉ
resource script file
ASCII text file with .RC extension, used to define resources for a Presentation
Manager application. Used as input to resource compiler.
ΓòÉΓòÉΓòÉ 33.174. REXX ΓòÉΓòÉΓòÉ
REXX
Restructured Extended Executor; procedural language included as part of OS/2
Version 2.0, which provides batch language functions along with structured
programming constructs such as loops, conditional testing and subroutines.
Programs or subroutines written using the REXX language may be invoked directly
from the command line, or from an application written in REXX or another
programming language.
ΓòÉΓòÉΓòÉ 33.175. run-time dynamic linking ΓòÉΓòÉΓòÉ
run-time dynamic linking
Form of dynamic linking whereby modules and resources are loaded into memory
during application execution, by the application issuing a WinLoadModule()
function call. Run-time dynamic linking is typically used for portions of the
application code that are rarely required (such as fatal error handling
routines); they are therefore explicitly loaded into memory when needed. In
this way, the memory requirements of the application may be reduced.
ΓòÉΓòÉΓòÉ 33.176. SAA ΓòÉΓòÉΓòÉ
SAA
See Systems Application Architecture.
ΓòÉΓòÉΓòÉ 33.177. scheduler ΓòÉΓòÉΓòÉ
scheduler
Component of OS/2 which provides automated task dispatching.
ΓòÉΓòÉΓòÉ 33.178. secondary thread ΓòÉΓòÉΓòÉ
secondary thread
Separate thread of execution created by a Presentation Manager application to
handle lengthy processing of a specific type of message using an object window.
ΓòÉΓòÉΓòÉ 33.179. segment ΓòÉΓòÉΓòÉ
segment
Unit of memory addressable by the Intel 80x86 processors. With the 8086 and
80286 processors, a segment may be from 16 bytes to 64 KB in size. With the
80386 and 80486 processors, a segment may be up to 4 GB in size.
ΓòÉΓòÉΓòÉ 33.180. segmented memory model ΓòÉΓòÉΓòÉ
segmented memory model
Mode of addressing used by Intel 80x86 processors, whereby memory is addressed
in segments. Individual units of up to 64 KB (8086/80286) or 4 GB
(80386/80486) in size may be allocated by an operating system that uses this
memory model.
ΓòÉΓòÉΓòÉ 33.181. seg16 ΓòÉΓòÉΓòÉ
seg16
#pragma directive used in C language programming under the IBM C Set/2
compiler, which ensures that automatic data structures do not cross a 64 KB
segment boundary, and are thus addressable by both 16-bit and 32-bit code.
This directive is used when declaring data structures that will be used as
parameters when invoking 16-bit functions or subroutines from 32-bit
applications.
ΓòÉΓòÉΓòÉ 33.182. semaphore ΓòÉΓòÉΓòÉ
semaphore
Data structure provided by OS/2, and used for synchronization between threads
and/or processes. OS/2 Version 2.0 allows mutex semaphores, event semaphores
and muxwait semaphores. Semaphores may also be private (owned and accessible
by a single process) or shared (accessible by all processes in the system). A
process may create up to 65,535 private semaphores, and there may be a
system-wide total of up to 65,535 shared semaphores in existence at any time.
ΓòÉΓòÉΓòÉ 33.183. shared semaphore ΓòÉΓòÉΓòÉ
shared semaphore
See semaphore.
ΓòÉΓòÉΓòÉ 33.184. siblings ΓòÉΓòÉΓòÉ
siblings
Term used in the Presentation Manager environment to describe two or more
windows that have the same parent window.
ΓòÉΓòÉΓòÉ 33.185. simple viewport ΓòÉΓòÉΓòÉ
simple viewport
A viewport within a help window or online document window that is the only
viewport within that window. This is the default case for the display of text
or graphics using the Information Presentation Facility. See also complex
viewport.
ΓòÉΓòÉΓòÉ 33.186. SNA ΓòÉΓòÉΓòÉ
SNA
System Network Architecture; defined series of layered interfaces and protocols
for communication between systems and devices.
ΓòÉΓòÉΓòÉ 33.187. SOM ΓòÉΓòÉΓòÉ
SOM
See system object model.
ΓòÉΓòÉΓòÉ 33.188. SOM Precompiler ΓòÉΓòÉΓòÉ
SOM Precompiler
Precompiler which generates C source code and header files from a class
definition file. The resulting code may then be edited by a programmer to add
application logic, and then compiled using a normal C compiler such as C Set/2.
ΓòÉΓòÉΓòÉ 33.189. source ΓòÉΓòÉΓòÉ
source
In a direct manipulation operation, the object or program from which a dragitem
is being dragged. See also direct manipulation, dragitem, target.
ΓòÉΓòÉΓòÉ 33.190. sparse object ΓòÉΓòÉΓòÉ
sparse object
Under OS/2 Version 2.0, a memory object that has been allocated but for which
no storage has yet been committed. A sparse object has a valid address range
in the process address space, but cannot be the target of a write operation
until one or more pages within the object are committed.
ΓòÉΓòÉΓòÉ 33.191. SQL ΓòÉΓòÉΓòÉ
SQL
Structured Query Language; Systems Application Architecture-conforming language
for the definition and manipulation of data stored in relational database
management systems. SQL is supported in the programmable workstation by OS/2
Database Manager, in the AS/400 midrange systems and in System/370 hosts by the
DB2 and SQL/DS products.
ΓòÉΓòÉΓòÉ 33.192. SRPI ΓòÉΓòÉΓòÉ
SRPI
Server-Requester Programming Interface; programming interface enabling
master-slave communication between a workstation application (the requester)
and a host application (the server) using an SNA LU2.0 communications link.
SRPI is supported in the PWS under DOS, OS/2 Extended Edition V1.x and OS/2
Extended Services, and in System/370 hosts running VM/CMS and MVS/TSO.
ΓòÉΓòÉΓòÉ 33.193. structured programming ΓòÉΓòÉΓòÉ
structured programming
Application design technique whereby applications are successively broken down
into their component functions until a level is achieved at which application
code may easily be generated. See functional decomposition.
ΓòÉΓòÉΓòÉ 33.194. subclassing ΓòÉΓòÉΓòÉ
subclassing
Technique whereby messages destined for a particular object are diverted to
another object that may perform special processing for a particular message
type or provide additional methods not provided by the parent object.
Subclassing is typically performed on individual instances of an object class,
rather than on the entire class.
ΓòÉΓòÉΓòÉ 33.195. synchronous processing ΓòÉΓòÉΓòÉ
synchronous processing
Invocation of another procedure whereby control does not return to the caller
until that procedure has completed its processing.
ΓòÉΓòÉΓòÉ 33.196. system ΓòÉΓòÉΓòÉ
system
Linkage convention used in C programming under the IBM C Set/2 compiler, which
causes the compiler to generate object code for a function or subroutine, such
that parameters are placed on the stack in right-to-left order, and the stack
is cleared by the calling function when control is returned. The system
linkage convention differs from the default optlink linkage convention in the
preservation of register values and the handling of return values. Use of the
system linkage convention is required for functions that are invoked by the
operating system or Presentation Manager, such as window and dialog procedures.
The system linkage convention is specified using the #pragma linkage directive.
ΓòÉΓòÉΓòÉ 33.197. system-modal ΓòÉΓòÉΓòÉ
system-modal
Term used to describe a message box or dialog box for which processing must be
completed before further interaction with any other window in the system may
take place.
ΓòÉΓòÉΓòÉ 33.198. system object model ΓòÉΓòÉΓòÉ
system object model
Set of base object classes and object-relationship protocol definitions that
defines a basic object-oriented layer on top of Presentation Manager, and which
is exploited by the Workplace Shell.
ΓòÉΓòÉΓòÉ 33.199. Systems Application Architecture ΓòÉΓòÉΓòÉ
Systems Application Architecture
Set of guidelines for application development, covering areas such as user
interfaces, application programming interfaces and communications environments.
Systems Application Architecture facilitates ease of use and application
portability between environments.
ΓòÉΓòÉΓòÉ 33.200. target ΓòÉΓòÉΓòÉ
target
In a direct manipulation operation, the object or program to which a dragitem
is being dragged. See also direct manipulation, dragitem, source.
ΓòÉΓòÉΓòÉ 33.201. task state ΓòÉΓòÉΓòÉ
task state
Set of information that embodies the current state of a thread (task) in the
system; composed of the register contents and stack belonging to a thread at
the time it is pre-empted by the scheduler.
ΓòÉΓòÉΓòÉ 33.202. thread ΓòÉΓòÉΓòÉ
thread
Atomic unit of dispatch under OS/2. One or more threads make up a process; the
threads within a process may share resources belonging to that process.
ΓòÉΓòÉΓòÉ 33.203. thunking ΓòÉΓòÉΓòÉ
thunking
Term used to describe the process of address conversion, stack and structure
realignment, etc., necessary when passing control between 16-bit and 32-bit
modules under OS/2 Version 2.0.
ΓòÉΓòÉΓòÉ 33.204. thunk procedure ΓòÉΓòÉΓòÉ
thunk procedure
Application procedure that performs thunking.
ΓòÉΓòÉΓòÉ 33.205. timer ΓòÉΓòÉΓòÉ
timer
Facility provided under OS/2 Presentation Manager, whereby Presentation Manager
will dispatch a message of class WM_TIMER to a particular window at specified
intervals. This capability may be used by an application to perform a specific
processing task at predetermined intervals, without the necessity for the
application to explicitly keep track of the passage of time.
ΓòÉΓòÉΓòÉ 33.206. title bar ΓòÉΓòÉΓòÉ
title bar
Area at the top of a CUA-conforming window that contains the title of the
window (typically identifying the data object or device to which the window
relates).
ΓòÉΓòÉΓòÉ 33.207. transient object ΓòÉΓòÉΓòÉ
transient object
A Workplace Shell object that does not persist beyond a system IPL. Transient
object classes are descendants of the WPTransient object class.
ΓòÉΓòÉΓòÉ 33.208. TSR ΓòÉΓòÉΓòÉ
TSR
Terminate-and-Stay-Resident; term used to describe a DOS application that
modifies an operating system interrupt vector to point to its own location
(known as hooking an interrupt). This process is not permitted under OS/2,
although facilities exist under OS/2 to provide the same capability for
applications.
ΓòÉΓòÉΓòÉ 33.209. user-level ΓòÉΓòÉΓòÉ
user-level
Term used to describe an application resource that is currently undergoing
modification and unit testing; when unit testing is complete, the resource is
then submitted for baselining and subsequent promotion to production level.
ΓòÉΓòÉΓòÉ 33.210. view ΓòÉΓòÉΓòÉ
view
In the Workplace Shell, a view is a window that displays the contents or
properties of an object is a particular manner. For example, an "icon view"
displays the contents of a container object as a series of icons. The same
object may also have a "settings view", which displays the characteristics of
the object.
ΓòÉΓòÉΓòÉ 33.211. viewport ΓòÉΓòÉΓòÉ
viewport
Under the Information Presentation Facility, a portion of a help window or
online document window that may be separately manipulated. The use of multiple
viewports in a window enables the display of different types of information in
the same window, with separate formatting and scrolling. Viewports may be
either simple or complex, and may be IPF-controlled or application-controlled.
ΓòÉΓòÉΓòÉ 33.212. VIO ΓòÉΓòÉΓòÉ
VIO
Term used to describe the OS/2 Video Subsystem, used by text-windowed and
full-screen protect-mode applications executing under OS/2.
ΓòÉΓòÉΓòÉ 33.213. window ΓòÉΓòÉΓòÉ
window
A conceptual identity under OS/2 presentation manager; a window is essentially
a handle associated with a data object such as a presentation space on the
screen or a database that, along with an associated window procedure, comprises
an application object. Hence a window may be considered as equivalent to an
application object.
ΓòÉΓòÉΓòÉ 33.214. window class ΓòÉΓòÉΓòÉ
window class
A group of windows having a common set of data object definitions and
processing requirements, and which therefore share a common window procedure.
In object-oriented terms, a window class equates to an object class.
ΓòÉΓòÉΓòÉ 33.215. window handle ΓòÉΓòÉΓòÉ
window handle
Unique identifier of a window, generated by Presentation Manager when the
window is created, and used by applications to direct messages to the window.
ΓòÉΓòÉΓòÉ 33.216. window procedure ΓòÉΓòÉΓòÉ
window procedure
A procedure in an OS/2 Presentation Manager application that processes messages
intended for a particular window class. In object-oriented terms, a window
procedure contains the data object definitions and methods associated with a
particular application object.
ΓòÉΓòÉΓòÉ 33.217. window words ΓòÉΓòÉΓòÉ
window words
Storage area within the control block maintained for each window by
Presentation Manager that is available for an application to store information
such as a pointer to a memory object containing instance data.
ΓòÉΓòÉΓòÉ 33.218. winproc ΓòÉΓòÉΓòÉ
winproc
See window procedure.
ΓòÉΓòÉΓòÉ 33.219. Workplace Environment ΓòÉΓòÉΓòÉ
Workplace Environment
User interface model defined in the 1991 IBM Systems Application Architecture
CUA Advanced Guide to User Interface Design, whereby direct manipulation of
icons is used to provide a conceptual analogy of the user's physical working
environment.
ΓòÉΓòÉΓòÉ 33.220. Workplace Shell ΓòÉΓòÉΓòÉ
Workplace Shell
Standard user interface component of OS/2 Version 2.0 that provides an
object-oriented interface for the end user. The implementation of the
Workplace Shell is based upon the system object model.
ΓòÉΓòÉΓòÉ 33.221. Workplace Shell object ΓòÉΓòÉΓòÉ
Workplace Shell object
An object created by the Workplace Shell, typically at the request of the user
or an application. A Workplace Shell object is very similar in concept to an
application object, in that it possesses data and methods that operate upon
that data. See also application object.
ΓòÉΓòÉΓòÉ 33.222. z-order ΓòÉΓòÉΓòÉ
z-order
Conceptual order of windows on the desktop; windows are considered to be
located "one on top of another".
ΓòÉΓòÉΓòÉ 33.223. 0:32 ΓòÉΓòÉΓòÉ
0:32
Term used to describe the addressing scheme used for the 32-bit flat memory
model, where a memory address is expressed as a 32-bit linear offset within the
linear address range.
ΓòÉΓòÉΓòÉ 33.224. 16:16 ΓòÉΓòÉΓòÉ
16:16
Term used to describe the addressing scheme used for the 16-bit segmented
memory model, where a memory address is expressed as a 16-bit segment selector,
and a 16-bit offset within that segment.
ΓòÉΓòÉΓòÉ 33.225. 80286 ΓòÉΓòÉΓòÉ
80286
Intel 80286 microprocessor, 16-bit microprocessor that provides both real and
virtual memory support, and allows multitasking and automated task dispatching.
Successor to the Intel 8086/8088 family.
ΓòÉΓòÉΓòÉ 33.226. 80386 ΓòÉΓòÉΓòÉ
80386
Intel 80386 microprocessor; the 32-bit processor upon which the OS/2 Version
2.0 operating system is based.
ΓòÉΓòÉΓòÉ 33.227. 80486 ΓòÉΓòÉΓòÉ
80486
Intel 80486 microprocessor; a 32-bit processor that implements a superset of
the 80386 processor instruction set.
ΓòÉΓòÉΓòÉ 33.228. 8086/8088 ΓòÉΓòÉΓòÉ
8086/8088
Microprocessor family developed by Intel Corporation for use in personal
computers. The 8086/8088 family provides 8-bit real memory addressing mode
only, and is limited to an address space of 1 MB.
ΓòÉΓòÉΓòÉ 33.229. _far16 ΓòÉΓòÉΓòÉ
_far16
Linkage convention used in C programming language within the #pragma linkage
directive under the IBM C Set/2 compiler, to indicate that a function or
subroutine resides in a 16-bit module, and that thunking is required when the
function or subroutine is invoked.
ΓòÉΓòÉΓòÉ 33.230. _Seg16 ΓòÉΓòÉΓòÉ
_Seg16
Keyword used in C programming language under the IBM C Set/2 compiler, to
indicate that a pointer should be stored in 16:16 format rather than 0:32
format. See also seg16.
ΓòÉΓòÉΓòÉ 33.231. #pragma linkage ΓòÉΓòÉΓòÉ
#pragma linkage
Directive used with the IBM C Set/2 compiler to determine the linkage
convention for a function or function type declaration. See also optlink and
system.
ΓòÉΓòÉΓòÉ 33.232. #pragma seg16 ΓòÉΓòÉΓòÉ
#pragma seg16
Directive used with the IBM C Set/2 compiler to ensure that a data structure is
aligned on a 64 KB segment boundary, and is thus addressable by 16-bit
application code. See also seg16.
ΓòÉΓòÉΓòÉ 33.233. #pragma stack16 ΓòÉΓòÉΓòÉ
#pragma stack16
Directive used with the IBM C Set/2 compiler to set the stack size for all
16-bit function calls made from a 32-bit application module.
ΓòÉΓòÉΓòÉ <hidden> ΓòÉΓòÉΓòÉ
Note that a dialog box is known as an action window under CUA'91. However, the
term dialog box is used in most Presentation Manager documentation, and will be
used throughout this document for