home *** CD-ROM | disk | FTP | other *** search
/ The Developer Connection…ice Driver Kit for OS/2 3 / DEV3-D1.ISO / docs / gg243774.inf (.txt) < prev    next >
Encoding:
OS/2 Help File  |  1993-10-19  |  718.2 KB  |  24,186 lines

Text Truncated. Only the first 1MB is shown below. Download the file for the complete contents.
  1.  
  2. ΓòÉΓòÉΓòÉ 1. (C) Copyright IBM Corp. 1992 ΓòÉΓòÉΓòÉ
  3.  
  4. (C) Copyright International Business Machines Corporation 1992. All rights 
  5. reserved. 
  6.  
  7. Note to U.S. Government Users - Documentation related to restricted rights - 
  8. Use, duplication or disclosure is subject to restrictions set forth in GSA ADP 
  9. Schedule Contract with IBM Corp. 
  10.  
  11.  
  12. ΓòÉΓòÉΓòÉ 2. Cover ΓòÉΓòÉΓòÉ
  13.  
  14.  
  15. ΓòÉΓòÉΓòÉ <hidden> Title Page ΓòÉΓòÉΓòÉ
  16.  
  17.  
  18.                                                                 OS/2 Version 2.0
  19.                                                            Volume 4: Application
  20.                                                                      Development
  21.  
  22.                                                     Document Number GG24-3774-01
  23.  
  24.                                                                     January 1993
  25.  
  26.  
  27.                                                          International Technical
  28.                                                                   Support Center
  29.  
  30.                                                                       Boca Raton
  31.  
  32.  
  33. ΓòÉΓòÉΓòÉ 3. Version Notice ΓòÉΓòÉΓòÉ
  34.  
  35.      Take Note! 
  36.  
  37.      Before using this information and the product it supports, be sure to read 
  38.      the general information under Special Notices. 
  39.  
  40.  Second Edition (January 1993) 
  41.  
  42.  This edition applies to Version 2.0 of Operating System/2. 
  43.  
  44.  Order publications through your IBM representative or the IBM branch office 
  45.  serving your locality. Publications are not stocked at the address given 
  46.  below. 
  47.  
  48.  A form for reader's comments appears at the back of this publication. If the 
  49.  form has been removed, address your comments to: 
  50.  
  51.   IBM Corporation, International Technical Support Center
  52.   Dept. 91J, Building 235-2 Internal Zip 4423
  53.   901 NW 51st Street
  54.   Boca Raton, Florida 33432
  55.  
  56.  When you send information to IBM, you grant IBM a non-exclusive right to use 
  57.  or distribute the information in any way it believes appropriate without 
  58.  incurring any obligation to you. 
  59.  
  60.  
  61. ΓòÉΓòÉΓòÉ 4. Abstract ΓòÉΓòÉΓòÉ
  62.  
  63. This document describes application development for OS/2 Version 2.0.  It forms 
  64. Volume 4 of a five volume set; the other volumes are: 
  65.  
  66.    o  OS/2 Version 2.0 - Volume 1:  Control Program, GG24-3730 
  67.  
  68.    o  OS/2 Version 2.0 - Volume 2:  DOS and Windows Environment, GG24-3731 
  69.  
  70.    o  OS/2 Version 2.0 - Volume 3:  Presentation Manager and Workplace Shell, 
  71.       GG24-3732 
  72.  
  73.    o  OS/2 Version 2.0 - Volume 5:  Print Subsystem, GG24-3775 
  74.  
  75.  The entire set may be ordered as OS/2 Version 2.0 Technical Compendium, 
  76.  GBOF-2254. 
  77.  
  78.  This document is intended for IBM system engineers, IBM authorized dealers, 
  79.  IBM customers, and others who require a knowledge of application development 
  80.  under OS/2 Version 2.0. 
  81.  
  82.  This document assumes that the reader is generally familiar with the function 
  83.  provided in previous releases of OS/2. 
  84.  
  85.   MAK - Revision 2.0
  86.  
  87.  
  88. ΓòÉΓòÉΓòÉ 5. Acknowledgements ΓòÉΓòÉΓòÉ
  89.  
  90. The advisors for this project were: 
  91.  
  92. Hans J. Goetz
  93. International Technical Support Center, Boca Raton
  94.  
  95. Giffin Lorimer
  96. International Technical Support Center, Boca Raton
  97.  
  98. The authors of this document are: 
  99.  
  100. Alan Chambers
  101. IBM United Kingdom
  102.  
  103. Franco Federico
  104. IBM United Kingdom
  105.  
  106. Douglas Pearless
  107. IBM New Zealand
  108.  
  109. Neil Stokes
  110. IBM Australia
  111.  
  112. This document was compiled and published with the aid of the International 
  113. Technical Support Center, Boca Raton. 
  114.  
  115. This document was converted to the Information Presentation Facility by: 
  116.  
  117. Michael Kaply
  118. IBM Programming Center, Boca Raton
  119.  
  120. Thanks to the following people for the invaluable advice and guidance provided 
  121. in the production of this document: 
  122.  
  123. Ian Ameline
  124. IBM Development Laboratories, Toronto
  125.  
  126. Mike Cowlishaw
  127. IBM United Kingdom Development Laboratories, Hursley
  128.  
  129. David Kerr
  130. IBM Programming Center, Boca Raton
  131.  
  132. Michael Kogan
  133. IBM Programming Center, Boca Raton
  134.  
  135. Peter Magid
  136. IBM Programming Center, Boca Raton
  137.  
  138. Greg Milligan
  139. IBM Canada
  140.  
  141. Larry Raper
  142. IBM Development Laboratories, Austin
  143.  
  144. Oliver Sims
  145. IBM United Kingdom
  146.  
  147. Thanks also to the many people, both within and outside IBM, who provided 
  148. suggestions and guidance, and who reviewed this document prior to publication. 
  149.  
  150. Thanks to the following people for providing excellent tools, used during 
  151. production of this document: 
  152.  
  153. Dave Hock (CUA Draw)
  154. IBM Cary.
  155.  
  156. J╨ærg von K╨önel (PM Spy)
  157. IBM Yorktown Heights.
  158.  
  159.  
  160. ΓòÉΓòÉΓòÉ 6. Special Notices ΓòÉΓòÉΓòÉ
  161.  
  162. This publication is intended to help the customer in the design and 
  163. implementation of OS/2 Presentation Manager applications under OS/2 Version 
  164. 2.0, using object-oriented design and programming principles.  The information 
  165. in this publication is not intended as the specification of any programming 
  166. interfaces that are provided by OS/2 Version 2.0.  See the PUBLICATIONS section 
  167. of the IBM Programming Announcement for OS/2 Version 2.0 for more information 
  168. about what publications are considered to be product documentation. 
  169.  
  170. References in this publication to IBM products, programs or services do not 
  171. imply that IBM intends to make these available in all countries in which IBM 
  172. operates.  Any reference to an IBM product, program, or service is not intended 
  173. to state or imply that only IBM's product, program, or service may be used. 
  174. Any functionally equivalent program that does not infringe any of IBM's 
  175. intellectual property rights may be used instead of the IBM product, program or 
  176. service. 
  177.  
  178. Information in this book was developed in conjunction with use of the equipment 
  179. specified, and is limited in application to those specific hardware and 
  180. software products and levels. 
  181.  
  182. IBM may have patents or pending patent applications covering subject matter in 
  183. this document.  The furnishing of this document does not give you any license 
  184. to these patents.  You can send license inquiries, in writing, to the IBM 
  185. Director of Commercial Relations, IBM Corporation, Purchase, NY 10577. 
  186.  
  187. The information contained in this document has not been submitted to any formal 
  188. IBM test and is distributed AS IS. 
  189.  
  190. The information about non-IBM ("vendor") products in this manual has been 
  191. supplied by the vendor and IBM assumes no responsibility for its accuracy 
  192. completeness. 
  193.  
  194. The use of this information or the implementation of any of these techniques is 
  195. a customer responsibility and depends on the customer's ability to evaluate and 
  196. integrate them into the customer's operational environment.  While each item 
  197. may have been reviewed by IBM for accuracy in a specific situation, there is no 
  198. guarantee that the same or similar results will be obtained elsewhere. 
  199. Customers attempting to adapt these techniques to their own environments do so 
  200. at their own risk. 
  201.  
  202. The following document contains examples of data and reports used in daily 
  203. business operations.  To illustrate them as completely as possible, the 
  204. examples contain the names of individuals, companies, brands, and products. All 
  205. of these names are fictitious and any similarity to the names and addresses 
  206. used by an actual business enterprise is entirely coincidental. 
  207.  
  208. The following terms, which are denoted by an asterisk (*) in this publication, 
  209. are trademarks of the International Business Machines Corporation in the United 
  210. States and/or other countries: 
  211.  
  212.  C/2
  213.  COBOL/2
  214.  Common User Access
  215.  CommonView
  216.  CUA
  217.  DATABASE 2
  218.  DB2
  219.  DCF
  220.  Document Composition Facility
  221.  FORTRAN/2
  222.  IBM
  223.  Macro Assembler/2
  224.  Micro Channel
  225.  OfficeVision
  226.  Operating System/2
  227.  OS/2
  228.  Personal System/2
  229.  Presentation Manager
  230.  PS/2
  231.  SAA
  232.  System/370
  233.  Systems Application Architecture
  234.  WIN-OS/2
  235.  Workplace Shell
  236.  
  237. The following terms, which are denoted by a double asterisk (* *) in this 
  238. publication, are trademarks of other companies. 
  239.  
  240.  Intel is a trademark of Intel Corporation.
  241.  Lotus is a trademark of the Lotus Development Corporation.
  242.  Microsoft is a trademark of Microsoft Corporation.
  243.  MS-DOS is a registered trademark of Microsoft Corporation.
  244.  Smalltalk/V is a trademark of Digitalk Inc.
  245.  Windows is a trademark of Microsoft Corporation.
  246.  286, 386, 486, SX are trademarks of Intel Corporation.
  247.  
  248.  
  249. ΓòÉΓòÉΓòÉ 7. Preface ΓòÉΓòÉΓòÉ
  250.  
  251. This document is intended as a general introduction to the concepts involved in 
  252. the design and implementation of applications which will execute in the OS/2 
  253. Presentation Manager and Workplace Shell environments under OS/2 Version 2.0. 
  254. It is not intended to be an exhaustive reference on the subject of Presentation 
  255. Manager programming, and should be used in conjunction with the official IBM 
  256. product documentation, and other reference books and documents, which are 
  257. mentioned herein. 
  258.  
  259. It must be stressed that this document is not intended to teach the reader how 
  260. to program in the "C" language or how to use the Presentation Manager 
  261. programming interface, nor is it intended to teach the theory of 
  262. object-oriented programming.  Rather, it serves as a guide to the integration 
  263. of various object-oriented software engineering techniques with the 
  264. Presentation Manager application model, in order to produce well-structured, 
  265. easily-maintainable applications which conform to CUA  guidelines. 
  266.  
  267. The information given in this document is generally independent of programming 
  268. language implementations (with certain exceptions noted in the text), and may 
  269. be used to develop applications in any supported programming language. 
  270. However, programming syntax examples used in this document are shown using the 
  271. "C" language, since this language is commonly used for Presentation Manager 
  272. application development, and most clearly illustrates the structure of the 
  273. Presentation Manager and Workplace Shell application models. 
  274.  
  275. This document is intended for: 
  276.  
  277.    o  Application designers, planners and development managers who require an 
  278.       understanding of the application of object-oriented principles to the 
  279.       Presentation Manager environment, and the productivity gains to be 
  280.       achieved from the use of such principles. 
  281.  
  282.    o  Programmers who wish to understand the structure of Presentation Manager 
  283.       and Workplace Shell applications, and the techniques by which 
  284.       applications may be constructed so as to achieve maximum function, with 
  285.       optimal levels of reusability and maintainability. 
  286.  
  287.  The code examples used in this document are available in electronic form via 
  288.  CompuServe** or through a local IBM Support BBS, as package RB3774.ZIP. IBM 
  289.  employees may obtain the code examples from the package GG243774 PACKAGE on 
  290.  OS2TOOLS. 
  291.  
  292.      Second Edition 
  293.  
  294.      This Second Edition includes programming information relating to 
  295.      application development under OS/2 Version 2.0, and supercedes the ITSC 
  296.      Technical Bulletin Presentation Manager Application Development, 
  297.      GG24-3543. 
  298.  
  299.  The document is organized as follows: 
  300.  
  301.    o  Overview provides a brief introduction to the topics covered in this 
  302.       document. 
  303.  
  304.       This chapter is recommended for all readers of the document. 
  305.  
  306.    o  Operating System/2 provides a brief technical overview of the OS/2 
  307.       Version 2.0 environment, comparing and contrasting it with the DOS 
  308.       environment and previous versions of OS/2.  The major features of OS/2 
  309.       Version 2.0 are described and their use by applications is discussed. 
  310.  
  311.       This chapter is recommended for those readers who are not familiar with 
  312.       the OS/2 Version 2.0 operating system environment, in order to provide 
  313.       them with a basic understanding of the capabilities of OS/2 Version 2.0. 
  314.  
  315.    o  Object-Oriented Applications explains the basic principles of 
  316.       object-oriented design and programming.  The object-oriented approach is 
  317.       compared and contrasted with the traditional procedural approach in terms 
  318.       of a simple application model, before the extension of the 
  319.       object-oriented paradigm into more complex scenarios is discussed.  Some 
  320.       suggestions and guidelines are also offered with regard to application 
  321.       design and implementation using the object-oriented approach. 
  322.  
  323.       This chapter is recommended for readers who do not already possess an 
  324.       understanding of the basic principles of object-oriented programming. 
  325.       This knowledge is essential in order to understand the programming 
  326.       guidelines presented later in the document. 
  327.  
  328.    o  The Presentation Manager Application Model describes the Presentation 
  329.       Manager application model, and illustrates the way in which the 
  330.       application model implements the object-oriented principles introduced in 
  331.       Object-Oriented Applications. 
  332.  
  333.       This chapter is recommended for all readers of this document, since it 
  334.       explains the basic structure of a Presentation Manager application, and 
  335.       the way in which the Presentation Manager application model facilitates 
  336.       the creation of object-oriented applications. 
  337.  
  338.    o  The Flat Memory Model describes the 32-bit flat memory model implemented 
  339.       in OS/2 Version 2.0, and discusses the programming considerations which 
  340.       arise from the differences between this memory model and the segmented 
  341.       memory model used by previous versions of OS/2. 
  342.  
  343.       This chapter is recommended for all programmers who intend to develop 
  344.       applications under OS/2 Version 2.0. 
  345.  
  346.    o  Building a Presentation Manager Application describes the major 
  347.       programming techniques required to implement a Presentation Manager 
  348.       application, including recommendations and established conventions in 
  349.       areas such as methods of opening and closing windows, displaying dialogs, 
  350.       communication between windows, managing user responsiveness etc.  The 
  351.       chapter also discusses certain software engineering techniques which may 
  352.       be used to enhance the level of modularity and optimize the granularity 
  353.       of the resulting application code. 
  354.  
  355.       This chapter is recommended for programmers and development managers who 
  356.       will be working on the implementation of Presentation Manager 
  357.       applications. 
  358.  
  359.    o  Workplace Shell and the System Object Model describes the system object 
  360.       model introduced in OS/2 Version 2.0, and its implementation by the OS/2 
  361.       Version 2.0 Workplace Shell.  The chapter describes the object-oriented 
  362.       application layer provided by the Workplace Shell, and explains how 
  363.       Workplace Shell objects are defined, created and implemented. 
  364.  
  365.       This chapter is recommended for programmers and development managers who 
  366.       wish to create objects for use on the Workplace Shell desktop. 
  367.  
  368.    o  Direct Manipulation explains the implementation of direct manipulation 
  369.       (drag and drop) techniques for carrying out required tasks in the 
  370.       Presentation Manager and Workplace Shell environments.  The chapter 
  371.       discusses the use of these techniques both by Presentation Manager 
  372.       windows and by Workplace Shell objects. 
  373.  
  374.       This chapter is recommended for programmers who wish to implement direct 
  375.       manipulation in their Presentation Manager applications or Workplace 
  376.       Shell object classes. 
  377.  
  378.    o  Presentation Manager Resources discusses the concept of Presentation 
  379.       Manager resources.  The chapter covers the types of application resources 
  380.       which may be defined in the Presentation Manager environment, their 
  381.       definition and conventions governing their use. 
  382.  
  383.       This chapter is recommended for all programmers who will develop 
  384.       Presentation Manager applications, since resources are used in most if 
  385.       not all applications. 
  386.  
  387.    o  Multitasking Considerations describes the ways in which multiple threads 
  388.       of execution may be used within a Presentation Manager  application, in 
  389.       order to isolate long-running application tasks from the user interface 
  390.       and thereby provide greater application responsiveness to the end user. 
  391.  
  392.       This chapter is recommended for programmers and development managers who 
  393.       will be building Presentation Manager applications which carry out 
  394.       lengthy processing tasks, or which require access to remote devices or 
  395.       systems. 
  396.  
  397.    o  Systems Application Architecture CUA Considerations discusses the 
  398.       implementation of various SAA CUA user interface specifications in 
  399.       Presentation Manager applications.  The chapter provides coding examples 
  400.       for a number of CUA techniques such as menu bar handling. 
  401.  
  402.       This chapter is recommended for programmers who wish to implement SAA CUA 
  403.       guidelines in their applications. 
  404.  
  405.    o  Application Migration discusses the migration of Presentation Manager 
  406.       applications to OS/2 Version 2.0 from previous versions of OS/2. 
  407.       Differences in implementation are described, along with additional 
  408.       facilities provided by Presentation Manager under OS/2 Version 2.0. 
  409.  
  410.       This chapter is recommended for application developers with Presentation 
  411.       Manager applications written for previous versions of OS/2, which they 
  412.       wish to modify in order to take full advantage of the capabilities of 
  413.       OS/2 Version 2.0. 
  414.  
  415.    o  Mixing 16-Bit and 32-Bit Application Modules describes the way in which 
  416.       32-bit applications under OS/2 Version 2.0 may make use of existing 
  417.       16-bit functions and window procedures, along with restrictions and 
  418.       programming considerations to be borne in mind when developing such 
  419.       applications. 
  420.  
  421.       This chapter is recommended for those programmers working in 
  422.       organizations with existing 16-bit runtime libraries or DLLs, and who 
  423.       wish to make use of functions contained within these libraries. 
  424.  
  425.    o  Compiling and Link Editing an Application describes the steps necessary 
  426.       to compile and link edit a Presentation Manager  application under OS/2 
  427.       Version 2.0, including the use of module definition files.  and the 
  428.       creation of dynamic link libraries to contain application code and 
  429.       Presentation Manager  resources. 
  430.  
  431.       This chapter is recommended for all programmers who will develop 
  432.       Presentation Manager applications, and who wish to understand how to 
  433.       create executable modules and dynamic link libraries. 
  434.  
  435.    o  Adding Online Help and Documentation examines the provision of online, 
  436.       context-sensitive help information for Presentation Manager  applications 
  437.       using the IPF  provided with Presentation Manager, and the use of this 
  438.       facility to create online documentation. 
  439.  
  440.       This chapter is recommended for application developers who wish to 
  441.       provide online help for their applications, or who wish to develop online 
  442.       documentation and tutorial programs. 
  443.  
  444.    o  Problem Determination describes some simple techniques for problem 
  445.       determination and resolution in the Presentation Manager environment, and 
  446.       discusses some common application problems. 
  447.  
  448.       This chapter is recommended for all application developers involved in 
  449.       testing and debugging Presentation Manager applications. 
  450.  
  451.    o  Generic Application Modules discusses the use of generic routines to 
  452.       perform commonly used functions within a Presentation Manager 
  453.       application, and identifies a number of areas where generic functions may 
  454.       be successfully applied. 
  455.  
  456.       This chapter is recommended for planners and development managers who 
  457.       will manage a number of application developers working on one or more 
  458.       Presentation Manager applications, and who wish to understand the 
  459.       benefits in terms of consistency and productivity which can be achieved 
  460.       through the use of common routines. 
  461.  
  462.    o  Managing Development provides some guidelines for the use of a local area 
  463.       network (LAN) to facilitate centralized control and administration of the 
  464.       workstation-based application development process. 
  465.  
  466.       This chapter is recommended for planners and development managers who 
  467.       will manage a number of application developers working on one or more 
  468.       Presentation Manager applications, and who wish to understand some of the 
  469.       ways in which a distributed development process may be managed and 
  470.       controlled. 
  471.  
  472.  The following appendixes are included in this document: 
  473.  
  474.    o  Naming Conventions provides some guidelines for naming conventions to be 
  475.       used with symbols, subroutines and variables in the Presentation Manager 
  476.       environment. These guidelines cover the use of Hungarian Notation for 
  477.       such names. 
  478.  
  479.       This chapter is recommended for planners and development managers who 
  480.       wish to implement a standard series of naming conventions for the 
  481.       application development projects under their control. 
  482.  
  483.    o  Application Program Construction presents guidelines for the structuring 
  484.       of applications and their component modules in order to achieve the 
  485.       optimum level of modularity and granularity within an application, thus 
  486.       promoting reuse of application code. 
  487.  
  488.       This chapter is recommended for planners and development managers who 
  489.       wish to gain the maximum productivity benefit over a number of 
  490.       Presentation Manager application development projects. 
  491.  
  492.    o  OS/2 Kernel API Functions compares the operating system kernel functions 
  493.       provided in OS/2 Version 2.0 with those provided in OS/2 Version 1┬╖3. 
  494.  
  495.       This chapter is recommended for programmers who will be migrating 
  496.       applications from previous versions of OS/2. 
  497.  
  498.    o  Problem Reporting Worksheet provides a worksheet which may be used when 
  499.       following the steps given in Problem Determination, to provide effective 
  500.       problem documentation which can then be used to reproduce application 
  501.       errors. 
  502.  
  503.       This chapter is recommended for application developers involved in 
  504.       testing and debugging Presentation Manager applications. 
  505.  
  506.  
  507. ΓòÉΓòÉΓòÉ 8. Related Publications ΓòÉΓòÉΓòÉ
  508.  
  509. The following publications are considered particularly suitable for a more 
  510. detailed discussion of the topics covered in this document. 
  511.  
  512.  
  513. ΓòÉΓòÉΓòÉ 8.1. Prerequisite Publications ΓòÉΓòÉΓòÉ
  514.  
  515.    o  IBM OS/2 Version 2.0 Application Design Guide, 10G6260 
  516.  
  517.    o  IBM OS/2 Version 2.0 Control Program Reference 
  518.  
  519.    o  IBM OS/2 Version 2.0 Presentation Manager Reference 
  520.  
  521.    o  IBM OS/2 Version 2.0 Programming Tools Reference. 
  522.  
  523.  
  524. ΓòÉΓòÉΓòÉ 8.2. Additional Publications ΓòÉΓòÉΓòÉ
  525.  
  526.    o  OS/2 Version 2.0 - Volume 1:  Control Program, GG24-3730 
  527.  
  528.    o  OS/2 Version 2.0 - Volume 2:  DOS and Windows Environment, GG24-3731 
  529.  
  530.    o  OS/2 Version 2.0 - Volume 3:  Presentation Manager and Workplace Shell, 
  531.       GG24-3732 
  532.  
  533.    o  OS/2 Version 2.0 - Volume 5:  Print Subsystem, GG24-3775 
  534.  
  535.    o  OS/2 Version 2.0 Remote Installation and Maintenance, GG24-3780 
  536.  
  537.    o  The Design of OS/2, Harvey M. Deitel and Michael J. Kogan, Addison Wesley 
  538.       1992 ISBN 0-201-54889-5 (SC25-4005) 
  539.  
  540.    o  Object Oriented Programming:  An Evolutionary Approach, Brad J. Cox, 
  541.       Addison Wesley 1987 ISBN 0-201-10393-1 
  542.  
  543.    o  Programmer's Guide to the OS/2 Presentation Manager, Michael J. Young, 
  544.       Sybex 1989 ISBN 0-89588-569-7 
  545.  
  546.    o  Programming the OS/2 Presentation Manager, Charles Petzold, Microsoft 
  547.       Press 1989 ISBN 1-55615-170-5 
  548.  
  549.    o  IBM OS/2 Version 2.0 Technical Library - Procedures Language/2 REXX 
  550.       Reference, 10G-6268 
  551.  
  552.    o  IBM C Set/2 User's Guide, SC09-1310 
  553.  
  554.    o  IBM C Set/2 Migration Guide, SC09-1369 
  555.  
  556.    o  IBM Systems Application Architecture CUA Advanced Guide to User Interface 
  557.       Design, SC34-4289 
  558.  
  559.    o  IBM Systems Application Architecture CUA Advanced Interface Design 
  560.       Reference, SC34-4290 
  561.  
  562.    o  IBM Systems Application Architecture Common Programming Interface 
  563.       Presentation Reference, SC26-4359. 
  564.  
  565.  
  566. ΓòÉΓòÉΓòÉ 9. Overview ΓòÉΓòÉΓòÉ
  567.  
  568. IBM* OS/2* Presentation Manager* is a graphical user interface facility that 
  569. allows the creation of object-oriented, event-driven applications which conform 
  570. to IBM Systems Application Architecture* (SAA*) Common User Access* (CUA*) 
  571. guidelines.  Presentation Manager  provides an application execution 
  572. environment under which such applications are executed, and under which they 
  573. may take full advantage of the advanced capabilities of the OS/2 operating 
  574. system environment, as well as a system-level mechanism to handle interaction 
  575. between the application and the user in a consistent and intuitive manner. 
  576.  
  577. The object-based Presentation Manager application model facilitates the use of 
  578. object-oriented software engineering principles such as data abstraction and 
  579. encapsulation.  The application of these principles enhances application 
  580. modularity and thereby contributes to increased potential for code reuse and 
  581. easier application maintenance through containment of change, thereby achieving 
  582. higher levels of productivity in the areas of application development and 
  583. maintenance. 
  584.  
  585. This document examines the Presentation Manager execution environment in order 
  586. to describe the structure and implementation of Presentation Manager 
  587. applications, and to illustrate the facilities provided by Presentation Manager 
  588. to support object-oriented techniques.  In addition, the document examines the 
  589. ways in which CUA guidelines may be implemented by Presentation Manager 
  590. applications within the object-oriented application model.  Particular emphasis 
  591. is given to the use of software engineering principles which facilitate the 
  592. creation of reusable code for common application services.  This is one of the 
  593. primary concerns of the object-oriented approach to application design, and is 
  594. also one aspect of the Systems Application Architecture  Common Applications 
  595. ("red layer") component. 
  596.  
  597. The document also discusses the management of workstation-based application 
  598. development projects.  Historically, workstation applications have typically 
  599. fallen into the systems software category, or have been "one-off" applications 
  600. and hence have not been subject to the same rules and disciplines imposed upon 
  601. the traditionally host-based line-of-business applications.  However, as the 
  602. OS/2 environment begins to provide a viable platform for the implementation of 
  603. workstation-based and cooperative line-of-business applications, typical 
  604. corporate investments in workstation software are increasing rapidly, and 
  605. therefore the management and maintenance of these investments must be 
  606. considered.  Some suggestions on the management of the workstation-based 
  607. development process are given in Managing Development. 
  608.  
  609.  
  610. ΓòÉΓòÉΓòÉ 9.1. User Interface ΓòÉΓòÉΓòÉ
  611.  
  612. The Presentation Manager user interface model facilitates an intuitive user 
  613. interface. While people typically approach their work tasks from a 
  614. "problem-domain" viewpoint, computers tend to adopt an "operator/operand" 
  615. approach that is inherently alien to the end user.  Traditionally, the required 
  616. translation between approaches has been left to the user, with applications and 
  617. their user interfaces written to conform to the computer's viewpoint rather 
  618. than that of the user.  This approach has often led to users having difficulty 
  619. relating to the technology, with consequently greater amounts of time and money 
  620. spent in user training. 
  621.  
  622. In recent times, a growing school of thought has emerged which contends that, 
  623. with the increasing power of computer systems and particularly with the advent 
  624. of powerful programmable workstations, the responsibility for this interface 
  625. translation should lie primarily with the application or the computer system 
  626. rather than with the user.  In order to achieve this, user interfaces must be 
  627. redesigned in order to operate in an object-action, event-driven manner which 
  628. corresponds with the users' problem domain viewpoint. 
  629.  
  630. Presentation Manager implements such a user interface, and Presentation Manager 
  631. applications may thus be designed and implemented in such a way as to provide 
  632. improved user-friendliness and encourage learning by exploration.  The details 
  633. of the Presentation Manager user interface are described in OS/2 Version 2.0 - 
  634. Volume 3:  Presentation Manager and Workplace Shell. 
  635.  
  636. Presentation Manager also facilitates consistency between applications by 
  637. handling the interface between user and application at a system level, 
  638. providing a number of standard constructs which may be exploited by 
  639. applications. Since these constructs typically appear and behave in the same 
  640. way regardless of the application under which they are implemented, a user need 
  641. learn only one set of user interface guidelines to be able to interact with 
  642. multiple applications.  This consistency reduces confusion for users who work 
  643. with multiple applications, and reduces the need for extensive application 
  644. training. 
  645.  
  646. The SAA CUA component provides guidelines for the use of these constructs to 
  647. fulfill particular input/output requirements within an application, such that a 
  648. level of consistency is achieved not only in the behaviour of the constructs 
  649. themselves, but also in their relationship to one another and thus in the 
  650. behaviour of the application as a whole.  These guidelines are documented in 
  651. the IBM Systems Application Architecture CUA Advanced Guide to User Interface 
  652. Design. 
  653.  
  654.  
  655. ΓòÉΓòÉΓòÉ 9.2. Object-Oriented Applications ΓòÉΓòÉΓòÉ
  656.  
  657. Many definitions of the term object-oriented programming may be found in 
  658. various publications and presentations appearing over the last few years. 
  659. These definitions often differ widely, and have resulted in a great deal of 
  660. confusion and debate as to the "true" meaning of the term. It may be 
  661. justifiably argued that there is no such true meaning, and the term 
  662. object-oriented may be used to describe techniques ranging from simple data 
  663. abstraction to the full inheritance hierarchies implemented by certain 
  664. object-oriented development tools. 
  665.  
  666.  
  667. ΓòÉΓòÉΓòÉ 9.2.1. Object-Oriented Design ΓòÉΓòÉΓòÉ
  668.  
  669. For the purpose of discussion within this document, an object-oriented 
  670. application will be defined as one where data objects are the focus of the 
  671. application.  A data object is defined to be a particular representation of a 
  672. logical data entity.  For example, a document being edited may exist in two 
  673. places: as an image in memory and as a file on a fixed disk.  Each of these two 
  674. forms constitutes a separate data object. 
  675.  
  676. The procedures that operate upon these data objects in order to carry out 
  677. application functions are encapsulated with the data objects to form 
  678. application objects. Application objects are logically independent units 
  679. comprising both data and function, which communicate with one another to 
  680. request actions, conveyed in the form of messages passed between the 
  681. communicating objects.  In object-oriented terminology, the procedures that are 
  682. invoked to carry out the required actions are known as methods. 
  683.  
  684. Several rules apply to the design and behaviour of application objects. These 
  685. are listed below: 
  686.  
  687.    o  A data object should be accessible only from within a single application 
  688.       object which "owns" the data object.  The definition, creation and/or 
  689.       establishment of access to the data object should also be achieved from 
  690.       within the application object; this is known as the principle of 
  691.       encapsulation. 
  692.  
  693.    o  The behaviour of and output from an application object should depend 
  694.       upon, and only upon, the type and contents of the messages it receives. 
  695.       The behaviour of an object should not depend upon any other external 
  696.       source. 
  697.  
  698.       As a corollary to the foregoing principle, the result of passing a 
  699.       particular type of message may also vary, depending upon the type of 
  700.       application object to which it is passed, and that object's 
  701.       interpretation of the message.  Adherence to this rule allows the 
  702.       behaviour of an object to differ, depending upon the nature of the 
  703.       messages received by that object; this differing behaviour is known as 
  704.       polymorphism. 
  705.  
  706.  For ease of processing, application objects with similar properties are 
  707.  grouped into object classes. Each object in a class is said to be an instance 
  708.  of that class. Application objects within the same class share properties such 
  709.  as data object definitions, class-specific variable definitions and values, 
  710.  and methods.  Objects therefore take on the properties of their class; this is 
  711.  known as inheritance. 
  712.  
  713.  It is the concept of inheritance that provides a distinguishing factor between 
  714.  the two major schools of thought which exist under the object-oriented 
  715.  paradigm: 
  716.  
  717.    o  The basic precept of the class-based theory of object-oriented design is 
  718.       that objects are defined in terms of their class, and that new classes 
  719.       are defined in terms of existing classes, with certain additions and 
  720.       modifications which distinguish the new class.  Thus there is a measure 
  721.       of interdependence between object classes, and an inheritance hierarchy 
  722.       is formed. 
  723.  
  724.       The primary advantage of the class-based approach is that it eases the 
  725.       task of defining object classes, since each new class belongs to a 
  726.       hierarchy of previously defined classes with their own properties and 
  727.       methods.  The application developer therefore need only explicitly define 
  728.       the distinguishing characteristics of each class. 
  729.  
  730.       The major disadvatange of the class-based approach is the consequent high 
  731.       level of interdependence between objects.  Since the unit of modularity 
  732.       is the entire inheritance hierarchy, rather than the individual object, 
  733.       reuse of a particular object presupposes reuse of all those objects in 
  734.       its hierarchy upon which the definition of the required object depends. 
  735.  
  736.       The class-based approach therefore provides a high initial productivity 
  737.       to the application developer, although with a consequent reduction in the 
  738.       level of granularity and an increase in run-time overhead. 
  739.  
  740.    o  The module-based theory of application development contends that while 
  741.       objects are defined in terms of their class, each new class is totally 
  742.       defined in its own right, and is not dependent upon the definitions of 
  743.       other classes.  Hence there is no inheritance hierarchy under the 
  744.       module-based approach. 
  745.  
  746.       The primary advantage of the module-based approach is that it avoids the 
  747.       object interdependence associated with the class-based approach, since 
  748.       each object class contains its own complete definition of properties and 
  749.       methods.  Thus the unit of modularity is the individual application 
  750.       object. 
  751.  
  752.       The disadvantage of this approach lies in the fact that the application 
  753.       developer is required to define each object class in its entirety, and 
  754.       typically cannot rely on previous definitions. [This may be overcome to 
  755.       some extent through subclassing, which is explained later in this 
  756.       chapter. ] The module-based approach therefore attains a higher level of 
  757.       modularity and independence between application objects, but at the 
  758.       expense of higher initial development time. 
  759.  
  760.  The object-oriented approach to application design is most suited to 
  761.  applications where the data is the focus of the application, and is less 
  762.  suitable where the procedure or sequence of actions is the critical factor in 
  763.  the design.  However, in mixed situations where only certain parts of an 
  764.  application or application system are procedurally oriented, as is the case 
  765.  with many work tasks, and where the provision of an event-driven user 
  766.  interface is desirable, the object-oriented paradigm can be extended to 
  767.  encompass procedurally oriented tasks.  This is discussed further in 
  768.  Object-Oriented Applications. 
  769.  
  770.  While object-oriented applications deal primarily with the manipulation of 
  771.  data entities and their logical representations, there are many situations 
  772.  where an application must deal with other entities such as remote devices or 
  773.  systems.  Administrative procedures defined by or imposed upon an organization 
  774.  may also be viewed as logical entities with which an application must 
  775.  interact.  The incorporation of such entities into the object-oriented 
  776.  application paradigm requires an expansion of the concept of an application 
  777.  object to include the definition of and methods pertaining to any type of 
  778.  entity addressed by the application.  This broadened definition is fundamental 
  779.  in making the object-oriented application model applicable to virtually any 
  780.  application scenario. 
  781.  
  782.  
  783. ΓòÉΓòÉΓòÉ 9.2.2. Object-Action Interfaces ΓòÉΓòÉΓòÉ
  784.  
  785. For the purpose of discussion within this document, an object-oriented 
  786. application will also be defined as one that implements an event-driven, 
  787. object-action user interface such as that specified in the IBM Systems 
  788. Application Architecture CUA Advanced Guide to User Interface Design.  With 
  789. such an interface, a user first selects an object to manipulate, then selects 
  790. one or more of a defined set of actions to be performed upon that object.  The 
  791. sequence of these actions, and hence the sequence of the dialog with the user, 
  792. is controlled by the user rather than by the application, where this is 
  793. possible within the requirements of the work task being performed. 
  794.  
  795. The concepts of object-oriented design and an object-action user interface are 
  796. distinct but complementary.  While it is possible to design and create an 
  797. object-oriented application without an object-oriented user interface, it it 
  798. far more difficult to implement a truly event-driven, object-action style of 
  799. user interface without embracing, at least a certain degree, the 
  800. object-oriented approach to design and implementation.  It thus follows that 
  801. the SAA CUA  user interface model cannot be fully implemented without some 
  802. measure of adherence to object-oriented design principles.  It is the provision 
  803. of an intuitive, event-driven user interface that constitutes one of the great 
  804. strengths of the object-oriented paradigm. 
  805.  
  806.  
  807. ΓòÉΓòÉΓòÉ 9.2.3. Benefits of the Object-Oriented Approach ΓòÉΓòÉΓòÉ
  808.  
  809. A fundamental benefit of an object-oriented approach from the viewpoint of the 
  810. end user is the ability for an application to behave in a manner that parallels 
  811. a typical human being's natural approach to problem solving.  The flexibility 
  812. of the object-action interface allows scope for individual variation in the 
  813. approach to a particular work task.  However, such a user interface relies upon 
  814. an object-oriented application implementation in order to allow such 
  815. flexibility.  Such an implementation is in turn dependent upon the correct 
  816. design approach, which must begin with a focus upon the entities that affect 
  817. the application, rather than upon the procedures to be performed upon those 
  818. entities. 
  819.  
  820. The object-oriented paradigm also encourages the concept of data abstraction 
  821. and encapsulation, whereby the definition of and establishment of access to 
  822. data objects is achieved from within the application object. Ideally, all 
  823. access to and manipulation of a data object is carried out from within a single 
  824. application object, thereby facilitating change management and application 
  825. maintenance. 
  826.  
  827. Another great benefit of the object-oriented approach is the increased 
  828. potential for creation of reusable code.  The independent nature of application 
  829. objects enables them to be coupled together in various ways to achieve desired 
  830. results, with the internal implementation details of each object and its data 
  831. structures being isolated from the other objects with which it communicates. 
  832. Applications that manipulate existing data objects may therefore be assembled 
  833. from a number of existing application objects, thus reducing the time and 
  834. effort required to develop the application. 
  835.  
  836. This potential for object reuse has also given rise to one of the great 
  837. criticisms levelled at the object-oriented approach; the "myth" of the 
  838. completely generic object.  Due to the impracticability of foreseeing all 
  839. possible actions that might be performed on a data object, it is impossible to 
  840. produce a complete set of methods for that object.  Hence an application object 
  841. might require modification at some stage in its life cycle, and is not truly 
  842. reusable. 
  843.  
  844. The object-oriented approach overcomes this potential problem by the use of a 
  845. concept known as subclassing, whereby a new application object is created 
  846. comprised of a data object and a number of new or modified methods which act 
  847. upon that object.  Messages destined for the original application object are 
  848. diverted to the new object;  the original object is said to have been 
  849. subclassed.  If the message is of a type with which the new object is 
  850. explicitly concerned, it processes the message using its own methods.  If not, 
  851. it passes the message on to the original object for processing.  In the 
  852. subclassing process, neither the sending object nor the original receiving 
  853. object should be aware that subclassing has taken place.  Subclassing therefore 
  854. provides a transparent means for modifying or adding to the behaviour of an 
  855. existing application object without modifying the object itself. 
  856.  
  857. The general principles of object-oriented design and programming, as they apply 
  858. to the Presentation Manager environment, are explored more fully in 
  859. Object-Oriented Applications. 
  860.  
  861.  
  862. ΓòÉΓòÉΓòÉ 9.3. Presentation Manager Application Model ΓòÉΓòÉΓòÉ
  863.  
  864. Contrary to popular belief, Presentation Manager provides far more than merely 
  865. the ability to achieve a windowed, graphical user interface for the display of 
  866. information on the screen.  Rather, Presentation Manager provides a 
  867. message-driven, object-based execution environment that facilitates the 
  868. provision of an event-driven, object-action user interface, and supports the 
  869. implementation of object-oriented design techniques. 
  870.  
  871. Presentation Manager enables the implementation of an object-action user 
  872. interface by providing an application programming interface that conforms to 
  873. the guidelines laid down in the IBM Systems Application Architecture Common 
  874. Programming Interface Presentation Reference, and a set of underlying system 
  875. services that support an object-oriented, event-driven application model.  The 
  876. Presentation Manager  programming interface provides user interface constructs 
  877. which conform to CUA  guidelines.  However, it must be strongly emphasized that 
  878. the term "presentation interface" is a misnomer, since Presentation Manager is 
  879. concerned with far more than merely the display of information on the screen. 
  880.  
  881. The Presentation Manager application model is centered around the concept of 
  882. windows. While a window typically appears as a rectangular area on the screen, 
  883. it is in fact a "handle" to a data object; a window concerned with data being 
  884. displayed on the screen is termed a display window, whereas a window concerned 
  885. with an internal data object is known as an object window.  Each window belongs 
  886. to a window class and is associated with a window procedure, which contains the 
  887. definition of the window's data object(s) and also contains methods to perform 
  888. all of the processing associated with that window.  Windows and their 
  889. associated window procedures communicate with the user and with each other, by 
  890. the use of messages that are routed to the appropriate window by Presentation 
  891. Manager. 
  892.  
  893. Since a window procedure may contain all the processing related to a particular 
  894. data object, along with the definition of and establishment of access to that 
  895. data object, Presentation Manager provides a suitable environment for data 
  896. encapsulation and abstraction, in that the internal representation and workings 
  897. of a data object may be "hidden" within the window procedure that "owns" the 
  898. data object.  Provided the external interfaces (that is, the message formats) 
  899. of the window procedure remain unchanged, other window procedures within an 
  900. application are insulated from changes to the data object or its processing. 
  901. This provides a powerful tool for the enhancement of application modularity and 
  902. the containment of change within an application.  This in turn facilitates the 
  903. task of application maintenance and change management, since affected 
  904. application modules may be easily identified. 
  905.  
  906. A close corellation may be drawn between the concept of an application object 
  907. and that of a window under Presentation Manager. The window becomes the 
  908. identity of, or "handle" to an object; the data referenced by the window 
  909. (whether a display space on the screen or a data file) becomes a data object; 
  910. the window procedure associated with a window contains the methods to act upon 
  911. that data object; and actions to be performed by the application object on its 
  912. data object are conveyed by way of messages routed to the window by 
  913. Presentation Manager.  Although Presentation Manager provides window classes to 
  914. allow grouping of objects with similar characteristics, a full inheritance 
  915. hierarchy is not supported, and thus Presentation Manager conforms more closely 
  916. to the module-based theory of object-oriented design than to the class-based 
  917. approach.  Development tools such as Smalltalk V/PM** are available to extend 
  918. the Presentation Manager application model and facilitate implementation of a 
  919. full inheritance hierarchy. 
  920.  
  921. The Presentation Manager application model, along with the underlying OS/2 
  922. environment, affords the ability to store an application object (that is, a 
  923. data object definition, along with the methods associated with that data 
  924. object, contained within a window procedure) in a library that may be 
  925. dynamically linked with an application.  This in turn provides the potential to 
  926. develop and implement applications composed of one or more generic objects 
  927. linked by a custom-built application harness, which allows applications to be 
  928. assembled more quickly and at less cost. 
  929.  
  930. The Presentation Manager programming interface includes a mechanism for 
  931. subclassing a window, whereby messages destined for a particular window may be 
  932. transparently diverted to another window for specialized processing. 
  933. Implementing an application using generic objects with subclassing to provide 
  934. specialized methods may greatly reduce the amount of coding required, and 
  935. consequently reduce the development time and cost of applications. 
  936.  
  937. The general implementation of and support for object-oriented programming 
  938. principles under Presentation Manager is discussed further in The Presentation 
  939. Manager Application Model.  The subject is examined in more detail, and 
  940. specific examples are discussed, in Building a Presentation Manager 
  941. Application. 
  942.  
  943.  
  944. ΓòÉΓòÉΓòÉ 9.3.1. Systems Application Architecture Conformance ΓòÉΓòÉΓòÉ
  945.  
  946. While Presentation Manager supports and facilitates the implementation of 
  947. object-oriented design techniques and provides support for the user interface 
  948. constructs and guidelines laid down by the CUA component of Systems Application 
  949. Architecture, it does not force an application developer to conform to 
  950. object-oriented design principles or CUA-conforming user interface guidelines. 
  951. While the rich function set provided by the Presentation Manager  programming 
  952. interface allows an application developer to interpret and implement CUA 
  953. guidelines in a number of ways, there are emerging conventions with regard to 
  954. the implementation of these guidelines. 
  955.  
  956. In order to achieve the benefits which accrue from adherence to object-oriented 
  957. and CUA principles, a measure of discipline is required on the part of the 
  958. application developer, so as to implement the application in such a way that 
  959. the maximum degree of object-independence and reusability is attained, and that 
  960. the optimal level of conformance to CUA conventions is achieved.  The subject 
  961. of CUA conformance is discussed in detail in Systems Application Architecture 
  962. CUA Considerations. 
  963.  
  964. Note that CUA conformance, along with consistency in the implementation of 
  965. application functions and user interface constructs, may be enforced or 
  966. enhanced through the use of standard functions and subroutines contained in 
  967. code libraries.  The creation of such libraries is facilitated by the modular 
  968. nature of the Presentation Manager  environment, and by the dynamic linking 
  969. capabilities of the OS/2 operating system.  This subject is discussed further 
  970. in Generic Application Modules. 
  971.  
  972.  
  973. ΓòÉΓòÉΓòÉ 9.3.2. Online Help and Documentation ΓòÉΓòÉΓòÉ
  974.  
  975. Presentation Manager also supports the development of online, context-sensitive 
  976. help panels, along with online documents for support of applications, business 
  977. processes and computer-based training.  Such information may be displayed in 
  978. windows on the Presentation Manager desktop, using the Information Presentation 
  979. Facility (IPF), which is shipped with the operating system. 
  980.  
  981. Help panels displayed using IPF are context-sensitive, thereby allowing the 
  982. user to request help on a specific topic, and the application to that help in a 
  983. window on the Presentation Manager desktop.  Help panels within an application 
  984. may be indexed, which allows a user to search for help on related topics in 
  985. addition to the topic initially requested. 
  986.  
  987. Phrases or illustrations within panels may be marked as selectable, and used to 
  988. display additional information, initiate application events or start new 
  989. applications.  This capability is provided by the hypertext and hypergraphics 
  990. facilities of IPF. 
  991.  
  992. Online documents may also be generated by IPF.  Such documents are not linked 
  993. to applications; they act as applications in their own right, and indeed may be 
  994. used to initiate the execution of application programs using the hypertext 
  995. facility of IPF.  Online documents may also be indexed, and keyword searches 
  996. may be conducted on document files; these facilities are part of IPF. 
  997.  
  998. Information Presentation Facility is described in detail in Adding Online Help 
  999. and Documentation. 
  1000.  
  1001.  
  1002. ΓòÉΓòÉΓòÉ 9.4. The Workplace Shell ΓòÉΓòÉΓòÉ
  1003.  
  1004. Under OS/2 Version 1┬╖3, the Presentation Manager provides a basis for the 
  1005. implementation of object-oriented software engineering principles, allowing the 
  1006. developer to take advantage of the benefits inherent in the object-oriented 
  1007. approach. However, the Presentation Manager application model lacks a built-in 
  1008. inheritance hierarchy, and therefore prevents the developer from realizing the 
  1009. productivity and consistency benefits that may be achieved under the principle 
  1010. of inheritance. 
  1011.  
  1012. OS/2 Version 2.0 extends the object-based Presentation Manager user interface 
  1013. with the introduction of the Workplace Shell*, and also provides an 
  1014. object-oriented application model that allows applications to exploit the 
  1015. principle of inheritance. The Workplace Shell application model views an 
  1016. application as a series of objects, typically represented by icons on the 
  1017. Workplace Shell desktop, which are manipulated by the user to achieve the 
  1018. required result. 
  1019.  
  1020. Objects may represent entities such as files, programs or devices, or may be 
  1021. containers that allow the user to logically group related objects.  The 
  1022. properties or contents of an object may be examined using a view of the object, 
  1023. which is typically implemented as a Presentation Manager window. 
  1024.  
  1025. The Workplace Shell application model is based upon the system object model, 
  1026. which defines a set of classes to form a basic inheritance hierarchy, and a set 
  1027. of protocols for interaction between application objects.  The Workplace Shell 
  1028. defines its own object classes that extend the inheritance hierarchy, and an 
  1029. application developer can continue to extend the hierarchy, subclassing 
  1030. existing object classes to create new classes. 
  1031.  
  1032. The Workplace Shell therefore brings both the end user and the application 
  1033. developer closer to the concept of direct object manipulation, and allows 
  1034. exploitation of the class-based theory of object-oriented programming.  The 
  1035. Workplace Shell application model, along with the creation and manipulation of 
  1036. Workplace Shell objects, is described in detail in Workplace Shell and the 
  1037. System Object Model. 
  1038.  
  1039.  
  1040. ΓòÉΓòÉΓòÉ 9.5. Summary ΓòÉΓòÉΓòÉ
  1041.  
  1042. Presentation Manager facilitates the implementation of an event-driven, 
  1043. object-action user interface and provides predefined constructs that enable a 
  1044. consistent, intuitive user interface for multiple applications, in line with 
  1045. the objectives of the Systems Application Architecture Common User Access 
  1046. component.  However, in order to gain the fullest benefit from such an 
  1047. interface, the application developer must adopt a certain degree of 
  1048. object-oriented principles in the design and implementation of applications. 
  1049.  
  1050. In order to support the implementation of an event-driven interface and 
  1051. facilitate the incorporation of object-oriented design techniques, Presentation 
  1052. Manager provides an object-based, event-driven execution environment with an 
  1053. application architecture that conforms closely to object-oriented theory, 
  1054. within the framework of the Systems Application Architecture  Common 
  1055. Programming Interface.  Windows become the handles by which the application 
  1056. references data objects, and windows communicate with one another and with the 
  1057. user in an event-driven manner.  With the addition of the Workplace Shell in 
  1058. OS/2 Version 2.0, the user and the programmer may deal directly with objects 
  1059. and take full advantage of the concept of inheritance. 
  1060.  
  1061. Benefits to be gained from the adoption of such principles include enhanced 
  1062. opportunity for code reuse with consequent reductions in development costs, and 
  1063. easier containment of change through encapsulation and data isolation. As the 
  1064. programmable workstation becomes more widely utilized as the platform for 
  1065. line-of-business applications, the importance of sound software engineering 
  1066. principles in the design and implementation of workstation applications will 
  1067. increase, in accordance with the requirement to be able to adequately manage 
  1068. and maintain these applications.  OS/2 and Presentation Manager together with 
  1069. the Workplace Shell, which extends the paradigm to further exploit 
  1070. object-oriented concepts, provide a platform for the implementation of such 
  1071. principles. 
  1072.  
  1073. It must be emphasized that Presentation Manager provides an application 
  1074. architecture at the operating system level which supports the implementation of 
  1075. certain object-oriented software engineering principles, and provides many of 
  1076. the facilities required by such an approach.  However, while Presentation 
  1077. Manager supports an object-oriented approach to application design, it does not 
  1078. force the application developer to conform to object-oriented design practices. 
  1079. Presentation Manager  does not provide, nor does it seek to provide, a complete 
  1080. development environment for object-oriented applications;  the provision of 
  1081. such function is the responsibility of application-enabling products that may 
  1082. reside and execute in the Presentation Manager environment. 
  1083.  
  1084. The remainder of this document will further explore the relationship between 
  1085. OS/2 Version 2.0, Presentation Manager and object-oriented programming, and 
  1086. examine the techniques by which object-oriented applications may be implemented 
  1087. in the Presentation Manager environment, using both the Presentation Manager 
  1088. and Workplace Shell application models. 
  1089.  
  1090.  
  1091. ΓòÉΓòÉΓòÉ 10. Operating System/2 ΓòÉΓòÉΓòÉ
  1092.  
  1093. This chapter briefly explains the differences between the PC DOS and Operating 
  1094. System/2 (hereafter referred to as OS/2) environments, and describes the 
  1095. features and capabilities of IBM OS/2 Version 2.0.  The chapter discusses 
  1096. OS/2's retention of compatibility with existing DOS applications, while 
  1097. providing support for multiprogramming and multitasking, larger memory, 
  1098. multiple concurrent communications, etc. 
  1099.  
  1100.  
  1101. ΓòÉΓòÉΓòÉ 10.1. History ΓòÉΓòÉΓòÉ
  1102.  
  1103. IBM and Microsoft** introduced OS/2 in 1987 as a successor to the PC DOS/MS 
  1104. DOS** operating system [For simplicity, the term "DOS" will be used throughout 
  1105. this document to refer to both the PC DOS and MS DOS products. ] in the 
  1106. programmable workstation environment.  In the years since its inception in the 
  1107. early 1980s, DOS has grown in both capabilities and sophistication, but by 1987 
  1108. advanced workstation users were demanding more sophistication from their 
  1109. applications, to an extent which was beyond the capabilities of DOS to deliver. 
  1110.  
  1111. The choice for operating system developers lay between further enhancing the 
  1112. existing DOS architecture to support more powerful processors, larger memory 
  1113. and so on, or migrating to a new, more powerful operating system architecture 
  1114. which offered more facilities to satisfy user requirements, a broader platform 
  1115. for application development, and potential for future expansion.  The latter 
  1116. choice was taken, and the result was OS/2. 
  1117.  
  1118. The OS/2 operating system environment provides a great deal more power and 
  1119. flexibility than the DOS environment, while maintaining a level of 
  1120. compatibility with existing DOS applications and data.  Enhancements made in 
  1121. OS/2 Version 1┬╖3 include: 
  1122.  
  1123.    o  Effective use of the advanced capabilities of the Intel 80286 processor 
  1124.  
  1125.    o  Support for system memory above 640 kilobytes (KB) 
  1126.  
  1127.    o  Support for multiprogramming and multitasking 
  1128.  
  1129.    o  Dynamic linking for system and application modules. 
  1130.  
  1131.  In addition, numerous other functions are provided to support and complement 
  1132.  these capabilities. 
  1133.  
  1134.  OS/2 Version 2.0 was developed as an extension of the original 16-bit 
  1135.  implementation used in OS/2 Version 1┬╖3, and is an advanced 32-bit 
  1136.  multitasking operating system for machines equipped with the Intel 80386** or 
  1137.  compatible processors.  The following new features are implemented in OS/2 
  1138.  Version 2.0: 
  1139.  
  1140.    o  Support for the Intel 80386 32-bit microprocessor instruction set; 
  1141.       previous versions of OS/2 only supported the 80386 in 80286 emulation 
  1142.       mode. 
  1143.  
  1144.    o  32-bit memory management with a flat memory model; previous versions of 
  1145.       OS/2 required applications to use the segmented memory model.  See Memory 
  1146.       Management for further information. 
  1147.  
  1148.    o  Enhanced hardware exploitation. 
  1149.  
  1150.    o  Support for multiple concurrent DOS applications with pre-emptive 
  1151.       multitasking and full memory protection. 
  1152.  
  1153.    o  Support for Microsoft Windows** applications. 
  1154.  
  1155.    o  New 32-bit programming environment. 
  1156.  
  1157.    o  Binary-level compatibility with previous versions of OS/2, allowing 
  1158.       16-bit applications written for previous versions to execute under 
  1159.       Version 2.0 without modification. 
  1160.  
  1161.    o  An enhanced Presentation Manager user shell, known as the Workplace 
  1162.       Shell, which implements the 1991 IBM Systems Application Architecture CUA 
  1163.       Workplace Environment. 
  1164.  
  1165.  The remainder of this chapter describes the features of OS/2 Version 2.0, and 
  1166.  also makes reference to architectural features implemented in previous 
  1167.  versions of OS/2 where appropriate. 
  1168.  
  1169.  
  1170. ΓòÉΓòÉΓòÉ 10.2. Intel 80386 32-Bit Microprocessor Support ΓòÉΓòÉΓòÉ
  1171.  
  1172. The basis for OS/2 Version 2.0 is its support for the Intel 80386 
  1173. microprocessor; previous versions of OS/2 were developed for the Intel 80286 
  1174. processor, and supported the 80386 in 80286 emulation mode only. Full support 
  1175. of the 80386 means that a powerful set of 32-bit features now becomes available 
  1176. to the operating system and applications, including enhanced memory management 
  1177. and more sophisticated multitasking capabilities.  The Intel 80386 and 80486 
  1178. offer significant improvements over the previous generation of 16-bit 
  1179. microprocessors, while retaining compatibility with these processors. 
  1180.  
  1181. The memory addressing capacity of the 80386 processor is significantly greater 
  1182. than that of the 80286: 
  1183.  
  1184.    o  4 gigabyte (GB) physical address space; this compares with the 640 
  1185.       kilobyte (KB) address space of DOS and the 16 megabyte (MB) address space 
  1186.       of OS/2 Version 1┬╖3. 
  1187.  
  1188.    o  64 terabyte (TB) virtual address space; DOS does not support virtual 
  1189.       memory, and OS/2 Version 1┬╖3 supports 2 GB of virtual memory. 
  1190.  
  1191.    o  1 byte to 4 gigabyte memory objects; this compares with a 64 KB maximum 
  1192.       size under DOS or OS/2 Version 1┬╖3. 
  1193.  
  1194.  OS/2 Version 2.0 uses many of these processor features and capabilities to 
  1195.  provide a more powerful and flexible operating system platform.  Note that 
  1196.  OS/2 Version 2.0 does not implement the full 64 TB virtual address space 
  1197.  provided by the 80386, since this requires use of the segmented memory model; 
  1198.  OS/2 Version 2.0 uses a flat memory model, as described in Memory Management. 
  1199.  
  1200.  
  1201. ΓòÉΓòÉΓòÉ 10.3. Memory Management ΓòÉΓòÉΓòÉ
  1202.  
  1203. Memory management is the way in which the operating system allows applications 
  1204. to access the system's memory.  This includes the way in which memory is 
  1205. allocated, either to a single application or to be shared by multiple 
  1206. applications.  The operating system must check the amount of memory available 
  1207. to an application, and must handle the situation where there is insufficient 
  1208. free memory to satisfy an application's requests. 
  1209.  
  1210. Memory management under DOS and OS/2 Version 1┬╖3 was achieved using units of 
  1211. memory known as segments, which could be from 16 bytes to 64 KB in size.  The 
  1212. memory model implemented by these operating systems was therefore known as a 
  1213. segmented memory model. The use of data structures larger than 64KB required 
  1214. the use of multiple segments, the management of which was the responsibility of 
  1215. the application.  This led to increased size and complexity, and reduced 
  1216. performance in applications which handled large data structures. 
  1217.  
  1218. In OS/2 Version 2.0, memory management has been enhanced to provide a flat 
  1219. memory model, which takes advantage of the 32-bit addressing scheme provided by 
  1220. the Intel 80386 architecture.  This means that through memory management, the 
  1221. system's memory is seen as one large linear address space of 4 GB. Applications 
  1222. have access to memory by requesting the allocation of memory objects. Under 
  1223. OS/2 Version 2.0, these memory objects can be of any size between 1 byte and 
  1224. 512 MB.  The use of a flat memory model removes the need for application 
  1225. developers to directly manipulate segments, thereby simplifying application 
  1226. development and removing a significant obstacle in porting applications between 
  1227. OS/2 Version 2.0 and other 32-bit environments such as AIX*. 
  1228.  
  1229. OS/2 Version 2.0 manages memory internally using pages, each of which is 4 KB 
  1230. in size.  Each memory object is regarded by the operating system as a set of 
  1231. one or more pages.  For practical purposes therefore, memory is allocated in 
  1232. units of 4 KB, although a page may be broken down into smaller parts and may 
  1233. contain multiple memory objects. 
  1234.  
  1235. One of the useful aspects of paged memory is the way in which memory 
  1236. overcommitment is handled; that is, what happens when there is no more real 
  1237. memory left to load applications or satisfy a request for memory from an 
  1238. application.  Under OS/2 Version 2.0, individual pages may be swapped to and 
  1239. from disk storage, rather than entire memory objects.  This improves swapping 
  1240. performance, particularly when large memory objects exist in the system. The 
  1241. fixed page size also improves swapping performance since the operating system 
  1242. need not be concerned with moving memory objects about in order to accomodate 
  1243. the various object sizes, as was the case with previous versions of OS/2. 
  1244.  
  1245. For a more detailed discussion of memory management under OS/2 Version 2.0, 
  1246. readers should refer to OS/2 Version 2.0 - Volume 1:  Control Program. 
  1247.  
  1248.  
  1249. ΓòÉΓòÉΓòÉ 10.4. Multiprogramming and Multitasking ΓòÉΓòÉΓòÉ
  1250.  
  1251. A multiprogramming operating system allows the concurrent execution of multiple 
  1252. applications in the same machine.  A multitasking operating system is an 
  1253. extension of the multiprogramming concept, which distributes processor time 
  1254. among multiple applications by giving each application access to the processor 
  1255. for short periods of time.  OS/2 implements both multiprogramming and 
  1256. multitasking. 
  1257.  
  1258. Multitasking may be supported in two forms: 
  1259.  
  1260.    o  Cooperative multitasking requires the active support of applications 
  1261.       running in the system, which must explicitly relinquish control of the 
  1262.       processor to allow other applications to execute.  This form of 
  1263.       multitasking is unreliable and frequently leads to poor performance, 
  1264.       since an ill-behaved application can monopolize the processor. 
  1265.  
  1266.    o  Pre-emptive multitasking uses a scheduler as part of the operating 
  1267.       system; the scheduler is responsible for selectively dispatching and 
  1268.       suspending multiple concurrent tasks in the system.  This form of 
  1269.       multitasking is more sophisticated, typically leads to greater overall 
  1270.       system throughput, and allows implementation of priority dispatching 
  1271.       schemes for various tasks. 
  1272.  
  1273.  Numerous mechanisms exist for providing multiprogramming support under DOS; 
  1274.  these include products such as Microsoft Windows.  However, since such 
  1275.  facilities are ultimately dependent upon the single-tasking architecture of 
  1276.  the DOS operating system, they typically provide only limited multitasking 
  1277.  capabilities; where pre-emptive multitasking is supported, schedulers are 
  1278.  typically primitive and performance is relatively poor.  Pre-emptive 
  1279.  multitasking is not possible during input/output operations, since these 
  1280.  operations are performed by the single-tasking DOS operating system. 
  1281.  
  1282.  OS/2 provides pre-emptive multitasking under the control of the operating 
  1283.  system, which is designed to use the multitasking protected mode of the Intel 
  1284.  80286 and 80386 processors.  OS/2 implements a pre-emptive task scheduler with 
  1285.  a multi-level priority scheme, which provides dynamic variation of priority 
  1286.  and round-robin dispatching within each priority level.  The dynamic variation 
  1287.  of priority is achieved on the basis of current activity, and is intended to 
  1288.  improve overall system performance and ensure that the system as a whole 
  1289.  responds adequately to user interactions. For circumstances where dynamic 
  1290.  variation of priority is inappropriate, the dynamic variation may be disabled 
  1291.  using a command in the CONFIG.SYS file, and task priority then becomes 
  1292.  absolute.  In either case, task priority may be set and altered dynamically 
  1293.  using a number of operating system functions available to OS/2 application 
  1294.  programmers. 
  1295.  
  1296.  The management of tasks executing in the system is further simplified and 
  1297.  streamlined under OS/2 Version 2.0.  This is due primarily to the fact that 
  1298.  support for processes executing in real mode (such as the DOS Compatibility 
  1299.  Box in OS/2 Version 1┬╖3) is no longer required, since the execution of DOS 
  1300.  applications is supported using virtual DOS machines which run as protected 
  1301.  mode processes.  See DOS Application Support for further information. 
  1302.  
  1303.  
  1304. ΓòÉΓòÉΓòÉ 10.4.1. Application Support ΓòÉΓòÉΓòÉ
  1305.  
  1306. OS/2 Version 2.0 supports concurrent execution of the following types of 
  1307. applications: 
  1308.  
  1309.    o  DOS applications, in full-screen mode or in windows on the Presentation 
  1310.       Manager desktop 
  1311.  
  1312.    o  Microsoft Windows applications, in windows on the Presentation Manager 
  1313.       desktop 
  1314.  
  1315.    o  16-bit OS/2 applications developed for previous versions of OS/2 
  1316.  
  1317.    o  New 32-bit applications developed for OS/2 Version 2.0. 
  1318.  
  1319.  All applications execute as protected mode processes under OS/2 Version 2.0, 
  1320.  and are therefore provided with pre-emptive multitasking and full memory 
  1321.  protection; each application is isolated from other applications and from the 
  1322.  OS/2 Version 2.0 operating system itself. 
  1323.  
  1324.  
  1325. ΓòÉΓòÉΓòÉ 10.4.2. Processes and Threads ΓòÉΓòÉΓòÉ
  1326.  
  1327. The term task (as in multitasking) refers to a hardware-defined task state. 
  1328. While OS/2 supports multitasking, it does not directly use the concept of a 
  1329. task as defined by the Intel 80386 processor architecture.  Instead, OS/2 makes 
  1330. a differentiation between processes and threads. 
  1331.  
  1332.  
  1333. ΓòÉΓòÉΓòÉ 10.4.2.1. Processes ΓòÉΓòÉΓòÉ
  1334.  
  1335. A process is most easily defined as a program executing in the system. Since it 
  1336. is possible for a single program to be invoked multiple times in a multitasking 
  1337. system such as OS/2, multiple processes may be executing the same program, and 
  1338. each such process is known as an execution instance of the program.  A process 
  1339. owns system resources such as threads, file handles etc, and a memory map that 
  1340. describes the region of memory owned by that process.  Since each process owns 
  1341. its own resources and memory map, which are administered by the operating 
  1342. system on behalf of the process, the resources of one process are protected 
  1343. from access by any other process. In situations where communication between 
  1344. processes is required, OS/2 provides a number of architected mechanisms by 
  1345. which they may be achieved. These mechanisms are described in Interprocess 
  1346. Communication and Synchronization. 
  1347.  
  1348.  
  1349. ΓòÉΓòÉΓòÉ 10.4.2.2. Threads ΓòÉΓòÉΓòÉ
  1350.  
  1351. A thread is the unit of dispatching for the operating system's scheduler, and 
  1352. therefore equates closely with the notion of an 80386 task as defined by the 
  1353. processor architecture.  Each thread is owned by a process, and a single 
  1354. process may have multiple threads.  When a process is created, one thread 
  1355. (known as the primary thread) is always created to run the code specified in 
  1356. the process creation system call.  Thus a process always has at least one 
  1357. thread.  Secondary threads are often used to perform lengthy operations such as 
  1358. document formatting, remote communications etc, thereby allowing the primary 
  1359. thread to continue interaction with the user. Secondary threads may be created 
  1360. and terminated at any time during execution of a process.  When the primary 
  1361. thread of a process is terminated, the process itself terminates. 
  1362.  
  1363. A thread executes for a short period of time before the operating system's 
  1364. scheduler preempts the thread and gains control.  The scheduler may then 
  1365. determine that there is some other thread that ought to run; if so, the 
  1366. scheduler saves the task state of the current thread and dispatches the new 
  1367. thread, which executes for a period of time until it too is preempted and 
  1368. control returns to the scheduler. 
  1369.  
  1370. OS/2 Version 2.0 supports up to 4096 threads within the system.  Note that this 
  1371. limit includes those threads used by the operating system and by applications 
  1372. executing under operating system control, such as the print spooler.  The 
  1373. number of threads available to applications will therefore be somewhat less 
  1374. than 4096. 
  1375.  
  1376. Since each thread is owned by a process, all threads within that process share 
  1377. the resources and memory map belonging to that process, and thus have access to 
  1378. those resources.  OS/2 does not protect memory resources from being accessed by 
  1379. multiple threads within the same process; this is the responsibility of the 
  1380. application developer.  However, OS/2 provides a number of architected 
  1381. mechanisms to aid the application developer in maintaining the integrity of the 
  1382. application's resources. 
  1383.  
  1384.  
  1385. ΓòÉΓòÉΓòÉ 10.4.3. Interprocess Communication and Synchronization ΓòÉΓòÉΓòÉ
  1386.  
  1387. Since OS/2 provides support for concurrent execution of multiple processes, 
  1388. with memory protection between these processes, it must also provide mechanisms 
  1389. to facilitate synchronization and communication between different processes and 
  1390. threads executing in the system, which may wish to share data and control 
  1391. information.  OS/2 provides a number of such mechanisms, as follows: 
  1392.  
  1393.    o  Shared memory 
  1394.  
  1395.    o  Queues 
  1396.  
  1397.    o  Pipes (both named and anonymous) 
  1398.  
  1399.    o  Presentation Manager messages 
  1400.  
  1401.    o  Semaphores. 
  1402.  
  1403.  These mechanisms allow application developers to implement applications using 
  1404.  multiple processes or threads, while retaining the ability to communicate data 
  1405.  and control information in a controlled manner, and to achieve synchronization 
  1406.  between various components of an application. 
  1407.  
  1408.  
  1409. ΓòÉΓòÉΓòÉ 10.4.3.1. Shared Memory ΓòÉΓòÉΓòÉ
  1410.  
  1411. The OS/2 memory management architecture utilizes the protect mode of the Intel 
  1412. 80386 processor to achieve memory isolation between processes.  A process has 
  1413. addressability only to its own memory objects.  However, in certain 
  1414. circumstances processes may wish to communicate and pass data to each other; 
  1415. OS/2 allows this by the use of shared memory objects.  Shared memory objects 
  1416. are dynamically requested from the operating system by the application during 
  1417. execution, and are flagged as shareable by OS/2.  It is the responsibility of 
  1418. the applications concerned however, to correctly synchronize the flow of data 
  1419. between processes.  OS/2 provides a number of mechanisms by which this 
  1420. synchronization may be achieved.  Shared memory and its usage is discussed in 
  1421. the IBM OS/2 Version 2.0 Application Design Guide. 
  1422.  
  1423.  
  1424. ΓòÉΓòÉΓòÉ 10.4.3.2. Queues ΓòÉΓòÉΓòÉ
  1425.  
  1426. Queueing system calls are implemented by a system service routine that uses 
  1427. shared memory and semaphores (see below) for serialization.  A queue is created 
  1428. by a process that then becomes the owner of that queue;  only the owner may 
  1429. read from the queue.  Other processes may write to the queue, but only the 
  1430. owner may look at elements on the queue, remove elements from the queue, purge 
  1431. or delete the queue.  Queues may be specified with FIFO (first-in, first-out) 
  1432. or LIFO (last-in, first-out) dispatching priority. 
  1433.  
  1434. A queue has a name, similar to a file name, by which it is known to both 
  1435. processes and by which it is referred to when the queue is first accessed by a 
  1436. particular process.  A series of operating system functions is provided by OS/2 
  1437. to create and access queues.  Queues are discussed in detail in the IBM OS/2 
  1438. Version 2.0 Application Design Guide. 
  1439.  
  1440.  
  1441. ΓòÉΓòÉΓòÉ 10.4.3.3. Pipes ΓòÉΓòÉΓòÉ
  1442.  
  1443. A pipe is a FIFO data structure that permits two processes to communicate using 
  1444. file system I/O calls.  The first process writes data into the pipe and the 
  1445. second process reads the data from the pipe.  However, the data is never 
  1446. actually written to an external file, but is held in a shared area in memory. 
  1447.  
  1448. A pipe may be named, in which case it has a name similar to a file name which 
  1449. is known by both processes, or it may be anonymous in which case read and write 
  1450. handles to the pipe are returned by the operating system when the pipe is 
  1451. created.  It is then the responsibility of the creating process to communicate 
  1452. these handles to other threads or processes. 
  1453.  
  1454. The creation of pipes is achieved using a number of OS/2 function calls; once 
  1455. created, pipes are then accessed using file system I/O functions. Pipes and 
  1456. their manipulation are discussed in the IBM OS/2 Version 2.0 Application Design 
  1457. Guide. 
  1458.  
  1459.  
  1460. ΓòÉΓòÉΓòÉ 10.4.3.4. Presentation Manager Messages ΓòÉΓòÉΓòÉ
  1461.  
  1462. In the OS/2 Presentation Manager programming environment, application routines 
  1463. known as window procedures communicate by receiving messages from one another 
  1464. and from Presentation Manager itself.  Messages may be passed between window 
  1465. procedures executing in the same thread, between different threads in a 
  1466. process, or between processes. 
  1467.  
  1468. Messages may be used to pass data between routines executing in different 
  1469. threads or processes, or to communicate events in order to achieve 
  1470. synchronization between threads and/or processes.  Presentation Manager 
  1471. messages may be used to invoke processing routines in either a synchronous or 
  1472. asynchronous manner.  The Presentation Manager messaging model conforms closely 
  1473. to object-oriented programming practices, and is described further in The 
  1474. Presentation Manager Application Model. 
  1475.  
  1476.  
  1477. ΓòÉΓòÉΓòÉ 10.4.3.5. Atoms ΓòÉΓòÉΓòÉ
  1478.  
  1479. Where character strings must be passed between threads, it is relatively simple 
  1480. to pass a pointer to the character string, since all threads within a process 
  1481. share access to memory objects.  Where strings must be passed between processes 
  1482. however, more complex methods such as shared memory must normally be used. 
  1483. OS/2 provides a way to simplify the passing of strings between processes, using 
  1484. atoms. 
  1485.  
  1486. An atom is effectively a "handle" to a string that is stored in an area of 
  1487. shared memory known as an atom table.  Atom tables are maintained by the 
  1488. operating system, and may be private to a particular process or shared by all 
  1489. processes in the system.  OS/2 creates a system atom table at system 
  1490. initialization time, which is accessible by all processes in the system. 
  1491.  
  1492. A process may add a string to an atom table, and obtain an atom that may 
  1493. subsequently be used to access the string.  Atoms that reference strings in the 
  1494. system atom table may be passed between processes using any of the methods 
  1495. described in the foregoing sections, and used by another process to obtain the 
  1496. contents of the string. 
  1497.  
  1498.  
  1499. ΓòÉΓòÉΓòÉ 10.4.3.6. Semaphores ΓòÉΓòÉΓòÉ
  1500.  
  1501. OS/2 applications may be implemented using multiple threads within one or more 
  1502. processes.  Within a single process, the OS/2 memory management architecture 
  1503. provides no memory protection for different threads, and hence multiple threads 
  1504. may have addressability to the same data areas.  It is important that the 
  1505. integrity of resources such as common data areas or files, shared between 
  1506. threads, be protected at all times.  Such resources must be accessed in a 
  1507. serialized fashion.  Although OS/2 provides no automatic protection for data 
  1508. resources between threads within a process, OS/2 allows an application to 
  1509. achieve this serialization of access by using semaphores. 
  1510.  
  1511. A semaphore is a data structure that may be "owned" by only one thread at any 
  1512. time. Semaphores may be used as flags by an application, to indicate that a 
  1513. data resource is being accessed.  A thread may request ownership of the 
  1514. semaphore; if the semaphore is already owned by another thread, the requesting 
  1515. thread is blocked until the first thread releases it. 
  1516.  
  1517. OS/2 Version 2.0 provides a number of different types of semaphores, to be used 
  1518. in different circumstances: 
  1519.  
  1520.    o  Mutex semaphores provide mutually exclusive access to a particular 
  1521.       resource such as a shared memory object.  These semaphores offer a useful 
  1522.       means of synchronizing access to such resources between different threads 
  1523.       or processes. 
  1524.  
  1525.    o  Event semaphores are used to signal system or application events. These 
  1526.       semaphores provide a means of signalling events to other threads or 
  1527.       processes, allowing such threads to suspend their execution and "wait" 
  1528.       for a particular event to occur. 
  1529.  
  1530.    o  MuxWait semaphores may be used when waiting for multiple events to occur 
  1531.       or multiple mutex semaphores to clear. 
  1532.  
  1533.  Within these semaphore types, OS/2 Version 2.0 provides both private and 
  1534.  shared semaphores.  The system semaphores and RAM semaphores provided by 
  1535.  previous versions of OS/2 are also supported, retaining compatibility with 
  1536.  applications developed for previous versions of the operating system.  Each 
  1537.  process in the system may have up to 65535 private semaphores, and there may 
  1538.  be up to 65535 shared semaphores in the system. 
  1539.  
  1540.  OS/2 Version 2.0 provides a number of operating system functions allowing the 
  1541.  creation and manipulation of semaphores.  Semaphores are discussed in the IBM 
  1542.  OS/2 Version 2.0 Application Design Guide. 
  1543.  
  1544.  
  1545. ΓòÉΓòÉΓòÉ 10.5. DOS Application Support ΓòÉΓòÉΓòÉ
  1546.  
  1547. OS/2 Version 1┬╖3 provides the capability for a single DOS application to be 
  1548. executed in the system using a facility known as the DOS Compatibility Box. 
  1549. The DOS application executes in real mode, and is automatically suspended if 
  1550. the DOS Compatibility Box is switched to the background; that is, pre-emptive 
  1551. multitasking is not supported in the DOS Compatibility Box under OS/2 Version 
  1552. 1┬╖3. 
  1553.  
  1554. OS/2 Version 2.0 provides the capability to pre-emptively multitask DOS 
  1555. applications along with OS/2 applications, using the Multiple Virtual DOS 
  1556. Machines feature of OS/2 Version 2.0.  The DOS support has been totally 
  1557. rewritten in OS/2 Version 2.0  and allows multiple concurrent DOS applications 
  1558. where each is executed as a single-threaded, protected mode OS/2 program.  This 
  1559. method of implementation provides pre-emptive multitasking for DOS 
  1560. applications, and allows normal OS/2 levels of memory protection; that is, it 
  1561. provides isolation of system memory and other applications, protection from 
  1562. illegal memory accesses by ill-behaved applications, and the ability to 
  1563. terminate sessions where applications are "hung". 
  1564.  
  1565. DOS support is achieved through the use of virtualization techniques, allowing 
  1566. the creation of multiple instances of separate, independent virtual DOS 
  1567. machines. Through this technique, a virtual interface is provided to each DOS 
  1568. machine, giving the impression that each application owns all of the required 
  1569. resources, both hardware and software. 
  1570.  
  1571. Each virtual DOS machine has more memory than the DOS Compatability Box 
  1572. implemented in previous versions of OS/2, and OS/2 Version 2.0 supports the use 
  1573. of Lotus**-Intel-Microsoft (LIM) expanded memory (EMS) and extended memory 
  1574. (XMS) to provide additional memory for those DOS applications that are capable 
  1575. of using such extensions.  OS/2 Version 2.0 maps this extended or expanded 
  1576. memory into the system's normal linear memory address space, and manages it in 
  1577. the same manner as any other allocated memory. 
  1578.  
  1579. The ability of a virtual DOS machine to run within a Presentation Manager 
  1580. window provides immediate productivity gains to existing DOS applications, 
  1581. since they may utilize Presentation Manager desktop features.  These features 
  1582. include window manipulation and the ability to cut/copy/paste information 
  1583. between applications using the clipboard. 
  1584.  
  1585. Application compatibility in the virtual DOS machine is also enhanced over 
  1586. previous versions of OS/2.  The virtual DOS machine can be used to execute 
  1587. DOS-based communications applications and other applications that address 
  1588. hardware I/O devices, through the use of virtual device drivers that map the 
  1589. device driver calls from the applications to the appropriate physical device 
  1590. driver within the operating system.  Applications using hardware devices that 
  1591. are not required to be shared with other applications in the same system may be 
  1592. accessed using the standard DOS device drivers, without the need for a virtual 
  1593. device driver.  Certain restrictions still apply with respect to communications 
  1594. line speed and time-critical interrupt handling. 
  1595.  
  1596. For applications that require specific versions of DOS in order to operate, 
  1597. OS/2 Version 2.0 provides the capability to load a physical copy of that 
  1598. version into a virtual DOS machine.  This provides compatability for those 
  1599. applications that internally manipulate DOS data structures or that use 
  1600. undocumented interfaces. 
  1601.  
  1602. Application compatability in a virtual DOS machine is further enhanced by the 
  1603. DOS settings feature, which allows virtual DOS machines to be customized to 
  1604. suit the requirements of the applications running in them.  Properties such as 
  1605. video characteristics, hardware environment emulation, and the use of memory 
  1606. extenders can all be customized using this feature. 
  1607.  
  1608. Multiple Virtual DOS Machines is described in more detail in OS/2 Version 2.0 - 
  1609. Volume 2:  DOS and Windows Environment. 
  1610.  
  1611.  
  1612. ΓòÉΓòÉΓòÉ 10.6. Microsoft Windows Application Support ΓòÉΓòÉΓòÉ
  1613.  
  1614. OS/2 Version 2.0 provides the capability for Microsoft Windows applications to 
  1615. run under OS/2 Version 2.0, in virtual DOS machines.  This support allows 
  1616. applications written for Windows 3.0 and previous versions of Windows to 
  1617. coexist and execute concurrently in the same machine. 
  1618.  
  1619. Each Windows applications executes as a protected mode process.  Windows 
  1620. applications are therefore subject to the full memory protection facilities 
  1621. provided to protected mode applications under OS/2 Version 2.0, and are 
  1622. protected from one another and from DOS or OS/2 applications executing in the 
  1623. system. This is in contrast to the native Windows 3.0 environment, where 
  1624. limited protection is provided for Windows 3.0 applications, and none at all 
  1625. for DOS applications unless Windows is running in enhanced mode. 
  1626.  
  1627. The execution of Windows applications as protected mode tasks also allows these 
  1628. applications to take full advantage of the pre-emptive multitasking 
  1629. capabilities of OS/2 Version 2.0, with full pre-emptive multitasking between 
  1630. Windows applications, DOS applications and OS/2 applications.  This is again in 
  1631. contrast to the native Windows 3.0 environment, where pre-emptive multitasking 
  1632. is available only for DOS applications, only when Windows 3.0 is running in 
  1633. enhanced mode, and only when no input/output operations are being performed, 
  1634. thereby impacting performance and preventing many applications written for 
  1635. previous versions of Windows from executing. OS/2 Version 2.0 has no such 
  1636. restriction. 
  1637.  
  1638. As with DOS applications, Windows applications may make use of EMS and XMS 
  1639. memory extenders in order to access memory above 640 KB.  This support is 
  1640. provided in an identical manner to that provided for DOS applications. 
  1641.  
  1642. Support for Microsoft Windows applications under OS/2 Version 2.0 is discussed 
  1643. in more detail in OS/2 Version 2.0 - Volume 2:  DOS and Windows Environment. 
  1644.  
  1645.  
  1646. ΓòÉΓòÉΓòÉ 10.7. Dynamic Linking ΓòÉΓòÉΓòÉ
  1647.  
  1648. OS/2 system services are requested by application programs using function 
  1649. calls; the external code references generated by such calls are resolved when 
  1650. the program is loaded or when the segments of the program are loaded, rather 
  1651. than at link-edit time.  This deferred resolution of external references is 
  1652. known as dynamic linking, and is available to applications, which may 
  1653. incorporate their own routines into dynamic link libraries (DLLs). 
  1654.  
  1655. Dynamic linking may be achieved in two ways under OS/2; 
  1656.  
  1657.    o  Load-time dynamic linking resolves external references within a code 
  1658.       segment at the time the segment is loaded into memory. 
  1659.  
  1660.    o  Run-time dynamic linking postpones the resolution until the actual 
  1661.       execution of the code, at which time the appropriate module is explicitly 
  1662.       loaded and invoked by the application. 
  1663.  
  1664.  Load-time dynamic linking is the simplest mechanism;  as already mentioned, 
  1665.  OS/2 system services are implemented in this way.  Load-time dynamic linking 
  1666.  is used whenever an application developer wishes to provide common services 
  1667.  that may be used by multiple applications, and which are implemented 
  1668.  independently of the applications that will use them.  Run-time dynamic 
  1669.  linking is used where particular routines may or may not be used by an 
  1670.  application, and thus should not be loaded into memory unless required. If an 
  1671.  application requires that such a routine be executed, the application may then 
  1672.  explicitly load the routine and execute it. 
  1673.  
  1674.  Dynamic linking provides an architected method of extending the services of 
  1675.  the operating system; all of the application programming interfaces supported 
  1676.  by OS/2 are implemented using dynamically linked modules.  An application 
  1677.  developer may use the same facilities to create his or her own dynamically 
  1678.  linked modules to provide additional services or standard routines that may be 
  1679.  used by applications executing in the system. 
  1680.  
  1681.  Dynamic linking is of benefit in that routines contained in DLLs are 
  1682.  completely independent of application code, and may be modified without the 
  1683.  need to re-link applications. In this way, DLLs contribute to the containment 
  1684.  of change within applications.  In addition, the contents of DLLs are not 
  1685.  limited to application code.  Presentation Manager  resources such as icons, 
  1686.  bitmaps, graphics fonts, window definitions etc, may be generated and stored 
  1687.  in a DLL for subsequent use by applications.  See Presentation Manager 
  1688.  Resources for a further discussion of Presentation Manager  resources.  DLLs 
  1689.  thus provide a powerful mechanism for the creation of reusable modules for 
  1690.  both full-screen and Presentation Manager applications. 
  1691.  
  1692.  Secondly, the creation of DLLs as re-entrant routines reduces the storage 
  1693.  requirements for OS/2 applications, since multiple applications may make use 
  1694.  of the same memory-resident copy of a DLL.  This re-entrancy and reusability, 
  1695.  in conjunction with the code independence gained by using a DLL, makes the DLL 
  1696.  a useful vehicle for implementation of standard service routines, which may be 
  1697.  accessed by any application or process within the system.  This contributes to 
  1698.  standardization within the business organization, which in turn can result in 
  1699.  improved productivity and reduced maintenance effort since the code to 
  1700.  implement a particular function need reside in only one location. 
  1701.  
  1702.  Note that a DLL is not a process under OS/2.  The re-entrant nature of a DLL 
  1703.  allows multiple applications to use the same memory-resident copy of the code; 
  1704.  however, each instance executes under the control of the process that invoked 
  1705.  it. 
  1706.  
  1707.  
  1708. ΓòÉΓòÉΓòÉ 10.8. Summary ΓòÉΓòÉΓòÉ
  1709.  
  1710. OS/2 provides the programmable workstation platform for the delivery of Systems 
  1711. Application Architecture application functionality in the standalone 
  1712. workstation and cooperative processing environments.  OS/2 overcomes the 
  1713. limitations of the DOS operating system by providing support for large physical 
  1714. and virtual address spaces and supporting concurrent execution of multiple 
  1715. applications with memory isolation and automated task dispatching.  While 
  1716. enforcing memory protection between applications, OS/2 provides architected 
  1717. mechanisms to allow interprocess communication and data sharing in a controlled 
  1718. manner. 
  1719.  
  1720. OS/2 also provides compatibility with existing DOS applications, since OS/2 
  1721. Version 1┬╖3 allows a single DOS application to run using the DOS Compatibility 
  1722. Box, and OS/2 Version 2.0 allows multiple concurrent DOS applications to 
  1723. execute in virtual DOS machines.  OS/2 Version 2.0 also supports Microsoft 
  1724. Windows applications in a similar manner to DOS applications.  This allows 
  1725. users of OS/2 systems to continue to use their existing DOS and Windows 
  1726. applications under the new operating system. 
  1727.  
  1728. OS/2 also implements dynamic linking, which allows an application developer to 
  1729. isolate common application services in separate modules known as dynamic link 
  1730. libraries (DLLs).  Calls to application services provided in a DLL are resolved 
  1731. at execution time, which means that any modifications to the routines contained 
  1732. in a DLL do not require any maintenance to applications using that DLL.  In 
  1733. addition, DLLs are created as re-entrant code, thus allowing multiple 
  1734. applications to use the same memory-resident copy of the DLL code and thereby 
  1735. reducing storage requirements. 
  1736.  
  1737. OS/2 provides an operating system environment for the programmable workstation 
  1738. that enables a far greater degree of functionality and sophistication on the 
  1739. part of application programs.  OS/2 Version 2.0 provides architected methods 
  1740. for overcoming most of the inherent limitations of the DOS and OS/2 Version 1┬╖3 
  1741. environments, and providing the workstation user with a higher level of 
  1742. capability in the workstation.  OS/2 provides the vehicle that will enable the 
  1743. fulfillment of the Systems Application Architecture cooperative processing 
  1744. direction. 
  1745.  
  1746.  
  1747. ΓòÉΓòÉΓòÉ 11. Object-Oriented Applications ΓòÉΓòÉΓòÉ
  1748.  
  1749. This chapter provides a brief overview of some concepts involved in 
  1750. object-oriented application design and programming, and the way in which this 
  1751. approach differs from traditional top-down functional decomposition. It is not 
  1752. intended as an indepth analysis of object-oriented programming, since such a 
  1753. task is beyond the scope of this document, but serves merely to provide a 
  1754. background against which the implementation of object-oriented principles under 
  1755. Presentation Manager may be discussed. 
  1756.  
  1757.  
  1758. ΓòÉΓòÉΓòÉ 11.1. Object-Oriented Concepts ΓòÉΓòÉΓòÉ
  1759.  
  1760. Object-oriented application design places the focus of an application on the 
  1761. logical entities or objects (typically items of data) upon which a program will 
  1762. operate, and attaches procedures or routines to manipulate these objects.  A 
  1763. logical data entity (such as a group of records) may have multiple 
  1764. representations within the system.  Each of these representations is known as a 
  1765. data object, and each data object may have a finite set of actions performed 
  1766. upon it. The data object itself, along with the routines (known as methods) 
  1767. used to perform these actions, are together regarded as an application object. 
  1768.  
  1769. Note that in the remainder of this document, the term data object will be used 
  1770. to denote a particular representation (for example, on the screen or in a disk 
  1771. file) of a logical data entity. The term application object will be used to 
  1772. denote the conjunction of a data object and its methods.  While these terms are 
  1773. not in general use, they will be used here in order to provide a distinction 
  1774. between a data item, and the conjunction of that data item and the routines 
  1775. that act upon it. 
  1776.  
  1777. Application objects typically respond to events, which originate outside the 
  1778. object and which may be system-initiated or user-initiated.  The sequence of 
  1779. these events determines the sequence of operations within the application, and 
  1780. the progression of dialog between the application and the user, rather than the 
  1781. application determining the sequence of the dialog, as is traditionally the 
  1782. case.  Such an object-oriented application environment is thus said to be 
  1783. event-driven. 
  1784.  
  1785. Events are communicated to an application object by means of a series of 
  1786. defined messages, which are not considered to be part of the objects between 
  1787. which they are passed.  The focus of the program thus becomes the object, 
  1788. rather than the procedure, and the program becomes a flow of messages between 
  1789. cooperating objects. 
  1790.  
  1791. Actions on a data object should be possible only by sending messages to the 
  1792. associated application object; an object's methods should not be directly 
  1793. accessible from another object, nor should the behavior of an object be 
  1794. dependent upon any external source other than the messages it receives.  A 
  1795. message should also specify only the action that is to be carried out, and not 
  1796. the way in which it is to be accomplished.  It is the responsibility of the 
  1797. receiving object to determine the way in which to carry out a requested action. 
  1798. Consequently, the behavior of an application object may differ, depending upon 
  1799. the class and content of its input messages.  A corollary of this statement is 
  1800. that the result of passing the same message class may vary, depending on the 
  1801. target object class and its interpretation of that message.  These guidelines 
  1802. outline the concept of polymorphism. 
  1803.  
  1804. One of the primary properties of an application object is its modularity; 
  1805. objects that obey the foregoing rules should be largely independent of one 
  1806. another, and the implementation of one object should not be dependent upon the 
  1807. internal details of another.  Data belonging to an application object should be 
  1808. accessible only by that object;  requests for access by other objects should be 
  1809. made via appropriate messages sent to the application object that "owns" the 
  1810. data object.  Thus the only information necessary to use an application object 
  1811. is a knowledge of the messages it can receive and operate upon (through its 
  1812. methods).  This rule encompasses the principle of encapsulation, which states 
  1813. that a data object should be defined, created and/or accessed solely from 
  1814. within its "owner" application object. 
  1815.  
  1816. Since a number of application objects may exist with similar characteristics, 
  1817. such objects are usually grouped into object classes. A class consists of those 
  1818. objects that share similar properties and methods.  An object class is 
  1819. typically associated with a single data object or type of data object, and has 
  1820. a defined, finite set of methods associated with it.  It is the class that 
  1821. normally defines the messages and methods applicable to an object.  Each object 
  1822. belonging to a particular class is then known as an instance of that class. 
  1823. Each instance inherits data objects and values defined for its class, and may 
  1824. also contain its own data, known as instance data; the properties of instance 
  1825. data are typically obtained from the definition of the object class, but the 
  1826. values are defined uniquely by each instance. 
  1827.  
  1828. The object-oriented approach is most suited to situations where the purpose of 
  1829. the application is the manipulation of data, whether on the screen or in a data 
  1830. file, and where the exact sequence of actions is not critical, provided all 
  1831. necessary actions are carried out.  The focus of an object-oriented application 
  1832. is the data objects that are being manipulated; the functions to be performed 
  1833. are subordinate to the data objects upon which they will act. In addition, the 
  1834. event-driven user interface places the user in control of the sequence of 
  1835. actions, and provides flexibility with respect to the way in which the desired 
  1836. result is achieved. 
  1837.  
  1838. An advantage of the object-oriented design approach for data manipulation 
  1839. applications is that a particular data object is "owned" by one application 
  1840. object, and that the definition of and establishment of access to that data 
  1841. object is achieved from within the application object.  Since application 
  1842. objects may be made relatively independent of one another, other objects may be 
  1843. isolated from changes to the data structure.  This greatly simplifies 
  1844. application maintenance, since all necessary changes need only be made within a 
  1845. single object. 
  1846.  
  1847. Note that since application objects are closely related only to their 
  1848. associated data objects, and not to the applications from which they are 
  1849. accessed, it follows that application objects may be constructed for each data 
  1850. object, and accessed from multiple applications.  An application need not be 
  1851. aware of the internal workings of an application object, but need only know the 
  1852. correct type and format of the messages through which to interact with the 
  1853. object.  Thus the object-oriented approach facilitates code reusability. 
  1854.  
  1855.  
  1856. ΓòÉΓòÉΓòÉ 11.1.1. Object-Oriented vs Functional Decomposition ΓòÉΓòÉΓòÉ
  1857.  
  1858. Under a traditional functional decomposition approach to program design, often 
  1859. referred to as structured programming, the function or procedure is the unit of 
  1860. modularity; programs are designed and implemented by placing a number of 
  1861. well-defined procedures in a particular order, and executing these procedures 
  1862. to achieve a desired result.  The focus of the design is the procedure or 
  1863. action to be performed.  Objects such as data structures are attached to 
  1864. procedures and passed between them using parameters.  A user typically selects 
  1865. an action to be performed, and then selects or enters a data object upon which 
  1866. to perform that action. Program Flow - Functional Decomposition Approach 
  1867.  
  1868. The functional decomposition approach is best suited to situations where the 
  1869. procedure is necessarily the focus of the application (for instance, a process 
  1870. management application), and where the correct sequencing of operations to be 
  1871. performed is a crucial factor in the successful execution of the required task. 
  1872. Under this approach, the application defines the sequence of actions which the 
  1873. user performs;  that is, the application controls the user interface. 
  1874.  
  1875. In an object-oriented approach, the application object is the unit of 
  1876. modularity.  Application objects communicate with each other and pass messages 
  1877. containing actions to be performed.  Object-oriented programming is hence the 
  1878. conceptual inverse of functional decomposition, and is a logical extension of 
  1879. the industry trend toward data-centric application design. Program Flow - 
  1880. Object-Oriented Approach 
  1881.  
  1882. This is not to say that an object-oriented application should not be 
  1883. structured.  Although such an application consists of objects that are largely 
  1884. independent of one another in programming terms, normal structured coding 
  1885. techniques should be followed in the creation of the methods within each 
  1886. application object. 
  1887.  
  1888. The object-oriented approach also requires firm management of the application 
  1889. development process in order to achieve the greatest possible level of 
  1890. productivity through code reuse.  Administration and control of existing 
  1891. objects is vital in order to allow application developers to access and use 
  1892. these objects in their applications.  Management of the application development 
  1893. process is discussed in greater detail in Managing Development, and the 
  1894. structuring of application source modules in order to provide optimal 
  1895. granularity is described in Application Program Construction. 
  1896.  
  1897. While it is possible for an application designed according to functional 
  1898. decomposition principles to implement some of the characteristics of 
  1899. object-oriented applications such as message passing, such applications should 
  1900. not be regarded as truly object-oriented.  If the design approach centers on 
  1901. procedures rather than data objects, then the application is designed along 
  1902. functional decomposition guidelines.  In this case, message passing is merely a 
  1903. replacement of the normal subroutine call mechanism, and does not significantly 
  1904. affect the structure of the application. 
  1905.  
  1906.  
  1907. ΓòÉΓòÉΓòÉ 11.1.2. Class-Based vs Module-Based ΓòÉΓòÉΓòÉ
  1908.  
  1909. The notion of object classes, and the extent to which this concept is taken, 
  1910. provides the distinguishing factor between two primary schools of thought 
  1911. within the object-oriented paradigm.  Under a class-based approach, objects are 
  1912. defined in terms of their class, and each class is defined in terms of other 
  1913. previously defined classes, the properties and methods of which are 
  1914. automatically conveyed upon the new class;  this is known as the principle of 
  1915. inheritance. 
  1916.  
  1917. For example, the object class "horse" may be defined as a sub-class of the 
  1918. object class "quadruped", with the additional properties of being able to be 
  1919. ridden and eating grass.  A further object class "pony" may then be defined as 
  1920. being a sub-class of the class "horse", with an additional upper limit on size. 
  1921. While this is a somewhat frivolous example, it illustrates the principle that 
  1922. an object class is defined in terms of other object classes, and need only 
  1923. explicitly define those properties and methods that are unique to that object 
  1924. class.  All other properties and methods are inherited from its parent class or 
  1925. classes.  This introduces the concept of an inheritance hierarchy, in that an 
  1926. object inherits not only the properties and methods of its class, but also 
  1927. those of other classes by way of which that class was defined. 
  1928.  
  1929. The major advantage of such an inheritance hierarchy is that, given a 
  1930. well-documented set of existing objects, it becomes extremely easy to create 
  1931. new object classes, simply by defining the new class in terms of other classes 
  1932. that already exist, and simply specifying any new or different properties or 
  1933. methods that apply to the new class.  This of course assumes the use of 
  1934. adequate object documentation and management practices.  Without such 
  1935. practices, it becomes difficult if not impossible to identify a suitable base 
  1936. object from a large library of existing object classes. 
  1937.  
  1938. However, many existing implementations of the class-based approach extend the 
  1939. inheritance hierarchy to a great degree, such that almost all imaginable object 
  1940. classes are defined in terms of parent object classes. While this provides a 
  1941. unified approach to the problem of object definition, the significant 
  1942. disadvantage of such an approach is the increased level of interdependence 
  1943. between objects.  The unit of modularity becomes the complete hierarchy rather 
  1944. than the individual object, since an object has no complete definition in its 
  1945. own right.  The reuse of a single object therefore requires the inclusion of 
  1946. its complete parent hierarchy.  Since it is typical for this parent hierarchy 
  1947. to be defined dynamically using run-time definitions for parent classes rather 
  1948. than defined statically at application generation, it is also possible for 
  1949. changes to a parent class to cause unforeseen side-effects in the behavior of 
  1950. descendant object classes.  Thus inheritance hierarchies require careful 
  1951. management to ensure that such side effects do not occur and adversely affect 
  1952. the integrity of applications and data. 
  1953.  
  1954. Where the inheritance hierarchy is taken to the extent of providing 
  1955. system-defined object classes, to which all application-defined object classes 
  1956. are linked, the hierarchy and thus the application is dependent upon the 
  1957. existence of a virtual machine conceptual environment, which must also be 
  1958. accepted along with the hierarchy.  This in turn may result in significant 
  1959. penalties in terms of application efficiency and run-time performance. 
  1960.  
  1961. A module-based approach to object-oriented programming defines each object as 
  1962. complete in its own right.  Objects may still be grouped into classes for 
  1963. easier definition and processing, but each class possesses its own complete set 
  1964. of properties and methods, and is not dependent upon another class for a part 
  1965. of this definition.  The primary advantage of the module-based approach is the 
  1966. increased level of independence between objects, with a finer degree of 
  1967. granularity in the application allowing object reuse with a lower level of 
  1968. overhead.  The main disadvantage of this approach is that each object class 
  1969. must be completely defined, requiring more work on the part of the application 
  1970. developer at the time the object is created. 
  1971.  
  1972. The concept of inheritance, while providing great potential for productivity 
  1973. enhancement during the application development process, must be carefully 
  1974. managed in order to avoid additional complications in application management 
  1975. and maintenance due to object interdependencies.  Side effects arising from 
  1976. modification to parent object classes may adversely affect the integrity of an 
  1977. application.  The alternative course of action, that of prohibiting the 
  1978. modification of existing objects in favor of creating new objects that inherit 
  1979. only the unmodified properties of the existing object, is often not viable due 
  1980. to the increased application overhead and managerial effort required to 
  1981. maintain and control an ever-expanding inheritance hierarchy. Reliance on the 
  1982. behavior of existing objects must therefore be viewed with extreme caution in 
  1983. the absence of effective management controls over object modification. 
  1984.  
  1985. The increase in development productivity provided by the use of inheritance may 
  1986. often be offset by the increased time and effort spent in regression testing of 
  1987. existing applications in order to determine any effects on these applications 
  1988. caused by the modification of existing object classes.  Tight managerial 
  1989. controls over development must therefore be maintained in order to identify and 
  1990. isolate those existing object classes that are modified and which are likely to 
  1991. affect existing applications. 
  1992.  
  1993. One technique that can be used to minimize the impact on existing applications 
  1994. is for the development organization to adopt a standard whereby, once an 
  1995. application object is deployed in a production environment, new applications 
  1996. that use the object may only modify its behavior through the use of subclassing 
  1997. (see Subclassing).  This means that the object itself is not modified, and 
  1998. other applications that use the object are not affected. 
  1999.  
  2000.  
  2001. ΓòÉΓòÉΓòÉ 11.1.3. Subclassing ΓòÉΓòÉΓòÉ
  2002.  
  2003. As already mentioned, the object-oriented approach facilitates the reuse of 
  2004. application code; generic objects may be created and used by multiple 
  2005. applications to perform actions upon the same data object or type of object. 
  2006. However, one of the criticisms often levelled at this capability is that it 
  2007. becomes impossible to foretell the total set of actions that may ever be 
  2008. required with respect to a particular data object, and that an object is 
  2009. therefore never truly reusable. 
  2010.  
  2011. The object-oriented approach overcomes this difficulty by providing a way for 
  2012. applications to modify the behavior of existing application objects without 
  2013. modifying the objects themselves; this is known as subclassing the object.  A 
  2014. subclass application object is composed of a data object definition and a 
  2015. certain number of methods to manipulate that object.  The subclass application 
  2016. object may contain methods that are not contained within the original 
  2017. application object created for that data object, or methods that are modified 
  2018. in some way from those contained in the original object.  In this way a 
  2019. subclass application object may add new methods to perform actions which are 
  2020. not performed by the original object class, or to handle certain types of 
  2021. message in a different way than that normally carried out by the original 
  2022. object class. Subclassing an Application Object 
  2023.  
  2024. When an application object has been subclassed, all messages intended for that 
  2025. object are directed to the subclass application object first.  The sending 
  2026. object need not be aware that the message has been diverted.  If the subclass 
  2027. application object does not contain a method to deal with a particular message, 
  2028. it should then pass the message on to the original application object, for 
  2029. processing by one of that object's methods.  The original application object 
  2030. receiving a message in this way should also be unaware that it has been 
  2031. subclassed. 
  2032.  
  2033. A useful application of the subclassing principle occurs when a generic 
  2034. application object is defined and stored away for use by many applications, 
  2035. taking advantage of the reusability aspects of the object-oriented approach. 
  2036. Where one application wishes to perform a particular action in a slightly 
  2037. different manner than that performed by the methods associated with the generic 
  2038. object, a subclass application object may be created containing a new method 
  2039. for that specific action only, and passing all other messages to the original 
  2040. application object for regular processing.  It can be seen that subclassing is 
  2041. a technique for application of the concept of inheritance, through its ability 
  2042. to transparently add properties and methods to existing objects. 
  2043.  
  2044. Subclassing also provides a way to overcome the danger of inadvertently 
  2045. impacting the behavior of other applications by modifying an existing 
  2046. application object.  If a standard is adopted whereby existing application 
  2047. objects in a production environment may only be modified through subclassing, 
  2048. such changes do not impact applications using the original object or which may 
  2049. themselves have subclassed that object.  In this way the need for regression 
  2050. testing of affected applications is eliminated, and the degree of 
  2051. object-management required is significantly reduced. 
  2052.  
  2053. When a functional requirement may be satisfied by modifying the methods of an 
  2054. existing application object (through subclassing), a decision must be made 
  2055. regarding the relative merits of modifying the object, against creating a new 
  2056. object.  Various texts advocate a rule whereby a new object should be created 
  2057. when more than 10% or 20% of an existing object's methods must be modified. 
  2058. However, the decision of whether to modify an existing object or create a new 
  2059. object must be taken on the basis of object complexity, degree of modification 
  2060. and experience. 
  2061.  
  2062.  
  2063. ΓòÉΓòÉΓòÉ 11.2. User View vs Application View ΓòÉΓòÉΓòÉ
  2064.  
  2065. A primary benefit of the object-oriented approach is its intuitive user 
  2066. interface; a user selects an object and performs a series of predefined actions 
  2067. upon that object.  This object-action style of interface encourages the user to 
  2068. explore the application through context-sensitive actions, and reduces the 
  2069. overall complexity of the user's interaction by reducing the levels of 
  2070. hierarchy required for the application. 
  2071.  
  2072. However, the end user may have a different view of an object-oriented 
  2073. application from that which must necessarily be taken by the application 
  2074. developer.  For instance, in the case of a text editor application editing a 
  2075. file, there may in fact be two versions of this file; one existing in memory, 
  2076. being manipulated by the application, and the other stored on a disk.  The 
  2077. application would consider these as two separate data objects, each with its 
  2078. own set of methods, and would create two application objects. 
  2079.  
  2080. Normal user interaction would take place with one object (the memory 
  2081. representation of the file), and when the user selects a "Save" action for the 
  2082. file, a message is passed to the second object (the disk representation of the 
  2083. file) with the information necessary to save updates on disk storage.  The user 
  2084. considers the logical data entity as the object being manipulated, while the 
  2085. application must distinguish between the representations of that data entity in 
  2086. various locations within the system. The user's metaphorical view of the data 
  2087. object is therefore not carried over to the application's view, which must by 
  2088. necessity be more concerned with the reality of that object's manipulation. 
  2089.  
  2090. Note however, that this distinction between representations should not be 
  2091. apparent to the end user.  The end user should perceive a single object (the 
  2092. text file) upon which he or she would perform actions.  Thus there is a 
  2093. distinction between the user's view and the application's view of the objects. 
  2094. An understanding of this distinction is important in order to comprehend the 
  2095. difference between an object-action user interface and an object-oriented 
  2096. application design. Object-Oriented Development Progression 
  2097.  
  2098. This diagram shows the interdependence of object-oriented design, 
  2099. implementation and user interface. 
  2100.  
  2101. The two concepts are complementary but distinct.  An event-driven, 
  2102. object-action user interface necessarily emerges from an object-oriented 
  2103. application design and implementation.  It is not possible to provide such an 
  2104. interface unless the application structure conforms to a certain level of 
  2105. object-oriented principles and practices.  This in turn is dependent upon an 
  2106. object-oriented application design.  For this reason, the proper implementation 
  2107. of the graphical user interface concepts defined in the IBM Systems Application 
  2108. Architecture CUA Advanced Guide to User Interface Design, requires applications 
  2109. to be designed and implemented using object-oriented guidelines. 
  2110.  
  2111.  
  2112. ΓòÉΓòÉΓòÉ 11.3. Object-Oriented Design ΓòÉΓòÉΓòÉ
  2113.  
  2114. The success of object-oriented design lies in the correct and intelligent 
  2115. definition of application objects and their methods as coherent and independent 
  2116. units.  The secret of a successful approach to this task is the consideration 
  2117. of the data objects themselves as the focus, rather than the procedures that 
  2118. will operate upon these objects.  Since the objects are typically associated 
  2119. with data, an entity-relationship model is often a useful starting point. 
  2120.  
  2121. Correctly-designed application objects facilitate reusability, since the data 
  2122. object and applicable actions are all defined within the application object. 
  2123. Additional applications that require manipulation of that data object may use 
  2124. the existing application object to achieve the required actions.  Certain 
  2125. applications may require additional, unforeseen actions, or that existing 
  2126. actions be carried out in a different manner; in such cases, subclassing the 
  2127. application object allows such modifications to be carried out.  One of the 
  2128. aims in the high-level design of an object-oriented application should be to 
  2129. make maximum use of existing application objects where possible, in order to 
  2130. reduce the design, coding and testing effort required.  This not only reduces 
  2131. the time and expense involved in application development, but enables 
  2132. application solutions to be delivered in a shorter time frame, allowing the 
  2133. business enterprise to respond more quickly to a dynamic marketplace. 
  2134.  
  2135. The correct definition of application objects and their boundaries also 
  2136. facilitates change management and maintenance of application code, since 
  2137. changes to a particular data object should affect only the application 
  2138. object(s) dealing with that data object.  Thus the effects of change are 
  2139. ideally confined to a single application object.  Modifications to a method 
  2140. within an application object should not affect the workings of other objects 
  2141. with which that application object interacts, provided the external interfaces 
  2142. of that object are not altered by the modification.  This containment of change 
  2143. within a single application object has the potential, in conjunction with 
  2144. proper configuration management techniques, to greatly ease the effort and cost 
  2145. involved in application maintenance. 
  2146.  
  2147. The following steps are necessary in the design of an object-oriented 
  2148. application: 
  2149.  
  2150.    1. Identify the data objects (that is, the different representations of the 
  2151.       logical data entity or entities upon which the application is to operate) 
  2152.       and the relationships between data objects. 
  2153.  
  2154.    2. Determine the set of applicable actions to be performed on each data 
  2155.       object. 
  2156.  
  2157.    3. Determine whether application objects have been previously been created 
  2158.       for the data objects to be manipulated by the application, and to what 
  2159.       extent these existing objects perform the required set of actions for 
  2160.       each object. 
  2161.  
  2162.    4. Determine the message classes required to achieve the desired 
  2163.       communication and to initiate required actions that are not already 
  2164.       satisfied through existing application objects. 
  2165.  
  2166.    5. Design the methods necessary to carry out the additional actions. 
  2167.  
  2168.  These steps are generic in nature, and must be combined with suitable 
  2169.  management controls, checkpoints and documentation standards to ensure 
  2170.  adequate design quality at each stage in the process. 
  2171.  
  2172.  
  2173. ΓòÉΓòÉΓòÉ 11.3.1. Object Identification ΓòÉΓòÉΓòÉ
  2174.  
  2175. The identification of data objects and their relationships should begin with 
  2176. the definition of a normal entity-relationship model, and the extension of this 
  2177. model to reflect the representations of data objects as well as the logical 
  2178. data entities involved.  The objective should be to achieve an optimal balance 
  2179. between the number of object classes and the size and complexity of each class, 
  2180. since each object may itself be composed of other objects, also bearing in mind 
  2181. that multiple objects of the same class may exist.  Optimizing the number of 
  2182. object classes will allow the number of message classes to be minimized, which 
  2183. in turn simplifies the design of the methods and the eventual testing of the 
  2184. object classes. 
  2185.  
  2186.  
  2187. ΓòÉΓòÉΓòÉ 11.3.2. Action Identification ΓòÉΓòÉΓòÉ
  2188.  
  2189. Having defined the data objects and their relationships, the set of actions 
  2190. pertaining to each data object should be determined. Once this point is 
  2191. achieved, the high-level design of the application objects, and therefore of 
  2192. the application itself, is essentially complete, and should be documented and 
  2193. approved by all concerned parties before the detailed design of methods 
  2194. commences.  Note that it is not necessary to define all of the applicable 
  2195. actions for each data object, since the essentially independent nature of 
  2196. methods allows additional actions to be added to an application object. 
  2197.  
  2198.  
  2199. ΓòÉΓòÉΓòÉ 11.3.3. Search for Existing Objects ΓòÉΓòÉΓòÉ
  2200.  
  2201. Once the data objects and the set of actions required for each object have been 
  2202. defined, the application designer should determine the existence of any 
  2203. previously-created application object classes for that type of data object. 
  2204. The use of existing application objects, with additional actions and methods 
  2205. handled through subclassing, can significantly reduce the amount of coding 
  2206. required. 
  2207.  
  2208. The accurate identification of existing application object classes requires 
  2209. that each application object, upon completing its final testing, must be placed 
  2210. in an object library, and its external interfaces (both input and output) must 
  2211. be fully documented and placed in a retrieval system from which the object's 
  2212. description may be recalled by designers of future applications.  The 
  2213. organization and level of sophistication of such a system is largely at the 
  2214. discretion of the development organization, but becomes more crucial as the 
  2215. number of application objects grows larger over time.  It is strongly 
  2216. recommended that any organization embarking on a strategy of object-oriented 
  2217. application development should adopt an efficient object library management 
  2218. system from the outset. 
  2219.  
  2220.  
  2221. ΓòÉΓòÉΓòÉ 11.3.4. Message Definition ΓòÉΓòÉΓòÉ
  2222.  
  2223. When the high-level design is complete, the message classes and their contents 
  2224. must be defined for each action that will be performed on and by an object. 
  2225. Note also that the same message class may be used with different object classes 
  2226. to achieve a different result, in accordance with the principle of 
  2227. polymorphism, thus reducing the number of defined message classes and 
  2228. simplifying the design of the application objects and their methods. 
  2229.  
  2230. The message classes comprise the interfaces between objects, and provide the 
  2231. input and output for the methods associated with the object.  These message 
  2232. interfaces must therefore be documented to facilitate reusability of the 
  2233. newly-created application objects by documenting the valid inputs and outputs 
  2234. for each object class, and the behavior of the object in response to these 
  2235. messages. 
  2236.  
  2237. Since the messages received and dispatched by an object constitute the inputs 
  2238. and outputs required and expected of that object, the documented message 
  2239. interfaces provide a valuable starting point for developing a test plan for the 
  2240. object.  Since the inputs, actions and outputs are known, a comprehensive set 
  2241. of test data may then be formulated to test the methods associated with each 
  2242. action, with both valid and invalid message inputs. 
  2243.  
  2244.  
  2245. ΓòÉΓòÉΓòÉ 11.3.5. Method Design ΓòÉΓòÉΓòÉ
  2246.  
  2247. Traditional functional decomposition techniques may then be used in the design 
  2248. of the methods to complete the required actions.  If the high-level design has 
  2249. been completed correctly, the application objects should be relatively 
  2250. independent of one another. It should therefore be possible to complete the 
  2251. development and testing of the methods for each object class as a separate task 
  2252. with each class, its methods and valid interfaces defined and unit-tested 
  2253. before the application is brought together for final integration-testing. 
  2254.  
  2255.  
  2256. ΓòÉΓòÉΓòÉ 11.4. Object-Oriented Implementations ΓòÉΓòÉΓòÉ
  2257.  
  2258. There has been much discussion in the computing industry press concerning 
  2259. application development products and tools that support the creation of 
  2260. object-oriented applications.  While the use of such products is a valuable aid 
  2261. in designing and developing an object-oriented application, it should not be 
  2262. construed that their use is essential to the successful implementation of an 
  2263. object-oriented approach. 
  2264.  
  2265. It is quite possible to implement module-based object-oriented principles to a 
  2266. practical and beneficial degree in the Presentation Manager  environment, using 
  2267. a "conventional" programming language such as "C".  However, the degree of 
  2268. discipline and amount of work required of the application developer is greater 
  2269. when a standard programming language is used.  Object-oriented tools or 
  2270. language extensions make the task of the application developer much easier, 
  2271. since many of the object-oriented concepts are handled by the tools themselves, 
  2272. without the need for the developer to concern him/herself with the details of 
  2273. their implementation. 
  2274.  
  2275. Object-oriented programming tools fall into two general categories: 
  2276.  
  2277.    o  Those that provide extensions to an existing programming language and 
  2278.       implement certain object-oriented conventions, such as C++. These 
  2279.       languages typically provide object-oriented constructs but do not force 
  2280.       an application developer into the use of such constructs.  The strength 
  2281.       of such implementations is their flexibility, but they have the inherent 
  2282.       weakness that it is easy to develop application code that does not 
  2283.       conform to object-oriented programming practices. 
  2284.  
  2285.    o  Those that provide a complete programming language syntax, which obeys 
  2286.       and implements object-oriented principles, such as Smalltalk V**. These 
  2287.       languages provide an additional benefit in that they force the 
  2288.       application developer into obeying object-oriented programming practices, 
  2289.       but at the expense of flexibility. 
  2290.  
  2291.  The tools that are marketed as "object-oriented" and which are currently 
  2292.  available in the marketplace tend to implement the class-based approach to 
  2293.  object-oriented programming.  Their primary benefit is thus that they provide 
  2294.  an inheritance hierarchy, and so make the task of object creation much easier 
  2295.  for the application developer, albeit at the risk of reduced code efficiency 
  2296.  and possible dependence upon a conceptual run-time environment. 
  2297.  
  2298.  The choice of an object-oriented programming tool is very much an individual 
  2299.  one, and depends on the requirements and priorities of the development 
  2300.  organization, the skills and prior experience of the application developers 
  2301.  concerned, and the degree to which object-oriented practices are to be 
  2302.  enforced within the organization. 
  2303.  
  2304.  
  2305. ΓòÉΓòÉΓòÉ 11.5. More Complex Objects ΓòÉΓòÉΓòÉ
  2306.  
  2307. For relatively simple applications where a data object is retrieved, 
  2308. manipulated and saved again, the foregoing definition of an application object 
  2309. will suffice.  However, the situation often arises when an application must 
  2310. perform some processing that is rather more complicated. Either the application 
  2311. must interface with another system or external device or a certain work task 
  2312. must be performed in a particular sequence of operations that is critical to 
  2313. the correct completion of the task.  The incorporation of such requirements 
  2314. into the object-oriented paradigm requires an expansion of the application 
  2315. object concept. 
  2316.  
  2317. The key to successful expansion of the object-oriented paradigm lies in the 
  2318. definition of a data object. Whereas a data object was previously defined as a 
  2319. manifestation of a logical data entity, the definition will now be expanded to 
  2320. include any other type of logical entity or source of information, such as an 
  2321. external system or a procedures manual. 
  2322.  
  2323.  
  2324. ΓòÉΓòÉΓòÉ 11.5.1. Device Manipulation ΓòÉΓòÉΓòÉ
  2325.  
  2326. The entity represented by an application object may be a physical device. For 
  2327. example, suppose an application is required to access a particular type of 
  2328. external data input device such as an MICR reader.  The definition of the 
  2329. protocols and specialized access routines necessary to interact with such a 
  2330. device can be encapsulated within an application object, and the various 
  2331. actions performed by the device on behalf of the application (such as getting 
  2332. the next MICR document) then become the methods associated with that object. 
  2333. The application thus regards the MICR reader as an object to which it passes 
  2334. messages in order to perform actions; the results of those actions are then 
  2335. conveyed back to the application, also by way of messages. 
  2336.  
  2337.  
  2338. ΓòÉΓòÉΓòÉ 11.5.2. Access to Remote Systems ΓòÉΓòÉΓòÉ
  2339.  
  2340. The representation of a physical device as an application object may be 
  2341. extended to encompass any external entity with which an application must 
  2342. interact.  Suppose that an application executing in a programmable workstation 
  2343. must interface with a number of server applications executing in a System/370 
  2344. host, using the SRPI interface.  The host system may be regarded as a logical 
  2345. entity, and a single application object created to interact with that entity. 
  2346. All communications-related and interface-specific code may then be encapsulated 
  2347. within that object, and other objects within the application need not concern 
  2348. themselves with the details of the SRPI communication.  A message passed to the 
  2349. application object by a requesting object elsewhere in the application will 
  2350. contain the name of the server application to be invoked, and the data to be 
  2351. passed to the server application.  A return message from the host-interaction 
  2352. object will contain the reply data from the server application. Encapsulation 
  2353. of Host Interaction Within Application Object 
  2354.  
  2355. The isolation of programming interfaces and protocols specific to the 
  2356. communications architecture, within the "Host" application object provides an 
  2357. easy means of insulating the remainder of the application from changes to 
  2358. communications network configurations or to the remote system itself.  Such 
  2359. changes would only require modification to the "Host" object. 
  2360.  
  2361.  
  2362. ΓòÉΓòÉΓòÉ 11.5.3. Procedure Manuals ΓòÉΓòÉΓòÉ
  2363.  
  2364. An administrative procedure, which is merely a set of information that 
  2365. documents the way in which a task must be performed, may also be regarded as a 
  2366. procedural entity that may be encapsulated in an application object. Such an 
  2367. application object typically contains a small number of methods, and may 
  2368. possibly contain only one. 
  2369.  
  2370. In the case of an object that contains only a single method and merely accepts 
  2371. data from a calling application object rather than possessing data objects of 
  2372. its own, the object may be regarded as simply a method rather than an 
  2373. application object in its own right.  Where it is desirable to invoke the 
  2374. procedure from a number of applications, the procedure may be placed in a 
  2375. separate executable module and dynamically bound to its calling applications, 
  2376. thereby maintaining independence of the procedure from the applications. 
  2377.  
  2378. A message is passed to the application object identifying the action to be 
  2379. performed and providing the necessary input data.  The application object will 
  2380. then typically carry out a modal dialog (or possibly a series of dialogs) with 
  2381. the end user to obtain any further information, leading the user through the 
  2382. necessary steps in the required order.  When the procedure has been completed, 
  2383. the application object terminates the dialog and possibly passes a message to 
  2384. its caller or to another application object, containing an acknowledgement of 
  2385. completion, or information collected during the procedure.  Where completion of 
  2386. a method is mandatory to correct execution of the application, this 
  2387. acknowledgement of completion provides a useful mechanism for the caller to 
  2388. determine that the method has been successfully executed. 
  2389.  
  2390. If such procedures are correctly defined at a generic level (for example, Enter 
  2391. the customer data), their application objects may be stored in a library and 
  2392. used by multiple applications.  More complex procedures may be constructed 
  2393. within an application by invoking a number of such application objects in 
  2394. sequence.  Acknowledgement messages from the application objects can be used to 
  2395. verify that the required steps have taken place. 
  2396.  
  2397. Thus it can be seen that the object-oriented paradigm, when the definition of a 
  2398. data object is sufficiently expanded to include all types of logical entity, 
  2399. and when properly applied with correctly designed application objects obeying 
  2400. the aforementioned rules and guidelines, is generally applicable to almost all 
  2401. applications.  A wide variety of applications may therefore achieve the 
  2402. modularization and reusability benefits afforded by an object-oriented design 
  2403. approach. 
  2404.  
  2405.  
  2406. ΓòÉΓòÉΓòÉ 11.6. Summary ΓòÉΓòÉΓòÉ
  2407.  
  2408. It can be seen from the foregoing discussion that the object-oriented paradigm 
  2409. is a logical consequence of the move toward data-centered application design. 
  2410. An object-oriented approach provides many benefits for applications which 
  2411. manipulate data, not the least of which is the ability to implement an 
  2412. intuitive, event-driven user interface where the user manipulates a number of 
  2413. conceptual objects in a metaphorical manner that mirrors the "real-life" 
  2414. manipulation of those objects. 
  2415.  
  2416. It should be stressed however, that object-oriented programming is not 
  2417. necessarily suited to all applications; its use is recommended only where data 
  2418. is the central factor in the application's task.  There may be situations where 
  2419. the procedure, rather than the data, is necessarily the focus of the 
  2420. application, or where an event-driven style of user interface is not 
  2421. appropriate to the task being performed.  In such cases, traditional structured 
  2422. programming techniques hold advantages over object-oriented programming. 
  2423. However, in situations where only a portion of the work task is procedurally 
  2424. oriented, it is possible for the two approaches to coexist within the same 
  2425. application. 
  2426.  
  2427. Object-oriented programming focuses on the principles of data abstraction and 
  2428. encapsulation, with all access to a data object being controlled by the 
  2429. application object which "owns" that data object.  This principle allows the 
  2430. object-oriented approach to facilitate the creation of reusable application 
  2431. objects, since the interface to an object is defined only by the messages it 
  2432. receives and dispatches.  The implementation details of the data objects or 
  2433. methods belonging to an application object are typically transparent to other 
  2434. application objects.  Thus the effects of changes to these data objects or 
  2435. methods may be contained within a single application object, easing the task of 
  2436. change management and application maintenance. 
  2437.  
  2438. A distinction must also be drawn between an object-oriented application design 
  2439. and an event-driven, object-action user interface.  The two concepts are 
  2440. complimentary in that the provision of a truly event-driven interface for the 
  2441. end user is dependent upon the application being designed and implemented 
  2442. according to object-oriented principles.  However, while the two concepts are 
  2443. complimentary, they are not identical and the difference must be borne in mind 
  2444. when designing an application. 
  2445.  
  2446. Object-oriented application design begins with a definition of logical data 
  2447. entities and their representations (data objects) in the system.  Once these 
  2448. data objects are defined, the actions relevant to each may be determined, and 
  2449. the design of the messages to convey each action and the methods necessary to 
  2450. achieve the actions may be undertaken.  The definition of messages and actions 
  2451. completes the high-level design of the application, and traditional functional 
  2452. decomposition techniques may then be applied to designing and developing the 
  2453. individual methods.  The independent nature of application objects and of the 
  2454. methods within an object facilitates modularization of the application, and 
  2455. allows the design, development and testing of the methods for each object to 
  2456. take place independently of the methods for other objects. 
  2457.  
  2458. A number of programming languages and tools exist which implement 
  2459. object-oriented programming practices to varying degrees.  These may exist in 
  2460. the form of object-oriented extensions to an existing programming language, or 
  2461. as complete programming languages in their own right.  The degree to which 
  2462. these products enforce object-oriented practices also varies from one product 
  2463. to the next.  It should be stressed however, that the implementation of 
  2464. object-oriented techniques in application design and development is not 
  2465. dependent upon the use of any particular tool or programming language, but 
  2466. rather depends on the correct application of object-oriented design concepts. 
  2467. When such concepts are correctly applied in the design of an application, it is 
  2468. quite possible to develop object-oriented applications in conventional 
  2469. programming languages such as "C".  The difference lies in the amount of 
  2470. latitude given to the individual application developer with respect to the 
  2471. interpretation of object-oriented principles. 
  2472.  
  2473. It may be argued with some justification, that according to many 
  2474. popularly-accepted definitions, the techniques offered in this chapter do not 
  2475. constitute a truly object-oriented application model.  However, such concepts 
  2476. as a full inheritance hierarchy are not directly supported by execution 
  2477. environments such as Presentation Manager, and are difficult to provide without 
  2478. the use of additional object-oriented programming tools.  It must be stressed 
  2479. that the methodology outlined herein is not intended to be a purist 
  2480. implementation of the full object-oriented paradigm, but is intended to 
  2481. illustrate the application of certain object-oriented principles to the design 
  2482. and implementation of Presentation Manager  applications, in accordance with 
  2483. the module-based approach to object-oriented programming. 
  2484.  
  2485. These principles, when applied to the Presentation Manager environment, afford 
  2486. significant enhancements in the areas of code reusability and application 
  2487. modularity, and subsequent benefits with respect to reduced development time 
  2488. and effort, and easier application maintenance and change management. 
  2489. Additional tools may be utilized to apply further object-oriented principles to 
  2490. Presentation Manager application design, in order to achieve the benefits 
  2491. associated with a class-based approach to object-oriented programming. However, 
  2492. such tools typically have additional drawbacks that must be weighed against 
  2493. their advantages, with regard to the specific development scenario. 
  2494.  
  2495.  
  2496. ΓòÉΓòÉΓòÉ 12. The Presentation Manager Application Model ΓòÉΓòÉΓòÉ
  2497.  
  2498. The Presentation Manager environment lends itself to the implementation of 
  2499. object-oriented programs under the module-based approach to object-oriented 
  2500. design.  Presentation Manager provides far more than merely a means of 
  2501. displaying information on the screen.  It implements an event-driven, 
  2502. object-based application execution environment and provides many services 
  2503. required for the definition and manipulation of application objects and 
  2504. messages. 
  2505.  
  2506. This chapter will examine the execution environment provided by Presentation 
  2507. Manager, describe the structure of a Presentation Manager application, and 
  2508. illustrate the implementation of basic object-oriented concepts in the 
  2509. Presentation Manager environment. 
  2510.  
  2511.  
  2512. ΓòÉΓòÉΓòÉ 12.1. Windows ΓòÉΓòÉΓòÉ
  2513.  
  2514. A window is the embodiment of an application object within the Presentation 
  2515. Manager application model.  To the end user, a window appears as a rectangular 
  2516. display area on the screen.  From an application viewpoint however, the concept 
  2517. of a window is far more powerful than this. Windows may be of two basic types: 
  2518.  
  2519.    o  Display windows have a physical identity represented by a rectangular 
  2520.       area on a screen; in this case the window represents a view of a 
  2521.       conceptual display surface known as a presentation space, which is in 
  2522.       fact a data entity being represented on the screen.  This is the average 
  2523.       end user's concept of a window. 
  2524.  
  2525.    o  Object windows have no physical manifestation, and are merely addresses 
  2526.       or "handles" to which messages may be directed.  An object window is 
  2527.       typically associated with an entity such as a file or database, and is 
  2528.       used to access this entity and perform actions upon it.  The object 
  2529.       window concept is very important to the implementation of object-oriented 
  2530.       principles under Presentation Manager, since it enables the creation of 
  2531.       non-visual objects within the Presentation Manager application model. 
  2532.       See Object Windows for further information. 
  2533.  
  2534.  Windows respond to events, communicated by way of messages, which may 
  2535.  originate from Presentation Manager as a result of user interaction, or from 
  2536.  other windows existing in the system.  Messages are routed to and between 
  2537.  windows by Presentation Manager on behalf of the application.  Windows may 
  2538.  interpret and process messages in different ways, in accordance with the 
  2539.  concept of polymorphism. 
  2540.  
  2541.  Each window existing in the system has a unique identifier known as its window 
  2542.  handle, which is assigned by Presentation Manager when the window is created. 
  2543.  This handle is used to identify a window in all communication between that 
  2544.  window and other parties, such as Presentation Manager or the user.  The 
  2545.  window handle is specified as the destination address used when passing 
  2546.  messages to a window.  See Messages for further discussion of Presentation 
  2547.  Manager messages.  A window is always aware of its own handle, since the 
  2548.  handle is part of every message passed to the window.  Presentation Manager 
  2549.  provides a number of mechanisms by which a window may determine the handles of 
  2550.  other windows in the system in order to pass messages to those windows; these 
  2551.  mechanisms are described in Window Communication. 
  2552.  
  2553.  
  2554. ΓòÉΓòÉΓòÉ 12.1.1. Window Classes ΓòÉΓòÉΓòÉ
  2555.  
  2556. Since many windows may be in existence at any time, windows having similar 
  2557. properties and behavior are grouped into window classes, with each window 
  2558. belonging to a class being an instance of that class. Window classes may be 
  2559. public (defined by Presentation Manager and usable by all applications in the 
  2560. system) or private (defined by the application and accessible only by that 
  2561. application unless an application developer decides otherwise; see Creating 
  2562. Reusable Code).  Private window classes are registered to Presentation Manager 
  2563. by the application upon initialization of the application. 
  2564.  
  2565. Presentation Manager maintains control information relating to each window 
  2566. created in the system, including properties such as window text, current size 
  2567. and location, etc.  In addition to this information, an application may specify 
  2568. an additional area of storage to be included within the window control block 
  2569. for application data relating to that window.  This storage is known as window 
  2570. words. The presence and size of window words is determined for each window 
  2571. class at the time the class is registered to Presentation Manager.  However, a 
  2572. new storage area is defined for each instance of the class, and window words 
  2573. may therefore be used for instance data. Window words typically contain 
  2574. pointers to dynamically-defined application data structures, which in turn 
  2575. contain the instance data. 
  2576.  
  2577.  
  2578. ΓòÉΓòÉΓòÉ 12.1.2. Window Procedures ΓòÉΓòÉΓòÉ
  2579.  
  2580. Each window class is associated with a window procedure, which defines and/or 
  2581. establishes access to data objects and performs processing related to that 
  2582. window class.  In object-oriented terms, the window procedure contains the 
  2583. methods to carry out actions upon the data object referenced by the window. 
  2584.  
  2585. A window procedure is normally invoked by Presentation Manager on behalf of the 
  2586. application.  The window procedure interprets messages passed by Presentation 
  2587. Manager  to the window and invokes a method (that is, a coherent set of 
  2588. application statements and/or routines) depending on the nature and contents of 
  2589. the message. 
  2590.  
  2591. See Window Procedures for a more complete discussion of window procedures' 
  2592. structure and behavior. 
  2593.  
  2594.  
  2595. ΓòÉΓòÉΓòÉ 12.2. Messages ΓòÉΓòÉΓòÉ
  2596.  
  2597. All interaction between the user and windows, or between one window and another 
  2598. in the Presentation Manager environment, takes place by way of messages. 
  2599. Whenever the user presses a key, moves or clicks the mouse, selects an item 
  2600. from a menu, etc., a message is generated and placed on a system message queue. 
  2601. Presentation Manager takes these messages in the order they were received by 
  2602. the system, determines the window for which each message is intended, and 
  2603. routes the message to a message queue belonging to the application that "owns" 
  2604. that window.  The application then dequeues each message in turn, and routes 
  2605. the message via Presentation Manager to the window procedure associated with 
  2606. that window, which processes the message. 
  2607.  
  2608. Messages may be of three types: 
  2609.  
  2610.    o  User-initiated; that is, the message is generated as the result of the 
  2611.       user selecting an action-bar item, pressing a key, etc. 
  2612.  
  2613.    o  Application-initiated; that is, the message is generated by one window 
  2614.       within the application for the communication of an event or required 
  2615.       action to another window. 
  2616.  
  2617.    o  System-initiated; that is, the message is generated by Presentation 
  2618.       Manager as the result of some system event such as a window having been 
  2619.       resized or moved. 
  2620.  
  2621.  A Presentation Manager application has the ability to process messages of any 
  2622.  of the three types, which allows the application to respond to any type of 
  2623.  event, regardless of its origin. 
  2624.  
  2625.  
  2626. ΓòÉΓòÉΓòÉ 12.2.1. Message Classes ΓòÉΓòÉΓòÉ
  2627.  
  2628. Messages are grouped into message classes, with each class representing a 
  2629. particular type of event such as character input, mouse movement, etc.  Many 
  2630. message classes are defined by Presentation Manager, and messages of these 
  2631. classes are usually dispatched by Presentation Manager to inform an application 
  2632. of system-initiated events.  These system-defined message classes are 
  2633. described, along with the default processing provided by Presentation Manager 
  2634. for each class, in the IBM OS/2 Version 2.0 Presentation Manager Reference. 
  2635.  
  2636. An application developer may define additional message classes unique to his or 
  2637. her particular application, for use by that application. Application-defined 
  2638. messages typically serve as a means of communication between windows, where one 
  2639. window passes information to another window, for processing by the window 
  2640. procedure associated with that window.  The destination window may then return 
  2641. a message to the calling window indicating completion, or may pass a message to 
  2642. a third window to trigger an additional action, dependent upon the requirements 
  2643. and design of the application. 
  2644.  
  2645. For example, the user may elect to update a file by selecting an item from a 
  2646. menu bar.  The window procedure associated with the display window to which the 
  2647. menu bar belongs may pass a message to an object window associated with the 
  2648. file to be updated.  The window procedure for this window would make the change 
  2649. and then pass a message to a third object window, which logs the update before 
  2650. passing a message back to the original window procedure indicating that the 
  2651. update is complete. 
  2652.  
  2653. Note that message classes need not be specific to a particular window class; 
  2654. messages of the same class may be passed to different window classes, with 
  2655. different results depending upon the processing of that message by the window 
  2656. procedure belonging to that window class.  This is in accordance with the 
  2657. object-oriented principle of polymorphism. 
  2658.  
  2659.  
  2660. ΓòÉΓòÉΓòÉ 12.2.2. Message Structure ΓòÉΓòÉΓòÉ
  2661.  
  2662. In order to allow any window the ability to process any message class, 
  2663. Presentation Manager  defines a standard format for messages.  In the 
  2664. Presentation Manager environment, a message is composed of four distinct 
  2665. attributes: 
  2666.  
  2667.    o  A window handle identifying the window for which the message is intended 
  2668.  
  2669.    o  A message ID identifying the particular class of message 
  2670.  
  2671.    o  Two message parameters, which are 32-bit fields containing a variety of 
  2672.       information, depending upon the class of message received. 
  2673.  
  2674.  All Presentation Manager applications must contain a message processing loop, 
  2675.  which receives the message from Presentation Manager (see Application 
  2676.  Structure), and routes it, using Presentation Manager message-dispatching 
  2677.  functions, to the appropriate window procedure for processing.  Thus 
  2678.  Presentation Manager actually invokes the window procedure on the 
  2679.  application's behalf. 
  2680.  
  2681.  
  2682. ΓòÉΓòÉΓòÉ 12.2.2.1. Message Identifier ΓòÉΓòÉΓòÉ
  2683.  
  2684. The message ID identifies the message class to which each message belongs, and 
  2685. is in fact an integer value which is typically replaced by a symbolic name for 
  2686. ease of use.  The symbolic names for all system-defined message classes are 
  2687. defined by Presentation Manager; symbolic names for application-defined 
  2688. (private) message classes must be declared by the application developer in the 
  2689. application's source code.  This is typically achieved by declaring an integer 
  2690. constant, the value of which is specified as an offset from the system-defined 
  2691. value WM_USER.  For example: 
  2692.  
  2693. #define WMP_MYMESSAGE     WM_USER+6
  2694.  
  2695. The use of an offset to a system-defined constant, rather than an absolute 
  2696. numeric value, eliminates the chance of using the same integer value as a 
  2697. system-defined message class (with consequently unpredictable results), and 
  2698. avoids the necessity to alter application code should the number or definition 
  2699. of system-defined message classes be altered in future versions of Presentation 
  2700. Manager. 
  2701.  
  2702.  
  2703. ΓòÉΓòÉΓòÉ 12.2.2.2. Message Parameters ΓòÉΓòÉΓòÉ
  2704.  
  2705. As noted above, message parameters may contain a variety of information.  When 
  2706. used for communication between window procedures, the window handle of the 
  2707. calling window may be passed to the destination window as one of the message 
  2708. parameters, in order that the destination window procedure may dispatch an 
  2709. acknowledgement or reply message to the calling window.  Qualifiers to the 
  2710. message type or small items of data may also be passed; for example, the 
  2711. Presentation Manager-defined WM_COMMAND message class (indicating a menu 
  2712. selection by the user) uses the first message parameter to identify the menu 
  2713. item selected. 
  2714.  
  2715. When large data structures are required to be passed between window procedures, 
  2716. and the data obviously cannot be contained within the two 32-bit message 
  2717. parameters, the convention is to allocate a memory object for the required data 
  2718. structure using the DosAllocMem() function, and to pass a pointer to that 
  2719. memory object as a parameter to the message.  Presentation Manager provides a 
  2720. number of macros to enable various types of data to be placed into and 
  2721. retrieved from message parameters.  The insertion and retrieval of data into 
  2722. and from message parameters is described in Creating Message Parameters. 
  2723.  
  2724.  
  2725. ΓòÉΓòÉΓòÉ 12.2.3. Message Processing ΓòÉΓòÉΓòÉ
  2726.  
  2727. Messages passed to a window may be processed in one of two basic ways: 
  2728.  
  2729.    o  Synchronously, in which case the message is passed directly to the target 
  2730.       window and is processed immediately; the window from which the message 
  2731.       originated suspends its execution until the message is processed. 
  2732.  
  2733.    o  Asynchronously, in which case the message is placed on a queue from which 
  2734.       it is subsequently retrieved and passed to the target window; the window 
  2735.       from which the message originated continues execution immediately after 
  2736.       the message is placed on the queue. 
  2737.  
  2738.  Synchronous and asynchronous processing are described in more detail in 
  2739.  Invoking a Window Procedure. 
  2740.  
  2741.  A message may also be dispatched to multiple windows at the same time, using 
  2742.  the message broadcasting facilities provided by the Presentation Manager 
  2743.  programming interface.  Broadcasting may be either synchronous or 
  2744.  asynchronous.  The implementation of message broadcasting is discussed in more 
  2745.  depth in Window Communication. 
  2746.  
  2747.  Messages that are not explicitly processed by an application in its window 
  2748.  procedures are passed to a default window procedure supplied by Presentation 
  2749.  Manager, which contains default processing for all message classes (in the 
  2750.  case of application-defined message classes, this default window procedure 
  2751.  simply ignores the message).  This technique is in accordance with the 
  2752.  principle of inheritance, in that a window procedure only contains methods for 
  2753.  those message classes with which it is directly concerned, and allows other 
  2754.  messages to be processed by the existing default window procedure.  Default 
  2755.  processing for each message class is described in the IBM OS/2 Version 2.0 
  2756.  Presentation Manager Reference. 
  2757.  
  2758.  For message classes that are processed by the application's window procedures, 
  2759.  the last operation in the message processing should be to provide a return 
  2760.  code to Presentation Manager.  In many cases, this return code determines 
  2761.  whether Presentation Manager performs its default message processing, after 
  2762.  the application's own message processing is complete.  The default message 
  2763.  processing may or may not be desirable, depending upon application 
  2764.  requirements.  This ability allows system-initiated events to be easily 
  2765.  detected and trapped by a Presentation Manager, enabling the application to 
  2766.  perform its own processing for the event before allowing the default 
  2767.  processing to occur. 
  2768.  
  2769.  
  2770. ΓòÉΓòÉΓòÉ 12.3. Application Structure ΓòÉΓòÉΓòÉ
  2771.  
  2772. All Presentation Manager applications have a similar structure.  The 
  2773. application is composed of a main routine, which performs initialization and 
  2774. termination functions, and which contains the application's main message 
  2775. processing loop, and a number of window procedures that process messages for 
  2776. window classes created and/or used by the application.  These window procedures 
  2777. are invoked and messages passed to them by Presentation Manager on behalf of 
  2778. the application, as shown in Message Flow in a Presentation Manager 
  2779. Application. Message Flow in a Presentation Manager Application 
  2780.  
  2781. Window procedures may also pass messages between one another in order to 
  2782. communicate events.  The flow of messages between the window procedures is also 
  2783. controlled by Presentation Manager on behalf of the application. 
  2784.  
  2785.  
  2786. ΓòÉΓòÉΓòÉ 12.3.1. Main Routine ΓòÉΓòÉΓòÉ
  2787.  
  2788. The main processing routine of a Presentation Manager application performs a 
  2789. number of initialization and termination functions for the application, as 
  2790. shown in Structure of an Application's Main Routine. 
  2791.  
  2792. int main()
  2793. {
  2794.   <Global data declarations>
  2795.  
  2796.   hAB  = WinInitialize(...);      /* Register application  */
  2797.   hMsgQ = WinCreateMsgQueue(...);    /* Create message queue  */
  2798.  
  2799.   WinRegisterClass(...);         /* Register window class  */
  2800.        :
  2801.   hFrame  = WinCreateWindow(...);    /* Create frame window   */
  2802.   hClient = WinCreateWindow(...);    /* Create client window  */
  2803.  
  2804.   WinAddSwitchEntry(...);        /* Add task manager entry */
  2805.  
  2806.   while (WinGetMsg(...))         /* Loop until WM_QUIT   */
  2807.      WinDispatchMsg(...);
  2808.  
  2809.   WinRemoveSwitchEntry(...);       /* Remove task mgr entry  */
  2810.  
  2811.   WinDestroyWindow(hFrame);       /* Destroy main window   */
  2812.   WinDestroyMsgQueue(hMsgQ);       /* Destroy message queue  */
  2813.   WinTerminate(hAB);           /* Deregister application */
  2814. }
  2815. Structure of an Application's Main Routine 
  2816.  
  2817. The application's main routine registers the application to Presentation 
  2818. Manager, creates the application's message queue and defines private window and 
  2819. message classes for the application before actual processing takes place. 
  2820. Other application-specific initialization processing may also take place at 
  2821. this time, such as the definition of global data items.  Note however, that the 
  2822. use of global data increases the interdependence of application modules and 
  2823. reduces the potential for subsequent code reuse.  Hence global data should be 
  2824. avoided wherever possible. 
  2825.  
  2826. The main routine also creates the application's main window.  Note that from an 
  2827. application viewpoint, a display window is actually a group of windows that 
  2828. appear and behave as a single unit.  Therefore the frame (with its associated 
  2829. title bar, menu bar, etc.) and the client areas are created separately, as 
  2830. shown in Structure of an Application's Main Routine.  This concept is explained 
  2831. in more detail in Window Hierarchy. 
  2832.  
  2833. During execution of the application, the only function of the main routine is 
  2834. to accept messages from the system queue and route them to window procedures 
  2835. via Presentation Manager.  This is performed using a message processing loop, 
  2836. which continues until a message of the system-defined class WM_QUIT is 
  2837. received, at which point the loop terminates and allows the application's 
  2838. termination processing to occur. 
  2839.  
  2840. Upon termination of the application, the main routine destroys any remaining 
  2841. windows, along with the application's message queue, and deregisters the 
  2842. application before terminating.  Any global data items acquired during 
  2843. initialization are also released at this time. 
  2844.  
  2845. When the user selects "Exit" from the menu bar, or selects the "Close" option 
  2846. on the system menu of the application's main window, the application is not 
  2847. automatically terminated.  These messages are passed to the window procedure 
  2848. for that window, and may be processed by the application.  The typical action 
  2849. performed by the window procedure in such cases is that a message of class 
  2850. WM_QUIT is posted to the application's message queue, which causes the message 
  2851. processing loop to terminate.  Conventions for closing windows and terminating 
  2852. applications are discussed further in Window Closure. 
  2853.  
  2854. Since Presentation Manager actually informs the application that it is being 
  2855. terminated rather than simply shutting the application down, the application is 
  2856. given a chance to perform any necessary termination processing and exit in an 
  2857. orderly manner.  When a window is destroyed, it receives a WM_DESTROY message 
  2858. from Presentation Manager, which may be processed by the window procedure to 
  2859. allow orderly termination of processing.  This enables the preservation of data 
  2860. integrity by Presentation Manager applications, which need not rely on the user 
  2861. completing a logical unit of work before terminating; any uncompleted units of 
  2862. work may be placed in an interim storage area on disk, or simply backed out as 
  2863. part of the WM_DESTROY message processing. 
  2864.  
  2865. This feature is also used by the "Shutdown" procedure of the Workplace Shell. 
  2866. When the user selects "Shutdown" from the menu bar, Presentation Manager posts 
  2867. a WM_QUIT message to the main window of each application executing in the 
  2868. system, informing the application that it is being terminated and allowing any 
  2869. termination processing to take place.  This facility allows for an orderly 
  2870. shutdown of the system and preserves the integrity of data objects. 
  2871.  
  2872.  
  2873. ΓòÉΓòÉΓòÉ 12.3.2. Window Procedures ΓòÉΓòÉΓòÉ
  2874.  
  2875. It has already been mentioned that each window class within an application, 
  2876. whether a display window or an object window, is associated with a window 
  2877. procedure, which receives all messages intended for windows within that class. 
  2878. The window procedure contains the methods used to perform actions upon the data 
  2879. object to which the window pertains, and thus contains the application logic 
  2880. for the manipulation of data objects.  It may thus be said that window 
  2881. procedures form the "heart" of a Presentation Manager  application. 
  2882.  
  2883. Upon invocation, the window procedure determines the type of message passed to 
  2884. it, and may either process the message explicitly or pass it on to a default 
  2885. window procedure supplied by Presentation Manager for standard processing.  A 
  2886. window procedure is essentially an extended CASE statement, as illustrated in 
  2887. Structure of a Window Procedure.  Each case within the window procedure 
  2888. contains a set of application statements and/or routines necessary to perform a 
  2889. particular action.  Thus in object-oriented terminology, each case is a method 
  2890. in its own right. 
  2891.  
  2892. MRESULT EXPENTRY wpMain(HWND hWnd, ULONG ulMsg, MPARAM mp1, MPARAM mp2)
  2893. {
  2894.     switch (ulMsg)
  2895.         {
  2896.         case WM_CREATE:
  2897.           WinDefWindowProc(hWnd, ulMsg, mp1, mp2);
  2898.           <perform initialization of instance variables>
  2899.           <define, create or establish access to data objects>
  2900.           return((MRESULT)FALSE);
  2901.           break;
  2902.         case WM_COMMAND:
  2903.           <determine command by examining message parameters>
  2904.           <perform processing for menu command>
  2905.           return((MRESULT)0);
  2906.           break;
  2907.         case WM_HELP:
  2908.           <perform help processing>
  2909.           return((MRESULT)0);
  2910.           break;
  2911.            :
  2912.            :
  2913.         case WM_DESTROY:
  2914.           <back out any incomplete updates>
  2915.           <close all open data objects>
  2916.           return((MRESULT)0);
  2917.           break;
  2918.         default:
  2919.           return((MRESULT)WinDefWindowProc(hWnd,
  2920.                            ulMsg,
  2921.                            mp1,
  2922.                            mp2));
  2923.           break;
  2924.         }
  2925. }
  2926. Structure of a Window Procedure 
  2927.  
  2928. A window procedure is declared to return the type MRESULT, which is a 32-bit 
  2929. data type declaration provided by Presentation Manager, and indicates the 
  2930. nature of the window procedure's return value. Note that in the above example, 
  2931. the returned values differ depending upon the message class; see Returning from 
  2932. a Window Procedure for further discussion.  Note also that in the default case 
  2933. shown in Structure of a Window Procedure, the window procedure did not decide 
  2934. the return value itself, but used the value returned by the Presentation 
  2935. Manager-supplied default window procedure. This is an established Presentation 
  2936. Manager convention. 
  2937.  
  2938. A window procedure should always be declared with the system linkage 
  2939. convention; this is typically achieved by declaring the function to be of type 
  2940. EXPENTRY.  This type identifier is defined in the system header file OS2DEF.H, 
  2941. and simply specifies use of the system linkage convention.  Use of the system 
  2942. linkage convention is required since a window procedure is invoked by 
  2943. Presentation Manager on the application's behalf, rather than directly by the 
  2944. application.  Note that under previous versions of OS/2, the EXPENTRY keyword 
  2945. resulted in use of the pascal linkage convention, for precisely the same 
  2946. reason. 
  2947.  
  2948. Subject to programming language conventions, a window procedure has the ability 
  2949. to define a data object or instance data, or to establish access to an existing 
  2950. data object as part of its initialization processing.  When a window is created 
  2951. by Presentation Manager in response to an application's request, Presentation 
  2952. Manager immediately dispatches a message of the system-defined class WM_CREATE 
  2953. to that window (see Structure of a Window Procedure).  The window procedure may 
  2954. process this message in order to define instance data or establish access to 
  2955. data objects.  Typically, a window procedure requests the allocation of a 
  2956. memory object as a control block for its instance data.  Initial values for the 
  2957. instance data are then placed in the control block, and a pointer to the 
  2958. control block is stored in the window words.  A window procedure thus supports 
  2959. the object-oriented concept of encapsulation, by allowing the dynamic 
  2960. allocation of and establishment of access to data objects, within a single 
  2961. application object. 
  2962.  
  2963. Note that prior to allocating instance data or performing any other processing 
  2964. for the WM_CREATE message, a window procedure should invoke the default message 
  2965. processing provided by Presentation Manager in the WinDefWindowProc() function. 
  2966. This ensures that the initialization of Presentation Manager's control data for 
  2967. the window is completed prior to WM_CREATE processing by the window procedure. 
  2968. This in turn ensures that the window handle, window words, etc., will be 
  2969. available during the window procedure's WM_CREATE processing. 
  2970.  
  2971.  
  2972. ΓòÉΓòÉΓòÉ 12.3.2.1. Invoking a Window Procedure ΓòÉΓòÉΓòÉ
  2973.  
  2974. A window procedure is invoked by dispatching a message to a window of the class 
  2975. with which the window procedure is associated.  Messages passed to a window are 
  2976. typically initiated as the result of user interaction or application events, or 
  2977. by Presentation Manager to indicate system events. 
  2978.  
  2979. While window procedures may be invoked directly using a normal subroutine call, 
  2980. it is recommended that messages be used for all communication between window 
  2981. procedures.  This conforms to standard object-oriented practice, in that an 
  2982. object should be accessible only via a message passed to it. 
  2983.  
  2984. Messages may be used to invoke a window procedure in two ways: 
  2985.  
  2986.    o  A message may be sent directly to the window procedure using the 
  2987.       WinSendMsg() call, in which case the window procedure executes 
  2988.       synchronously, and control does not return to the calling procedure until 
  2989.       processing is completed.  This method of invocation is similar to a 
  2990.       normal subroutine call, but preserves the message-driven structure of the 
  2991.       application.  Note that since the message is sent directly to the window 
  2992.       procedure and not placed on a queue, the normal serialization of message 
  2993.       processing is disturbed.  This may cause different results from those 
  2994.       intended by the user; thus WinSendMsg() should be used with care. 
  2995.  
  2996.    o  A window procedure may also be invoked by posting a message to a queue 
  2997.       associated with the window procedure, using the WinPostMsg() call.  With 
  2998.       this call the window procedure executes asynchronously, and control 
  2999.       returns to the calling procedure immediately after the message is placed 
  3000.       in the queue.  This method of invocation provides a convenient and 
  3001.       powerful means for serialized and yet asynchronous processing.  It then 
  3002.       becomes the responsibility of the application developer to ensure 
  3003.       synchronization between different window procedures. 
  3004.  
  3005.  Invoking a window procedure by posting a message to it via a queue has an 
  3006.  advantage over the use of WinSendMsg() or a direct subroutine call in that, 
  3007.  where multiple windows are passing messages to a single receiving window, 
  3008.  these messages are queued by Presentation Manager and dispatched to the 
  3009.  receiving object in the order in which they were initiated.  Provided all 
  3010.  sending windows obey the established conventions and post messages to queues, 
  3011.  this ensures the correct sequencing of message processing by the receiving 
  3012.  window, helps preserve the user's intention and facilitates maintaining the 
  3013.  integrity of data objects. 
  3014.  
  3015.  A window procedure accepts four parameters upon invocation; these correspond 
  3016.  to the four attributes of a message as described in Messages and to the 
  3017.  parameters of the WinSendMsg() and WinPostMsg() functions, and are as follows: 
  3018.  
  3019.    1. The handle of the window for which the message was intended 
  3020.  
  3021.    2. A message-class identifier 
  3022.  
  3023.    3. Two 32-bit message parameters. 
  3024.  
  3025.  Note that the behavior of a window procedure, and the result obtained from 
  3026.  processing by a window procedure, are dependent upon the class and contents of 
  3027.  the message sent to it.  Similarly, the same message class may be interpreted 
  3028.  in a different manner by window procedures belonging to different window 
  3029.  classes.  In this way, a window procedure supports the object-oriented concept 
  3030.  of polymorphism. 
  3031.  
  3032.  
  3033. ΓòÉΓòÉΓòÉ 12.3.2.2. Window Procedure Processing ΓòÉΓòÉΓòÉ
  3034.  
  3035. A window procedure will normally determine the message class, and take action 
  3036. based upon that class and the contents of the message parameters.  Where the 
  3037. action involves the manipulation of data objects and/or instance data, the 
  3038. window procedure typically obtains access to the window's control block by 
  3039. retrieving its pointer from the window words.  The window procedure then has 
  3040. access to the data values, resource handles, etc., required to complete the 
  3041. action. 
  3042.  
  3043. Note that the example given earlier in this chapter contains explicit 
  3044. processing options for only four types of messages; the application allows 
  3045. Presentation Manager to handle all other types of messages, by passing the 
  3046. message to the system-supplied default window procedure using the 
  3047. WinDefWindowProc() function.  This illustrates one of the basic principles of a 
  3048. Presentation Manager application; the window procedure processes only those 
  3049. messages with which it is explicitly concerned, and passes all other messages 
  3050. to Presentation Manager for default processing.  A window procedure must pass 
  3051. such messages on to Presentation Manager, or unpredictable results may occur. 
  3052.  
  3053. This "catchall" approach to implementation also allows the stepwise 
  3054. implementation of methods during application development.  An application 
  3055. developer may code a window procedure such that all command messages are, by 
  3056. default, passed to a routine that displays a message informing the user that 
  3057. the requested action is not yet implemented.  As the method for each action is 
  3058. designed and coded, a case for that action may be added to the window 
  3059. procedure.  Thus implementation of methods for an object proceeds in a stepwise 
  3060. and independent fashion until all necessary methods are implemented. 
  3061.  
  3062. As mentioned earlier in this chapter and illustrated in Structure of a Window 
  3063. Procedure, a window procedure may process messages of any type, including the 
  3064. WM_DESTROY message, which is posted to a window upon termination.  A window 
  3065. procedure may explicitly process this message in order to close files and 
  3066. terminate access to data objects in an orderly manner, thus preserving the 
  3067. integrity of those data objects.  This ability allows the window procedure to 
  3068. further support the principle of encapsulation. 
  3069.  
  3070.  
  3071. ΓòÉΓòÉΓòÉ 12.3.2.3. Returning from a Window Procedure ΓòÉΓòÉΓòÉ
  3072.  
  3073. By convention, a window procedure typically returns a Boolean value (type 
  3074. MRESULT) to its caller, to indicate the result of message processing for that 
  3075. message.  The value returned is significant, since Presentation Manager takes 
  3076. action depending upon that value.  The defined return values for each 
  3077. system-defined message class, along with the default processing provided by 
  3078. Presentation Manager for each class, are given in the IBM OS/2 Version 2.0 
  3079. Presentation Manager Reference.  Naturally, the return values for user-defined 
  3080. message classes are defined by the application developer. 
  3081.  
  3082. If the window procedure has been invoked synchronously using WinSendMsg(), the 
  3083. result is returned by Presentation Manager to the calling window procedure, 
  3084. which may interrogate and act upon it.  If the window procedure has been 
  3085. invoked asynchronously using the WinPostMsg() function, the result is returned 
  3086. to Presentation Manager only.  Presentation Manager then uses this result to 
  3087. determine whether any post-processing should be carried out for the message. 
  3088. Note that while the WinPostMsg() function call also provides a Boolean return 
  3089. code to the caller, this code only indicates whether the message was 
  3090. successfully posted to the queue, and not the successful processing of the 
  3091. message by the target window procedure. 
  3092.  
  3093.  
  3094. ΓòÉΓòÉΓòÉ 12.3.3. Dialog Procedures ΓòÉΓòÉΓòÉ
  3095.  
  3096. A dialog procedure is a special type of window procedure that is associated 
  3097. with a modal dialog box and processes messages intended for that dialog box. 
  3098. The structure of a dialog procedure is similar to that of a "normal" window 
  3099. procedure, and it processes messages in the same way, although certain message 
  3100. classes received by a dialog procedure are different from those received and 
  3101. processed by a normal window procedure.  The structure of a typical dialog 
  3102. procedure is shown in Structure of a Dialog Procedure. 
  3103.  
  3104. MRESULT EXPENTRY dpDProc(HWND hWnd, ULONG ulMsg, MPARAM mp1, MPARAM mp2)
  3105. {
  3106.     switch (ulMsg)
  3107.         {
  3108.         case WM_INITDLG:
  3109.           <extract initialization data from message parameters>
  3110.           <establish initial values for control window data>
  3111.           return((MRESULT)TRUE);
  3112.           break;
  3113.         case WM_CONTROL:
  3114.           <determine originator of message and message contents>
  3115.           <perform control-specific processing>
  3116.           return((MRESULT)0);
  3117.           break;
  3118.         case WM_COMMAND:
  3119.           switch LOUSHORT(mp1):
  3120.               {
  3121.               case DID_OK:
  3122.                 <complete dialog>
  3123.                 WinDismissDlg(hWnd,TRUE);
  3124.                 break;
  3125.               case DID_CANCEL:
  3126.                 <cancel dialog>
  3127.                 WinDismissDlg(hWnd,FALSE);
  3128.                 break;
  3129.               }
  3130.           return((MRESULT)0);
  3131.           break;
  3132.         default:
  3133.           return((MRESULT)WinDefDlgProc(hWnd,
  3134.                          ulMsg,
  3135.                          mp1,
  3136.                          mp2));
  3137.           break;
  3138.         }
  3139. }
  3140. Structure of a Dialog Procedure 
  3141.  
  3142. Since modal dialog boxes do not belong to a class, they are not registered to 
  3143. Presentation Manager in the manner of a normal window.  A dialog procedure is 
  3144. associated with a dialog box as part of a WinDlgBox() call, which loads a modal 
  3145. dialog box and processes the dialog as a single operation, or a WinLoadDlg() 
  3146. call, which loads the dialog box into memory but does not process it;  the 
  3147. dialog box may subsequently be processed by a WinProcessDlg() call.  The 
  3148. processes of providing input to and obtaining results from a dialog procedure 
  3149. are discussed in Building a Presentation Manager Application. 
  3150.  
  3151. Note that since a modeless dialog box is simply an optimized (non-sizable) 
  3152. window with no other inherent properties such as modality, it receives the same 
  3153. messages as a standard window, and its methods are therefore contained within a 
  3154. normal window procedure rather than a dialog procedure. 
  3155.  
  3156. Note that a dialog box must use the system linkage convention, since it is 
  3157. simply a specialized form of window procedure.  This is achieved using the 
  3158. EXPENTRY keyword. 
  3159.  
  3160. Upon creation, a dialog box receives a message of the system-defined class 
  3161. WM_INITDLG.  This is similar to the WM_CREATE message received by a normal 
  3162. window upon creation, and may be processed in a similar way.  The first 
  3163. parameter in the WM_INITDLG message may be used to pass a pointer to the dialog 
  3164. procedure, referencing a data structure containing initialization information 
  3165. or other application-specified data. 
  3166.  
  3167. A dialog box also receives messages of class WM_CONTROL indicating events 
  3168. occurring in control windows within the dialog box.  The window identifier of 
  3169. the control window that dispatched the message, along with the nature of the 
  3170. message, is indicated in the message parameters.  The WM_CONTROL message is 
  3171. described in the IBM OS/2 Version 2.0 Presentation Manager Reference.  The 
  3172. dialog procedure may wish to explicitly process events indicated by WM_CONTROL 
  3173. messages, or it may allow such messages to pass on to the default Presentation 
  3174. Manager-supplied dialog procedure WinDefDlgProc(). 
  3175.  
  3176. A dialog box also typically receives WM_COMMAND messages, which are generated 
  3177. when a pushbutton within the dialog box is pressed by the user. The identity of 
  3178. the pushbutton is indicated in the first parameter of the WM_COMMAND message. 
  3179.  
  3180. The symbolic names DID_OK and DID_CANCEL are defined by Presentation Manager, 
  3181. and by convention are used to refer to the "OK" and "Cancel" pushbuttons 
  3182. respectively. The definition of dialog boxes is described in detail in 
  3183. Presentation Manager Resources. 
  3184.  
  3185. A dialog procedure is terminated and the dialog box is destroyed when the 
  3186. dialog procedure issues a WinDismissDlg() call to Presentation Manager, 
  3187. typically as a result of the user pressing a pushbutton. By convention, this 
  3188. call specifies a parameter indicating TRUE if the user completed the dialog by 
  3189. pressing an "Enter" or "OK" pushbutton, or FALSE if the user cancelled the 
  3190. dialog by pressing a "Cancel" pushbutton.  The value specified in this 
  3191. parameter is returned to the window procedure that issued the WinDlgBox() or 
  3192. WinProcessDlg() call, as the return value from that call. 
  3193.  
  3194. Message boxes do not require an application-supplied procedure to carry out 
  3195. their processing.  The simple nature of the message box dialog allows it to be 
  3196. processed by Presentation Manager on the application's behalf, and to return 
  3197. the result to the application for subsequent action. 
  3198.  
  3199.  
  3200. ΓòÉΓòÉΓòÉ 12.3.4. Subroutines ΓòÉΓòÉΓòÉ
  3201.  
  3202. Subroutines may be used in a Presentation Manager application, in the same way 
  3203. as they are used in any other application. However, in order to conform to 
  3204. object-oriented practices, subroutine calls should only be used to achieve 
  3205. functional isolation within the methods of a single application object, or to 
  3206. perform a standard processing function that is common to a number of objects; 
  3207. in this case, the scope of each execution instance of the subroutine is limited 
  3208. to a single object.  In accordance with object-oriented programming guidelines, 
  3209. communication between objects (windows) should be achieved using messages, and 
  3210. hence window procedures should not be invoked directly as subroutines.  See 
  3211. Passing Control for further discussion on the use of subroutines in 
  3212. Presentation Manager applications. 
  3213.  
  3214.  
  3215. ΓòÉΓòÉΓòÉ 12.3.5. Partitioning the Application ΓòÉΓòÉΓòÉ
  3216.  
  3217. With the dynamic linking capabilities of OS/2, it is possible to partition an 
  3218. application into a number of executable modules.  A single base program may be 
  3219. augmented by one or more dynamic link libraries.  Such an approach has a number 
  3220. of advantages: 
  3221.  
  3222.    o  Application code that is only executed in exceptional circumstances, such 
  3223.       as little-used functions, exception and error-handling routines etc, is 
  3224.       not loaded unless it is required.  This may significantly reduce the load 
  3225.       time and memory requirements of the application. 
  3226.  
  3227.    o  Common functions may be shared between applications, since dynamic link 
  3228.       libraries are re-entrant and a single memory-resident copy of the library 
  3229.       code may be used by all applications.  This can further reduce the memory 
  3230.       requirements of an application. 
  3231.  
  3232.    o  Functions placed in dynamic link libraries are isolated from the main 
  3233.       application, and may be modified without the need to re-link the 
  3234.       application.  This facilitates application maintenance and update, since 
  3235.       only the new version of the DLL need be distributed. 
  3236.  
  3237.  Applications written for the Workplace Shell should be partitioned in this 
  3238.  manner.  Since the shell displays all objects on the desktop at system 
  3239.  initialization, all applications must potentially be loaded at this time. 
  3240.  This can dramatically increase the time required for system initialization, 
  3241.  along with the overall memory requirements of the system. 
  3242.  
  3243.  These requirements may be significantly reduced by having only the minimum 
  3244.  code (that is, the code required to accept and identify messages) loaded at 
  3245.  application startup, and placing all processing function into dynamic link 
  3246.  libraries that are loaded only when one of their entry points is called. 
  3247.  
  3248.  Application developers must give careful consideration to correct partitioning 
  3249.  of the application. Groups of functions that are interdependent and which call 
  3250.  one another, or are typically called in close sequence should be placed in a 
  3251.  single DLL module.  Functions that are independent of one another should be 
  3252.  placed in separate DLLs.  This approach will minimize the load time and memory 
  3253.  requirements of the application. 
  3254.  
  3255.  
  3256. ΓòÉΓòÉΓòÉ 12.4. Presentation Manager Resources ΓòÉΓòÉΓòÉ
  3257.  
  3258. Presentation Manager allows the application developer to define application 
  3259. resources externally to the application code.  Resources may include 
  3260. definitions for the following items: 
  3261.  
  3262.  Fonts                    Graphic fonts may be created and modified using the 
  3263.                           Font Editor supplied as part of the IBM Developer's 
  3264.                           Toolkit for OS/2 2.0. 
  3265.  Icons                    Application and window icons, mouse-pointers and 
  3266.                           bitmaps may be created and modified using the Icon 
  3267.                           Editor supplied as part of the IBM Developer's 
  3268.                           Toolkit for OS/2 2.0. 
  3269.  Menus                    Menu bars and pulldown menus may be defined for 
  3270.                           display windows. 
  3271.  String Tables            Tables of text strings may be defined for use by an 
  3272.                           application. 
  3273.  Accelerator Tables       Tables of accelerator keys (for example, F3 for Quit) 
  3274.                           may be defined for display windows. 
  3275.  Help Tables              Tables of help panels may be defined for each display 
  3276.                           window or each control window in a dialog box.  See 
  3277.                           Adding Online Help and Documentation for further 
  3278.                           discussion of help panels. 
  3279.  Dialog Templates         Dialog boxes may be created or modified and stored as 
  3280.                           dialog templates, using the Dialog Box Editor 
  3281.                           supplied as part of the IBM Developer's Toolkit for 
  3282.                           OS/2 2.0. 
  3283.  Window Templates         Window templates may be created or modified and 
  3284.                           stored as window templates, using the dialog editor 
  3285.                           supplied as part of the IBM Developer's Toolkit for 
  3286.                           OS/2 2.0. 
  3287.  
  3288.  Except where noted above, resources are defined in a resource script file, an 
  3289.  ASCII text file that may be manipulated using a standard text editor. This 
  3290.  resource script file serves as input to a resource compiler, which is provided 
  3291.  as part of the IBM Developer's Toolkit for OS/2 2.0.  The resource compiler 
  3292.  produces a precompiled version of the resources, which is then incorporated 
  3293.  into the application's executable code or stored in a dynamic link library for 
  3294.  use by one or more applications. 
  3295.  
  3296.  It is usual for simple text-based resources such as menus and string tables to 
  3297.  be placed directly into the resource script file using an ASCII text editor. 
  3298.  However, non-textual resources such as icons or bitmaps, or more complex 
  3299.  text-based resources such as dialog templates, are typically stored in 
  3300.  separate files and referenced from the resource script file. 
  3301.  
  3302.  A major benefit of defining such resources externally to the application is 
  3303.  that changes may be made to resource definitions without affecting the 
  3304.  application code itself.  Modifications such as new icons, altered commands or 
  3305.  menus, etc., may be implemented quickly and easily by making simple changes at 
  3306.  a single point in the application. 
  3307.  
  3308.  As a further example, the task of providing national language versions of an 
  3309.  application is simplified, since all text such as menus and messages may be 
  3310.  defined outside the application code, and multiple language-specific versions 
  3311.  of such resources may be linked into a single version of the application code. 
  3312.  In this way, the user interface properties of a display window may be modified 
  3313.  without affecting the internal implementation of the window procedure or its 
  3314.  methods. 
  3315.  
  3316.  The creation and use of Presentation Manager resources is discussed in 
  3317.  Presentation Manager Resources. 
  3318.  
  3319.  
  3320. ΓòÉΓòÉΓòÉ 12.5. Creating Reusable Code ΓòÉΓòÉΓòÉ
  3321.  
  3322. The ability to define resources such as window and dialog templates externally 
  3323. to the application, in conjunction with the dynamic linking facilities provided 
  3324. by the OS/2 operating system, provides a powerful tool for the creation of 
  3325. generic application objects, comprised of window/dialog templates and their 
  3326. associated window or dialog procedures.  These application objects may be 
  3327. defined and stored in dynamic link libraries for subsequent use by one or more 
  3328. applications.  This practice is in accordance with the guidelines for Systems 
  3329. Application Architecture Common Applications, which provide for common 
  3330. application services within and between environments, as well as common user 
  3331. applications.  This concept is further discussed in Generic Application 
  3332. Modules.  Note however, that the use of generic application objects presupposes 
  3333. that the nature of and message interfaces to such application objects are 
  3334. well-defined and documented, in order to allow application developers to 
  3335. correctly select and interact with the generic objects. 
  3336.  
  3337. For instance, a standard dialog box that will be used by many applications 
  3338. could be defined in a dialog template, resource compiled and stored in a 
  3339. dynamic link library, along with the dialog procedure which performs the 
  3340. processing for that dialog.  The dialog can then be loaded from the DLL by any 
  3341. application which needs to use it.  The dialog need be coded only once, and may 
  3342. be modified at any time while requiring no source code changes to the 
  3343. applications that access it.  The fact that DLL code is not bound with the 
  3344. application at link edit time like other library code also means that no 
  3345. changes are required to the object code of the applications, and thus 
  3346. recompilation and link edit is not required.  An example of this technique is 
  3347. given in Presentation Manager Resources. 
  3348.  
  3349. The window or dialog procedure associated with a generic object should contain 
  3350. all the methods normally used to perform actions upon that object, but need not 
  3351. contain every action that will ever be necessary.  If an application requires a 
  3352. specialized action on a generic object (that is, a previously undefined action 
  3353. or a modification of an existing action), the window acting as a handle to that 
  3354. object may be subclassed, and a new window procedure substituted for the 
  3355. existing window procedure. This new window procedure would contain methods to 
  3356. process the specific messages in which it has an interest, and would then 
  3357. invoke the original window procedure to handle any other message classes, in 
  3358. accordance with the object-oriented principle of inheritance. Subclassing is 
  3359. discussed further in Subclassing. 
  3360.  
  3361.  
  3362. ΓòÉΓòÉΓòÉ 12.6. Window Hierarchy ΓòÉΓòÉΓòÉ
  3363.  
  3364. Presentation Manager organizes windows hierarchically; each window in the 
  3365. system has a parent, and may optionally have an owner.  These parent and owner 
  3366. relationships determine the behavior of the window in response to certain 
  3367. messages, and may be used by applications to navigate the window hierarchy. 
  3368.  
  3369.  
  3370. ΓòÉΓòÉΓòÉ 12.6.1. Parent/Child Relationship ΓòÉΓòÉΓòÉ
  3371.  
  3372. The parent/child relationship between windows is mentioned in OS/2 Version 2.0 
  3373. - Volume 3:  Presentation Manager and Workplace Shell, with regard to the 
  3374. clipping of a child window to the borders of its parent. However, this 
  3375. hierarchy goes further in Presentation Manager, since all windows, both display 
  3376. windows and object windows, have a designated parent window. For top-level 
  3377. display windows, this parent window is the desktop, and is identified by the 
  3378. HWND_DESKTOP constant.  Other display windows within an application, which are 
  3379. child windows of the application's main window, may have the top-level 
  3380. application window as their parent, or indeed subsequent levels of the window 
  3381. hierarchy may be created, dependent on application requirements.  A window's 
  3382. parent is identified to Presentation Manager by the application when the window 
  3383. is created.  Thus the window hierarchy within a particular desktop is 
  3384. dynamically defined at execution time. 
  3385.  
  3386. As well as being uniquely identified by its window handle, a child window may 
  3387. also be identified by a window identifier, which is unique between children of 
  3388. a particular parent window.  This identifier is an integer value, which in 
  3389. practice is usually replaced by a more meaningful symbolic name that defines an 
  3390. integer constant.  The window identifier is supplied as a parameter when the 
  3391. application requests creation of the window by Presentation Manager.  When a 
  3392. window's parent and identifier are known, the WinWindowFromID() function may be 
  3393. used to determine its window handle so that operations may be performed upon 
  3394. it.  See Window Communication for further information. 
  3395.  
  3396. The parent/child hierarchy is useful for application design purposes, since in 
  3397. many cases, a window and its children may be regarded and manipulated as a 
  3398. single unit.  For example, sizing a parent window automatically clips all 
  3399. children of that window to the boundaries of the parent, and closing a parent 
  3400. window results in each of its children being closed.  This simplifies the 
  3401. application logic required for applications that create multiple windows. 
  3402.  
  3403.  
  3404. ΓòÉΓòÉΓòÉ 12.6.1.1. Frame and Client Windows ΓòÉΓòÉΓòÉ
  3405.  
  3406. The concepts of frame and client areas for a window are discussed in OS/2 
  3407. Version 2.0 - Volume 3:  Presentation Manager and Workplace Shell.  In fact, 
  3408. these frame and client areas are separate windows in their own right; the frame 
  3409. window of the application's "main window" is a top-level window with the 
  3410. desktop as its parent, and the client window is a child of the frame window. 
  3411. Frame control windows such as maximize/minimize icons, the title bar, the menu 
  3412. bar, etc., are also separate windows from the application viewpoint, and are 
  3413. regarded as children of the frame window.  Note that although they are separate 
  3414. windows, the end user perceives and manipulates the entire group as a single 
  3415. unit. 
  3416.  
  3417. The frame window and its children all belong to system-defined generic window 
  3418. classes, and thus have their own window procedures defined by Presentation 
  3419. Manager.  The exception is the client window, the window class of which is 
  3420. defined by the application; the window procedure is therefore defined to 
  3421. Presentation Manager when the window class is registered.  Note that window 
  3422. procedures for system-defined window classes may be subclassed by the 
  3423. application in order to provide specialized processing of certain messages. 
  3424.  
  3425. The children of a frame window have specific window identifiers assigned to 
  3426. them by Presentation Manager.  These window identifiers are unique for each 
  3427. frame window.  The predefined window identifiers are shown in Window 
  3428. Identifiers. 
  3429.  
  3430. ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
  3431. Γöé Window Identifiers.  This table shows the window identifiers      Γöé
  3432. Γöé assigned by Presentation Manager to the children of a frame window.   Γöé
  3433. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  3434. Γöé CHILD WINDOW      Γöé WINDOW IDENTIFIER    Γöé DEFINED BY       Γöé
  3435. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  3436. Γöé Client Window     Γöé FID_CLIENT       Γöé Application      Γöé
  3437. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  3438. Γöé System Menu      Γöé FID_SYSMENU       Γöé Presentation Manager  Γöé
  3439. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  3440. Γöé Menu Bar        Γöé FID_MENU        Γöé Presentation Manager  Γöé
  3441. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  3442. Γöé Title Bar       Γöé FID_TITLEBAR      Γöé Presentation Manager  Γöé
  3443. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  3444. Γöé Min/Max Icon      Γöé FID_MINMAX       Γöé Presentation Manager  Γöé
  3445. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  3446. Γöé Vertical Scroll Bar  Γöé FID_VERTSCROLL     Γöé Presentation Manager  Γöé
  3447. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  3448. Γöé Horizontal Scroll Bar Γöé FID_HORZSCROLL     Γöé Presentation Manager  Γöé
  3449. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  3450. Γöé NOTE:  The "Defined by" column indicates whether the window procedure  Γöé
  3451. Γöé that determines a window's appearance and behavior is supplied by    Γöé
  3452. Γöé Presentation Manager or the application.                Γöé
  3453. ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
  3454.  
  3455. These identifiers may be used to communicate with child windows of a particular 
  3456. frame window, without the necessity to determine the window handle of the child 
  3457. window.  This concept is applicable to all windows including control windows 
  3458. within a dialog box.  See Window Communication for further information. 
  3459.  
  3460.  
  3461. ΓòÉΓòÉΓòÉ 12.6.1.2. Object Windows ΓòÉΓòÉΓòÉ
  3462.  
  3463. Object windows do not have a parent in the visual sense, as considerations such 
  3464. as clipping do not arise (since the window is never displayed).  For the 
  3465. purposes of standardization, Presentation Manager considers every object window 
  3466. to have a conceptual parent; this parent may be referenced using the constant 
  3467. HWND_OBJECT.  This technique allows an object window to be created using the 
  3468. same Presentation Manager function as that used to create a display window.  It 
  3469. is also useful in allowing logical grouping of windows with similar functions, 
  3470. or which need to be treated as a group for application purposes, under a single 
  3471. conceptual parent. 
  3472.  
  3473. For example, all the object windows created by a particular application may be 
  3474. grouped as children of a single "dummy" parent window.  When the application 
  3475. terminates and wishes to destroy all these windows, only a single function call 
  3476. to destroy the parent need be issued; Presentation Manager will automatically 
  3477. destroy each of the children in turn before destroying the parent.  Due to the 
  3478. way in which Presentation Manager  destroys windows by first passing a 
  3479. WM_DESTROY message to the window, each object window is given a chance to exit 
  3480. in an orderly manner. 
  3481.  
  3482.  
  3483. ΓòÉΓòÉΓòÉ 12.6.2. Window Ownership ΓòÉΓòÉΓòÉ
  3484.  
  3485. A window may have an owner as well as having a parent.  While a window's 
  3486. relationship to its parent is mainly concerned with display, the relationship 
  3487. with its owner is concerned primarily with function.  The owner is assumed to 
  3488. have some interest in events that take place within a window.  For example, a 
  3489. frame window is the parent of its frame control windows (icons, menu bar, 
  3490. etc.,) and is also their owner.  When certain events take place, such as the 
  3491. user selecting an item from a menu bar, the control windows notify their owner 
  3492. by dispatching notification messages (the menu bar for instance, typically 
  3493. dispatches a message of class WM_COMMAND).  Thus the owner receives 
  3494. notification of the event, and may perform some action in response. 
  3495.  
  3496. The concept of ownership is usually applied to system-defined window classes 
  3497. such as control windows.  Since the window procedures for these window classes 
  3498. are defined by Presentation Manager rather than by the application, it is 
  3499. necessary for a control window to notify its owner of any event that may be 
  3500. significant to the owner. 
  3501.  
  3502. There is typically no owner relationship between frame and client windows. 
  3503. Messages received by the frame window that are deemed to be of possible 
  3504. interest to the client window are passed to the client window automatically by 
  3505. the system-supplied frame window procedure, by virtue of the predefined 
  3506. parent/child relationship between the frame and client windows. 
  3507.  
  3508. Should application requirements dictate, the application developer may 
  3509. establish an owner relationship between any two windows within his/her 
  3510. application, provided those windows are created by the same thread.  Owner 
  3511. relationships are not permitted between windows created by different threads. 
  3512.  
  3513.  
  3514. ΓòÉΓòÉΓòÉ 12.6.3. Z-Order ΓòÉΓòÉΓòÉ
  3515.  
  3516. A desktop is typically regarded as a two-dimensional display space;  in fact, a 
  3517. desktop is three-dimensional, since when windows overlap on the desktop, one 
  3518. window is conceptually "on top of" the other.  This concept of "stacking" 
  3519. windows applies even when windows do not actually overlay one another on the 
  3520. desktop.  The order in which windows appear on the desktop is known as the 
  3521. z-order. The z-order is known to Presentation Manager, and a number of function 
  3522. calls are provided that enable an application to request window handles of 
  3523. specific windows in the z-order using the WinGetNextWindow() function to obtain 
  3524. the handle of the next window in the z-order, or the WinQueryWindow() function 
  3525. to obtain the handle of a window at a specified position in the z-order. 
  3526.  
  3527. Since the z-order changes dynamically as different applications create and 
  3528. destroy windows, Presentation Manager takes a "snapshot" of the desktop state 
  3529. when the application issues a WinBeginEnumWindows() call.  This function 
  3530. accepts a window handle as a parameter, and the z-order of all immediate 
  3531. children of that window is recorded by Presentation Manager.  A call to this 
  3532. function should be issued before any WinGetNextWindow() call is issued, or 
  3533. before any WinQueryWindow() call is issued that specifies a position in the 
  3534. z-order.  When the application no longer wishes to interrogate the recorded 
  3535. window hierarchy, a WinEndEnumWindows() call should be made. 
  3536.  
  3537. The concepts of z-order and window enumeration are useful in circumstances 
  3538. where an operation or sequence of operations must be performed on a number of 
  3539. windows in order.  Windows with the same parent always appear contiguously in 
  3540. the z-order, and thus may be easily processed in succession. 
  3541.  
  3542.  
  3543. ΓòÉΓòÉΓòÉ 12.7. Subclassing ΓòÉΓòÉΓòÉ
  3544.  
  3545. Windows may be subclassed by replacing the window procedure defined by the 
  3546. window class with another window procedure.  This new subclass window procedure 
  3547. typically processes some of the messages routed to it, and then calls the 
  3548. original window procedure to process any other messages.  This technique 
  3549. parallels the definition of subclassing given in Object-Oriented Applications. 
  3550.  
  3551. Presentation Manager implements subclassing by having the application call the 
  3552. WinSubclassWindow() function, specifying the handle of the window to be 
  3553. subclassed and the new subclass window procedure.  Note that only the window 
  3554. specified is affected by the WinSubClassWindow() function call; other windows 
  3555. of the same class are not subclassed.  Once the call is successfully issued, 
  3556. any messages destined for the original window procedure are automatically 
  3557. routed to the subclass window procedure by Presentation Manager.  The object 
  3558. (whether a window or the operating system) from which the message originated is 
  3559. unaware of the subclass window procedure's interference.  An example of a 
  3560. subclass window procedure is given in Subclass Window Procedure. 
  3561.  
  3562. The subclassing concept enables messages destined for particular windows to be 
  3563. intercepted and the processing resulting from certain messages to be altered. 
  3564. This provides a powerful mechanism that facilitates the creation and use of 
  3565. generic windows (application objects), while retaining the ability for the 
  3566. application to modify the behavior of such windows should the need arise.  The 
  3567. use of subclassing enables a newly created window to take on the properties and 
  3568. methods of existing window classes in accordance with the principle of 
  3569. inheritance. 
  3570.  
  3571. Presentation Manager enables the effect of subclassing a window to be reversed 
  3572. by the application issuing the WinSubclassWindow() call a second time for the 
  3573. same window, specifying the original window procedure.  Presentation Manager 
  3574. then routes messages directly to their intended destination.  This capability 
  3575. allows windows to be temporarily subclassed to meet changing requirements at 
  3576. different points during application execution. 
  3577.  
  3578.  
  3579. ΓòÉΓòÉΓòÉ 12.8. Summary ΓòÉΓòÉΓòÉ
  3580.  
  3581. It can be seen from the foregoing discussion that Presentation Manager provides 
  3582. a base that facilitates the implementation of module-based object-oriented 
  3583. conventions by application programs.  The concepts of an application object and 
  3584. its methods are implemented under Presentation Manager as a window and its 
  3585. window procedure. 
  3586.  
  3587. Windows are grouped into classes and a window procedure is associated with a 
  3588. window on the basis of its class, in a parallel to the concept of allocating 
  3589. methods to an object class rather than to individual instances of that class. 
  3590. Window classes are defined in isolation however, and the concept of an 
  3591. inheritance hierarchy is not imposed by Presentation Manager, thus further 
  3592. enhancing the potential for efficient reuse by increasing object granularity. 
  3593. Presentation Manager allows windows to be subclassed, in order to allow 
  3594. additional or modified methods to be applied to an object in response to new or 
  3595. specialized actions.  This provides an additional enhancement to the capability 
  3596. of code reuse, since it is not necessary to create a new object class in order 
  3597. to implement small modifications to an existing class. 
  3598.  
  3599. Windows communicate with the system and with each other by way of messages, 
  3600. which are queued and routed by Presentation Manager, and which are processed in 
  3601. a serial fashion by the target window procedure.  This messaging model is a 
  3602. practical implementation of the message-driven communication precept of 
  3603. object-oriented application design. 
  3604.  
  3605. While not supported explicitly by Presentation Manager, the object-oriented 
  3606. concept of encapsulation is supported implicitly by the ability of a window 
  3607. procedure to define and thus "own" a data object.  The concept of polymorphism 
  3608. is also supported by Presentation Manager, since the behavior and results 
  3609. obtained from a window procedure are dependent upon, and only upon the class 
  3610. and contents of messages sent to that window procedure.  In a similar fashion, 
  3611. the result of a message is dependent upon the window procedure (application 
  3612. object) to which it is passed.  The isolation of data objects within an 
  3613. application object facilitates the containment of change by enhancing 
  3614. application modularity, thus easing the task of change management and 
  3615. application maintenance. 
  3616.  
  3617. ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
  3618. Γöé Application Object/Window Correlation                  Γöé
  3619. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  3620. Γöé APPLICATION OBJECT   Γöé SUPPORTED       Γöé IMPLEMENTATION     Γöé
  3621. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  3622. Γöé Message Communication Γöé Yes          Γöé PM Message       Γöé
  3623. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  3624. Γöé Class Association   Γöé Yes          Γöé Window Class      Γöé
  3625. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  3626. Γöé Class Data       Γöé Yes          Γöé Defined in Window    Γöé
  3627. Γöé            Γöé            Γöé Procedure        Γöé
  3628. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  3629. Γöé Instance Data     Γöé Yes          Γöé Stored in Window Words Γöé
  3630. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  3631. Γöé Encapsulation     Γöé Yes          Γöé In Window Procedure   Γöé
  3632. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  3633. Γöé Polymorphism      Γöé Yes          Γöé In Window Procedure   Γöé
  3634. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  3635. Γöé Inheritance      Γöé Partial        Γöé Via Subclassing     Γöé
  3636. ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
  3637.  
  3638. The ability to encapsulate the definitions of data objects with the methods 
  3639. used to manipulate those objects, and to store the resulting application 
  3640. objects in object libraries, facilitates the notion of reusability, which is 
  3641. one of the central precepts of object-oriented programming.  The dynamic 
  3642. linking facilities provided by OS/2 further extend the potential for reusable 
  3643. application objects.  Reusable objects may be defined and stored for use by 
  3644. multiple applications;  indeed, multiple objects may direct messages to a 
  3645. single instance of an object executing in the system.  The message queueing and 
  3646. serialization provided by Presentation Manager ensures the correct sequence of 
  3647. processing to preserve the user's intention and facilitate the integrity of 
  3648. data objects. 
  3649.  
  3650. It may be seen that the concept of an application object as defined in 
  3651. Object-Oriented Applications and the implementation of a window under 
  3652. Presentation Manager have a strong correlation.  A window may be regarded as 
  3653. the identity of an application object.  That object is associated with a data 
  3654. object and a set of methods (the window procedure) that perform actions upon 
  3655. the data object.  Class-specific data is defined within the window procedure, 
  3656. while storage for instance data is defined dynamically and pointers typically 
  3657. stored in window words.  Windows communicate with the user and with one another 
  3658. by way of messages.  Thus the window is the implementation of an application 
  3659. object under Presentation Manager. 
  3660.  
  3661. Hence Presentation Manager provides an execution environment and a basic 
  3662. application architecture that supports the implementation of object-oriented 
  3663. applications, within the boundaries of IBM Systems Application Architecture. 
  3664. Although it does not provide a complete development environment that enforces 
  3665. object-oriented guidelines, it offers the basis upon which such a development 
  3666. environment may be based. 
  3667.  
  3668.  
  3669. ΓòÉΓòÉΓòÉ 13. The Flat Memory Model ΓòÉΓòÉΓòÉ
  3670.  
  3671. The task of dynamically allocating memory within an application is greatly 
  3672. simplified in the 32-bit OS/2 Version 2.0 environment through use of the flat 
  3673. memory model. The application developer need no longer be concerned with the 
  3674. maximum 64KB segment size imposed by the 80286 processor architecture.  Larger 
  3675. amounts of memory may be allocated and subsequently manipulated as single units 
  3676. known as memory objects, rather than as multiple segments as was the case with 
  3677. previous versions of OS/2.  This reduces application complexity, facilitating 
  3678. improved performance and reducing application development time. 
  3679.  
  3680. This chapter describes the use of the flat memory model for application 
  3681. programming, in order to allocate and manipulate system memory.  The chapter 
  3682. also examines the facilities provided by OS/2 Version 2.0 that enable 
  3683. applications to handle memory protection exceptions. 
  3684.  
  3685. The concept of the flat memory model is described in OS/2 Version 2.0 - Volume 
  3686. 1:  Control Program.  The functions necessary to manipulate memory from within 
  3687. applications are described in detail in the IBM OS/2 Version 2.0 Control 
  3688. Program Reference. 
  3689.  
  3690.  
  3691. ΓòÉΓòÉΓòÉ 13.1. DosAllocMem() Function ΓòÉΓòÉΓòÉ
  3692.  
  3693. The DosAllocSeg() function implemented under previous versions of OS/2 is 
  3694. replaced in Version 2.0 by the DosAllocMem() function, which allows allocation 
  3695. of memory objects greater than 64KB in size.  To take an example, Allocating 
  3696. Memory in Previous Versions of OS/2 shows the code necessary under OS/2 Version 
  3697. 1┬╖3 to allocate a 72KB area of memory for use by an application: 
  3698.  
  3699. SEL    sel1, sel2;
  3700. PVOID  pSegment1, pSegment2;
  3701.  
  3702. DosAllocSeg(0, &sel1, SEG_NONSHARED);
  3703. DosAllocSeg(8192, &sel2, SEG_NONSHARED);
  3704.  
  3705. pSegment1=MAKEP(sel1, 0);
  3706. pSegment2=MAKEP(sel2, 0);
  3707. Allocating Memory in Previous Versions of OS/2
  3708.  
  3709. This example shows the use of the DosAllocSeg() function to allocate multiple 
  3710. segments in order to access 72KB of memory. 
  3711.  
  3712. The application must then use pSegment1 to reference the lower 64KB and 
  3713. pSegment2 to reference the upper 8KB of the memory object.  This requires 
  3714. conditional testing for each memory reference, and thereby introduces 
  3715. additional complication to the application code.  Use of the DosAllocHuge() 
  3716. function simplifies this slightly, but arithmetic is still required in order to 
  3717. correctly calculate offsets within the higher area of memory. 
  3718.  
  3719. Under OS/2 Version 2.0, a single DosAllocMem() function call is required in 
  3720. order to perform the same task, as shown in Allocating Memory in OS/2 Version 
  3721. 2.0. 
  3722.  
  3723. PVOID  pObject;             /* 32-bit linear pointer to memory object */
  3724.  
  3725. DosAllocMem(&pObject,       /* Allocate memory object                 */
  3726.             73727,          /* Size of memory object                  */
  3727.             PAG_READ |      /* Allow read access                      */
  3728.             PAG_WRITE);     /* Allow write access                     */
  3729. Allocating Memory in OS/2 Version 2.0
  3730.  
  3731. This example shows the use of the DosAllocMem() function to allocate a single 
  3732. 72KB memory object. 
  3733.  
  3734. Subsequent references to this memory object may simply use a 32-bit offset 
  3735. within the allocated address range. 
  3736.  
  3737. Note that since OS/2 Version 2.0 uses paged memory internally, memory allocated 
  3738. using DosAllocMem() is always allocated in multiples of 4KB. Thus, a request 
  3739. for 10 bytes will actually result in a full 4KB page being committed in real 
  3740. storage.  Since this will lead to high fragmentation and consequent waste of 
  3741. memory, the allocation of many small memory objects using DosAllocMem() 
  3742. directly is not recommended.  Application developers should initially use 
  3743. DosAllocMem() to allocate the maximum storage likely to be required, and then 
  3744. use the DosSubAlloc() function to allocate individual memory objects.  This 
  3745. technique allows the storage of multiple small memory objects within the same 
  3746. 4KB page, thereby reducing fragmentation and making more efficient use of 
  3747. storage. 
  3748.  
  3749. Note that the DosAllocHuge() function provided under previous versions of OS/2 
  3750. has no counterpart under Version 2.0.  This function is not required since 
  3751. DosAllocMem() allows the theoretical allocation of memory objects of a size up 
  3752. to that of the application's entire process address space. 
  3753.  
  3754. Memory objects allocated using DosAllocMem() may be freed using the 
  3755. DosFreeMem() function. 
  3756.  
  3757.  
  3758. ΓòÉΓòÉΓòÉ 13.2. Allocating versus Committing Memory ΓòÉΓòÉΓòÉ
  3759.  
  3760. Under OS/2 Version 2.0, there is a distinction between allocating a memory 
  3761. object and committing that object. This distinction was not present in previous 
  3762. versions of OS/2, and is a very important concept for the application developer 
  3763. to grasp.  When a memory object is allocated, space is reserved in the linear 
  3764. address space, but no real storage or swap file space is reserved for the 
  3765. object.  This space is only reserved when the memory object or parts thereof 
  3766. are committed.  A memory object that has not been committed is known as a 
  3767. sparse object. 
  3768.  
  3769. A memory object may be committed in two ways: 
  3770.  
  3771.    o  It may be committed (in its entirety) at the time it is allocated, using 
  3772.       the PAG_COMMIT flag in the DosAllocMem() function. 
  3773.  
  3774.    o  It may be committed in stages at some later point, using the DosSetMem() 
  3775.       function. 
  3776.  
  3777.  The former technique is intended for small memory objects, the size of which 
  3778.  is fixed and can be determined in advance by the application developer.  The 
  3779.  latter technique is intended for memory objects such as external data files, 
  3780.  which may vary in size. 
  3781.  
  3782.  Memory must be committed prior to being accessed by the application. Failure 
  3783.  to do this will result in a page fault (Trap 000E) exception. 
  3784.  
  3785.  
  3786. ΓòÉΓòÉΓòÉ 13.2.1. Committing Storage at Allocation ΓòÉΓòÉΓòÉ
  3787.  
  3788. For memory objects that have a fixed size, such as internal application 
  3789. storage, control blocks and most instance data, memory objects should be 
  3790. committed immediately upon allocation, allowing the application to access the 
  3791. memory object without the inconvenience and additional overhead of explicitly 
  3792. committing the storage at a later time. 
  3793.  
  3794. Storage for a memory object may be committed using the PAG_COMMIT flag in the 
  3795. DosAllocMem() function call used to allocate the memory object, as shown in 
  3796. Committing Storage During Allocation. 
  3797.  
  3798. PVOID  pObject;             /* 32-bit linear pointer to memory object */
  3799.  
  3800. DosAllocMem(&pObject,       /* Allocate memory object                 */
  3801.             73727,          /* Size of memory object                  */
  3802.             PAG_READ   |    /* Allow read access                      */
  3803.             PAG_WRITE  |    /* Allow write access                     */
  3804.             PAG_COMMIT);    /* Commit storage immediately             */
  3805. Committing Storage During Allocation 
  3806.  
  3807. This example shows the use of the PAG_COMMIT flag with the DosAllocMem() 
  3808. function. 
  3809.  
  3810. The above example creates a 72KB memory object in a similar manner to that 
  3811. shown in Allocating Memory in OS/2 Version 2.0, but commits the storage during 
  3812. allocation, so that is immediately available for use by the application. 
  3813.  
  3814.  
  3815. ΓòÉΓòÉΓòÉ 13.2.2. Dynamically Committing Storage ΓòÉΓòÉΓòÉ
  3816.  
  3817. Under DOS and previous versions of OS/2, it is common for an application to 
  3818. allocate a small memory segment to contain a data structure.  If the data 
  3819. structure outgrows the size of the segment, the segment size may be 
  3820. progressively increased using the DosReallocSeg() or DosReallocHuge() 
  3821. functions, moving the segments within the machine's physical memory in order to 
  3822. accommodate the increased size requirements.  This is not possible under 
  3823. Version 2.0, since the paged memory implementation does not allow memory 
  3824. objects to be moved within memory once they are allocated; hence the 
  3825. DosReallocSeg() and DosReallocHuge() functions have no counterparts in the 
  3826. 32-bit environment. 
  3827.  
  3828. Under OS/2 Version 2.0, an application can allocate an area of storage in its 
  3829. process address space, but may commit only a small amount of that storage at 
  3830. the time the application is initialized.  In this way, the application does not 
  3831. use a large amount of storage in a situation where it is not required, and 
  3832. thereby avoids placing unnecessary resource demands on the operating system. 
  3833. This can result in improved overall system performance. 
  3834.  
  3835. If the storage requirements for a memory object increase during execution (for 
  3836. example, the size of a spreadsheet increases), and exceed the amount of storage 
  3837. initially committed, the application may dynamically commit additional storage 
  3838. up to the maximum specified in the DosAllocMem() function call that allocated 
  3839. the memory object. 
  3840.  
  3841. This dynamic commitment of storage is typically achieved using the guard page 
  3842. technique.  A page within the memory object may be specified as a guard page 
  3843. using the PAG_GUARD flag in the DosAllocMem() function call or in a DosSetMem() 
  3844. call made subsequent to the allocation.  Once this is done, any memory 
  3845. reference to that page will generate a guard page exception.  The guard page 
  3846. exception warns the application that the upper boundary of the committed 
  3847. portion of a memory object has been reached, and allows appropriate action to 
  3848. be taken in order to avoid a page fault exception. 
  3849.  
  3850. Note that the memory protection scheme implemented by OS/2 Version 2.0 
  3851. allocates pages to individual processes.  An exception is only generated when 
  3852. an application attempts to write into a page which is not allocated to the 
  3853. current process under which the application is running.  If the page is 
  3854. allocated to the current process, no exception is generated.  Use of the guard 
  3855. page technique is therefore strongly recommended in circumstances where the 
  3856. amount of data to be written into a memory object is variable, or where the 
  3857. size of the memory object or its data may grow during execution. 
  3858.  
  3859. The recommended method of using guard pages is to initially allocate the memory 
  3860. object as a sparse object, and then commit the amount of storage required for 
  3861. the current size of the data, flagging the uppermost page of the memory object 
  3862. as a guard page.  This technique is shown in Using a Guard Page With a Memory 
  3863. Object. 
  3864.  
  3865. PVOID  pObject;         /* 32-bit linear pointer to memory object */
  3866.  
  3867. DosAllocMem(&pObject,      /* Allocate memory object         */
  3868.       73727,       /* Size of memory object          */
  3869.       PAG_READ |     /* Allow read access            */
  3870.       PAG_WRITE);     /* Allow write access           */
  3871.  
  3872. DosSetMem(pObject,       /* Set memory attributes for object    */
  3873.      8192L,        /* Two pages (8192 bytes)         */
  3874.      PAG_DEFAULT |     /* Default attributes from allocation   */
  3875.      PAG_COMMIT);     /* Commit page               */
  3876.  
  3877. DosSetMem(pObject+4096,     /* Set memory attributes for object    */
  3878.      1L,          /* Two pages (8192 bytes)         */
  3879.      PAG_DEFAULT |     /* Default attributes from allocation   */
  3880.      PAG_COMMIT  |     /* Commit page               */
  3881.      PAG_GUARD);      /* Flag page as guard page         */
  3882. Using a Guard Page With a Memory Object 
  3883.  
  3884. The example shown in Using a Guard Page With a Memory Object allocates a memory 
  3885. object that is 72KB in size as a sparse object, commits the first two pages 
  3886. (8KB) of the object and specifies the uppermost of the two pages as a guard 
  3887. page.  Any attempt by the application to write into this uppermost page will 
  3888. result in a guard page exception. 
  3889.  
  3890. The guard page exception generated when an application attempts to write into a 
  3891. guard page can be trapped and processed by an application-registered exception 
  3892. handler, to commit further pages within the memory object.  A simple guard page 
  3893. exception handler is shown in Guard Page Exception Handler. 
  3894.  
  3895. ULONG GPHandler(PEXCEPTIONREPORTRECORD pX)
  3896. {
  3897.    ULONG ulAttribs;            /* Memory attributes     */
  3898.    ULONG ulSize;              /* Range in pages      */
  3899.  
  3900.    if (pX->ExceptionNum ==         /* If guard page exception  */
  3901.      XCPT_GUARD_PAGE_VIOLATION)
  3902.      {
  3903.       ulSize=1L;            /* One page         */
  3904.       DosQueryMem(           /* Query memory attributes  */
  3905.         (PVOID)pX->ExceptionInfo[1],  /* Page base address     */
  3906.         &ulSize,            /* Single page        */
  3907.         &ulAttribs);          /* Memory attributes     */
  3908.       if (((ulAttrs & PAG_FREE) ||   /* If page is available   */
  3909.         (ulAttrs & PAG_COMMIT))==0)  /* but is not committed   */
  3910.         {
  3911.         DosSetMem(           /* Commit page        */
  3912.          (PVOID)pX->ExceptionInfo[1], /* Page base address    */
  3913.          1L,             /* Single page only     */
  3914.          PAG_DEFAULT |        /* Default attributes    */
  3915.          PAG_COMMIT);        /* Set commit flag      */
  3916.         return(XCPT_CONTINUE_EXECUTION); /* Done          */
  3917.         }
  3918.      }
  3919.    if (pX->ExceptionNum ==         /* If access violation    */
  3920.      XCPT_ACCESS_VIOLATION)
  3921.      {
  3922.      if (pX->ExceptionInfo[1])      /* If page address not NULL */
  3923.       {
  3924.       ulSize=1L;            /* One page         */
  3925.       DosQueryMem(           /* Query memory attributes  */
  3926.         (PVOID)pX->ExceptionInfo[1],  /* Page base address     */
  3927.         &ulSize,            /* Single page        */
  3928.         &ulAttribs);          /* Memory attributes     */
  3929.       if (((ulAttrs & PAG_FREE) ||   /* If page is available   */
  3930.         (ulAttrs & PAG_COMMIT))==0)  /* but is not committed   */
  3931.         {
  3932.         DosSetMem(           /* Commit page        */
  3933.          (PVOID)pX->ExceptionInfo[1], /* Page base address    */
  3934.          1L,             /* Single page only     */
  3935.          PAG_DEFAULT |        /* Default attributes    */
  3936.          PAG_COMMIT);        /* Set commit flag      */
  3937.         return(XCPT_CONTINUE_EXECUTION); /* Done          */
  3938.         }
  3939.       }
  3940.      }
  3941.    return(XCPT_CONTINUE_SEARCH);      /* Chain to next handler if */
  3942. }                       /* any other exception    */
  3943. Guard Page Exception Handler 
  3944.  
  3945. This exception handler also handles the situation where an application writes 
  3946. directly to an uncommitted page rather than to the guard page, as is possible 
  3947. with non-sequential write operations. 
  3948.  
  3949. The exception handler shown in Guard Page Exception Handler handles two types 
  3950. of exception:  the guard page exception and the page fault exception.  The 
  3951. latter occurs when an application attempts to write to an uncommitted page in 
  3952. the memory object that is not the guard page.  This can occur when a memory 
  3953. object is accessed in a non-sequential manner. 
  3954.  
  3955. The example shown above handles the guard page exception simply by committing 
  3956. the next page in the memory object, and making this page the new guard page. 
  3957. Guard page exceptions should not be allowed to pass through to the operating 
  3958. system's default guard page exception handler, since the default handler 
  3959. operates by committing the next lower page in the memory object and making this 
  3960. the new guard page.  This is done because the default handler is intended 
  3961. mainly to handle dynamic stack growth; stacks are always propagated downward. 
  3962.  
  3963. The exception handler shown in Guard Page Exception Handler also handles the 
  3964. page fault exception, where a write operation is attempted into a page other 
  3965. than the guard page, which has not previously been committed.  The exception 
  3966. handler responds to this exception by querying the properties of the page in 
  3967. question and, if the page has been allocated but not yet committed, proceeds to 
  3968. commit the page. 
  3969.  
  3970. If the page has not been allocated (that is, it does not lie within the 
  3971. boundaries of the memory object), or if the exception is neither a guard page 
  3972. exception nor a page fault exception, the exception handler does not process 
  3973. the exception, and returns control to the operating system, which will invoke 
  3974. any other exception handlers registered for the current thread (see Exception 
  3975. Handling). 
  3976.  
  3977. A guard page exception handler is registered by the application using the 
  3978. DosSetExceptionHandler() function.  This function is illustrated in Registering 
  3979. a Guard Page Exception Handler. 
  3980.  
  3981. EXCEPTIONREGISTRATIONRECORD Exception;
  3982.   :
  3983.   :
  3984. Exception.ExceptionHandler = (_ERR *)&GPHandler; /* Set entry point addr */
  3985.  
  3986. DosSetExceptionHandler(&Exception);        /* Register handler   */
  3987. Registering a Guard Page Exception Handler 
  3988.  
  3989. This example shows the use of the DosSetExceptionHandler() function. 
  3990.  
  3991. The DosSetExceptionHandler() function can also be used to register exception 
  3992. handlers for other types of system exception; see Exception Handling for 
  3993. further information. 
  3994.  
  3995. Note that OS/2 Version 2.0 provides its own exception handlers within the 
  3996. service layers for all 32-bit system functions.  These exception handlers allow 
  3997. the service routines to recover from page fault exceptions and general 
  3998. protection exceptions encountered due to bad pointers in applications' function 
  3999. calls.  The function call returns an ERROR_BAD_PARAMETER code rather than a 
  4000. Trap 00D or Trap 00E code, thereby allowing the application to recover.  This 
  4001. represents a significant enhancement over previous versions of OS/2, since it 
  4002. allows easier debugging and more flexible pointer handling. 
  4003.  
  4004.  
  4005. ΓòÉΓòÉΓòÉ 13.3. Suballocating Memory ΓòÉΓòÉΓòÉ
  4006.  
  4007. Under OS/2 Version 2.0, the granular unit of memory is the page. This means 
  4008. that the minimum possible memory allocation for a single DosAllocMem() function 
  4009. call is 4KB.  For example, if an application requests the allocation of 10 
  4010. bytes of storage, the operating system will allocate a full 4KB page; the 
  4011. remaining storage in this page will be wasted. 
  4012.  
  4013. It is therefore recommended that for dynamic allocation of small memory objects 
  4014. for uses such as instance data, each window procedure should use a single 
  4015. DosAllocMem() function call to allocate a storage pool, and subdivide this 
  4016. storage as required using the DosSubAlloc() function, as shown in Suballocating 
  4017. Memory. 
  4018.  
  4019. #define    POOLSIZE  8192        /* Size of storage pool    */
  4020. PVOID     pPool;            /* Base address of pool    */
  4021.  
  4022. CTRLSTRUCT1  *Struct1;           /* Control structure 1     */
  4023. CTRLSTRUCT2  *Struct2;           /* Control structure 2     */
  4024.  
  4025. DosAllocMem(&pPool,             /* Allocate storage for pool  */
  4026.       POOLSIZE,            /* Size of memory object    */
  4027.       PAG_READ  |           /* Allow read access      */
  4028.       PAG_WRITE |           /* Allow write access     */
  4029.       PAG_COMMIT);          /* Commit storage immediately */
  4030.  
  4031. DosSubSet(pPool,              /* Initialize for suballoc   */
  4032.      DOS_SUBINIT,           /* Initialize flag       */
  4033.      POOLSIZE);            /* Size of pool        */
  4034.  
  4035. DosSubAlloc(pPool,             /* Suballocate storage     */
  4036.       &Struct1,            /* Pointer to memory object  */
  4037.       sizeof(CTRLSTRUCT1));      /* Size of storage required  */
  4038. DosSubAlloc(pPool,             /* Suballocate storage     */
  4039.       &Struct2,            /* Pointer to memory object  */
  4040.       sizeof(CTRLSTRUCT2));      /* Size of storage required  */
  4041. Suballocating Memory 
  4042.  
  4043. Storage must be suballocated in multiples of 8 bytes.  Any requested 
  4044. suballocation which is not a multiple of 8 bytes will have its size rounded up 
  4045. to a multiple of 8 bytes. 
  4046.  
  4047. Storage to be suballocated must first be allocated using the DosAllocMem() 
  4048. function, and initialized for suballocation using the DosSubSet() function. 
  4049. Note that control information for the suballocation uses 64 bytes of the 
  4050. storage pool; this must be taken into account when determining the size 
  4051. requirements for the pool. 
  4052.  
  4053. In Suballocating Memory, the storage in the pool is committed during 
  4054. allocation, since the example assumes that the total storage requirement is 
  4055. known in advance. In situations where the exact size of the storage required is 
  4056. not known, the storage may be allocated but not committed, and the 
  4057. suballocation procedure will then progressively commit storage as required. 
  4058. This is indicated by specifying the DOS_SPARSE_OBJ flag in the DosSubSet() 
  4059. function call. 
  4060.  
  4061. Memory that has been suballocated using the DosSubAlloc() function may be freed 
  4062. using the DosSubFree() function.  The storage is then available for future 
  4063. suballocation.  Note, however, that the suballocation procedure does not 
  4064. reorganize suballocated memory objects within a pool.  Thus freeing objects 
  4065. within the pool may result in memory fragmentation. 
  4066.  
  4067. A storage pool initialized for suballocation using the DosSubSet() function 
  4068. should be removed using the DosSubUnset() function before the memory in the 
  4069. pool is freed.  This function call releases the operating system resources used 
  4070. by the suballocation procedure. 
  4071.  
  4072. When using the C Set/2 compiler, the malloc() function may be used to allocate 
  4073. memory.  This function has many of the advantages of the DosSubAlloc() 
  4074. function, but avoids the need for the application to explicitly allocate, set 
  4075. and suballocate memory.  The malloc() function also provides greater 
  4076. independence for application code from the platform upon which it executes, 
  4077. allowing the application to be more easily migrated to platforms other than 
  4078. OS/2 Version 2.0. 
  4079.  
  4080. The malloc() function works as follows: 
  4081.  
  4082.    o  The first call to malloc() from a particular application (process) causes 
  4083.       malloc() to request a memory object from the operating system. The 
  4084.       malloc() service routine adds 16 bytes to the size specified in the 
  4085.       function call, and rounds the result upward to the next even power of 2. 
  4086.       This amount of memory is then requested from the operating system using a 
  4087.       DosAllocMem() call.  The operating system will then allocate memory, 
  4088.       rounding the service routine's request size upward to the nearest 
  4089.       multiple of 4KB.  The malloc() function then fulfills the application's 
  4090.       request, with some wastage due to the page-granular allocation. 
  4091.  
  4092.    o  For subsequent calls to malloc(), the malloc() service routine first 
  4093.       checks whether it has sufficient memory remaining from a previous 
  4094.       request; if so, it allocates that memory and returns control to the 
  4095.       application.  If not, the service routine requests additional memory from 
  4096.       the operating system using the DosAllocMem() function. 
  4097.  
  4098.  Note that the free() function, used to free memory which has been allocated 
  4099.  using malloc(), does not return the memory to the operating system; rather, 
  4100.  that memory is held by malloc() for future use.  In order to return memory to 
  4101.  the operating system, the application must issue a heapmin() function call. 
  4102.  
  4103.  
  4104. ΓòÉΓòÉΓòÉ 13.4. Exception Handling ΓòÉΓòÉΓòÉ
  4105.  
  4106. The following outcomes are possible when a memory object is referenced by the 
  4107. application: 
  4108.  
  4109.    o  If the memory has not been allocated or committed, a general protection 
  4110.       exception (Trap 000D) will occur. 
  4111.  
  4112.    o  If the memory has been allocated but not committed, a page fault 
  4113.       exception (Trap 000E) will occur. 
  4114.  
  4115.       In both of the above cases, the exception is reported to the 
  4116.       application's general protection exception handler, if one has been 
  4117.       registered by the application.  The application may then deal with the 
  4118.       error.  If an exception handler has not been registered by the 
  4119.       application, the default exception handler provided by the operating 
  4120.       system will terminate the application. 
  4121.  
  4122.    o  If the page to be referenced has been defined as a guard page, a guard 
  4123.       page exception is generated.  If the application has not registered its 
  4124.       own handler for this exception, the system's default handler will commit 
  4125.       the page, and mark the next page in the memory object as the new guard 
  4126.       page for the object.  Once the guard page exception has been processed, 
  4127.       execution proceeds normally. 
  4128.  
  4129.    o  If none of the above conditions occur, the memory object is accessed and 
  4130.       execution proceeds normally. 
  4131.  
  4132.  Exception handlers for the various types of exception may be registered using 
  4133.  the DosSetExceptionHandler() function, as shown in Registering a Guard Page 
  4134.  Exception Handler. 
  4135.  
  4136.  Note that unlike previous versions of OS/2, application handlers need not be 
  4137.  written in assembly language;  high-level programming languages may be used. 
  4138.  
  4139.  Exception handlers are registered on a per-thread basis, and multiple 
  4140.  exception handlers may be registered for each thread.  When more than one 
  4141.  exception handler is registered, the handlers are chained, with the most 
  4142.  recent addition being placed at the start of the chain.  When an exception 
  4143.  occurs, control is passed to the first handler, which may handle the exception 
  4144.  and return XCPT_CONTINUE_EXECUTION, in which case the operating system returns 
  4145.  control to the application. 
  4146.  
  4147.  If the exception handler cannot handle a particular exception, it returns 
  4148.  XCPT_CONTINUE_SEARCH, in which case the operating system passes control to the 
  4149.  next exception handler in the chain.  In this way, control is eventually 
  4150.  passed to the operating system's default exception handlers. 
  4151.  
  4152.  When an exception handler is no longer required, it can be removed from the 
  4153.  chain using the DosUnsetExceptionHandler() function. 
  4154.  
  4155.  Exception handling and the various operating system exceptions that can occur 
  4156.  are described in the IBM OS/2 Version 2.0 Control Program Reference. 
  4157.  
  4158.  
  4159. ΓòÉΓòÉΓòÉ 13.5. Shared Memory Objects ΓòÉΓòÉΓòÉ
  4160.  
  4161. By default, memory objects allocated by an application are private to the 
  4162. process in which that application executes.  However, OS/2 allows memory to be 
  4163. shared among applications for interprocess communication.  Shared memory 
  4164. objects are allocated in a similar manner to private memory objects, using the 
  4165. DosAllocSharedMem() function. 
  4166.  
  4167. Note that while private memory objects are allocated using addresses upward 
  4168. from the lower limit of the process address space, shared memory objects are 
  4169. allocated downward from the upper limit of the process address space. Hence the 
  4170. private and shared memory arenas grow toward one another as more memory objects 
  4171. are allocated during execution. 
  4172.  
  4173. Shared memory objects may be freed in the same manner as private memory 
  4174. objects, using the DosFreeMem() function. 
  4175.  
  4176.  
  4177. ΓòÉΓòÉΓòÉ 13.5.1. Named versus Anonymous Shared Memory Objects ΓòÉΓòÉΓòÉ
  4178.  
  4179. Shared memory objects may be named or anonymous.  Named shared memory objects 
  4180. have names of the form: 
  4181.  
  4182. \SHAREMEM\<objectname.ext>
  4183.  
  4184. A named shared memory object may be accessed by another process using the 
  4185. DosGetNamedSharedMem() function. 
  4186.  
  4187. An anonymous shared memory object must be declared as "giveable" or "gettable" 
  4188. when it is allocated, in order that it may be made available to other processes 
  4189. using the DosGiveSharedMem() or DosGetSharedMem() functions.  An example is 
  4190. given in Allocating Shared Memory. 
  4191.  
  4192. MYSTRUCT *MYSTRUCT;
  4193. APIRET  rc;
  4194.  
  4195. rc = DosAllocSharedMem(&MyStruct,     /* Allocate memory object    */
  4196.             NULL,       /* Anonymous memory object    */
  4197.             sizeof(MYSTRUCT), /* Size of memory object     */
  4198.             OBJ_GIVEABLE |   /* Object is giveable      */
  4199.             PAG_WRITE   |   /* Write access is allowed    */
  4200.             PAG_READ   |   /* Read access is allowed    */
  4201.             PAG_COMMIT);    /* Commit storage immediately  */
  4202.  
  4203. rc = DosGiveSharedMem(MyStruct,      /* Give access to object     */
  4204.            pidOther,      /* Process to receive access   */
  4205.            PAG_WRITE |     /* Write access is allowed    */
  4206.            PAG_READ);     /* Read access is allowed    */
  4207. Allocating Shared Memory 
  4208.  
  4209. This example shows the use of the DosAllocSharedMem() function, declaring a 
  4210. memory object as "giveable". 
  4211.  
  4212. The DosGiveSharedMem() function can be used at any time to provide another 
  4213. process with a specified level of access to a memory object, provided that the 
  4214. owner of the memory object knows the process ID of the process to which access 
  4215. is to be given. 
  4216.  
  4217.  
  4218. ΓòÉΓòÉΓòÉ 13.5.2. Committing Shared Memory Objects ΓòÉΓòÉΓòÉ
  4219.  
  4220. Like private memory objects, shared memory objects have a distinction between 
  4221. allocating and committing storage.  Shared memory objects may be committed upon 
  4222. allocation, or subsequently using exception handlers and the DosSetMem() 
  4223. function.  The guard page technique may be used with shared memory objects as 
  4224. well as private memory objects. 
  4225.  
  4226. One distinction between shared memory objects and private memory objects is 
  4227. that private memory objects may be "de-committed" if the required amount of 
  4228. memory reduces during execution; that is, physical storage is released without 
  4229. releasing the corresponding address ranges in the process address space. 
  4230. Shared memory objects may not be de-committed, to avoid the situation where one 
  4231. process may de-commit a page that is being accessed by another process. 
  4232.  
  4233.  
  4234. ΓòÉΓòÉΓòÉ 13.6. Summary ΓòÉΓòÉΓòÉ
  4235.  
  4236. Dynamic memory allocation is greatly simplified under OS/2 Version 2.0, since 
  4237. the application developer is no longer required to explicitly code for the 
  4238. 80286 segmented memory model, with its size limitation of 64KB per segment. 
  4239. Larger units of memory may be allocated and manipulated as single units, 
  4240. simplifying application code and reducing development time for applications 
  4241. that manipulate large data structures. 
  4242.  
  4243. When executable modules compiled for different environments are executed within 
  4244. the same process, the operating system handles interaction between these 
  4245. modules through thunk layers.  The conversions made within the thunk layers are 
  4246. transparent to the application modules themselves, and do not require 
  4247. consideration by the application developer.  This enables executable files, 
  4248. dynamic link libraries, and resources from different environments to be mixed 
  4249. within the same application. 
  4250.  
  4251. In general, application developers using OS/2 Version 2.0 are provided with a 
  4252. greater level of function and, at the same time, may take advantage of greatly 
  4253. simplified application development through use of the 32-bit flat memory model, 
  4254. which removes much of the inherent complexity of memory manipulation within the 
  4255. application.  Developers may produce applications more efficiently under 
  4256. Version 2.0, and may easily migrate their applications to and from the OS/2 
  4257. Version 2.0 environment. 
  4258.  
  4259.  
  4260. ΓòÉΓòÉΓòÉ 14. Building a Presentation Manager Application ΓòÉΓòÉΓòÉ
  4261.  
  4262. While the steps necessary to create a Presentation Manager application are 
  4263. generally similar to those required to create any kind of application in the 
  4264. programmable workstation environment under OS/2, there are some specific 
  4265. considerations to be borne in mind with regard to the implementation of 
  4266. object-oriented concepts in Presentation Manager  applications, since the 
  4267. Presentation Manager environment does not force the application developer to 
  4268. obey such guidelines.  Therefore, this chapter  will discuss the implementation 
  4269. of the general concepts outlined in  The Presentation Manager Application 
  4270. Model, in such a way that they conform to  object-oriented principles and 
  4271. achieve the highest level of modularity. 
  4272.  
  4273. For the purposes of discussion, this chapter will assume that the source code 
  4274. is written using the "C" language. Other programming languages may be used to 
  4275. create Presentation Manager applications while preserving the overall 
  4276. application architecture, provided these languages support the creation of 
  4277. reentrant code and allow recursion. 
  4278.  
  4279.  
  4280. ΓòÉΓòÉΓòÉ 14.1. Language Considerations ΓòÉΓòÉΓòÉ
  4281.  
  4282. Presentation Manager applications may be written using the following 
  4283. programming languages: 
  4284.  
  4285.    o  Assembler language 
  4286.    o  "C" 
  4287.    o  COBOL/2 (after May 7th 1991) 
  4288.    o  FORTRAN (OS/2 Version 1.2 and above) 
  4289.  
  4290.  The use of Assembler language should be avoided wherever possible.  While 
  4291.  coding to such a low-level language may provide significant performance 
  4292.  improvements in critical applications, it is typically more  costly in terms 
  4293.  of programmer productivity and subsequent code maintenance.  Assembler code is 
  4294.  also less portable than that written using higher-level languages. 
  4295.  
  4296.  The requirements of the Presentation Manager execution environment restrict 
  4297.  the use of some COBOL and FORTRAN compilers.  Presentation Manager requires 
  4298.  window procedures to be reentrant, and a FORTRAN or COBOL compiler that 
  4299.  supports the creation of reentrant code must be used. In addition, much of the 
  4300.  default message processing provided by Presentation Manager results in 
  4301.  synchronous messages being sent to window procedures.  This practice is 
  4302.  effectively a recursive subroutine call, and requires window procedures to be 
  4303.  written in a language that supports recursion. 
  4304.  
  4305.  In order to create COBOL or FORTRAN source code that executes in the 
  4306.  Presentation Manager environment, from a compiler that does not support 
  4307.  reentrant or recursive procedures, the application developer must adopt one of 
  4308.  two solutions: 
  4309.  
  4310.    1. Create a "C" program to provide the Presentation Manager windowing and 
  4311.       dialog management functions, and combine this program with called COBOL 
  4312.       or FORTRAN subprograms to perform the actual processing for the 
  4313.       application. 
  4314.  
  4315.    2. Create a "winproc-less" application, where a main routine written in 
  4316.       COBOL or FORTRAN creates a message-processing loop, captures  and 
  4317.       explicitly processes all message classes.  Such an application has  no 
  4318.       window procedures. 
  4319.  
  4320.    3. Use the "language support window procedure" provided with the OS/2 
  4321.       Programmer's Toolkit under OS/2 Version 1┬╖3, which provides processing 
  4322.       for most message classes and returns selected messages to the application 
  4323.       for processing. 
  4324.  
  4325.  Where the use of COBOL or FORTRAN is unavoidable, solution (1) above is 
  4326.  recommended, since it provides additional flexibility, maintains SAA 
  4327.  conformance, retains much of the object-oriented nature of the application, 
  4328.  and allows the best use to be made of existing host COBOL or FORTRAN 
  4329.  application code, since the subprograms used are invoked using standard 
  4330.  language conventions, and data is passed to them using a  normal parameter 
  4331.  list and returned the same way.  The subprograms therefore interact with the 
  4332.  calling application in much the same way as an ISPF dialog, minimizing the 
  4333.  requirement for modification of existing code and reducing the need to retrain 
  4334.  application developers. 
  4335.  
  4336.  Object-oriented programming languages such as Smalltalk and C++ are becoming 
  4337.  increasingly popular for the creation of object-oriented code, and are 
  4338.  well-suited to the Presentation Manager application model.  Organizations may 
  4339.  wish to investigate the viability of these languages for particular 
  4340.  development projects and environments. 
  4341.  
  4342.  
  4343. ΓòÉΓòÉΓòÉ 14.2. Function and Data Types ΓòÉΓòÉΓòÉ
  4344.  
  4345. Presentation Manager provides a number of specialized function and data type 
  4346. definitions (such as MRESULT, MPARAM, etc.) for use by Presentation Manager 
  4347. applications.  While these type definitions are not "standard" C language 
  4348. types, their use is strongly recommended.  OS/2 maps these type definitions 
  4349. into standard C language types  using #define statements embedded in the OS/2 
  4350. header file os2.h.  Since the mapping may vary between OS/2 Version 1┬╖3 and 
  4351. Version 2.0  due to differences between the 16-bit and 32-bit operating system 
  4352. architectures, the use of Presentation Manager's type definitions insulates the 
  4353. application source code from the underlying architecture. 
  4354.  
  4355.  
  4356. ΓòÉΓòÉΓòÉ 14.3. Object-Oriented Programming Practices ΓòÉΓòÉΓòÉ
  4357.  
  4358. While Presentation Manager allows an application developer to implement the 
  4359. fundamental concepts of object-oriented programming in his or her applications, 
  4360. it does not restrict the application developer to the use  of these 
  4361. conventions. Therefore to ensure the correct implementation  of object-oriented 
  4362. conventions and to enable the maximum level of granularity, a number of 
  4363. guidelines are offered: 
  4364.  
  4365.    o  The use of multi-purpose application objects (window procedures) should 
  4366.       be avoided;  for example, a single window procedure should not handle 
  4367.       both user interaction and file access.  Manipulation of separate data 
  4368.       objects should be achieved using separate window procedures. Background 
  4369.       data objects (that is, files or databases) should be manipulated using 
  4370.       object windows. 
  4371.  
  4372.    o  As a corollary of the above rule, multiple window procedures should not 
  4373.       be created to act upon a single data object; where possible, all actions 
  4374.       on a particular data object should be performed by a single window 
  4375.       procedure.  This behavior simplifies any future maintenance should the 
  4376.       definition of the logical data entity or its representation change.  Note 
  4377.       that this guideline may need to be overridden in circumstances where an 
  4378.       action requires lengthy processing, in order to preserve application 
  4379.       responsiveness. 
  4380.  
  4381.    o  The definition, creation and/or establishment of access to data objects 
  4382.       should be achieved, where possible, from within a window procedure in 
  4383.       order to preserve the concept of data encapsulation.  That is to say, the 
  4384.       use of global data should be minimized in order to enhance modularity and 
  4385.       maximize object independence. 
  4386.  
  4387.    o  The input, output and behavior associated with a window procedure should 
  4388.       depend solely on the class and contents of the messages it receives, and 
  4389.       should not depend on any other external data or parameter, other than a 
  4390.       data structure to which a pointer is passed as a message parameter.  This 
  4391.       preserves the concept of object polymorphism and enhances the potential 
  4392.       for reuse. 
  4393.  
  4394.  These guidelines, when obeyed, will enable an application to conform to the 
  4395.  established guidelines for object-oriented programming as discussed  in 
  4396.  Object-Oriented Applications. 
  4397.  
  4398.  
  4399. ΓòÉΓòÉΓòÉ 14.4. Application Main Routine ΓòÉΓòÉΓòÉ
  4400.  
  4401. A sample application main routine is illustrated in Sample Application Main 
  4402. Routine (Part 1) - Registration and Sample Application Main Routine (Part 2) - 
  4403. Window Creation.  The functions performed by the main routine are as follows: 
  4404.  
  4405.    1. Register the application to Presentation Manager, and obtain an anchor 
  4406.       block handle (that is, an application handle), using the WinInitialize() 
  4407.       function. 
  4408.  
  4409.    2. Create a message queue, into which Presentation Manager will place all 
  4410.       messages intended for the application, using the WinCreateMsgQueue() 
  4411.       function and passing both the anchor block handle and the required queue 
  4412.       size to Presentation Manager, which returns a message queue handle to the 
  4413.       application.  Note that if the queue size specified is zero (as shown in 
  4414.       the example above) then the default queue size of 10 messages is used. 
  4415.  
  4416.    3. Register one or more window classes, for the windows that will be created 
  4417.       by the application, and associate a window procedure with each window 
  4418.       class, using using the WinRegisterClass() function.  Parameters passed to 
  4419.       this function include the name of the window class and the name of the 
  4420.       window procedure to be associated with the class.  Presentation Manager 
  4421.       returns a Boolean value indicating success or failure.  Note the 4 bytes 
  4422.       (32 bits) requested for window words, which may be used by the window 
  4423.       procedure to store the address of its instance data block. 
  4424.  
  4425.             #define  INCL_WIN
  4426.             #include <os2.h>
  4427.  
  4428.             #define  WCP_MAIN   "WCP_MAIN"
  4429.  
  4430.             MRESULT EXPENTRY wpMain(HWND,ULONG,MPARAM,MPARAM);
  4431.  
  4432.             int main()
  4433.             {
  4434.               struct MYSTRUCT InitData;
  4435.  
  4436.               static CHAR szTitle[] = "Main Window";
  4437.  
  4438.               FRAMECDATA fcdata;          /* Control data for window  */
  4439.               HAB   hAB;             /* Anchor block handle    */
  4440.               HMQ   hMsgQ;            /* Message queue handle    */
  4441.               HWND  hFrame, hClient;       /* Window handles       */
  4442.               QMSG  qMsg;             /* Message queue structure  */
  4443.               APIRET rc;              /* Flag            */
  4444.  
  4445.               memset(&fcdata,0,sizeof( fcdata );  /* Initialize         */
  4446.               fcdata.cb    = sizeof( fcdata );
  4447.  
  4448.               hAB  = WinInitialize(0);      /* Register appl. to PM    */
  4449.               hMsgQ = WinCreateMsgQueue(hAB,0);  /* Create message queue    */
  4450.  
  4451.               rc = WinRegisterClass(hAB,      /* Register window class   */
  4452.                          WCP_MAIN,   /* Name of class       */
  4453.                          wpMain,    /* Window procedure name   */
  4454.                          0L,      /* No style          */
  4455.                          4);      /* 32 bits in window words  */
  4456.       Sample Application Main Routine (Part 1) - Registration 
  4457.  
  4458.    4. Create a main display window for the application, using two consecutive 
  4459.       WinCreateWindow() calls (as shown in Sample Application Main Routine 
  4460.       (Part 2) - Window Creation) or a single WinCreateStdWindow() call.  Note 
  4461.       the separate handles used for the frame and client windows. The values 
  4462.       specified for fcdata.flCreateFlags control the appearance of the window, 
  4463.       the controls it contains and its position on the screen. 
  4464.  
  4465.    5. Optionally, create an entry for the application in the Workplace Shell 
  4466.       Window List, using the WinAddSwitchEntry() function.  Note that this step 
  4467.       is omitted from Sample Application Main Routine (Part 2) - Window 
  4468.       Creation for reasons of clarity, and is shown separately in 
  4469.       WinAddSwitchEntry() Function. 
  4470.  
  4471.       Note that under OS/2 Version 2.0, the WinCreateSwitchEntry() function is 
  4472.       provided in addition to the WinAddSwitchEntry() function. These two 
  4473.       functions accept identical parameters and carry out identical tasks; the 
  4474.       WinCreateSwitchEntry() function is intended to provide consistent 
  4475.       function naming conventions.  The WinAddSwitchEntry() function is 
  4476.       retained under OS/2 Version 2.0 for compatability with existing 
  4477.       applications, but use of the WinCreateSwitchEntry() function is 
  4478.       recommended. 
  4479.  
  4480.    6. Establish a message processing loop, whereby the application requests 
  4481.       Presentation Manager to supply messages from the system queue and 
  4482.       subsequently invokes Presentation Manager to dispatch them to the 
  4483.       appropriate window procedure. This loop uses nested WinGetMsg() and 
  4484.       WinDispatchMsg() calls. 
  4485.  
  4486.    7. Upon receivng the special message class WM_QUIT, which will cause 
  4487.       WinGetMsg() to return false and hence terminate the while loop, remove 
  4488.       any remaining windows using the WinDestroyWindow() function, remove the 
  4489.       application's entry from the Window List using the WinRemoveSwitchEntry() 
  4490.       function, destroy the message queue and deregister the application before 
  4491.       terminating.  These latter functions are achieved using the 
  4492.       WinDestroyMsgQueue() and WinTerminate() calls. 
  4493.  
  4494.      fcdata.flCreateFlags = FCF_TITLEBAR    |  FCF_SYSMENU  |
  4495.                 FCF_SIZEBORDER   |  FCF_MINMAX   |
  4496.                 FCF_SHELLPOSITION;
  4497.  
  4498.     hFrame=WinCreateWindow(HWND_DESKTOP,   /* Create frame window    */
  4499.                 WC_FRAME,     /* Frame window class     */
  4500.                 (PSZ)0,      /* No window text       */
  4501.                 0L,        /* No style          */
  4502.                 0,0,0,0,     /* PM shell will position   */
  4503.                 (HWND)0,     /* No owner          */
  4504.                 HWND_TOP,     /* On top of siblings     */
  4505.                 0,        /* No window identifier    */
  4506.                 &fcdata,     /* Frame control data     */
  4507.                 0);        /* Presentation parameters  */
  4508.     hClient=WinCreateWindow(hFrame,     /* Create client window    */
  4509.                 WCP_MAIN,    /* Window class        */
  4510.                 szTitle,     /* Window title        */
  4511.                 01,       /* Standard style       */
  4512.                 0,0,0,0,     /* PM shell will position   */
  4513.                 (HWND)0,     /* No owner          */
  4514.                 HWND_TOP,    /* On top of siblings     */
  4515.                 FID_CLIENT,   /* Client window identifier  */
  4516.                 &InitData,    /* Initialization data    */
  4517.                 0);       /* Presentation parameters  */
  4518.  
  4519.     /*   <Create Window List entry for application>           */
  4520.  
  4521.     while (WinGetMsg(hAB, &qMsg, 0, 0, 0))
  4522.        WinDispatchMsg(hAB, &qMsg);
  4523.  
  4524.     /*   <Remove Window List entry for application>           */
  4525.  
  4526.     WinDestroyWindow(hFrame);        /* Destroy frame & children  */
  4527.     WinDestroyMsgQueue(hMsgQ);        /* Destroy message queue   */
  4528.     WinTerminate(hAB);            /* Deregister application   */
  4529.   }
  4530.  Sample Application Main Routine (Part 2) - Window Creation 
  4531.  
  4532.  The structure of the main routine is similar for both the application (that 
  4533.  is, the application's primary thread) and any secondary threads created by the 
  4534.  application.  See Multitasking Considerations for further discussion on 
  4535.  secondary threads. 
  4536.  
  4537.  In Sample Application Main Routine (Part 1) - Registration, note the use of 
  4538.  the EXPENTRY keyword in the function prototype to specify the system linkage 
  4539.  convention for the window procedure wpMain.  This is required whenever 
  4540.  declaring a window procedure or dialog procedure, since such procedures are 
  4541.  normally invoked by Presentation Manager on the application's behalf, rather 
  4542.  than directly by the application. 
  4543.  
  4544.  If the application is to appear in and be selectable from the Workplace Shell 
  4545.  Window List, the main routine must issue a WinAddSwitchEntry() function call, 
  4546.  after creating the application's main window and before entering the message 
  4547.  processing loop. [Note that under OS/2 Version 2.0, use of the 
  4548.  WinCreateSwitchEntry() function is recommended, for reasons of consistency in 
  4549.  function names. ] This function call is shown in WinAddSwitchEntry() Function. 
  4550.  
  4551.   SWCNTRL  SwitchData;            /* Switch control data block  */
  4552.   HSWITCH  hSwitch;              /* Switch entry handle     */
  4553.     :
  4554.     :
  4555.   SwitchData.hwnd = hFrame;          /* Set frame window handle   */
  4556.   SwitchData.hwndIcon = 0;          /* Use default icon      */
  4557.   SwitchData.hprog = 0;            /* Use default program handle */
  4558.   SwitchData.idProcess = 0;          /* Use current process id   */
  4559.   SwitchData.idSession = 0;          /* Use current session id   */
  4560.   SwitchData.uchVisibility = SWL_VISIBLE;   /* Make visible        */
  4561.   SwitchData.fbJump = SWL_JUMPABLE;      /* Make jumpable via Alt+Esc  */
  4562.   SwitchData.szSwTitle[0] = '\0';       /* Use default title text   */
  4563.  
  4564.   hSwitch = WinAddSwitchEntry(&SwitchData);  /* Add switch entry      */
  4565.  WinAddSwitchEntry() Function 
  4566.  
  4567.  This function adds the application to the OS/2 Window List. Note that under 
  4568.  OS/2 Version 2.0, the WinCreateSwitchEntry() function should be used. 
  4569.  
  4570.  Note that the application may set the swTitle field of the SwitchData 
  4571.  structure to NULL.  Presentation Manager will then determine the title under 
  4572.  which the application was started from the Presentation Manager shell, and use 
  4573.  this title for the switch entry. 
  4574.  
  4575.  The WinAddSwitchEntry() function returns a switch entry handle, which may be 
  4576.  stored by the application and used during termination to remove the switch 
  4577.  entry from the Workplace Shell Window List using the WinRemoveSwitchEntry() 
  4578.  function. 
  4579.  
  4580.  The switch entry may be accessed by a window procedure at any time during 
  4581.  application execution.  The switch entry handle is obtained using the 
  4582.  WinQuerySwitchHandle() function, and the SwitchData control structure may then 
  4583.  be obtained using the WinQuerySwitchEntry() function, and altered using the 
  4584.  WinChangeSwitchEntry() function.  This capability may be used to allow a 
  4585.  window procedure to obtain the handle of the application's main window, in 
  4586.  order to post or send messages to that window.  This is discussed in 
  4587.  Identifying the Destination Window. 
  4588.  
  4589.  
  4590. ΓòÉΓòÉΓòÉ 14.5. Using Windows ΓòÉΓòÉΓòÉ
  4591.  
  4592. As mentioned in Window Procedures, window procedures within a Presentation 
  4593. Manager application are reentrant; that is, the same window procedure is used 
  4594. for multiple instances of the same window class.  However, a window class may 
  4595. have separate data objects associated with each instance of that class, which 
  4596. may be used to store temporary data necessary during the existence of that 
  4597. object;  such data is known as instance data.  These data objects may need to 
  4598. be  created/opened and initialized.  Upon the window being closed, data 
  4599. objects may need to be closed or destroyed in a controlled fashion. 
  4600.  
  4601. Presentation Manager allows such function to be performed by a window 
  4602. procedure, since messages are sent to a window by Presentation Manager 
  4603. informing the window procedure of events such as creation or closure of the 
  4604. window.  These messages are discussed below. 
  4605.  
  4606.  
  4607. ΓòÉΓòÉΓòÉ 14.5.1. Window Creation ΓòÉΓòÉΓòÉ
  4608.  
  4609. A window is created by Presentation Manager in response to the application 
  4610. issuing  a WinCreateStdWindow() function call or a WinCreateWindow() call; an 
  4611. example of the WinCreateWindow() call is given in Sample Application Main 
  4612. Routine (Part 2) - Window Creation. 
  4613.  
  4614. The first statement in the example specifies the attributes of the frame 
  4615. window, which are contained in the data variable fcdata.flCreateFlags. These 
  4616. values determine the control windows that are created with the frame window 
  4617. (FCF_SYSMENU, FCF_MINMAX etc), and also indicate to Presentation Manager that 
  4618. it should select the position of the window on the desktop (FCF_SHELLPOSITION). 
  4619.  
  4620. The window is then created in two steps; firstly the frame window is created, 
  4621. with the desktop as its parent, and then the client window is created with the 
  4622. frame window as its parent.  The frame window belongs to the system-defined 
  4623. window class WC_FRAME, whereas the client window belongs to an 
  4624. application-defined window class WCP_MAIN, which is assumed to have already 
  4625. been defined to Presentation Manager using a WinRegisterClass() call. 
  4626.  
  4627. If it is necessary to pass initialization information to a window upon its 
  4628. creation, this may be achieved using the CtlData parameter in the 
  4629. WinCreateWindow() function.  This parameter  is a 32-bit pointer, which may 
  4630. reference an application-defined data  structure.  This pointer is passed to 
  4631. the window as the first parameter  of the WM_CREATE message.  The window may, 
  4632. during its processing of  this message, extract the pointer from the message 
  4633. parameter and use it  to access the data structure.  See Sample Application 
  4634. Main Routine (Part 2) - Window Creation for an  example of this technique. 
  4635.  
  4636. When an application requests that Presentation Manager creates a window of a 
  4637. particular class, a message of the system-defined class WM_CREATE is sent to 
  4638. the window procedure associated with that class.  The window procedure may 
  4639. capture this message by including a case for it, and perform any processing 
  4640. such as opening files or databases, allocating memory objects and setting 
  4641. instance data to initial default values. 
  4642.  
  4643. In coding the method for this message class, the first statement should be a 
  4644. call to WinDefWindowProc(), which will enable Presentation Manager to perform 
  4645. default processing and complete the initialization of  the window (such as 
  4646. allocating a window handle) before the application-specific processing is 
  4647. carried out.  If the default processing is not completed first, the window 
  4648. handle and any window words may not be allocated before the application makes 
  4649. function calls that reference them, thus causing these calls to fail. 
  4650.  
  4651. Where instance data or resource handles will be used by the window, and must be 
  4652. maintained beyond the processing of a single message, a data structure should 
  4653. be defined to contain these items.  Memory for the data structure should be 
  4654. requested from the operating system, and a  pointer to the memory object stored 
  4655. in the window words, as part of the  WM_CREATE processing.  See Instance Data 
  4656. and Window Words for further information. 
  4657.  
  4658.  
  4659. ΓòÉΓòÉΓòÉ 14.5.2. Window Processing ΓòÉΓòÉΓòÉ
  4660.  
  4661. During execution, a window processes messages passed to it by Presentation 
  4662. Manager, using the methods defined in its window procedure.  Upon receiving a 
  4663. message, the window procedure performs three basic tasks: 
  4664.  
  4665.    1. The window procedure determines the message class by examining the 
  4666.       message class identifier. 
  4667.  
  4668.    2. Depending upon the message class, the window procedure executes a series 
  4669.       of application instructions and/or subroutines to perform the action 
  4670.       requested by the message. 
  4671.  
  4672.    3. The window procedure passes a return code to Presentation Manager. 
  4673.  
  4674.  As part of the second step above, the window procedure may extract necessary 
  4675.  information from the parameters passed with the message, using a number of 
  4676.  macros provided by Presentation Manager.  These macros are described in 
  4677.  Creating Message Parameters. 
  4678.  
  4679.  The window procedure may also gain access to instance data or resource handles 
  4680.  stored in a control block during processing of previous messages. This control 
  4681.  block is generally allocated upon creation of the window and a pointer to it 
  4682.  stored in the window words.  The window procedure may retrieve this pointer 
  4683.  from the window words at  the start of processing for the current message. 
  4684.  SeeInstance Data and Window Words. 
  4685.  
  4686.  
  4687. ΓòÉΓòÉΓòÉ 14.5.3. Window Closure ΓòÉΓòÉΓòÉ
  4688.  
  4689. A window is closed (removed from the screen and destroyed) by Presentation 
  4690. Manager  in response to the application issuing a WinDestroyWindow() call, 
  4691. specifying the handle of the window to be destroyed.  In normal circumstances 
  4692. the handle of the frame window is specified; destroying the frame window 
  4693. destroys that window and all of its children, including the client window 
  4694. associated with that frame. 
  4695.  
  4696. When an application requests that Presentation Manager close a window, a 
  4697. system-defined message of class WM_DESTROY is sent to the client window, and 
  4698. thus to the window procedure associated with that class.  The window procedure 
  4699. may capture and process this message, backing out any uncompleted units of 
  4700. work, and destroying or terminating access to data objects.  The window 
  4701. procedure should then return a value of zero. 
  4702.  
  4703. Note that although closing and destroying a parent window will also close and 
  4704. destroy all children of that window, the WM_DESTROY message is sent to the 
  4705. parent window, and processed before the children are destroyed.  Hence when 
  4706. processing a WM_DESTROY message, a window procedure may assume that all its 
  4707. children still exist. 
  4708.  
  4709. If the user explicitly requests closure of a window by selecting the  "Close" 
  4710. option on the system menu, a system-defined message of  class WM_CLOSE is sent 
  4711. to the window procedure.  The window procedure  may also capture and process 
  4712. this message in a similar manner to that  used for WM_DESTROY messages. 
  4713.  
  4714. Note that explicit processing of the WM_CLOSE message class is recommended for 
  4715. all Presentation Manager windows, since the default processing provided by 
  4716. Presentation Manager causes a WM_QUIT message to be posted to the application's 
  4717. message queue. This may result in unwarranted termination of the application. 
  4718. The window procedure for a child window should process a WM_CLOSE message by 
  4719. issuing a WinDestroyWindow() call for its frame window.  The window procedure 
  4720. for an application's main window should process a WM_CLOSE message by posting a 
  4721. WM_QUIT message to itself.  This will cause the application to terminate (see 
  4722. Terminating an Application). 
  4723.  
  4724. In order to handle the closure of a window in the most elegant manner, the 
  4725. following course of action is recommended: 
  4726.  
  4727.    o  Explicit processing should be provided for both WM_CLOSE and WM_DESTROY 
  4728.       messages: 
  4729.  
  4730.         -  A window procedure should process a WM_CLOSE message by issuing a 
  4731.            WinDestroyWindow() call for its own frame window if it is a child 
  4732.            window, or a WM_QUIT message to itself if it is an application's 
  4733.            main window.  In both cases, the window procedure should then return 
  4734.            a value of zero. 
  4735.  
  4736.         -  A window procedure should process a WM_DESTROY message by closing 
  4737.            any files or databases that it has opened, and freeing any resources 
  4738.            such as memory objects. 
  4739.  
  4740.    o  Selection of the "Exit" option from a menu bar should result in the 
  4741.       closure of the window to which the menu bar belongs, by  having the 
  4742.       window procedure issue a WinDestroyWindow() call for its frame window. If 
  4743.       the window is the application's main window, it should be closed by 
  4744.       having the window procedure post a WM_QUIT message to itself (see 
  4745.       Terminating an Application).  This will result in a WM_DESTROY message 
  4746.       being posted to the main window and each of its children as part of the 
  4747.       application's termination processing.  These messages may be captured and 
  4748.       processed by the appropriate window procedures in order to close data 
  4749.       objects, back out incomplete units of work, etc. 
  4750.  
  4751.  The release of data objects and Presentation Manager resources is discussed in 
  4752.  Instance Data and Window Words. 
  4753.  
  4754.  
  4755. ΓòÉΓòÉΓòÉ 14.5.4. Instance Data and Window Words ΓòÉΓòÉΓòÉ
  4756.  
  4757. For data that is private to a particular instance of a window class, each 
  4758. window may have an area of storage associated with it, assigned by Presentation 
  4759. Manager and located within the Presentation Manager control block for that 
  4760. window.  This area is known as the window words. The amount of space allocated 
  4761. for window words in a particular window class is variable, and is defined in 
  4762. the WinRegisterClass() function call at the time the class is registered to 
  4763. Presentation Manager. 
  4764.  
  4765. It is recommended that for storage of amounts of data larger than four bytes, a 
  4766. memory object is obtained from the operating system using  the DosAllocMem() or 
  4767. DosSubAlloc() functions, and a pointer to this object is placed in the window 
  4768. words of the associated window.  An example of this technique is given in 
  4769. Storing Instance Data in Window Words. 
  4770.  
  4771. MYSTRUCT *MyStruct;
  4772.   :
  4773. switch (ulMsg)                /* Switch on message class  */
  4774.     {
  4775.     case WM_CREATE:
  4776.       WinDefWindowProc(hWnd,      /* Perform default init    */
  4777.                ulMsg,
  4778.                mp1,
  4779.                mp2);
  4780.       DosAllocMem(MyStruct,      /* Allocate memory object   */
  4781.             sizeof(MYSTRUCT),  /* Size of memory object   */
  4782.             PAG_READ  |     /* Allow read access     */
  4783.             PAG_WRITE |     /* Allow write access     */
  4784.             PAG_COMMIT);     /* Commit storage now     */
  4785.       hFrame=WinQueryWindow(hwnd,   /* Get frame window handle  */
  4786.                  QW_PARENT,
  4787.                  FALSE);
  4788.       WinSetWindowULong(hFrame,    /* Place pointer in window  */
  4789.                QWL_USER,   /* words           */
  4790.                (ULONG)MyStruct);
  4791.       return((MRESULT)0);
  4792.       break;
  4793.        :
  4794. Storing Instance Data in Window Words 
  4795.  
  4796. This example shows the allocation of a memory object, and the storage of a 
  4797. pointer to that memory object in window words. 
  4798.  
  4799. A memory object corresponding to the size of the data structure MYSTRUCT is 
  4800. obtained from the operating system using the DosAllocMem() function, and a 
  4801. pointer to this memory object is set by the application. This pointer is then 
  4802. placed in the window words of the current window's parent (that is, the frame 
  4803. window) using the WinSetWindowULong() function, at offset QWL_USER.  A number 
  4804. of predefined Presentation Manager window classes, including the frame window 
  4805. class, contain a 32-bit word at this offset, which is available for application 
  4806. use. 
  4807.  
  4808. Note the use of the PAG_COMMIT flag in the DosAllocMem() function call. This 
  4809. flag causes storage to be allocated immediately for the memory object being 
  4810. created, since OS/2 Version 2.0 by default uses a two-phase process for dynamic 
  4811. memory allocation. 
  4812.  
  4813. The concept of committing memory is new to Version 2.0, and allows a storage 
  4814. map for the application to be defined, but the storage is not reserved in 
  4815. memory until it is needed, at which time the application may explicitly commit 
  4816. the storage using the DosSetMem() function.  Optionally, the application may 
  4817. set the PAG_COMMIT flag in the DosAllocMem() function call to commit the 
  4818. storage immediately upon allocation. 
  4819.  
  4820. Failure to commit storage, either by use of the PAG_COMMIT flag or the 
  4821. DosSetMem() function, will result in a page fault exception (Trap 000E) when 
  4822. the application attempts to write to the storage area.  The concept of 
  4823. allocating and committing storage is explained fully in OS/2 Version 2.0 - 
  4824. Volume 1:  Control Program, and the use of these techniques by applications is 
  4825. described in The Flat Memory Model. 
  4826.  
  4827. After the memory object containing instance data is initially allocated, the 
  4828. window procedure may access it during processing of subsequent messages by 
  4829. issuing a WinQueryWindowULong() call to Presentation Manager, as shown in 
  4830. Retrieving Instance Data from Window Words. 
  4831.  
  4832.     case WMP_MYMESSAGE:
  4833.       hFrame=WinQueryWindow(hwnd,
  4834.                  QW_PARENT,
  4835.                  FALSE);
  4836.       MyStruct=WinQueryWindowULong(hFrame,
  4837.                      QWL_USER);
  4838.       <Perform action>
  4839.       return((MRESULT)0);
  4840.       break;
  4841.        :
  4842. Retrieving Instance Data from Window Words 
  4843.  
  4844. Upon termination of the window by the application, the window procedure 
  4845. receives a WM_DESTROY message.  As described in Window Closure , the window 
  4846. procedure should process this message by releasing any resources to which it 
  4847. has access.  This includes the instance data control block, which must be 
  4848. released using the DosFreeMem() function as shown in Releasing Instance Data 
  4849. Storage. 
  4850.  
  4851.     case WM_DESTROY:
  4852.       hFrame=WinQueryWindow(hwnd,
  4853.                  QW_PARENT,
  4854.                  FALSE);
  4855.       MyStruct=WinQueryWindowULong(hFrame,
  4856.                      QWL_USER);
  4857.       <Release data objects>
  4858.       <Release Presentation Manager resources>
  4859.       DosFreeMem(MyStruct);
  4860.       return((MRESULT)0);
  4861.       break;
  4862.        :
  4863. Releasing Instance Data Storage 
  4864.  
  4865. In the above example, the pointer to the instance data control block is first 
  4866. retrieved from the window words, giving access to the handles of any data 
  4867. objects or Presentation Manager resources obtained by the window, in order that 
  4868. these may be released.  Once this has been achieved, the memory object 
  4869. containing the control block is released by the window procedure.  Failure to 
  4870. release the data objects and resources before freeing the memory object would 
  4871. result in a general protection exception (Trap 000D) when the data objects or 
  4872. resources were subsequently released. 
  4873.  
  4874.  
  4875. ΓòÉΓòÉΓòÉ 14.5.5. Subclassing a Window ΓòÉΓòÉΓòÉ
  4876.  
  4877. The use of subclassing to modify the methods of an existing window class has 
  4878. been described in Subclassing.  An application subclasses a particular window 
  4879. instance (rather than the entire window class) by creating a subclass window 
  4880. procedure, and registering this window procedure to Presentation Manager using 
  4881. the WinSubclassWindow() function. 
  4882.  
  4883. The use of the WinSubclassWindow() function is shown in WinSubclassWindow() 
  4884. Function. 
  4885.  
  4886. PFNWP pOldWinProc;
  4887.  
  4888. pOldWinProc = WinSubclassWindow(hWnd, wpSubclass);
  4889. WinSubclassWindow() Function 
  4890.  
  4891. The WinSubclassWindow() function substitutes a new window procedure, known as 
  4892. the subclass window procedure, for the original window procedure associated 
  4893. with the window being subclassed.  The window handle of the window, along with 
  4894. the entry point of the  subclass window procedure, is passed to the 
  4895. WinSubclassWindow() function.  The function returns the entry point address of 
  4896. the original window procedure for that window. 
  4897.  
  4898. Once a window has been subclassed, Presentation Manager routes messages 
  4899. destined for that window to the subclass window procedure. The subclass window 
  4900. procedure may: 
  4901.  
  4902.    o  Process the message itself, if it indicates an action for which the 
  4903.       method must be modified. 
  4904.  
  4905.       The subclass window procedure then returns control immediately to 
  4906.       Presentation Manager. 
  4907.  
  4908.    o  Pass the message on to the original window procedure for that window, if 
  4909.       the subclass window procedure is not explicitly concerned with the action 
  4910.       indicated by the message. 
  4911.  
  4912.       The original window procedure is directly invoked by the subclass window 
  4913.       procedure; note that this is one of the few instances where direct 
  4914.       invocation of a window procedure is recommended.  The return code from 
  4915.       the original window procedure is then returned to Presentation Manager. 
  4916.  
  4917.    o  Both of the above, if the subclass window procedure must perform some 
  4918.       processing in addition to that normally performed by the original window 
  4919.       procedure. 
  4920.  
  4921.       The additional processing performed by the subclass window procedure may 
  4922.       be performed either before or after the processing performed by the 
  4923.       original window procedure.  This sequence is at the discretion of the 
  4924.       application developer, and depends largely on the desired modification in 
  4925.       the window's behavior. 
  4926.  
  4927.  A subclass window procedure is similar in structure to a "normal" window 
  4928.  procedure, except that instead of calling the WinDefWindowProc() function as 
  4929.  its default case, it should invoke the original window procedure.  This means 
  4930.  that the entry point address of the original window procedure must be known to 
  4931.  and accessible from the subclass window procedure.  Note also that the entry 
  4932.  point address might not be that of the original window procedure specified 
  4933.  when the window class was registered to Presentation Manager, since the window 
  4934.  might previously have been subclassed, and the current subclassing operation 
  4935.  might be effectively subclassing the subclass window procedure. 
  4936.  
  4937.  The entry point address of the original procedure can be supplied to the 
  4938.  subclass window procedure in a number of ways: 
  4939.  
  4940.    o  It may be determined from the information returned by the 
  4941.       WinSubclassWindow() call, and passed to the subclass window procedure in 
  4942.       an application-defined message.  The subclass window procedure may then 
  4943.       store the entry point address in a global variable or in the window words 
  4944.       of the window, assuming the available window words are not already in 
  4945.       use. 
  4946.  
  4947.    o  It may be determined by the subclass window procedure itself by querying 
  4948.       Presentation Manager.  Note, however, that this method will only work if 
  4949.       the window has not previously been subclassed, since Presentation Manager 
  4950.       only records the original window procedure (as specified in the 
  4951.       WinRegisterClass() function call) in the CLASSINFO structure for the 
  4952.       window. 
  4953.  
  4954.  An example of a subclass window procedure, including a query to obtain the 
  4955.  original entry point address from the Presentation Manager class information, 
  4956.  is given in Subclass Window Procedure. 
  4957.  
  4958.   MRESULT EXPENTRY wpSubclass(HWND  hWnd,
  4959.                 ULONG  ulMsg,
  4960.                 MPARAM mp1,
  4961.                 MPARAM mp2)
  4962.   {
  4963.       CHAR    szClass[7];
  4964.       CLASSINFO WinClass;
  4965.       PFNWP   pWinProc;
  4966.  
  4967.       BOOL    bSuccess;
  4968.       ULONG   ulRetLength;
  4969.  
  4970.       switch (ulMsg)
  4971.           {
  4972.           case WMP_MESSAGE1:
  4973.                :
  4974.             <Perform application specific processing>
  4975.                :
  4976.             return((MRESULT)0);
  4977.             break;
  4978.           case WMP_MESSAGE2:
  4979.                :
  4980.             <Perform application specific processing>
  4981.                :
  4982.             break;
  4983.           default:
  4984.             break;
  4985.           }
  4986.       ulRetLength=WinQueryClassName(hWnd,
  4987.                      sizeof(szClass),
  4988.                      szClass);
  4989.       bSuccess=WinQueryClassInfo(NULL,
  4990.                     szClass,
  4991.                     &WinClass);
  4992.       pWinProc=WinClass.pfnWindowProc;
  4993.       return((MRESULT)(*pWinProc)(hWnd,
  4994.                     ulMsg,
  4995.                     mp1,
  4996.                     mp2);
  4997.   }
  4998.  
  4999.  Subclass Window Procedure 
  5000.  
  5001.  Subclass Window Procedure shows each of the possible cases listed above.  The 
  5002.  message class WMP_MESSAGE1 is explicitly processed by the subclass window 
  5003.  procedure, which then returns control to Presentation Manager with a return 
  5004.  statement upon completion. 
  5005.  
  5006.  The message class WMP_MESSAGE2 is also explicitly processed by the subclass 
  5007.  window procedure, but in this case it is required that the processing 
  5008.  performed by the original window procedure be allowed to occur, after the 
  5009.  subclass window procedure's processing.  The subclass window procedure 
  5010.  therefore does not return control immediately to Presentation Manager, but 
  5011.  merely terminates the switch statement, allowing  the final four statements to 
  5012.  be executed. 
  5013.  
  5014.  For other message classes with which the subclass window procedure is not 
  5015.  concerned, the default case also terminates the switch statement, allowing the 
  5016.  final four statements to be executed. 
  5017.  
  5018.  These final statements determine the entry point address of the original 
  5019.  window procedure, using the WinQueryClassName() and WinQueryClassInfo() 
  5020.  functions to access control information held by Presentation Manager.  This 
  5021.  entry point address is then used to invoke the original window procedure to 
  5022.  process messages with which the subclass window procedure is not concerned, or 
  5023.  for which the normal processing must be allowed to occur. 
  5024.  
  5025.  The last four statements in the example above are common to all subclass 
  5026.  window procedures, and organizations undertaking development of Presentation 
  5027.  Manager applications may wish to incorporate them into a standard subroutine 
  5028.  and place them in a library for access by developers. 
  5029.  
  5030.  Note that a subclass window procedure, like all window and dialog procedures, 
  5031.  must use the system linkage convention.  This is normally achieved by 
  5032.  declaring the subclass window procedure using the EXPENTRY keyword. 
  5033.  
  5034.  
  5035. ΓòÉΓòÉΓòÉ 14.6. Window Communication ΓòÉΓòÉΓòÉ
  5036.  
  5037. Presentation Manager provides a number of mechanisms for communicating between 
  5038. windows.  All of these mechanisms use the Presentation Manager message concept. 
  5039. The exact technique used in any particular situation is dependent upon the 
  5040. nature of the communications and the types of windows involved. 
  5041.  
  5042.  
  5043. ΓòÉΓòÉΓòÉ 14.6.1. Standard Windows ΓòÉΓòÉΓòÉ
  5044.  
  5045. Data may be passed to a window upon its creation, using the CtlData parameter 
  5046. of the WinCreateWindow() function.  The contents of this parameter (a 32-bit 
  5047. pointer) are passed  to the target window as a parameter to the WM_CREATE 
  5048. message.  The  contents may then be extracted from the message parameter and 
  5049. used by  the window procedure. 
  5050.  
  5051. When an application wishes to pass a message between two standard windows that 
  5052. currently exist, whether they are display windows or object windows, either of 
  5053. two methods may be used, depending on whether  the desired communication is to 
  5054. be synchronous or asynchronous. 
  5055.  
  5056.    o  When a synchronous message is to be passed, the WinSendMsg() function is 
  5057.       used, and the target window procedure is invoked directly by Presentation 
  5058.       Manager, in a similar fashion to a normal function call.  The return code 
  5059.       from the window procedure is passed by Presentation Manager to the 
  5060.       calling window procedure, where it may be interrogated and acted upon. 
  5061.  
  5062.    o  When a message is to be processed asynchronously, the WinPostMsg() 
  5063.       function is used.  In this case the message is posted to a queue 
  5064.       associated with the thread that created the target window, and the return 
  5065.       code to the calling window procedure merely indicates that the message 
  5066.       was successfully placed on the queue.  In order for the target window 
  5067.       procedure to pass a return code or acknowledgement back to the calling 
  5068.       window procedure, it must include another WinPostMsg() call as part of 
  5069.       the processing of the message. 
  5070.  
  5071.  The use of WinPostMsg() is recommended over that of WinSendMsg(), since posted 
  5072.  messages are processed in the order in which they arrive in the queue, and the 
  5073.  integrity of the user's intention is thus preserved in the order of 
  5074.  processing.  In addition, synchronous window procedures are invoked and 
  5075.  executed without the original window procedure completing its processing and 
  5076.  returning control to the message processing loop.  Thus the application  is 
  5077.  prevented from processing additional user interaction, which may  lead to 
  5078.  violation of the SAA CUA responsiveness guidelines. 
  5079.  
  5080.  
  5081. ΓòÉΓòÉΓòÉ 14.6.2. Dialog Boxes ΓòÉΓòÉΓòÉ
  5082.  
  5083. Communication between a standard window and a modeless dialog box is achieved 
  5084. in a similar fashion to that used between two standard windows, since the 
  5085. modeless dialog box is merely a normal window without a sizable border. 
  5086. However, communication between a standard window and a modal dialog box must be 
  5087. achieved in a different manner, since a modal dialog box is typically loaded 
  5088. and processed in a single WinDlgBox() function call, and the dialog box only 
  5089. has an existence during the execution of that function call.  An example of the 
  5090. WinDlgBox() function is shown in WinDlgBox() Function. 
  5091.  
  5092. MYSTRUCT *MyStruct;
  5093.   :
  5094. DosAllocMem(MyStruct,         /* Allocate memory object      */
  5095.       sizeof(MYSTRUCT),     /* Size of memory object      */
  5096.       PAG_READ  |        /* Allow read access        */
  5097.       PAG_WRITE |        /* Allow write access        */
  5098.       PAG_COMMIT);        /* Commit storage now        */
  5099.  
  5100. <Initialize values in MyStruct>    /* Set initialization data     */
  5101.  
  5102. rc = WinDlgBox(HWND_DESKTOP,      /* Desktop is parent        */
  5103.         hwnd,          /* Current window is owner     */
  5104.         dpMyDialog,       /* Entry point of dialog procedure */
  5105.         (HMODULE)0,       /* Resource is in EXE file     */
  5106.         DC_MYDIALOG,      /* Dialog resource identifier    */
  5107.         MyStruct);       /* Pointer to initialization data  */
  5108. WinDlgBox() Function 
  5109.  
  5110. Data may be passed to a dialog procedure at initialization time by creating a 
  5111. data structure and passing a pointer to that structure in the CreateParams 
  5112. field of the WinDlgBox() function, as shown in WinDlgBox() Function.  This 
  5113. pointer is passed to the dialog procedure as the second parameter of the 
  5114. WM_INITDLG message, and may be accessed by the dialog procedure during the 
  5115. processing of this message.  Note that this is the only time at which input may 
  5116. be passed to a dialog box, since the dialog is processed within the scope of a 
  5117. single application statement; either a WinDlgBox() call or a WinProcessDlg() 
  5118. call may be used.  The WM_INITDLG message is described in the IBM OS/2 Version 
  5119. 2.0 Presentation Manager Reference. 
  5120.  
  5121. Information may be conveyed from a dialog procedure to its calling window 
  5122. procedure in one of two ways: 
  5123.  
  5124.    o  The dialog box may provide an unsigned integer (USHORT) parameter to the 
  5125.       WinDismissDlg() function, and this value is passed to the calling window 
  5126.       procedure as the return code from the WinDlgBox() function.  This 
  5127.       technique is useful where an acknowledgement or simple return data must 
  5128.       be conveyed. 
  5129.  
  5130.    o  The dialog box may issue a WinPostMsg() call to pass a message to the 
  5131.       queue associated with its calling window. The window procedure may then 
  5132.       receive and process that message in the normal way.  This technique is 
  5133.       useful when more complex data or structures must be conveyed. 
  5134.  
  5135.  The latter technique above may also be used to convey information to  a window 
  5136.  other than the window that invoked the dialog.  This may be necessary in 
  5137.  situations where a dialog box is invoked by one window procedure on behalf of 
  5138.  a group of windows. 
  5139.  
  5140.  
  5141. ΓòÉΓòÉΓòÉ 14.6.3. Control Windows ΓòÉΓòÉΓòÉ
  5142.  
  5143. As mentioned in Systems Application Architecture CUA Considerations, control 
  5144. windows are typically used in dialog boxes, and are hence accessed from the 
  5145. dialog procedure associated with their parent dialog box.  Such communication 
  5146. is synchronous in nature, since it usually involves insertion or retrieval of 
  5147. data into or from control windows, or other tasks that are part of the modal 
  5148. dialog with the user. 
  5149.  
  5150. Under OS/2 Version 2.0, some additional functions have been introduced into the 
  5151. Presentation Manager programming interface, to ease more complex 
  5152. communications, such as those involving list boxes.  Since communication with 
  5153. list boxes is therefore somewhat different from that involving other control 
  5154. window classes, list boxes are discussed separately in List Boxes. 
  5155.  
  5156.  
  5157. ΓòÉΓòÉΓòÉ 14.6.3.1. General Control Windows ΓòÉΓòÉΓòÉ
  5158.  
  5159. Communication between a dialog procedure and the control windows associated 
  5160. with its dialog box is typically achieved using the WinSendDlgItemMsg() 
  5161. function, which is documented in the IBM OS/2 Version 2.0 Presentation Manager 
  5162. Reference.  This function  is similar in function and behavior to the 
  5163. WinSendMsg()  function, in that it passes a synchronous message to the 
  5164. destination  window.  However, instead of accepting the handle of the 
  5165. destination  window as its first parameter, it accepts the handle of the 
  5166. control  window's parent and the window identifier of the control window itself 
  5167. as the first two parameters of the call.  For example, to send a  message of 
  5168. class EM_SETTEXTLIMIT to an entry field named EF_PRODNAME,  which is a child of 
  5169. the dialog box with handle hDlgBox, the function call shown in Communicating 
  5170. with a Control Window is used: 
  5171.  
  5172. rc = WinSendDlgItemMsg(hDlgBox,          /* Parent dialog box   */
  5173.             EF_PRODNAME,        /* Control identifier  */
  5174.             EM_SETTEXTLIMIT,      /* Message        */
  5175.             20,            /* Message parameters  */
  5176.             0);
  5177. Communicating with a Control Window 
  5178.  
  5179. It is possible to perform an equivalent function using the WinSendMsg() call, 
  5180. by obtaining the control window's handle using the WinWindowFromID() function. 
  5181. However, for purposes of standardization and in accordance with emerging 
  5182. conventions, it is recommended that the WinSendDlgItemMsg() function be used to 
  5183. send messages to control windows.  Note that for this purpose, the definition 
  5184. of control  windows includes both the system menu and menu bar; messages sent 
  5185. to  these menus (in order to insert, modify or delete items) should be sent 
  5186. using the WinSendDlgItemMsg() function. 
  5187.  
  5188. Similarly, it is recommended that the WinSetDlgItemText() and 
  5189. WinQueryDlgItemText() functions be used to set and query the contents of 
  5190. control windows from within the application.  For example, assume that the user 
  5191. has completed interaction with a dialog box, and pressed the "Enter" or "OK" 
  5192. button, and the application wishes to obtain the contents of an entry field 
  5193. named EF_PRODNAME, which is child of the dialog box with  handle hDlgBox.  The 
  5194. function call call shown in Querying Information From a Control Window is used. 
  5195.  
  5196. rc = WinQueryDlgItemText(hDlgBox,          /* Parent dialog box  */
  5197.              EF_PRODNAME,        /* Control identifier */
  5198.              sizeof(szBuffer),     /* Size of buffer   */
  5199.              szBuffer);         /* Pointer to buffer  */
  5200. Querying Information From a Control Window 
  5201.  
  5202. The WinQueryDlgItemText() function copies the contents of the entry field into 
  5203. the string szBuffer, and returns the number of characters copied. 
  5204.  
  5205. The WinSetDlgItemText() function is typically used in situations where some of 
  5206. the information necessary to complete an action is known; this information is 
  5207. then displayed in the appropriate entry fields within the dialog box, and the 
  5208. user fills in the missing fields.  Another use of this function is to provide 
  5209. default values for entry fields.  Both the WinSetDlgItemText() and 
  5210. WinQueryDlgItemText() functions are documented in the IBM OS/2 Version 2.0 
  5211. Presentation Manager Reference. 
  5212.  
  5213.  
  5214. ΓòÉΓòÉΓòÉ 14.6.3.2. List Boxes ΓòÉΓòÉΓòÉ
  5215.  
  5216. The complexity of communication with list boxes has been greatly reduced under 
  5217. OS/2 Version 2.0.  The Presentation Manager programming interface now includes 
  5218. a number of functions that allow most communication requirements to be achieved 
  5219. in a single step.  Note that these functions may also be used for communication 
  5220. with a combo box (prompted entry field). 
  5221.  
  5222. Insertion and deletion of list box items is carried out using the 
  5223. WinInsertLboxItem() and WinDeleteLboxItem() functions, which are new to OS/2 
  5224. Version 2.0.  The WinInsertLboxItem() function is illustrated in Inserting an 
  5225. Item Into a List Box. 
  5226.  
  5227.  hLBox = WinWindowFromID(hWnd,       /* Get list box window handle */
  5228.              LB_LIST);
  5229.  
  5230.  ulIndex = WinInsertLboxItem(hLBox,     /* Insert list box item    */
  5231.                LIT_END,    /* Insert at end of list    */
  5232.                szItemText);  /* Item text          */
  5233. Inserting an Item Into a List Box 
  5234.  
  5235. An application may obtain the text of a selected item in the list box using the 
  5236. WinQueryLboxSelectedItem() and WinQueryLboxItemText() functions.  The use of 
  5237. these functions is illustrated in Querying a Selected List Box Item. 
  5238.  
  5239. hLBox = WinWindowFromID(hWnd,        /* Get list box window handle */
  5240.             LB_LIST);
  5241.  
  5242. ulIndex = WinQueryLboxSelectedItem(hLBox); /* Get index of selected item */
  5243.  
  5244. ulLength = WinQueryLboxItemText(hLBox,       /* Get item text    */
  5245.                 usIndex,      /* Index of item    */
  5246.                 szBuffer,      /* Text buffer     */
  5247.                 sizeof(szBuffer)); /* Max no. of chars  */
  5248. Querying a Selected List Box Item 
  5249.  
  5250. Other functions include the WinQueryLboxCount() function, which returns the 
  5251. number of items in a list box, and the WinQueryLboxItemTextLength() function, 
  5252. which returns the length of list box item's text. 
  5253.  
  5254. All of these list box manipulation functions are described in the IBM OS/2 
  5255. Version 2.0 Presentation Manager Reference. 
  5256.  
  5257.  
  5258. ΓòÉΓòÉΓòÉ 14.6.4. Message Boxes ΓòÉΓòÉΓòÉ
  5259.  
  5260. Communication between a window or dialog procedure and a message box  is 
  5261. relatively simple.  The message box is created and processed using  the 
  5262. WinMessageBox() function, and the only input data provided to this function is 
  5263. the title of the message box and the text of the message to be displayed.  The 
  5264. application may affect the style of the message box, by specifying style 
  5265. attributes in the function call, as described in the IBM OS/2 Version 2.0 
  5266. Presentation Manager Reference. 
  5267.  
  5268. An example of the WinMessageBox() function is given in WinMessageBox() 
  5269. Function. 
  5270.  
  5271. rc = WinMessageBox(HWND_DESKTOP,     /* Desktop is parent       */
  5272.           hWnd,         /* Current window is parent   */
  5273.           pszMsgText,      /* Pointer to message text    */
  5274.           "Open the File"    /* Message title         */
  5275.           0,           /* Message box identifier    */
  5276.           MB_OKCANCEL  |    /* Include OK & Cancel buttons  */
  5277.           MB_DEFBUTTON1 |    /* Default to OK         */
  5278.           MB_HELP);       /* Include help button      */
  5279. WinMessageBox() Function 
  5280.  
  5281. The result of the user's interaction with the message box (that is, the 
  5282. identifier of the button that was pressed) is communicated to the application 
  5283. in the form of an unsigned integer returned by the WinMessageBox() call.  The 
  5284. application may then interrogate this returned value to determine the 
  5285. subsequent action to be taken. 
  5286.  
  5287.  
  5288. ΓòÉΓòÉΓòÉ 14.6.5. Identifying the Destination Window ΓòÉΓòÉΓòÉ
  5289.  
  5290. When passing messages between windows using the WinPostMsg() or WinSendMsg() 
  5291. functions, the window handle of the destination window must be known and 
  5292. specified in the message.  If window handles are not defined globally, the 
  5293. required handle must be obtained from Presentation Manager.  This may be 
  5294. achieved in a number of ways: 
  5295.  
  5296.    o  If the target window has a known relationship to the current window  or 
  5297.       to another window for which the handle is already known, the 
  5298.       WinQueryWindow() function may be used to obtain the window handle of the 
  5299.       target window. For example, if a window wishes to post a message to its 
  5300.       own parent window, the technique shown in Obtaining a Window Handle - 
  5301.       WinQueryWindow() Function may be used. 
  5302.  
  5303.             hTarget = WinQueryWindow(hWnd,    /* Base window for relation  */
  5304.                          QW_PARENT,  /* Relationship to base wndw */
  5305.                          FALSE);   /* Do not lock window     */
  5306.       Obtaining a Window Handle - WinQueryWindow() Function 
  5307.  
  5308.       The WinQueryWindow() call returns the handle of the required  window. 
  5309.       Relationships other than parent/child may also be used by this function; 
  5310.       the valid relationships are described, along with the WinQueryWindow() 
  5311.       function, in the IBM OS/2 Version 2.0 Presentation Manager Reference. 
  5312.  
  5313.    o  If the parent window and window identifier of the target window are 
  5314.       known, the WinWindowFromID() function may be used to obtain the window 
  5315.       handle of the target window. For example, if a window wishes to post a 
  5316.       message to the client window of its application's main window, assuming 
  5317.       the frame window handle is known, the method shown in Obtaining a Window 
  5318.       Handle - WinWindowFromID() Function may be used. 
  5319.  
  5320.             hTarget = WinWindowFromID(hMainFrame,  /* Parent window known   */
  5321.                          FID_CLIENT); /* Window identifier    */
  5322.       Obtaining a Window Handle - WinWindowFromID() Function 
  5323.  
  5324.       The WinWindowFromID() function also returns the handle of the required 
  5325.       window. 
  5326.  
  5327.    o  If the target window is the application's main window, its handle may be 
  5328.       obtained by first querying the application's switch entry in the 
  5329.       Workplace Shell Window List to obtain the handle of the main frame window 
  5330.       (using the WinQuerySwitchHandle() and WinQuerySwitchEntry() functions), 
  5331.       then using the WinWindowFromID() function to obtain the handle of the 
  5332.       client window, as shown in Obtaining a Window Handle Using the Switch 
  5333.       Entry. 
  5334.  
  5335.             hSwitch = WinQuerySwitchHandle(hWnd,0);
  5336.             ulSuccess = WinQuerySwitchEntry(hSwitch,
  5337.                             SwitchData);
  5338.             hTarget = WinWindowFromID(SwitchData.hwnd,
  5339.                          FID_CLIENT);
  5340.       Obtaining a Window Handle Using the Switch Entry 
  5341.  
  5342.       The above example assumes that the application has been added to the OS/2 
  5343.       Window List using the WinAddSwitchEntry() function, and the handle of its 
  5344.       main frame window supplied as a parameter.  See WinAddSwitchEntry() 
  5345.       Function. 
  5346.  
  5347.  When passing messages synchronously to control windows using the 
  5348.  WinSendDlgItemMsg() function, it is generally assumed that the target control 
  5349.  window is a child of the current window or dialog box.  Thus the parent window 
  5350.  handle is the handle of the current window, and the window identifier is also 
  5351.  known to the current window procedure.  An exception is the case where a 
  5352.  window procedure wishes to send a message to a frame control of its own parent 
  5353.  frame window.  In this case a WinQueryWindow() call must be issued with the 
  5354.  QW_PARENT parameter to determine the handle of the frame window.  The 
  5355.  WinSendDlgItemMsg() function may then be used with this handle and the window 
  5356.  identifier of the required frame control. 
  5357.  
  5358.  
  5359. ΓòÉΓòÉΓòÉ 14.6.6. Creating Message Parameters ΓòÉΓòÉΓòÉ
  5360.  
  5361. Before a message can be passed to a target window, its message parameters must 
  5362. be created from the necessary data items.  As mentioned in Messages, message 
  5363. parameters are 32-bit fields.  Presentation Manager  provides a number of 
  5364. macros to convert existing data types into the correct representation, and to 
  5365. extract data from message parameters within the target window procedure.  These 
  5366. macros are described in Presentation Manager Macros. 
  5367.  
  5368. ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
  5369. Γöé Presentation Manager Macros.  This table shows the "C" language     Γöé
  5370. Γöé macros provided by Presentation Manager to facilitate the con-     Γöé
  5371. Γöé struction and extraction of message parameters.             Γöé
  5372. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  5373. Γöé MACRO     Γöé USAGE                          Γöé
  5374. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  5375. Γöé MPFROMP    Γöé Produces an MPARAM data type from a pointer       Γöé
  5376. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  5377. Γöé MPFROMHWND  Γöé Produces an MPARAM data type from a window handle (HWND)Γöé
  5378. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  5379. Γöé MPFROMCHAR  Γöé Produces an MPARAM data type from an unsigned character Γöé
  5380. Γöé        Γöé (UCHAR)                         Γöé
  5381. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  5382. Γöé MPFROMSHORT  Γöé Produces an MPARAM data type from a short integer (SHORTΓöé
  5383. Γöé        Γöé or USHORT)                        Γöé
  5384. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  5385. Γöé MPFROM2SHORT Γöé Produces an MPARAM data type from two short integers   Γöé
  5386. Γöé        Γöé (SHORT or USHORT)                    Γöé
  5387. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  5388. Γöé MPFROMSH2CH  Γöé Produces an MPARAM data type from a short integer (SHORTΓöé
  5389. Γöé        Γöé or USHORT) and two characters (CHAR or UCHAR)      Γöé
  5390. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  5391. Γöé MPFROMLONG  Γöé Produces an MPARAM data type from a long integer (LONG  Γöé
  5392. Γöé        Γöé or ULONG)                        Γöé
  5393. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  5394. Γöé PVOIDFROMMP  Γöé Produces a pointer from an MPARAM data type       Γöé
  5395. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  5396. Γöé HWNDFROMMP  Γöé Produces a window handle (HWND) from an MPARAM data typeΓöé
  5397. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  5398. Γöé CHAR1FROMMP  Γöé Produces a character (UCHAR) from bits 0-7 of an MPARAM Γöé
  5399. Γöé        Γöé data type                        Γöé
  5400. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  5401. Γöé CHAR2FROMMP  Γöé Produces a character (UCHAR) from bits 8-15 of an MPARAMΓöé
  5402. Γöé        Γöé data type                        Γöé
  5403. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  5404. Γöé CHAR3FROMMP  Γöé Produces a character (UCHAR) from bits 16-23 of an    Γöé
  5405. Γöé        Γöé MPARAM data type                     Γöé
  5406. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  5407. Γöé CHAR4FROMMP  Γöé Produces a character (UCHAR) from bits 24-31 of an    Γöé
  5408. Γöé        Γöé MPARAM data type                     Γöé
  5409. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  5410. Γöé SHORT1FROMMP Γöé Produces an unsigned short integer (USHORT) from bits  Γöé
  5411. Γöé        Γöé 0-15 of an MPARAM data type               Γöé
  5412. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  5413. Γöé SHORT2FROMMP Γöé Produces an unsigned short integer (USHORT) from bits  Γöé
  5414. Γöé        Γöé 16-31 of an MPARAM data type               Γöé
  5415. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  5416. Γöé LONGFROMMP  Γöé Produces an unsigned long integer (ULONG) from an MPARAMΓöé
  5417. Γöé        Γöé data type                        Γöé
  5418. ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
  5419. For example, to create message parameter mp1 composed of  two unsigned integers 
  5420. usInt1 and usInt2, the following statement is used: 
  5421.  
  5422. mp1 = MPFROM2SHORT(usInt1,usInt2);
  5423.  
  5424. Similarly, to extract two unsigned integers usInt3 and usInt4 from the message 
  5425. parameter mp2, the following statements are used: 
  5426.  
  5427. usInt3 = SHORT1FROMMP(mp2);
  5428. usInt4 = SHORT2FROMMP(mp2);
  5429.  
  5430. Characters, pointers, window handles, etc., may all be placed into and 
  5431. retrieved from message parameters using macros supplied by Presentation 
  5432. Manager. 
  5433.  
  5434.  
  5435. ΓòÉΓòÉΓòÉ 14.6.7. Broadcasting Messages ΓòÉΓòÉΓòÉ
  5436.  
  5437. In certain circumstances, a window procedure may wish to indicate an  event to 
  5438. multiple windows, and therefore need to pass the same message  to each of these 
  5439. windows.  Presentation Manager provides the capability for a message  to be 
  5440. broadcast to multiple windows with a single WinBroadcastMsg() function call. 
  5441.  
  5442. The WinBroadcastMsg() function passes a message of a specified class to the 
  5443. descendants of a specified parent window, as shown in WinBroadcastMsg() 
  5444. Function. 
  5445.  
  5446. rc = WinBroadcastMsg(hwnd,           /* Current is parent    */
  5447.            WMP_MYMESSAGE,      /* Message identifier    */
  5448.            mp1,           /* 1st message parameter  */
  5449.            mp2,           /* 2nd message parameter  */
  5450.            BMSG_POST);        /* Post message via queue  */
  5451. WinBroadcastMsg() Function 
  5452.  
  5453. The example shown in WinBroadcastMsg() Function passes a message of the 
  5454. application-defined class WMP_MYMESSAGE to all children of the current window 
  5455. (that is, the window associated with the window procedure in which the function 
  5456. call is made), with message parameters as shown.  The message is posted to the 
  5457. target windows via a message queue, and is thus processed asynchronously; the 
  5458. WinBroadcastMsg() function also allows for synchronous processing using the 
  5459. BMSG_SEND flag. 
  5460.  
  5461. The parent/child hierarchy allows windows to be grouped in particular ways to 
  5462. suit application requirements.  For example, all the  object windows created by 
  5463. an application may be created as children of  a "dummy" master object window. 
  5464. If a particular message must then  be sent to all these object windows (for 
  5465. example, to close all the  windows), this can be done by broadcasting the 
  5466. message to all children  of the master object window. 
  5467.  
  5468. The BMSG_DESCENDANTS flag may be set in the WinBroadcastMsg() call to cause a 
  5469. message to be passed to all descendants of the specified parent window, rather 
  5470. than just the direct children of that parent.  This enables a message to be 
  5471. broadcast  to a wider target group, should the application so require. 
  5472. Alternatively, the BMSG_FRAMEONLY flag may be set, causing the message  to be 
  5473. passed only to frame windows.  This is useful in situations where  an 
  5474. application wishes to initiate an action by multiple display windows  at the 
  5475. same time. 
  5476.  
  5477. The WinBroadcastMsg() function must be used with caution,  particularly when it 
  5478. may cause messages to be sent to windows created  by other applications.  This 
  5479. is possible if the BMSG_DESCENDANTS flag  is set and the desktop window is 
  5480. specified as the parent, and may cause  complications in other applications. 
  5481. For example, consider the  following message definitions: 
  5482.  
  5483. Application 1
  5484.  
  5485. #define     WMP_REFRESH     WM_USER+12
  5486.  
  5487. Application 2
  5488.  
  5489. #define     WMP_CLOSEALL    WM_USER+12
  5490.  
  5491. In the example above, each application defines a message class, and each 
  5492. message is to be used for a different purpose.  However, both messages have the 
  5493. same message identifier.  Now let us assume that Application 1 makes the 
  5494. following function call: 
  5495.  
  5496. rc = WinBroadcastMsg(HWND_DESKTOP,
  5497.                      WMP_REFRESH,
  5498.                      mp1,
  5499.                      (MPARAM)0,
  5500.                      BMSG_POST);
  5501.  
  5502. This function call would cause a WMP_REFRESH message to be passed to all 
  5503. display windows in Application 1 and Application 2.  However, the windows in 
  5504. Application 2 would interpret the message as a WMP_CLOSEALL message, with 
  5505. possibly undesirable results. 
  5506.  
  5507. It is therefore strongly recommended that developers exercise extreme care in 
  5508. using the WinBroadcastMsg() function, in order to accurately determine the 
  5509. potential results of the messages being broadcast. 
  5510.  
  5511.  
  5512. ΓòÉΓòÉΓòÉ 14.7. Passing Control ΓòÉΓòÉΓòÉ
  5513.  
  5514. The use of functions and subroutines in an object-oriented application 
  5515. executing in the Presentation Manager raises some issues with regard to object 
  5516. boundaries.  In general, the scope of a function or subroutine should be 
  5517. restricted to a single application object, and the processing performed by that 
  5518. subroutine should therefore relate only to the data object(s) owned by that 
  5519. application object.  If a subroutine invoked from one application object will 
  5520. perform processing on a data object related to a different application object, 
  5521. then the subroutine should be invoked by the second  application object, by way 
  5522. of a message passed from the first application object. 
  5523.  
  5524. Four general types of subroutines may exist within an object-oriented 
  5525. application.  These are discussed in the following sections, and are classified 
  5526. according to the nature of their inputs and outputs. 
  5527.  
  5528.  
  5529. ΓòÉΓòÉΓòÉ 14.7.1. Direct Invocation/Direct Return ΓòÉΓòÉΓòÉ
  5530.  
  5531. This type of subroutine corresponds to the "conventional" subroutine call, in 
  5532. that a parameter list is passed to the subroutine from the calling routine, and 
  5533. a number of parameters and/or a return code is returned at the end of the 
  5534. subroutine's execution.  Within an object-oriented application, such 
  5535. subroutines should be used to perform processing that is limited in scope to a 
  5536. single application object (such as an SQL query on a database owned by the 
  5537. application object), or to perform a standard processing function that is 
  5538. common to a number of objects, but where the scope of each execution instance 
  5539. is limited to a single object.  For example, a function DrawCircle may be 
  5540. called by a number  of window procedures to display a circular graphics 
  5541. primitive;  however,  each invocation of the function is from a single window 
  5542. procedure. 
  5543.  
  5544.  
  5545. ΓòÉΓòÉΓòÉ 14.7.2. Direct Invocation/Message Return ΓòÉΓòÉΓòÉ
  5546.  
  5547. This type of subroutine should be used where the scope of the processing 
  5548. performed by a subroutine is limited to a single application  object, but where 
  5549. the result of that processing must be communicated to  an application object 
  5550. other than the one that invoked the subroutine.  Since the conventional method 
  5551. of achieving communication between  objects is via messages, the subroutine 
  5552. posts a message to the affected  application object using the WinPostMsg() 
  5553. call, or  synchronously passes the message to the application object using the 
  5554. WinSendMsg() call (this latter call should be used with caution; see Message 
  5555. Invocation/Direct Return).  The message is routed to the destination window by 
  5556. Presentation Manager.  The subroutine typically returns to its caller in the 
  5557. normal fashion; this method of passing control is therefore merely a variation 
  5558. of the previously described Direct Invocation/Direct Return method. 
  5559.  
  5560. Assuming that the calling routine is a window procedure, the return code (if 
  5561. any) from the subroutine is passed to the calling window procedure and that 
  5562. procedure completes its execution before the message  resulting from the called 
  5563. subroutine is processed. 
  5564.  
  5565. Note that this technique can be used where the called subroutine executes in a 
  5566. secondary thread, and the resulting message is passed back to the calling 
  5567. window procedure in the primary thread to indicate the completion of the 
  5568. secondary thread's processing.  See Multitasking Considerations for further 
  5569. discussion of multiple threads. 
  5570.  
  5571.  
  5572. ΓòÉΓòÉΓòÉ 14.7.3. Message Invocation/Direct Return ΓòÉΓòÉΓòÉ
  5573.  
  5574. This type of subroutine occurs with window procedures that are invoked 
  5575. synchronously via a WinSendMsg() call.  The message is processed, and the 
  5576. return code from the window procedure is routed to the calling routine by 
  5577. Presentation Manager.  The calling routine then completes its execution.  If 
  5578. any queued messages are generated by the called window procedure or subroutine, 
  5579. these messages are not processed until the calling routine completes its 
  5580. execution and  the application issues its next WinGetMsg() call.  This is  so, 
  5581. even if the called window procedure or subroutine executes in a  separate 
  5582. thread. 
  5583.  
  5584. This type of invocation should be used for access to another application 
  5585. object, where the function to be performed must be executed  synchronously and 
  5586. the result returned directly to the caller.  However,  use of the WinSendMsg() 
  5587. call in preference to the  WinPostMsg() call for communication between objects 
  5588. may  result in messages being processed out of order due to the application 
  5589. pre-empting the normal order of execution determined by the message  queue. 
  5590. The WinSendMsg() function should thus be used with care.  The use of this call 
  5591. may also extend the time interval between successive WinGetMsg() calls to 
  5592. Presentation Manager, thus decreasing the  application's responsiveness to user 
  5593. interaction. 
  5594.  
  5595.  
  5596. ΓòÉΓòÉΓòÉ 14.7.4. Message Invocation/Message Return ΓòÉΓòÉΓòÉ
  5597.  
  5598. This is the case for window procedures invoked in the standard way using a 
  5599. WinPostMsg() call from another window or using the WinDispatchMsg() function 
  5600. from the application's main routine.  In this case the message  is processed, 
  5601. and any messages generated during execution are posted to  the appropriate 
  5602. queue, but the return code from the window procedure is  passed only to 
  5603. Presentation Manager, and does not reach the calling window procedure. For this 
  5604. reason, it is important that any message that requires acknowledgement be 
  5605. handled in such a way that the window procedure generates a message that is 
  5606. routed to the calling window, and that contains the required acknowledgement. 
  5607.  
  5608. This type of invocation should be used for access to other application objects, 
  5609. where the function to be performed need not be performed synchronously, and 
  5610. where acknowledgement or completion of the  processing may be indicated by a 
  5611. subsequent message posted to the caller. 
  5612.  
  5613. Note that this should be the default method of invocation for window 
  5614. procedures, since the asynchronous nature of the processing allows the 
  5615. application to maintain the highest level of responsiveness to user 
  5616. interaction. 
  5617.  
  5618. Note also that a window may receive messages from a number of sources. This 
  5619. allows a window to service requests from a number of other windows, in 
  5620. accordance with a client-server architecture.  This concept is discussed 
  5621. further in Client-Server Applications. 
  5622.  
  5623.  
  5624. ΓòÉΓòÉΓòÉ 14.7.5. External Macros ΓòÉΓòÉΓòÉ
  5625.  
  5626. An application may also pass control synchronously to an external routine such 
  5627. a macro or subprogram written using the Restructured Extended Executor (REXX) 
  5628. procedure language.  This can be achieved quite easily by calling the REXX 
  5629. command interpreter using the RexxStart() function from any point within the 
  5630. application.  This function is illustrated in Calling External Macros. 
  5631.  
  5632. #define INCL_REXXSAA
  5633.  
  5634. #include <rexxsaa.h>
  5635.   :
  5636. PSZ szFileName;                 /* File to be accessed  */
  5637. PSZ szOptions;                  /* Command arguments   */
  5638.  
  5639. RXSTRING arg;                  /* REXX argument string  */
  5640. RXSTRING RexxRetValue;              /* Result         */
  5641.  
  5642. LONG lRexxRC;                  /* REXX return code    */
  5643.  
  5644. static RXSYSEXIT ExitList[] = {{"TIXXSIO", RXSIO}, /* Exit handler    */
  5645.                 {NULL, RXENDLST}};
  5646.   :
  5647. arg.strptr = szOptions;             /* Set argument string  */
  5648. arg.strlength = strlen(szOptions);        /* Size of arg string   */
  5649.  
  5650. rc = RexxStart(1,                /* Call REXX      */
  5651.         &arg,               /* Argument string   */
  5652.         (PSZ)"RexxProc",         /* REXX proc file    */
  5653.         NULL,               /* Procedure in file  */
  5654.         (PSZ)"TIXX",           /* ADDRESS environment */
  5655.         (SHORT)RXCOMMAND,         /* REXX command     */
  5656.         (PRXSYSEXIT)ExitList,       /* Exit list routines  */
  5657.         &lRexxRC,             /* Return code address */
  5658.         &RexxRetValue);          /* Returned result   */
  5659. Calling External Macros 
  5660.  
  5661. This example shows the use of the RexxStart() function to call the REXX command 
  5662. interpreter from within an application. 
  5663.  
  5664. Commands are passed to the REXX interpreter using command strings defined using 
  5665. the RXSTRING data type, which is defined in the rexxsaa.h header file.  This 
  5666. structure contains the string pointer and an unsigned long integer containing 
  5667. the length of the string in bytes.  A number of commands may be passed in a 
  5668. single operation, by specifying an array of RXSTRING structures in the second 
  5669. parameter to the RexxStart() function.  The first parameter specifies the 
  5670. number of commands being passed. 
  5671.  
  5672. The third parameter to the RexxStart() function defines the name of the REXX 
  5673. procedure to be invoked.  In Calling External Macros, the procedure is 
  5674. contained in the file REXXPROC, with an assumed default file extension of .CMD. 
  5675.  
  5676. If the REXX procedure invoked by the application issues its own commands such 
  5677. as SAY (to output information to the screen), a subcommand handler must be 
  5678. specified in the RexxStart() function call, in order to trap such output.  A 
  5679. subcommand handler is simply a subroutine which accepts, as parameters, the 
  5680. function and subfunction names issued by the REXX procedure, along with a 
  5681. pointer to an RXSTRING structure which may be used by the subcommand handler to 
  5682. return any information to the REXX procedure. A subcommand handler may reside 
  5683. within the application's main executable module or in a DLL, and must be 
  5684. registered prior to issuing the RexxStart() function call, using the 
  5685. RexxRegisterSubcomExe() or RexxRegisterSubcomDll() functions. 
  5686.  
  5687. The REXX interpreter's operating environment may be customized through the use 
  5688. of user exits, whereby special routines may be inserted at particular points in 
  5689. the interpreter's execution.  Such routines are specified using an array of 
  5690. RXSYSEXIT structures, which identify the exit point and the entry point address 
  5691. of the routine to be invoked at that point.  The address of this array is 
  5692. passed in the RexxStart() function call. 
  5693.  
  5694. Use of the REXX interpreter, the RexxStart() function and its supporting 
  5695. functions are described in detail in the IBM OS/2 Version 2.0 Technical Library 
  5696. - Procedures Language/2 REXX Reference. 
  5697.  
  5698.  
  5699. ΓòÉΓòÉΓòÉ 14.8. Terminating an Application ΓòÉΓòÉΓòÉ
  5700.  
  5701. A Presentation Manager application is normally terminated by a message of the 
  5702. class WM_QUIT being posted to the application's message queue.  The message may 
  5703. be posted by any window procedure or subroutine within the application, or by 
  5704. Presentation Manager as the result of the user selecting the "Shutdown" option 
  5705. from the Presentation Manager desktop.  The message may result  from the user 
  5706. selecting an "Exit" option from the menu bar, or  selecting the "Close" option 
  5707. in the system menu of the application's main window. 
  5708.  
  5709. The WM_QUIT message causes the next WinGetMsg() call to return FALSE.  This in 
  5710. turn causes the application's message processing loop to terminate. 
  5711.  
  5712. By convention, a Presentation Manager application performs standard termination 
  5713. processing such as: 
  5714.  
  5715.    o  Destroying the application's main window 
  5716.  
  5717.    o  Destroying the application's message queue 
  5718.  
  5719.    o  Deregistering the application from Presentation Manager. 
  5720.  
  5721.  The application may additionally perform its own termination functions such as 
  5722.  closing or destroying any global data objects.  Secondary threads are normally 
  5723.  terminated from within the window procedure that created them, as part of that 
  5724.  window procedure's WM_DESTROY message processing.  See Multitasking 
  5725.  Considerations for further information. 
  5726.  
  5727.  
  5728. ΓòÉΓòÉΓòÉ 14.9. Summary ΓòÉΓòÉΓòÉ
  5729.  
  5730. It can be seen that by making effective use of the facilities provided by 
  5731. Presentation Manager, and by following a number of simple guidelines in the 
  5732. design and implementation of applications, it is relatively simple to develop a 
  5733. Presentation Manager application that conforms to module-based object-oriented 
  5734. programming standards, and achieves benefits through reduced development effort 
  5735. and easier application maintenance, due to code reuse and encapsulation. 
  5736.  
  5737. It must be accepted however, that some deviation from strict object-oriented 
  5738. practice may be necessary in order to preserve other important goals such as 
  5739. the preservation of responsiveness to the end user. Adherence to academic 
  5740. principles should not take precedence over achievement of the required result. 
  5741.  
  5742. The mapping of data objects into application objects must be approached with 
  5743. great care in the design stage of a Presentation Manager  application. 
  5744. Presentation Manager allows the creation of window procedures (application 
  5745. objects) that operate on more than one data object, and of multiple window 
  5746. procedures that operate on the same data object.  This practice should be 
  5747. discouraged however, since it reduces the level  of encapsulation in the 
  5748. application object, increases the interdependence between application objects, 
  5749. and consequently reduces the benefits attainable through code reuse and 
  5750. containment of change. 
  5751.  
  5752. Notwithstanding, the Presentation Manager environment affords great opportunity 
  5753. for the development of applications that implement the general principles of 
  5754. the object-oriented approach.  A central precept of object-oriented design is 
  5755. the generic nature and consequent reusability  of the objects so created. 
  5756. Adherence to guidelines that promote conformance to object-oriented concepts 
  5757. such as data abstraction, encapsulation and polymorphism, in conjunction with 
  5758. the facilities  provided by Presentation Manager for object creation, 
  5759. communication and subclassing, and by the OS/2 operating system in the form of 
  5760. dynamic linking, facilitates the development of highly granular, reusable 
  5761. generic objects in the Presentation Manager environment. 
  5762.  
  5763.  
  5764. ΓòÉΓòÉΓòÉ 15. Workplace Shell and the System Object Model ΓòÉΓòÉΓòÉ
  5765.  
  5766. The Workplace Shell provided under OS/2 Version 2.0 introduces an 
  5767. object-oriented layer into the Presentation Manager environment. It provides a 
  5768. mechanism for the registration of object classes, creation of objects within 
  5769. those classes, and the inheritance of characteristics and behaviors from 
  5770. existing object classes. Using the Workplace Shell, an application may be 
  5771. created as a series of objects that interact on the desktop, and which the user 
  5772. manipulates to perform the required application processing. Each object 
  5773. possesses data, which may be defined for the entire class or for each instance, 
  5774. and a set of methods that operate upon that data. 
  5775.  
  5776. The Workplace Shell functions that allow the creation and manipulation of 
  5777. objects are based upon the system object model, which establishes a basic 
  5778. inheritance hierarchy for objects in the system and defines the underlying 
  5779. protocols which regulate the relationships between objects. The concepts behind 
  5780. the system object model are described in detail in OS/2 Version 2.0 - Volume 3: 
  5781. Presentation Manager and Workplace Shell, and System Object Model Guide and 
  5782. Reference. 
  5783.  
  5784. This chapter is an enhanced and expanded version of Chapter 7 in OS/2 Version 
  5785. 2.0 - Volume 4:  Writing Applications. It adds more detail about areas of 
  5786. WPS/SOM programming, such as Drag/Drop and debugging, and provides a further 
  5787. example Workplace Object to illustrate these techniques.  This new version of 
  5788. the chapter is included in both the revised version of OS/2 Version 2.0 - 
  5789. Volume 4:  Writing Applications, and also in &volborg.. 
  5790.  
  5791. This chapter includes examples of code from two Workplace Objects that have 
  5792. been especially written for this document. They are the pwFolder and 
  5793. pwFinanceFile Workplace Objects. The full source for these and other examples 
  5794. can be found on the diskette included with this document and the program 
  5795. listings are in Source Code for the PWFolder and PWFinanceFile objects. 
  5796.  
  5797.  
  5798. ΓòÉΓòÉΓòÉ 15.1. Objects in the Workplace Shell ΓòÉΓòÉΓòÉ
  5799.  
  5800. An object in the Workplace Shell conforms closely to the definition of an 
  5801. application object given in The Presentation Manager Application Model, in that 
  5802. it consists of a set of data and a number of methods that operate upon that 
  5803. data. Each Workplace Shell object is an instance of a particular object class. 
  5804. In accordance with normal object-oriented theory, the class defines the basic 
  5805. characteristics of the object and the way in which the object responds to 
  5806. events. 
  5807.  
  5808.  
  5809. ΓòÉΓòÉΓòÉ 15.1.1. Inheritance Hierarchy ΓòÉΓòÉΓòÉ
  5810.  
  5811. Each object class is descended from another class, known as its parent class. 
  5812. Since the system object model supports the object-oriented concept of 
  5813. inheritance, a class may inherit data and methods from its parent class, which 
  5814. in turn may inherit data and methods from its parent, and so on. A class which 
  5815. inherits properties from other classes is therefore known as a descendant of 
  5816. those classes, and the classes from which it inherits are known as ancestors. 
  5817. The implementation of inheritance in the Workplace Shell means that when 
  5818. creating a new object class, a programmer simply subclasses the parent class, 
  5819. and need only define those characteristics that are not defined by, or are 
  5820. different from those of the parent class. This greatly simplifies the process 
  5821. of creating a new object class. 
  5822.  
  5823. Under the system object model, every object class is a descendant of the base 
  5824. class SOMObject. This class defines the basic characteristics and behaviors 
  5825. common to all objects in the system. Other object classes are subclasses of 
  5826. this class.  The system object model provides two additional classes, SOMClass 
  5827. and SOMClassManager, to form the basis of an inheritance hierarchy. The 
  5828. Workplace Shell extends this hierarchy by creating a number of classes of its 
  5829. own, based upon the SOMObject class. These Workplace Shell object classes 
  5830. define the characteristics of the object types that are defined and implemented 
  5831. by the Workplace Shell itself. 
  5832.  
  5833. The inheritance hierarchy implemented by the Workplace Shell is illustrated in 
  5834. Workplace Shell Inheritance Hierarchy. Workplace Shell Inheritance Hierarchy 
  5835.  
  5836. As well as being descended from the system object model base inheritance 
  5837. hierarchy, all Workplace Shell object classes are descended from one of three 
  5838. base storage classes defined by the Workplace Shell. These classes are so named 
  5839. because they directly influence the storage of control information and instance 
  5840. data for the class. The three predefined base storage classes are: 
  5841.  
  5842.    o  WPAbstract, which is the base class for abstract objects such as 
  5843.       programs, devices, etc., and for which control information is stored in 
  5844.       the system initialization file OS2.INI. 
  5845.  
  5846.    o  WPFileSystem, which is the base class for objects that are stored as 
  5847.       files in the file system, and for which control information is stored in 
  5848.       the file system as extended attributes. 
  5849.  
  5850.    o  WPTransient, which is the base class for objects that only exist during 
  5851.       execution of a particular program; that is, the object is created and 
  5852.       used for a particular purpose during processing, and then immediately 
  5853.       deleted from the system. 
  5854.  
  5855.  An application developer may extend the Workplace Shell inheritance hierarchy 
  5856.  by introducing new object classes based upon those already implemented by the 
  5857.  Workplace Shell itself.  Indeed, the developer may even introduce new base 
  5858.  classes, although this is definitely a non-trivial exercise and should be 
  5859.  approached with caution. 
  5860.  
  5861.  
  5862. ΓòÉΓòÉΓòÉ 15.1.2. Metaclasses ΓòÉΓòÉΓòÉ
  5863.  
  5864. Just as each Workplace Shell object is an instance of a class, the class itself 
  5865. is an instance of another class known as its metaclass. Just as an object has 
  5866. instance data and methods that pertain only to a specific instance of the 
  5867. class, so the metaclass has class data and methods that pertain to the entire 
  5868. class. Such methods are known as class methods, whereas methods that operate 
  5869. only for a particular instance of the class are known as instance methods. 
  5870.  
  5871. Class methods and data are available to the programmer when creating new object 
  5872. classes. A programmer may introduce new class data and methods for an object 
  5873. class, as well as instance data and methods. Similarly, a new object class may 
  5874. override existing class methods to modify the processing performed by those 
  5875. methods. 
  5876.  
  5877.  
  5878. ΓòÉΓòÉΓòÉ 15.1.3. Class Implementation ΓòÉΓòÉΓòÉ
  5879.  
  5880. Each object class in the Workplace Shell resides in a dynamic link library 
  5881. (DLL). A programmer creates an object class by defining its characteristics in 
  5882. a class definition file. This file is then used as input to the SOM 
  5883. Precompiler, in order to produce "C" source code and header files for the 
  5884. object class. This source code includes basic definitions for the object 
  5885. class's data and methods; the code is then edited by the programmer to include 
  5886. the logic for each of the required methods. Once the code is complete, it is 
  5887. compiled and link edited in the normal way to produce a dynamic link library; 
  5888. see OS/2 2.1 Volume 4: Writing Applications, Chapter 14 "Compiling and Link 
  5889. Editing an Application" for further information on compiling and link editing. 
  5890.  
  5891. When an object class has been created, it must be registered with the Workplace 
  5892. Shell, which includes the DLL in a list of libraries loaded at initialization 
  5893. time. The entry points for the DLL are known to the Workplace Shell, and may be 
  5894. called in order to invoke the object's methods. 
  5895.  
  5896. The process of creating an object class from a class definition file is 
  5897. described in Defining an Object. 
  5898.  
  5899.  
  5900. ΓòÉΓòÉΓòÉ 15.2. Object Structure ΓòÉΓòÉΓòÉ
  5901.  
  5902. In the simplest case, an object in the Workplace Shell consists of methods and 
  5903. instance data. The PM Window Manager communicates events to the Workplace Shell 
  5904. using messages, which in turn invokes the object's methods to perform the 
  5905. processing indicated by the event. This is in accordance with the definition of 
  5906. an application object given in OS/2 2.1 Volume 4: Writing Applications, Chapter 
  5907. 4 "The Presentation Manager Application Model". Note that since the Workplace 
  5908. Shell provides a more extensive inheritance hierarchy than the base 
  5909. Presentation Manager application model, the method invoked by a particular 
  5910. message may belong explicitly to the object in question, or may belong to its 
  5911. parent (and be inherited from that parent). 
  5912.  
  5913. The structure of an object in the Workplace Shell is therefore very similar to 
  5914. that of a window in the conventional Presentation Manager application model; 
  5915. the Workplace Shell object simply takes the object-oriented concepts to a 
  5916. higher degree of implementation. Therefore the constructs implemented by 
  5917. Presentation Manager under previous versions of OS/2 can often be implemented 
  5918. more elegantly with the Workplace Shell. 
  5919.  
  5920. For the remainder of this chapter, two examples are used to explain the 
  5921. structure and behavior of an object class. These are the pwFolder and 
  5922. pwFinanceFile Workplace Objects. 
  5923.  
  5924.    o  The pwFolder Workplace Object is a specific type of Workplace Shell 
  5925.       folder which has a password defined so that it can be locked to prevent 
  5926.       access by an unauthorized user. This object class is implemented by 
  5927.       subclassing the WPFolder class to create a new object class named 
  5928.       PWFolder, adding new methods and overriding existing methods where 
  5929.       appropriate. 
  5930.  
  5931.    o  The pwFinanceFile Workplace Object is a specific type of Workplace Shell 
  5932.       data file which has a password defined so that it can be locked to 
  5933.       prevent access by an unauthorized user. Additional methods have been 
  5934.       added to provide specific behavior and this is covered later in this 
  5935.       chapter. This object class is implemented by subclassing the WPDataFIle 
  5936.       class to create a new object class named PWFinanceFIle, adding new 
  5937.       methods and overriding existing methods where appropriate. 
  5938.  
  5939.  Sample code is provided in the text, and on an included diskette, for the 
  5940.  various methods used to add the password protection to the folder. 
  5941.  
  5942.  
  5943. ΓòÉΓòÉΓòÉ 15.2.1. Methods ΓòÉΓòÉΓòÉ
  5944.  
  5945. In a Presentation Manager application, a window procedure receives messages 
  5946. from Presentation Manager, determines the type of message and invokes a series 
  5947. of program statements (which effectively constitute a method) as a result of 
  5948. that message. A Workplace Shell object operates in a similar fashion, except 
  5949. that the Workplace Shell itself determines the type of message and invokes the 
  5950. corresponding method, without any explicit action on the part of the object. 
  5951.  
  5952. Therefore, whereas the Presentation Manager window procedure comprises a case 
  5953. statement with each case being a method, the Workplace Shell object eliminates 
  5954. the need for the case statement and allows the Workplace Shell to invoke the 
  5955. methods directly.  The syntax for invoking a method from within an object or 
  5956. application is hence very similar to that for invoking a subroutine;  the only 
  5957. real difference is that a method may be accessed from outside the object itself 
  5958. (that is, from another object or from an application), while a subroutine is 
  5959. normally private to the object. 
  5960.  
  5961. Many methods are defined by the WPObject class, from which application-defined 
  5962. classes are typically descended. When creating a new object class, a programmer 
  5963. may override the methods already defined by the class's ancestors, and/or 
  5964. include new methods specific to the class being created. The methods defined by 
  5965. the WPObject class are described in the IBM OS/2 Version 2.0 Presentation 
  5966. Manager Reference. Programmers who wish to create new object classes descended 
  5967. from this case should read the descriptions of these methods to determine the 
  5968. extent of the modifications necessary. 
  5969.  
  5970.  
  5971. ΓòÉΓòÉΓòÉ 15.2.1.1. Invoking a Method ΓòÉΓòÉΓòÉ
  5972.  
  5973. As mentioned in OS/2 2.1 Volume 4: Writing Applications, Chapter 4 "The 
  5974. Presentation Manager Application Model" , methods within an object are invoked 
  5975. as a result of messages that communicate events to the object. These events may 
  5976. be initiated by the user (for example, as a result of clicking the mouse on an 
  5977. object's context menu), by the object itself or another object, or by the 
  5978. system to indicate a system event such as opening or closing a view of the 
  5979. object. 
  5980.  
  5981. The syntax for invoking a method is similar to that for invoking a subroutine, 
  5982. with one exception. The first parameter passed in the call is a pointer to an 
  5983. object that is capable of invoking the method called the "receiver", and this 
  5984. is typically a pointer to the object itself. This is illustrated in Invoking a 
  5985. Method, where a sample invocation of a method named _wpSetTitle is shown. 
  5986.  
  5987. PWFolder *somSelf;                              /* Pointer to self       */
  5988. PSZ      szTitle;                               /* Title string          */
  5989.  
  5990. _wpSetTitle(somSelf,szTitle);                   /* Set title string      */
  5991. Invoking a Method 
  5992.  
  5993. The _wpSetTitle method is defined by the WPObject class, and is inherited by 
  5994. all classes descended from the class. The method accepts a title string and 
  5995. sets the title of the object; that is, the text that appears below the object's 
  5996. icon on the Workplace Shell desktop. 
  5997.  
  5998. The pointer somSelf is defined by the SOM Precompiler when it creates the "C" 
  5999. source code from the class definition file. In the example above, somSelf is 
  6000. defined as a pointer to an object of class PWFolder and within a method, allows 
  6001. the method to access the instance data of the object to which it belongs. The 
  6002. need to pass this pointer arises from the limitations of the "C" language 
  6003. syntax under which the current implementation of the Workplace Shell operates; 
  6004. other languages such as C++ may be able to invoke methods in a more elegant 
  6005. manner. 
  6006.  
  6007.  
  6008. ΓòÉΓòÉΓòÉ 15.2.1.2. Method Processing and Instance Data ΓòÉΓòÉΓòÉ
  6009.  
  6010. Within a method, the somSelf pointer, passed as the first parameter in the call 
  6011. to the method, acts as a pointer to the method's own object, and allows the 
  6012. method to access its instance data. The SOM Precompiler automatically provides 
  6013. a base pointer named somThis that references the instance data, and includes a 
  6014. call to a method that initializes this pointer from the object pointer: 
  6015.  
  6016. PWFolderData *somThis = PWFolderGetData(somSelf);
  6017.  
  6018. When this statement has successfully executed upon entry to the method, the 
  6019. method has access to the object's instance data. For example, the 
  6020. password-protected folder has a password string, which may be accessed by a 
  6021. method using the following name: 
  6022.  
  6023. somThis->szPassword
  6024.  
  6025. To make things simpler, the SOM Precompiler generates a macro for each instance 
  6026. variable, in a manner similar to that used for function names: 
  6027.  
  6028.    #define _szPassword (somThis->szPassword)
  6029.    #define _szCurrentPassword (somThis->szCurrentPassword)
  6030.    #define _szUserid (somThis->szUserid)
  6031.  
  6032. This macro is included in a header file for the object class, and avoids the 
  6033. need for the programmer to type the complete name throughout the source code. 
  6034.  
  6035. Once the instance data is available to the method, any application logic may be 
  6036. performed, including the use of OS/2 and Presentation Manager resources.  See 
  6037. Accessing Presentation Manager Resources From a Workplace Shell Object for 
  6038. additional considerations on the use of Presentation Manager resources from 
  6039. within a Workplace Shell object. 
  6040.  
  6041.  
  6042. ΓòÉΓòÉΓòÉ 15.2.1.3. Returning from a Method ΓòÉΓòÉΓòÉ
  6043.  
  6044. In order to return control to its calling routine, a method simply uses the 
  6045. return statement. Any valid form of return code may be passed to the calling 
  6046. routine as a parameter to this statement, provided that the data type of the 
  6047. return code is consistent with the declaration of the method. The data type of 
  6048. the return code is typically set by the SOM Precompiler, and a default return 
  6049. statement provided, based on information supplied by the programmer when the 
  6050. method is defined in the Methods section of the class definition file (see 
  6051. Class Definition File). 
  6052.  
  6053.  
  6054. ΓòÉΓòÉΓòÉ 15.2.1.4. Overriding Existing Methods ΓòÉΓòÉΓòÉ
  6055.  
  6056. A new object class may override one or more of the existing methods defined by 
  6057. its parent class, either to completely replace the processing performed by 
  6058. these methods, or to add its own processing to that already performed by the 
  6059. parent. An example of an object class overriding the _wpSetTitle method is 
  6060. shown in Overriding an Existing Method. 
  6061.  
  6062. SOM_Scope BOOL SOMLINK pwfolder_wpSetTitle(PWFolder *somSelf,
  6063.                                            PSZ pszNewTitle)
  6064. {
  6065.     CHAR szBuf[100];                            /* Character buffer      */
  6066.  
  6067.     PWFolderData *somThis =                     /* Get instance data     */
  6068.                  PWFolderGetData(somSelf);
  6069.     PWFolderMethodDebug("PWFolder",             /* Set debug info        */
  6070.                         "pwfolder_wpSetTitle");
  6071.  
  6072.     strcpy(szBuf,pszNewTitle);                  /* Get current title     */
  6073.  
  6074.     if ((strcmp(_szCurrentPassword,             /* If folder is locked   */
  6075.                 _szPassword)) != 0)
  6076.         if((strstr(szBuf,"LOCKED")) == NULL )   /* and <LOCKED> not in   */
  6077.                                                 /* current title         */
  6078.           strcat(szBuf," <LOCKED>");            /* Add <LOCKED> to title */
  6079.  
  6080.     return(parent_wpSetTitle(somSelf,           /* Allow default proc to */
  6081.                               szBuf));          /* occur                 */
  6082. }
  6083. Overriding an Existing Method 
  6084.  
  6085. This example shows the _wpSetTitle method being overridden to add the word 
  6086. "LOCKED" to the end of the title of a locked password-protected folder. 
  6087.  
  6088. The example given in Overriding an Existing Method shows the use of 
  6089. class-specific processing to modify the title of a password-protected folder. 
  6090. The inclusion of the string "<LOCKED>" at the end of the user-specified title 
  6091. provides a visual indication to the user that the folder is locked. Additional 
  6092. visual indication is provided by modifying the icon when the folder is in the 
  6093. locked state; the code that carries out this operation is included in the 
  6094. _LockFolder method shown in Adding a New Method. 
  6095.  
  6096. The strings _szCurrentPassword and _szPassword are instance data items defined 
  6097. by the new object class. These data items are actually accessed using the 
  6098. somThis pointer; however, the SOM Precompiler defines a macro for each instance 
  6099. data item, as described in Method Processing and Instance Data. 
  6100.  
  6101. Note that most workplace methods require that parent processing be performed 
  6102. during the override function. Normally this would be part of the return 
  6103. statement, but some methods require parent processing to be done first. You 
  6104. should check the method description to determine where the parent processing 
  6105. needs to be done. 
  6106.  
  6107.  
  6108. ΓòÉΓòÉΓòÉ 15.2.1.5. Adding New Methods ΓòÉΓòÉΓòÉ
  6109.  
  6110. In addition to overriding existing methods defined by the parent class, an 
  6111. object class may also add new methods to carry out processing for events not 
  6112. handled by the parent class. For example, the password-protected folder example 
  6113. must have a mechanism to lock the folder. This is implemented as a new method 
  6114. named _LockFolder, as shown in Adding a New Method. 
  6115.  
  6116. SOM_Scope BOOL SOMLINK pwfolder_LockFolder(PWFolder *somSelf)
  6117. {
  6118.     HPTR  hLockedIcon;
  6119.  
  6120.     PWFolderData *somThis =                     /* Get instance data     */
  6121.                  PWFolderGetData(somSelf);
  6122.     PWFolderMethodDebug("PWFolder",             /* Set debug info        */
  6123.                         "pwfolder_LockFolder");
  6124.  
  6125.     strcpy(_szCurrentPassword,                  /* Invalidate current    */
  6126.            "NOPASSWD");                         /* password              */
  6127.     _wpSetTitle(somSelf,                        /* Set title             */
  6128.                 _wpQueryTitle(somSelf) );
  6129.  
  6130.     hLockedIcon = WinLoadPointer(HWND_DESKTOP,  /* Load "lock" icon      */
  6131.                                  (HMODULE)0,
  6132.                                  LOCK);
  6133.  
  6134.     _wpSetIcon(somSelf,                         /* Set icon to locked    */
  6135.                hLockedIcon);                    /* appearance            */
  6136.  
  6137.     return((BOOL)0);                            /* Return                */
  6138. }
  6139. Adding a New Method 
  6140.  
  6141. This method simply copies a default string to the variable _szCurrentPassword 
  6142. that contains the last supplied password entry from the user, so that when a 
  6143. comparison is made between this variable and the folder's password, the two do 
  6144. not match. This effectively locks the folder and prevents any view of it being 
  6145. opened. To provide a visual indication to the end user that the folder is 
  6146. locked, a "locked" icon is loaded using the Presentation Manager 
  6147. WinLoadPointer() function, and the _wpSetIcon method is invoked to set this as 
  6148. the folder's new icon on the desktop. 
  6149.  
  6150. Note that the definition for adding a new method is very similar to that for 
  6151. overriding an existing method. The primary difference is that, since the new 
  6152. method is specific to the object class and is not defined by the parent class, 
  6153. there is no need to invoke the parent class's method to perform default 
  6154. processing for the method. 
  6155.  
  6156.  
  6157. ΓòÉΓòÉΓòÉ 15.2.1.6. Attaching a Method to the Context Menu ΓòÉΓòÉΓòÉ
  6158.  
  6159. A method may be invoked as a result of the user selecting an item from the 
  6160. object's context menu. In order to allow this, an item must be added to the 
  6161. context menu, and an appropriate action must be taken by the object when that 
  6162. item is selected by the user. 
  6163.  
  6164. An item can be added to the context menu for an object class by overriding the 
  6165. _wpModifyPopupMenu method defined by the WPObject class, and including a call 
  6166. to the _wpInsertPopupMenuItem method to insert the item.  This technique is 
  6167. shown in Adding an Item to a Context Menu. 
  6168.  
  6169. #define MI_LOCK     WPMENUID_USER+1
  6170.    :
  6171.    :
  6172. SOM_Scope BOOL SOMLINK pwfolder_wpModifyPopupMenu(PWFolder *somSelf,
  6173.                                                   HWND hwndMenu,
  6174.                                                   HWND hwndCnr,
  6175.                                                   ULONG iPosition)
  6176. {
  6177.     PWFolderData *somThis =                     /* Get instance data     */
  6178.                  PWFolderGetData(somSelf);
  6179.     PWFolderMethodDebug("PWFolder",             /* Set debug info        */
  6180.                         "pwfolder_wpModifyPopupMenu");
  6181.  
  6182.     _wpInsertPopupMenuItems(somSelf,            /* Insert menu item      */
  6183.                             hwndMenu,           /* Menu handle           */
  6184.                             iPosition,          /* Default position      */
  6185.                             hModule,            /* Module handle         */
  6186.                             MI_LOCK,            /* Menu item id          */
  6187.                             0);                 /* No submenu id         */
  6188.  
  6189.     return(parent_wpModifyPopupMenu(somSelf,    /* Allow default proc to */
  6190.                                     hwndMenu,   /* occur                 */
  6191.                                     hwndCnr,
  6192.                                     iPosition));
  6193. }
  6194. Adding an Item to a Context Menu 
  6195.  
  6196. The example shown in Adding an Item to a Context Menu adds a Lock item to the 
  6197. context menu for the password-protected folder object. This allows the folder 
  6198. to be locked by the user at any time, irrespective of whether a view of the 
  6199. folder is currently open. 
  6200.  
  6201. The _wpInsertPopupMenuItem method adds a menu item or a submenu to the existing 
  6202. context menu for the object. The item identifier for the menu item or submenu 
  6203. (MI_LOCK in the above example) is an integer constant that is typically defined 
  6204. in the header file. Note that the value of this constant should be specified as 
  6205. an offset from the system-defined constant WPMENUID_USER, rather than an 
  6206. absolute integer value. Following this convention will avoid any clashes with 
  6207. item identifiers defined by the Workplace Shell for default context menu items. 
  6208.  
  6209. Since the password-protected folder is a descendant of the WPFolder class 
  6210. defined by the Workplace Shell, the default context menu items for the WPFolder 
  6211. class should also appear. The default processing for the parent class is 
  6212. therefore invoked as part of the _wpModifyPopupMenu processing for the new 
  6213. object class. 
  6214.  
  6215. Once the required item is added to the context menu, the object must be able to 
  6216. detect when the item is selected in order to invoke the appropriate method. is 
  6217. invoked by the system whenever the user selects an item from the context menu. 
  6218. This method, which is defined by the WPObject class, may be overridden by a new 
  6219. object class in order to check for the presence of a new item and invoke the 
  6220. appropriate method. The item identifier of the selected item is passed as a 
  6221. parameter to the _wpMenuItemSelected method, and is normally interrogated using 
  6222. a case statement, as shown in Invoking a Method via a Context Menu Item. 
  6223.  
  6224. SOM_Scope void SOMLINK pwfolder_wpMenuItemSelected(PWFolder *somSelf,
  6225.                                                    HWND hwndFrame,
  6226.                                                    ULONG MenuId)
  6227. {
  6228.     PWFolderData *somThis =                     /* Get instance data     */
  6229.                  PWFolderGetData(somSelf);
  6230.     PWFolderMethodDebug("PWFolder",             /* Set debug info        */
  6231.                         "pwfolder_wpMenuItemSelected");
  6232.  
  6233.     switch (MenuId)                             /* Switch on item id     */
  6234.            {
  6235.            case MI_LOCK:                        /* If "Lock" item        */
  6236.                 _LockFolder(somSelf);           /* Lock folder           */
  6237.                 break;
  6238.            default:                                  /* else             */
  6239.                 parent_wpMenuItemSelected(somSelf,   /* Allow default    */
  6240.                                           hwndFrame, /* processing to    */
  6241.                                           MenuId);   /* occur            */
  6242.                 break;
  6243.            }
  6244.     return;
  6245. }
  6246. Invoking a Method via a Context Menu Item 
  6247.  
  6248. The _wpMenuItemSelected method consists of a case statement that determines the 
  6249. item selected from the context menu. In the above example, an explicit case is 
  6250. included only for the MI_LOCK item defined by this class. All other menu items 
  6251. are defined by the parent class, and their selection is therefore handled by 
  6252. allowing the parent class's default processing to occur. 
  6253.  
  6254.  
  6255. ΓòÉΓòÉΓòÉ 15.2.1.7. Modifying the Standard Context Menu Items ΓòÉΓòÉΓòÉ
  6256.  
  6257. The _wpFilterPopupMenu method can be used to filter out (remove) standard menu 
  6258. items that are inherited from the ancestor classes, or to reinstate any of the 
  6259. standard pop-up menu items. This method can also be used to determine if the 
  6260. ancestor classes have filtered out any of the Workplace Shell-provided standard 
  6261. menu items, by checking to see if any of the flags associated with the menu 
  6262. items are not set. 
  6263.  
  6264. The ulFlags parameter of "C" type ULONG is really a bit array which is binary 
  6265. ORed together with the ancestor classes ulFlags when the parent method is 
  6266. called, effectively adding these menu items together. The resultant ulFlags is 
  6267. then returned from the _wpFilterPopupMenu method. 
  6268.  
  6269. But if the parent method is called first, then the resultant flags are binary 
  6270. ANDed with the complement of the menu item (flag) to be removed. Upon returning 
  6271. this from the object's _wpFilterPopupMenu, the item will now be removed from 
  6272. the pop-up menu. 
  6273.  
  6274. To determine if a menu item is present or not, first call the parent method and 
  6275. then simply binary AND the menu item flag with the parent method result. If the 
  6276. result of this operation is the menu item flag that was ANDed, then the flag 
  6277. has been set by the ancestor classes; otherwise it has been removed. 
  6278.  
  6279. Filtering the Pop-up Menu Items shows how to test for a menu item, removing the 
  6280. menu item if it is present, or adding it if the ancestor classes removed it. In 
  6281. this case the Create another menu item is the menu item of interest. 
  6282.  
  6283. SOM_Scope ULONG   SOMLINK pwFinanceFile_wpFilterPopupMenu(PWFinanceFile *somSelf,
  6284.                 ULONG ulFlags,
  6285.                 HWND hwndCnr,
  6286.                 BOOL fMultiSelect)
  6287. { ULONG ulPopupFlags;
  6288.  
  6289.     PWFinanceFileData *somThis = PWFinanceFileGetData(somSelf);
  6290.     PWFinanceFileMethodDebug("PWFinanceFile","pwFinanceFile_wpFilterPopupMenu");
  6291.  
  6292.     /* first find out what our ancestors have done! */
  6293.     ulPopupFlags = parent_wpFilterPopupMenu(somSelf,ulFlags,hwndCnr,fMultiSelect);
  6294.  
  6295.     /* now what has been done to the "Create another" menu item */
  6296.     if ((ulPopupFlags & CTXT_NEW) == CTXT_NEW) {
  6297.  
  6298.        /* the "Create another" menu item is on our Popup, so remove it */
  6299.        ulPopupFlags = ulPopupFlags & ~CTXT_NEW;
  6300.     } else {
  6301.  
  6302.        /* the "Create another" menu item is NOT on our Popup, so add it */
  6303.        ulPopupFlags = ulPopupFlags | CTXT_NEW;
  6304.     } /* endif */
  6305.  
  6306.     return(ulPopupFlags);
  6307. }
  6308. Filtering the Pop-up Menu Items 
  6309.  
  6310.  
  6311. ΓòÉΓòÉΓòÉ 15.2.1.8. Class Methods ΓòÉΓòÉΓòÉ
  6312.  
  6313. Most object methods are instance methods; that is, they act upon one particular 
  6314. instance of an object class, rather than upon all instances of the class. 
  6315.  
  6316. However, there are times when it is useful to have methods that operate on the 
  6317. object class itself. These methods may operate on class data rather than 
  6318. instance data, thereby affecting the entire class rather than a single instance 
  6319. of the class.  Such methods are known as class methods. The class method 
  6320. _wpclsQueryTitle is defined by the WPObject class, and is overridden in the 
  6321. password-protected folder example. An example of the overridden 
  6322. _wpclsQueryTitle method is given in Class Method Example. 
  6323.  
  6324. PSZ szDefaultClassTitle = "Password Folder";
  6325.  
  6326. /*
  6327.  *
  6328.  *  METHOD: wpclsQueryTitle                               PUBLIC
  6329.  *
  6330.  *  PURPOSE:
  6331.  *    Return the string "Password Folder"
  6332.  *
  6333.  */
  6334. #undef SOM_CurrentClass
  6335. #define SOM_CurrentClass M_PWFolderCClassData.parentMtab
  6336. SOM_Scope PSZ SOMLINK pwfoldercls_wpclsQueryTitle(M_PWFolder *somSelf)
  6337. {
  6338.     /* M_PWFolderData *somThis = M_PWFolderGetData(somSelf); */
  6339.     M_PWFolderMethodDebug("M_PWFolder","pwfoldercls_wpclsQueryTitle");
  6340.  
  6341.     return(szDefaultClassTitle);
  6342. }
  6343.  
  6344. Class Method Example 
  6345.  
  6346. This example shows an overridden class method _wpclsQueryTitle, which is 
  6347. modified to supply a default title for an object within the class. 
  6348.  
  6349. The purpose of this class method is to provide the password-protected folder 
  6350. with a default title. This is the title that will appear with the folder's 
  6351. template icon in the Templates folder, and which is given to any instances of 
  6352. the class that are instantiated without a title. Since the default title 
  6353. applies to all instances of the class, it is implemented in a class method 
  6354. rather than an instance method. 
  6355.  
  6356. The prefix "M_" denotes the metaclass in the SOM-generated "C" source. As 
  6357. already mentioned, the first parameter passed to a method is a pointer to a 
  6358. type of object that can invoke that method; this is true for both instance 
  6359. methods and class methods; for a class method the first parameter contains a 
  6360. pointer to an instance of the metaclass. 
  6361.  
  6362.             Pointer to instance of metaclass
  6363.             which is a class object ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
  6364.                                              
  6365.    pwfoldercls_wpclsQueryTitle(M_PWFolder *somSelf)
  6366.                                   
  6367.         Type is Metaclass ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
  6368.  
  6369. Since a class is also an object, it follows that the class itself has its own 
  6370. "instance data"; hence the next line of code appears as follows: 
  6371.  
  6372.     /* M_PWFolderData *somThis = M_PWFolderGetData(somSelf); */
  6373.  
  6374. This statement would access the SOM object's class data. However, since no 
  6375. class data is specified in the .CSC file, there is nothing to access and so the 
  6376. SOM Precompiler has commented the line out to reflect this. 
  6377.  
  6378. For simple examples, it is easier to use global variables in the DLL for class 
  6379. data. This technique has been used in Class Method Example; the default title 
  6380. string is stored at the beginning of the program into the global variable 
  6381. szDefaultTitle. However, using this technique means that class data can be 
  6382. accessed by instance methods, which is never desirable, and may have adverse 
  6383. consequences, although these may generally be avoided by sound programming 
  6384. techniques. 
  6385.  
  6386.  
  6387. ΓòÉΓòÉΓòÉ 15.2.1.9. Invoking Another Object's Methods ΓòÉΓòÉΓòÉ
  6388.  
  6389. An object may invoke a method in another object class. This technique is useful 
  6390. in a client-server situation, where one object creates another object of a 
  6391. different class and then wishes to have that object perform certain actions. 
  6392. The system object model provides programming functions that can be used to 
  6393. determine the necessary information and invoke the method. An example is given 
  6394. in Invoking a Method in Another Object Class. 
  6395.  
  6396. SOMAny *RecordClass;                            /* Class object pointer  */
  6397. somID  idQueryMethod;                           /* Method id             */
  6398.  
  6399. CHAR   szQueryBuffer[100];                      /* Query data buffer     */
  6400. PVOID  pFindData;                               /* Returned data buffer  */
  6401.    :
  6402.    :
  6403. rc = DosAllocSharedMem(&pFindData,              /* Alloc shared memory   */
  6404.                        NULL,                    /* No name               */
  6405.                        sizeof(szQueryBuffer)+1, /* Size of memory object */
  6406.                        OBJ_GIVEABLE  |          /* Make object giveable  */
  6407.                        PAG_WRITE     |          /* Allow write access    */
  6408.                        PAG_READ      |          /* Allow read access     */
  6409.                        PAG_COMMIT);             /* Commit storage now    */
  6410.  
  6411. strcpy(pFindData,szQueryBuffer);                /* Copy data to buffer   */
  6412.  
  6413. RecordClass = _somFindClass(SOMClassMgrObject,  /* Get class obj pointer */
  6414.                             SOM_IdFromString("Record"),
  6415.                                              1,1));
  6416. idQueryMethod = SOM_IdFromString("clsQuery");   /* Get method id         */
  6417.  
  6418. _somDispatchL(RecordClass,                      /* Invoke method         */
  6419.               idQueryMethod,                    /* Method id             */
  6420.               (void *)0,                        /* No descriptor string  */
  6421.               pFindData,                        /* Method parameters     */
  6422.               somSelf);
  6423. Invoking a Method in Another Object Class 
  6424.  
  6425. The example given in Invoking a Method in Another Object Class shows part of a 
  6426. "database client" object that sends a database query to a "database server" 
  6427. object. The client first allocates a shared memory object into which it loads 
  6428. the query. The client then uses the _somFindClass method and the 
  6429. SOM_IdFromString macro to determine the object pointer for the object, and the 
  6430. method identifier for the required method. The _somDispatchL method is then 
  6431. used to invoke the method. 
  6432.  
  6433. It is also possible to invoke a class method using the object pointer to that 
  6434. class, obtained using the _somFindClass method shown in Invoking a Method in 
  6435. Another Object Class. This requires the header file for the class to be 
  6436. included in the source code for the class that will invoke the method, using a 
  6437. #include statement. In the module definition file for the invoking class, the 
  6438. following IMPORT statements must be provided: 
  6439.  
  6440.         IMPORTS
  6441.            record.RecordCClassData
  6442.            record.RecordClassData
  6443.            record.RecordNewClass
  6444.            record.M_RecordCClassData
  6445.            record.M_RecordClassData
  6446.            record.M_RecordNewClass
  6447.  
  6448. When these steps have been carried out, a method in the other class may be 
  6449. invoked directly, as follows: 
  6450.  
  6451. _clsQueryDatabase(RecordClass,               /* Invoke class method   */
  6452.                   pQuery,                    /* Method specific       */
  6453.                   Folder);                   /* parameters            */
  6454.  
  6455. While this technique is less clean than the previous approach since it requires 
  6456. the inclusion of the header file and import statements, it provides better 
  6457. performance. 
  6458.  
  6459.  
  6460. ΓòÉΓòÉΓòÉ 15.2.2. Subroutines ΓòÉΓòÉΓòÉ
  6461.  
  6462. Subroutines may be accessed from within a Workplace Shell object, in much the 
  6463. same manner as from any other program. Normal programming language calling 
  6464. conventions are used.  Subroutines used by the object may reside within the 
  6465. same DLL as the object itself, or may be in a different DLL. 
  6466.  
  6467. A number of guidelines for the use of subroutines within Presentation Manager 
  6468. applications are given in OS/2 2.1 Volume 4: Writing Applications, Chapter 4 
  6469. "The Presentation Manager Application Model". Note that similar guidelines 
  6470. apply to the use of subroutines within Workplace Shell objects, since these 
  6471. objects should also adhere to object-oriented programming principles. 
  6472.  
  6473.  
  6474. ΓòÉΓòÉΓòÉ 15.3. Defining an Object ΓòÉΓòÉΓòÉ
  6475.  
  6476. The definition of an object is achieved using a language known as the Object 
  6477. Interface Definition Language. The statements that define an object class are 
  6478. entered into the class definition file for the class, which is an ASCII file 
  6479. and may thus be created using any normal text editor.  The class definition 
  6480. file is used as input to the SOM Precompiler, which will generate a number of 
  6481. files from the class definition file. 
  6482.  
  6483.  
  6484. ΓòÉΓòÉΓòÉ 15.3.1. Files ΓòÉΓòÉΓòÉ
  6485.  
  6486. The SOM Precompiler generates a number of files that are used to define an 
  6487. object class to the Workplace Shell and to other classes that may wish to 
  6488. inherit the characteristics and behaviors of the class. These files are: 
  6489.  
  6490.  .H        A public header file for programs that use the class. 
  6491.  .PH       A private header file, which provides usage bindings to any private 
  6492.            methods implemented by the class. 
  6493.  .IH       An implementation header file, which provides macros, etc., to 
  6494.            support the implementation of the class. 
  6495.  .C        A template C file, to which code may be added to implement the 
  6496.            class. 
  6497.  .SC       A language-neutral class definition. 
  6498.  .PSC      A private language-neutral core file, which contains private parts 
  6499.            of the interface for the class. 
  6500.  .DEF      An OS/2 DLL module definition file containing the relevant exports 
  6501.            need to implement the class. 
  6502.  
  6503.  These files may then be used as input to a C compiler, generating object code 
  6504.  that is in turn linked to create a dynamic link library, which implements the 
  6505.  object class. 
  6506.  
  6507.  
  6508. ΓòÉΓòÉΓòÉ 15.3.2. Class Definition File ΓòÉΓòÉΓòÉ
  6509.  
  6510. The class definition file contains all the information necessary to implement a 
  6511. new class. The file is divided into the following sections: 
  6512.  
  6513.    1. Include section 
  6514.  
  6515.    2. Class section 
  6516.  
  6517.    3. Parent Class section 
  6518.  
  6519.    4. Release Order section 
  6520.  
  6521.    5. Metaclass section 
  6522.  
  6523.    6. Passthru section 
  6524.  
  6525.    7. Data section 
  6526.  
  6527.    8. Methods section 
  6528.  
  6529.  Each of these sections is described in more detail below, using examples from 
  6530.  the password-protected folder class described earlier in this chapter. 
  6531.  
  6532.  
  6533. ΓòÉΓòÉΓòÉ 15.3.2.1. Include Section ΓòÉΓòÉΓòÉ
  6534.  
  6535. Since all system object model classes have a parent, it is necessary to know 
  6536. the name of the parent class and the location of its interface definition. The 
  6537. include section specifies the location of the interface definition file for the 
  6538. parent. In the folder example, only a single line is included: 
  6539.  
  6540. #
  6541. # Include the class definition file for the parent class
  6542. #
  6543. include <wpfolder.sc>
  6544.  
  6545. Since the folder example is simply a specialized form of the WPFolder class, it 
  6546. uses this class as its parent and inherits much of its behavior from the 
  6547. WPFolder class. The include section therefore specifies the interface 
  6548. definition for the WPFolder class. A full list of Workplace Shell classes and 
  6549. their definition files can be found in the IBM OS/2 Version 2.0 Presentation 
  6550. Manager Reference. 
  6551.  
  6552. Note that the comments that start with a "#" are discarded by the SOM 
  6553. Precompiler; hence the comment in the example above will not be seen in the SOM 
  6554. Precompiler-generated files. 
  6555.  
  6556.  
  6557. ΓòÉΓòÉΓòÉ 15.3.2.2. Class Section ΓòÉΓòÉΓòÉ
  6558.  
  6559. This section provides basic information about the new class, specifying its 
  6560. name and various attributes. The password folder example has the following 
  6561. class section entry: 
  6562.  
  6563. #
  6564. #   Define the new class
  6565. #
  6566. class: PWFolder,
  6567.        file stem = pwfolder,
  6568.        external prefix = pwFolder_,
  6569.        class prefix = pwFoldercls_,
  6570.        major version = 1,
  6571.        minor version = 1,
  6572.        local;
  6573. -- PWFolder is a Password-protected folder.
  6574. -- Its derived as follows:
  6575. --        SOMOject
  6576. --          - WPObject
  6577. --             - WPFileSystem
  6578. --                - WPFolder
  6579. --                   - PWFolder
  6580.  
  6581. All class definition files must contain a class section.  Certain statements 
  6582. within the class section are mandatory, while others are optional. 
  6583.  
  6584. The first item in the class section is a name: 
  6585.  
  6586. class: PWFolder,
  6587.  
  6588. All classes must have a name. 
  6589.  
  6590. The file stem specifies the file name to be used by the SOM Precompiler for the 
  6591. generated files. For example, if the file stem statement reads: 
  6592.  
  6593. file stem = myfile
  6594.  
  6595. then the .DEF file generated by the SOM Precompiler would be called myfile.def. 
  6596.  
  6597. The external prefix specifies a prefix to be used by the SOM Precompiler on all 
  6598. function names. Hence if an external prefix of "pwFolder_" is specified and a 
  6599. method is named "SetInfo", the function name generated by the SOM Precompiler 
  6600. would be "pwFolder_SetInfo". 
  6601.  
  6602. The SOM Precompiler normally generates a macro for all methods defined by the 
  6603. class, such that the method is referenced in the source code by its defined 
  6604. name, preceded by an underscore character. For example, the method 
  6605. pwFolder_SetInfo described above would be referenced simply as _SetInfo. This 
  6606. helps make the source code more readable and avoids the need for the programmer 
  6607. to type the full name when editing the code. 
  6608.  
  6609. The class prefix is similar to the external prefix, except that it is used 
  6610. specifically for functions that are class methods. The differences between 
  6611. class methods and instance methods are discussed in Class Methods. 
  6612.  
  6613. The major version and minor version are used to ensure that the bindings are at 
  6614. the right level for the class implementation code. 
  6615.  
  6616. The local option is used to specify that binding files should be linked 
  6617. locally. In "C" programming terms, this means that the following source code is 
  6618. generated: 
  6619.  
  6620.    #include "wpfolder.h"
  6621.  
  6622. If the global option is used, the resulting source code would be as follows: 
  6623.  
  6624. #include <wpfolder.h>
  6625.  
  6626. The last part of the class section is for comments.  Using "--" as the comment 
  6627. style causes a comment block to be passed through to the interface definition 
  6628. (.SC) file. 
  6629.  
  6630.  
  6631. ΓòÉΓòÉΓòÉ 15.3.2.3. Parent Class Section ΓòÉΓòÉΓòÉ
  6632.  
  6633. The parent class section specifies the parent of the new class. All classes 
  6634. must have this section. The parent class section for the password-protected 
  6635. folder example appears as follows: 
  6636.  
  6637. #
  6638. # Parent class
  6639. #
  6640. parent: WPFolder;
  6641.  
  6642.  
  6643. ΓòÉΓòÉΓòÉ 15.3.2.4. Release Order Section ΓòÉΓòÉΓòÉ
  6644.  
  6645. This section allows the programmer to specify the sequence in which the methods 
  6646. and public data will be released. Since this sequence is maintained by the SOM 
  6647. Precompiler, other programs using this class will not need to be recompiled 
  6648. every time something new is added to the class. 
  6649.  
  6650. Note that for future compatibility it is essential that all public and private 
  6651. methods are listed in the release order section, and their order does not 
  6652. change. It is strongly suggested that the "-r" option be used with the SOM 
  6653. compiler to produce any release order warnings. 
  6654.  
  6655. The password-protected folder example has only one public method in addition to 
  6656. those already defined by its ancestor classes. This method is seen in the 
  6657. release section as follows: 
  6658.  
  6659. #
  6660. # Specify the release order of new methods
  6661. #
  6662. release order: LockFolder;
  6663.  
  6664. Since other public methods are defined by the parent class or by its ancestors, 
  6665. the programmer creating an object class need not define these methods in the 
  6666. class definition file. Hence the programmer need not be aware of the existing 
  6667. methods in the parent class, unless they require modification for use by the 
  6668. new class. This is in accordance with the object-oriented concept of 
  6669. encapsulation. 
  6670.  
  6671.  
  6672. ΓòÉΓòÉΓòÉ 15.3.2.5. Metaclass Section ΓòÉΓòÉΓòÉ
  6673.  
  6674. For the password-protected folder example (and in most other cases) an explicit 
  6675. metaclass is not required. The concept of metaclasses is discussed in 
  6676. Metaclasses. Readers desiring more knowledge of programming using metaclasses 
  6677. should refer to the IBM SOM Programming Reference. 
  6678.  
  6679.  
  6680. ΓòÉΓòÉΓòÉ 15.3.2.6. Passthru Section ΓòÉΓòÉΓòÉ
  6681.  
  6682. This section allows the programmer to define blocks of C source code that are 
  6683. passed through to any of the files generated by the SOM Precompiler. Each 
  6684. passthru block is distinguished by an identifier, the syntax of which is as 
  6685. follows: 
  6686.  
  6687.    passthru: <language>.<suffix>
  6688.  
  6689. The password-protected folder example has two passthru sections. The first 
  6690. passthru is "C.h", which passes the code block to the C binding file 
  6691. pwfolder.h. This block of code defines a DebugBox macro, which can be used 
  6692. anywhere in the code for the new class. 
  6693.  
  6694. #
  6695. # Passthru a debug message box to the .ih file
  6696. # (for inclusion in the .c file)
  6697. #
  6698. passthru: C.h, after;
  6699.  
  6700. #define DebugBox(Title, Text) WinMessageBox(HWND_DESKTOP,
  6701.                                             HWND_DESKTOP,
  6702.                                             (PSZ)Text,
  6703.                                             (PSZ)Title,
  6704.                                             0,
  6705.                                             MB_OK |
  6706.                                             MB_INFORMATION)
  6707.  
  6708. endpassthru;
  6709.  
  6710. The second passthru block is "C.ph"; this passes the code block to the C 
  6711. binding file pwfolder.ph. This block is used to define a data structure that is 
  6712. accessed by the private methods _GetInfo and _SetInfo, and is used to pass 
  6713. information to and from the dialog procedure that prompts the user for the 
  6714. folder password. 
  6715.  
  6716. #
  6717. # Passthru private definitions to the .ph file
  6718. # (for inclusion in the .c file)
  6719. #
  6720. passthru: C.ph;
  6721.  
  6722. typedef struct _PWF_INFO {
  6723.                          CHAR   szPassword[20];
  6724.                          CHAR   szCurrentPassword[20];
  6725.                          CHAR   szUserid[20];
  6726.                          } PWF_INFO;
  6727. typedef PWF_INFO *PPWF_INFO;
  6728.  
  6729. endpassthru;
  6730.  
  6731.  
  6732. ΓòÉΓòÉΓòÉ 15.3.2.7. Data Section ΓòÉΓòÉΓòÉ
  6733.  
  6734. This section lists the instance variables used by the class. In the 
  6735. password-protected folder example, three variables are defined as follows: 
  6736.  
  6737. #
  6738. # Define instance data for the class
  6739. #
  6740. data:
  6741. CHAR szPassword[20];
  6742. --  This is the password that locks the folder
  6743. CHAR szCurrentPassword[20];
  6744. --  This is the password the user has entered to be
  6745. --  checked against the lock password
  6746. CHAR szUserid[20];
  6747. --  The userid data is here for future expansion
  6748.  
  6749. Note that the szUserid instance variable is not used in the version discussed 
  6750. in this document, since the current example assumes only a single workstation 
  6751. user. However, it is feasible for user identification to be obtained at 
  6752. startup, and held by the system for authentication against a password to 
  6753. determine whether access is permitted. 
  6754.  
  6755.  
  6756. ΓòÉΓòÉΓòÉ 15.3.2.8. Methods Section ΓòÉΓòÉΓòÉ
  6757.  
  6758. The last section in the class definition file contains a list of all the 
  6759. methods to be defined by the object class. ANSI C function-prototype syntax is 
  6760. used to define each method. When coding these definitions, it is recommended 
  6761. that the methods be divided into the following parts: 
  6762.  
  6763.    1. Methods that are new for this class 
  6764.  
  6765.    2. Methods that are overridden from ancestor classes 
  6766.  
  6767.  The following section shows two methods taken from the folder example's class 
  6768.  definition file. 
  6769.  
  6770.  This first method will be used in the password dialog to take a copy of the 
  6771.  object's instance data and place it in a structure that the dialog code may 
  6772.  access. 
  6773.  
  6774.   #
  6775.   # Define new methods
  6776.   #
  6777.   methods:
  6778.  
  6779.   BOOL QueryInfo(PPWF_INFO pPWFolderInfo), private;
  6780.   --
  6781.   -- METHOD:   QueryInfo                                   PRIVATE
  6782.   --
  6783.   -- PURPOSE:  Copy the PWFolder instance data into
  6784.   --           the PWF_INFO structure that pPWFolderInfo
  6785.   --           points to.
  6786.   --
  6787.  
  6788.  The second example shows an overridden method. This method originates in the 
  6789.  WPObject class, which is a base class. It is used to set up the password 
  6790.  string when the folder object is created. 
  6791.  
  6792.   #
  6793.   # Specify methods being overridden
  6794.   #
  6795.  
  6796.   override wpSetup;
  6797.   --
  6798.   -- OVERRIDE: wpSetup                                     PUBLIC
  6799.   --
  6800.   -- PURPOSE:  Here we can set the folder password
  6801.   --           to that passed in from the object
  6802.   --           create command.
  6803.   --
  6804.  
  6805.  More detailed information on class definition files and the OIDL is given in 
  6806.  the IBM SOM Programming Reference. 
  6807.  
  6808.  
  6809. ΓòÉΓòÉΓòÉ 15.3.3. C Implementation of an Object Class ΓòÉΓòÉΓòÉ
  6810.  
  6811. When the SOM Precompiler has been run successfully against a class definition 
  6812. file, it will produce all the source files necessary to build a Workplace Shell 
  6813. DLL. The most important of these files for the C programmer is the C source 
  6814. code file, which has an extension of .C. This file contains definitions and 
  6815. "function stubs" for all the methods defined by the class. This file must be 
  6816. edited by the programmer to add the actual application logic to each method. A 
  6817. SOM Precompiler-generated Function Stub shows the SOM Precompiler-generated 
  6818. function stub for the QueryInfo method from the folder example. 
  6819.  
  6820. /*
  6821.  *
  6822.  *  METHOD:   QueryInfo                                   PRIVATE
  6823.  *
  6824.  *  PURPOSE:  Copy the PWFolder instance data into
  6825.  *            the PWF_INFO structure that pPWFolderInfo
  6826.  *            points to.
  6827.  *                           ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇ2
  6828.  */                          Γöé                           ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇ3
  6829.                                                         
  6830. SOM_Scope BOOL     SOMLINK pwFolder_QueryInfo(PWFolder *somSelf,
  6831.                                PPWF_INFO pPWFolderInfo)
  6832. {       ΓööΓöÇΓöÇΓöÇ1
  6833.     PWFolderData *somThis = PWFolderGetData(somSelf);  4
  6834.     PWFolderMethodDebug("PWFolder","pwfolder_QueryInfo");  5
  6835.  
  6836.     <application logic>  6
  6837.  
  6838.     return((BOOL)0);
  6839. }             
  6840.               ΓööΓöÇΓöÇΓöÇΓöÇ7
  6841. A SOM Precompiler-generated Function Stub 
  6842.  
  6843. Notes: 
  6844.  
  6845. 1 SOM_Scope declares the function scope according to the language being used. 
  6846. For example, in C++, SOM_Scope would be defined as extern C but in C it is 
  6847. simply defined as extern. 
  6848.  
  6849. 2 It can be seen that the external prefix "pwfolder_", which was specified in 
  6850. the class definition file, has been placed in front of the function as 
  6851. expected. Note that the SOM Precompiler generates a macro for this function in 
  6852. the private header file: 
  6853.  
  6854.    #define _QueryInfo PWFolder_QueryInfo
  6855.  
  6856. This avoids the necessity for the programmer to type the full function name, 
  6857. and helps make the code more readable. 
  6858.  
  6859. 3 Since SOM uses the C language, methods from SOM objects cannot be referenced 
  6860. in a very elegant manner. The first parameter to a SOM method must be a pointer 
  6861. to an object that can invoke that method. In the actual method function, this 
  6862. pointer is given the name somSelf. For example, the difference between C and 
  6863. C++ is as follows: 
  6864.  
  6865.    /* Let us say */
  6866.  
  6867.         pMyObject =  (pointer to an object);
  6868.  
  6869.    // in C++ the following syntax may be used
  6870.  
  6871.         pMyObject->Method(param1, param2....);
  6872.  
  6873.    /* but in C the following is required */
  6874.  
  6875.         Method(pMyObject, param1, param2....);
  6876.  
  6877. 4 This statement uses the pointer to the object to initialize a pointer to 
  6878. access the object's instance data. See Method Processing and Instance Data for 
  6879. further information on instance data. 
  6880.  
  6881. 5 This line will perform tracing. Tracing is switched on whenever the SOM 
  6882. global variable SOM_TraceLevel is set to a non-zero value. 
  6883.  
  6884. 6 This section is left blank by the SOM Precompiler for the developer to fill 
  6885. with the application logic. This logic may include access to system and/or 
  6886. Presentation Manager resources. For the password-protected folder example, the 
  6887. _QueryInfo method must copy the instance variables to the PWF_INFO data 
  6888. structure defined in the passthru section of the class definition file. The 
  6889. code required to do this is as follows: 
  6890.  
  6891.    strcpy(pPWFolderInfo->szPassword, _szPassword);
  6892.    strcpy(pPWFolderInfo->szCurrentPassword, _szCurrentPassword);
  6893.    strcpy(pPWFolderInfo->szUserid, _szUserid);
  6894.  
  6895. This code must be inserted in the C source file by the programmer, after the 
  6896. file is generated by the SOM Precompiler. This may be done using a normal text 
  6897. editor. 
  6898.  
  6899. 7 Finally, the SOM Precompiler provides a default zero return statement, 
  6900. typecast with the return data type of the method as declared in the methods 
  6901. section of the class definition file. This statement may be altered by the 
  6902. programmer if required, provided that consistency with the method's prototype 
  6903. and declaration is maintained. 
  6904.  
  6905.  
  6906. ΓòÉΓòÉΓòÉ 15.4. Object Behavior ΓòÉΓòÉΓòÉ
  6907.  
  6908. The behavior of an object in the Workplace Shell is very similar to that of a 
  6909. window under Presentation Manager. An object must have its class registered 
  6910. with the system, an instance of that class must be created ("instantiated") in 
  6911. the system, and that instance (and any other instance) then receives messages 
  6912. and uses its methods to process these messages. When processing is completed, 
  6913. the instance may be destroyed. 
  6914.  
  6915. One significant difference between a Workplace Shell object class and a window 
  6916. class under Presentation Manager is that Workplace Shell object classes are 
  6917. normally persistent; that is, while a Presentation Manager window class is 
  6918. defined only for the duration of the application's execution, a Workplace Shell 
  6919. object class remains defined to the system, and is useable by any application 
  6920. until such time as it is explicitly deregistered from the system. 
  6921.  
  6922.  
  6923. ΓòÉΓòÉΓòÉ 15.4.1. Creating an Object ΓòÉΓòÉΓòÉ
  6924.  
  6925. A new object class in the Workplace Shell is typically created by taking an 
  6926. existing object class and subclassing it, introducing new data and methods, and 
  6927. modifying existing behaviors where required. The new object class is then 
  6928. registered with the Workplace Shell, and is available from that point on. 
  6929.  
  6930.  
  6931. ΓòÉΓòÉΓòÉ 15.4.1.1. Registration ΓòÉΓòÉΓòÉ
  6932.  
  6933. Once an object class has been defined, compiled and placed into a dynamic link 
  6934. library, it must be registered with Workplace Shell before it can be used. This 
  6935. may be accomplished in any of two ways: 
  6936.  
  6937.    o  An object class may be registered with the Workplace Shell using the 
  6938.       WinRegisterObjectClass() function. This function records the name of the 
  6939.       object class, and the name of the DLL that contains the code to implement 
  6940.       the class. Note that if specifying a fully qualified path name for 
  6941.       pszModName, then the DLL does not need to be placed in the LIBPATH. 
  6942.  
  6943.    o  Additionally an object may also be registered with the Workplace Shell 
  6944.       using the SysRegisterObjectClass() function from REXX. Like the 
  6945.       WinRegisterObjectClass, this function also records the name of the object 
  6946.       class, and the name of the DLL that contains the code to implement the 
  6947.       class. 
  6948.  
  6949.  An example of the WinRegisterObjectClass() function is given in Registering a 
  6950.  Workplace Shell Object Class, and an example of the SysRegisterObjectClass() 
  6951.  function is given in REXX Code to Register a Workplace Object. 
  6952.  
  6953.   PSZ  pszClassName = "NewObject";                /* Class name            */
  6954.   PSZ  pszModName = "NEWOBJ";                     /* DLL module for class  */
  6955.   BOOL bSuccess;                                  /* Success flag          */
  6956.  
  6957.   bSuccess = WinRegisterObjectClass(pszClassName, /* Register class        */
  6958.                                     pszModName);  /* DLL module name       */
  6959.  Registering a Workplace Shell Object Class 
  6960.  
  6961.  Registering a Workplace Shell Object Class provides a very simple example; a 
  6962.  useful technique for registering object classes is to build a simple program 
  6963.  that reads a set of strings from an ASCII data file and uses these strings as 
  6964.  parameters to the WinRegisterObjectClass() function. In this way, a generic 
  6965.  object-registration routine can be built and used for multiple object classes, 
  6966.  without the need to modify and recompile source code. 
  6967.  
  6968.  REXX Code to Register a Workplace Object shows a sample piece of REXX code 
  6969.  that registers a class called pwFolder to the Workplace Shell. Notice that the 
  6970.  DLL which contains the pwFolder Workplace Object is also copied from the 
  6971.  current directory. If this copy was unsuccessful, the author of this code 
  6972.  assumed this was because the Workplace Shell has the DLL opened and so the 
  6973.  REXX code deregisters the class from the Workplace Shell. 
  6974.  
  6975.   /*  */
  6976.   Call RxFuncadd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
  6977.   Call SysLoadFuncs
  6978.  
  6979.   '@echo off'
  6980.  
  6981.   'copy pwfolder.dll c:\os2\dll 1>nul: 2>nul:'
  6982.  
  6983.   if rc then do
  6984.      say 'Error DLL could not be updated please re-boot'
  6985.      /* Remove bad entry */
  6986.      RetCode = SysDeregisterObjectClass( "PWFolder");
  6987.      'pause'
  6988.      exit(1)
  6989.      end
  6990.  
  6991.   RetCode = SysRegisterObjectClass( "PWFolder", "pwfolder")
  6992.  
  6993.   if RetCode then
  6994.      say 'PWFolder Class registered'
  6995.   else do
  6996.      say 'Error PWFolder Class failed to register'
  6997.      /* Remove false entry */
  6998.      RetCode = SysDeregisterObjectClass( "PWFolder");
  6999.      exit(1)
  7000.      end
  7001.  REXX Code to Register a Workplace Object 
  7002.  
  7003.  Note that once an object class has been registered with the Workplace Shell, 
  7004.  it is permanently available until it is explicitly deleted by deregistering 
  7005.  it. See Deregistering an Object Class for information on deregistering an 
  7006.  object class. 
  7007.  
  7008.  
  7009. ΓòÉΓòÉΓòÉ 15.4.1.2. Class Data ΓòÉΓòÉΓòÉ
  7010.  
  7011. Class data is owned by the object class rather than by an instance of that 
  7012. class. It is therefore available to all instances of the class, and must be 
  7013. initialized prior to instantiating any objects within the class. 
  7014.  
  7015. For this reason, class data is initialized when the object classes are loaded 
  7016. from their DLLs, either during Workplace Shell initialization or dynamically 
  7017. during execution. Class data initialization is performed by the _wpclsInitData 
  7018. class method, which is called by the system when the class is loaded. If a new 
  7019. object class has class data that must be initialized, it should override the 
  7020. _wpclsInitData method and perform its class-specific processing. 
  7021.  
  7022. An example of an overridden _wpclsInitData method from the password-protected 
  7023. folder example is shown in Initializing Class Data. 
  7024.  
  7025. HMODULE   hModule;
  7026.    :
  7027.    :
  7028. SOM_Scope void SOMLINK pwfoldercls_wpclsInitData(M_PWFolder *somSelf)
  7029. {
  7030.     CHAR  ErrorBuffer[100];                     /* Error buffer          */
  7031.  
  7032.     /* M_PWFolderData *somThis =
  7033.                       M_PWFolderGetData(somSelf); */
  7034.     M_PWFolderMethodDebug("M_PWFolder",         /* Set debug info        */
  7035.                           "pwfoldercls_wpclsInitData");
  7036.  
  7037.     DosLoadModule((PSZ) ErrorBuffer,            /* Get module handle     */
  7038.                   sizeof(ErrorBuffer),          /* Size of error buffer  */
  7039.                   "PWFOLDER",                   /* Name of DLL           */
  7040.                   &hModule);                    /* Module handle         */
  7041.  
  7042.     parent_wpclsInitData(somSelf);              /* Allow default proc    */
  7043. }
  7044. Initializing Class Data 
  7045.  
  7046. In the example shown in Initializing Class Data, a global variable hModule is 
  7047. used to contain the module handle for the DLL, which is required when loading 
  7048. Presentation Manager resources such as strings, pointers or dialogs. Since a 
  7049. global variable is used rather than a class data variable, the first statement 
  7050. in the overridden method, which obtains a handle to the class data, is not 
  7051. required and is therefore commented out. 
  7052.  
  7053. Any class data items obtained or initialized by an object class from within the 
  7054. _wpclsInitData method should also be freed by the object class, by overriding 
  7055. the _wpclsUnInitData method. This method is invoked by the system when an 
  7056. object class is deregistered (see Deregistering an Object Class), or when the 
  7057. Workplace Shell process is terminated. An example of the _wpclsUnInitData 
  7058. method is shown in Freeing Class Data Items. 
  7059.  
  7060. SOM_Scope void   SOMLINK pwfoldercls_wpclsUnInitData(M_PWFolder *somSelf)
  7061. {
  7062.     /* M_PWFolderData *somThis
  7063.                       = M_PWFolderGetData(somSelf); */
  7064.     M_PWFolderMethodDebug("M_PWFolder",         /* Set debug info        */
  7065.                           "pwfoldercls_wpclsUnInitData");
  7066.  
  7067.     DosFreeModule(hModule);                     /* Free module handle    */
  7068.  
  7069.     parent_wpclsUnInitData(somSelf);            /* Allow default proc    */
  7070. }
  7071. Freeing Class Data Items 
  7072.  
  7073. The example shown in Freeing Class Data Items assumes that the module handle 
  7074. for the DLL has already been obtained and stored in the global variable 
  7075. hModule, as shown in Initializing Class Data. 
  7076.  
  7077.  
  7078. ΓòÉΓòÉΓòÉ 15.4.1.3. Instantiation ΓòÉΓòÉΓòÉ
  7079.  
  7080. Once an object class has been registered with the Workplace Shell, an instance 
  7081. of that class may be created; this is known as instantiation. This may be done 
  7082. in one of three ways. One of the simplest method is to open the Templates 
  7083. folder and drag the template for the object class to the required location. 
  7084. Alternatively, an object may be created from within an application using the 
  7085. WinCreateObject() function. An example of this is shown in C Code to Create an 
  7086. Object. And lastly REXX Code to Create an Object shows a sample piece of REXX 
  7087. code that creates a Workplace Object called pwFolder, along with some 
  7088. parameters for the object. 
  7089.  
  7090. PSZ  pszClassName   = "NewObject";              /* Class name            */
  7091. PSZ  pszObjectTitle = "My New Object";          /* Object title          */
  7092. PSZ  pszParams = "ICON=C:\\ICONS\\MYNEWICON.ICO"; /* Setup string        */
  7093. PSZ  pszLocation = "C:\\Desktop\\MyNewFolder";  /* Location for object   */
  7094.  
  7095. ULONG ulFlags;                                  /* Creation flags        */
  7096.  
  7097. HOBJECT hObject;                                /* Object handle         */
  7098.  
  7099. hObject = WinCreateObject(pszClassName,         /* Create object         */
  7100.                           pszObjTitle,          /* Title for icon        */
  7101.                           pszParams,            /* Setup string          */
  7102.                           pszLocation,          /* Location for object   */
  7103.                           CO_REPLACEIFEXISTS);  /* Creation flags        */
  7104. C Code to Create an Object 
  7105.  
  7106. /*  */
  7107. Call RxFuncadd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
  7108. Call SysLoadFuncs
  7109.  
  7110. '@echo off'
  7111.  
  7112. RetCode = SysCreateObject( "PWFolder", "FinanceFile", "<WP_DESKTOP>",
  7113.                            "PASSWORD=wps;OBJECTID=<MyFinanceFile>")
  7114.  
  7115. if RetCode then
  7116.    say 'PWFolder Object created'
  7117. else do
  7118.    say 'Error creating object'
  7119.    exit(1)
  7120.    end
  7121. REXX Code to Create an Object 
  7122.  
  7123. Note that the pszParams parameter shown in C Code to Create an Object is used 
  7124. to contain a setup string, which can be used to pass one or more of a number of 
  7125. parameters to the object class. In the example, it is used only to set the icon 
  7126. for the object, but may also be used to specify other parameters for that 
  7127. instance of the class. The keywords and values supported by the WPObject class 
  7128. are documented in the IBM OS/2 Version 2.0 Presentation Manager Reference; 
  7129. other object classes may add their own keywords and values. 
  7130.  
  7131. The final parameter contains one or more flags which determine the behavior of 
  7132. the WinCreateObject() call if the object being created clashes with an object 
  7133. that already exists with the specified name and in the specified location. 
  7134. Valid actions are for the call to fail, to update the existing object or to 
  7135. replace the existing object. These flags are documented in the IBM OS/2 Version 
  7136. 2.0 Presentation Manager Reference. 
  7137.  
  7138. The setup string is passed as a parameter to the method, which can either be 
  7139. invoked when the object is instantiated, or during a call to WinSetObjectData. 
  7140. Because a call can be made to the _wpSetup method from WinSetObjectData, you 
  7141. must not process any default settings other than those related to the 
  7142. parameters passed to the _wpSetup method. This method is defined by the 
  7143. WPObject class, and may be overridden by a new object class in order to check 
  7144. for its own keywords and take appropriate setup action. 
  7145.  
  7146. The _wpSetup method accepts the setup string as a parameter, and may then parse 
  7147. the setup string, extract any class-specific data and perform appropriate 
  7148. processing on that data. However, since many of the keywords that may be 
  7149. specified in the setup string are defined by the WPObject class and are handled 
  7150. by the default _wpSetup method, the default processing must be carried out. In 
  7151. this particular case, the default processing may be carried out before or after 
  7152. the class-specific processing. 
  7153.  
  7154. An example of an overridden _wpSetup method is shown in Parameters and Settings 
  7155. for the Remote Terminal; this example shows the use of an additional parameter 
  7156. in the setup string (PASSWORD=) to set an initial password for a 
  7157. password-protected folder upon folder creation. The setup string is parsed from 
  7158. within the object by calling the _wpScanSetupString method. Both of these 
  7159. methods, along with the keywords supported by the WPObject class, are described 
  7160. in the IBM OS/2 Version 2.0 Presentation Manager Reference. 
  7161.  
  7162. After performing the class-specific processing in the _wpSetup method, an 
  7163. object class should invoke its parent class's _wpSetup method to perform the 
  7164. default processing for any other keywords in the setup string that are defined 
  7165. by the parent class. 
  7166.  
  7167. Before the _wpSetup method is invoked, the system invokes the object's 
  7168. _wpInitData method, which allows an object to allocate resources and initialize 
  7169. its instance data. See Instance Data for further details. 
  7170.  
  7171. Note that unlike a Presentation Manager window, which exists only for the 
  7172. duration of an application's execution, an object remains in existence 
  7173. permanently unless explicitly deleted from the system. 
  7174.  
  7175. SOM_Scope BOOL SOMLINK pwfolder_wpSetup(PWFolder *somSelf,
  7176.                                         PSZ pszSetupString)
  7177. {
  7178.     CHAR  pszInitPword[20];                     /* Buffer for password   */
  7179.     BOOL  bFound;                               /* Success flag          */
  7180.     ULONG ulRetLength;
  7181.  
  7182.     PWFolderData *somThis =                     /* Get instance data     */
  7183.                  PWFolderGetData(somSelf);
  7184.     PWFolderMethodDebug("PWFolder",             /* Set debug info        */
  7185.                         "pwfolder_wpSetup");
  7186.  
  7187.     if (pszSetupString != NULL)                 /* If string is present  */
  7188.        {
  7189.        bFound=_wpScanSetupString(somSelf,        /* Scan setup string to */
  7190.                                  pszSetupString, /* find keyword         */
  7191.                                  "PASSWORD"
  7192.                                  pszInitPword,
  7193.                                  &RetLength);
  7194.  
  7195.        if (bFound)                              /* If parameter present  */
  7196.           {
  7197.           strcpy(_szPassword,                   /* Copy p'word to folder */
  7198.                  pszInitPword);                 /* p'word and current    */
  7199.           strcpy(_szCurrentPassword,            /* p'word - initialize   */
  7200.                  pszInitPword);                 /* in unlocked state     */
  7201.           }
  7202.        }
  7203.     return (parent_wpSetup(somSelf,             /* Allow default proc to */
  7204.                            pszSetupString));    /* occur                 */
  7205. }
  7206. Object Setup 
  7207.  
  7208. This example shows an overridden _wpSetup method which parses the setup string 
  7209. to extract class-specific parameters. 
  7210.  
  7211.  
  7212. ΓòÉΓòÉΓòÉ 15.4.1.4. Instance Data ΓòÉΓòÉΓòÉ
  7213.  
  7214. When an object is created or awakened from a dormant state, the _wpInitData 
  7215. method is invoked by the system. This method allows an object to initialize its 
  7216. instance data to a known state. Operating system resources should be allocated 
  7217. at this stage, but Presentation Manager resources should not, since a view of 
  7218. the object is not yet being opened. The allocation of Presentation Manager 
  7219. resources is typically done during processing of the _wpOpen method (see 
  7220. Opening an Object). 
  7221.  
  7222. If an object has its own instance data, which must be initialized to a known 
  7223. state before processing may be carried out, the object should override the 
  7224. _wpInitData method in its class definition file, and include the initialization 
  7225. code. However, for any object class other than a base storage class, the 
  7226. default initialization processing must be carried out in addition to the 
  7227. class-specific processing. This allows the correct initialization of any 
  7228. instance data items defined by the parent class, and ensures that the new 
  7229. object class behaves in a manner consistent with its ancestors. 
  7230.  
  7231. Initializing Instance Data shows an overridden _wpInitData method, which 
  7232. initializes the password information for a password-protected folder. 
  7233.  
  7234. SOM_Scope void SOMLINK pwfolder_wpInitData(PWFolder *somSelf)
  7235. {
  7236.     CHAR  ErrorBuffer[100];                     /* Error data buffer     */
  7237.  
  7238.     PWFolderData *somThis =                     /* Get instance data     */
  7239.                  PWFolderGetData(somSelf);
  7240.     PWFolderMethodDebug("PWFolder",             /* Set debug info        */
  7241.                         "pwfolder_wpInitData");
  7242.  
  7243.     strcpy(_szCurrentPassword,                  /* Initialize folder     */
  7244.            "password");                         /* password              */
  7245.     strcpy(_szPassword,                         /* Set current password  */
  7246.            "password");                         /* to folder password    */
  7247.                                                 /* ie. Set unlocked      */
  7248.  
  7249.     return(parent_wpInitData(somSelf));         /* Perform default proc  */
  7250. }
  7251. Initializing Instance Data 
  7252.  
  7253. Note that during processing of the _wpInitData method, the instance data of the 
  7254. object is not necessarily in a known state. The programmer must therefore take 
  7255. great care when carrying out any processing during the execution of this 
  7256. method, in order to avoid using data that may not yet have been initialized 
  7257. correctly. Failure to follow this guideline may cause unpredictable results for 
  7258. the object. 
  7259.  
  7260.  
  7261. ΓòÉΓòÉΓòÉ 15.4.2. Using an Object ΓòÉΓòÉΓòÉ
  7262.  
  7263. A user typically accesses an object by opening a view of that object. For 
  7264. example, to access the contents of a folder object, the user opens the default 
  7265. view (usually an icon view) of the folder, which then displays its contents. 
  7266. This is certainly true for container objects such as folders, and for the 
  7267. password-protected folder class used as an example in this chapter, although 
  7268. other "device" objects such as printers or the shredder may be used without a 
  7269. view. 
  7270.  
  7271. When no view of an object is open, and the folder within which the object 
  7272. resides is not open, the object is said to be dormant; typically, no system 
  7273. resources are allocated to the object and its instance data is in an unknown 
  7274. state. Opening and closing views of an object therefore involve not only the 
  7275. opening and closing of windows, but also allocating and freeing resources, and 
  7276. saving and restoring the instance data of the object. Similarly, opening a 
  7277. folder requires saving and restoring the instance data of the objects in that 
  7278. folder. 
  7279.  
  7280.  
  7281. ΓòÉΓòÉΓòÉ 15.4.2.1. Opening an Object ΓòÉΓòÉΓòÉ
  7282.  
  7283. As mentioned above, a user typically interacts with an object using a view of 
  7284. that object. An object may support various types of view; for example, the 
  7285. WPFolder object class supports icon, tree, details and settings views. By 
  7286. default, an object class supports the view types defined by its ancestors, and 
  7287. a programmer may also define new view types for the object class. 
  7288.  
  7289. When a view of an object is opened, the _wpViewObject method is invoked by the 
  7290. Workplace Shell. This method determines if there is already an open view of the 
  7291. view specified for the object. If there is not then _wpOpen is called to open a 
  7292. view for the object. If there already is an open view, _wpViewObject checks the 
  7293. objects settings for concurrent views. If concurrent views are set, the _wpOpen 
  7294. is called to open an additional view of the object with the specified view. 
  7295. Therefore your programs should call _wpViewObject and not _wpOpen, but override 
  7296. _wpOpen to add your own unique views. Note that the concurrent view setting can 
  7297. normally be found on an object's settings notebook, under the "Window" tab, and 
  7298. is labelled "Object Open Behavior". 
  7299.  
  7300. The _wpOpen method is defined and implemented by the base storage class 
  7301. WPObject, and may be overridden by a new object class to perform its own 
  7302. class-specific processing. The supported views for each object class are 
  7303. implemented as part of the _wpOpen method, using Presentation Manager windows. 
  7304.  
  7305. When a view is opened by the user from a context menu, the _wpMenuItemSelected 
  7306. method is invoked (see Attaching a Method to the Context Menu for more detailed 
  7307. discussion of this method). The _wpMenuItemSelected method typically invokes 
  7308. the _wpViewObject method, which may invoke the _wpOpen method as outlined 
  7309. above. 
  7310.  
  7311. When the user opens a view by double-clicking the mouse on an object's icon, 
  7312. the _wpViewObject method invokes the _wpOpen method and passes an OPEN_DEFAULT 
  7313. value. The default processing for the _wpOpen method invokes the to determine 
  7314. the default view for the object, and immediately invokes the _wpOpen method a 
  7315. second time with the identifier for that view. 
  7316.  
  7317. An example of an overridden _wpOpen method is given in Opening an Object. This 
  7318. example shows a password-protection facility being added to a folder to prevent 
  7319. access by unauthorized users. Upon invocation of the _wpOpen method, the 
  7320. password-protected folder object class displays a dialog box to accept a 
  7321. password from the user. It then compares that password with the correct 
  7322. password for that folder before actually opening the folder. Visual cues such 
  7323. as the folder's icon and the word "Locked" on the folder's title are modified 
  7324. or removed during the _wpOpen processing. 
  7325.  
  7326. SOM_Scope HWND SOMLINK pwfolder_wpOpen(PWFolder *somSelf,
  7327.                                        HWND hwndCnr,
  7328.                                        ULONG ulView,
  7329.                                        ULONG param)
  7330. {   ULONG ulResult;
  7331.     CHAR  szTitle[100];
  7332.  
  7333.     PWFolderData *somThis =
  7334.                  PWFolderGetData(somSelf);      /* Set instance data     */
  7335.     PWFolderMethodDebug("PWFolder",             /* Set debug info        */
  7336.                         "pwfolder_wpOpen");
  7337.  
  7338.     if ((strcmp(_szCurrentPassword,             /* If not locked         */
  7339.                 _szPassword)) == 0)
  7340.        return(parent_wpOpen(somSelf,            /* Allow open to proceed */
  7341.                             hwndCnr,            /* in normal way, using  */
  7342.                             ulView,             /* default processing    */
  7343.                             param));
  7344.  
  7345.     ulResult = WinDlgBox(HWND_DESKTOP,          /* Display p'word dialog */
  7346.                          HWND_DESKTOP,          /* Desktop is owner      */
  7347.                          dpPassword,            /* Dialog procedure      */
  7348.                          hModule,               /* Module handle         */
  7349.                          DLG_PASSWORD,          /* Dialog resource id    */
  7350.                          (PVOID)somSelf);       /* Object pointer        */
  7351.  
  7352.     if (ulResult == DID_OK)                     /* If not cancelled      */
  7353.        {
  7354.        if ((strcmp(_szCurrentPassword,          /* If correct password   */
  7355.                    _szPassword)) == 0)
  7356.           {
  7357.           strcpy(szTitle,                       /* Get title string      */
  7358.                  _wpQueryTitle(somSelf));
  7359.           szTitle[strlen(szTitle)-9] = '\0';    /* Remove <LOCKED>       */
  7360.           _wpSetTitle(somSelf,szTitle);         /* Reset title string    */
  7361.  
  7362.           <Set icon to unlocked state>
  7363.  
  7364.           return (parent_wpOpen(somSelf,        /* Allow default _wpOpen */
  7365.                                 hwndCnr,        /* processing to occur   */
  7366.                                 ulView,         /* by invoking parent's  */
  7367.                                 param));        /* method                */
  7368.           }
  7369.        else
  7370.           {
  7371.           WinMessageBox(HWND_DESKTOP,           /* Display message box   */
  7372.              HWND_DESKTOP,
  7373.              "Password incorrect. Folder remains locked.",
  7374.              "Password Failed",
  7375.              0, MB_OK | MB_CUAWARNING);
  7376.           return((BOOL)0);                      /* Return FALSE          */
  7377.           }
  7378.        }
  7379. }
  7380. Opening an Object 
  7381.  
  7382. This example shows the _wpOpen method, which is called by the system when a 
  7383. view of an object is opened, being overridden to add password protection to a 
  7384. folder. 
  7385.  
  7386. Since the view being opened in this case is a view defined by the WPFolder 
  7387. class, the actual opening of the view and presentation of the folder's contents 
  7388. is handled using the default processing supplied by the parent class, which is 
  7389. called after the class-specific processing has completed. 
  7390.  
  7391. If an object class wishes to create a new view, it must add the name of the 
  7392. view to the Open submenu in the object's context menu, and include a case for 
  7393. that view in the _wpMenuItemSelected method. This method then invokes 
  7394. _wpViewObject with a specific value in the ulView parameter, indicating the 
  7395. view to be opened. The class-specific processing for _wpOpen must test for this 
  7396. value, open a window and display the correct information using Presentation 
  7397. Manager functions. 
  7398.  
  7399. The example in Opening an Object does not include the code to set the folder's 
  7400. icon to the "unlocked" state. This code is identical to the code used in Adding 
  7401. a New Method to set  the icon to the "locked" state; the resource identifier of 
  7402. the "unlocked" icon is simply substituted in the _wpOpen method for the 
  7403. identifier of the "locked" icon. 
  7404.  
  7405. Note that in many cases, it is important for an object class to allow the 
  7406. default processing for _wpOpen to occur before it attempts to carry out its own 
  7407. processing. This allows instance data and control information to be established 
  7408. and initialized before the object attempts any processing using these items. In 
  7409. Opening an Object however, the additional class-specific processing determines 
  7410. whether the object should open at all; if processing is allowed to proceed, no 
  7411. alteration to the default processing takes place. The default processing may 
  7412. therefore be carried out after the additional class-specific processing 
  7413. introduced by the password-protected folder class. 
  7414.  
  7415. The default processing for the _wpOpen method supports a number of views, 
  7416. depending upon the parent class of the object; for example, the processing for 
  7417. the WPFolder class supports ICON, TREE and DETAILS views. For new object 
  7418. classes which support additional views, the _wpOpen method must be overridden 
  7419. and the additional view types opened explicitly as windows using appropriate 
  7420. Presentation Manager functions. Since a view of an object is essentially a 
  7421. window, new views can be implemented as normal Presentation Manager windows and 
  7422. the correct information displayed using text or graphical programming 
  7423. functions, according to the requirements of the object class. 
  7424.  
  7425. The application must always define a new view if it introduces one. Never 
  7426. process OPEN_DEFAULT other than passing it to the parent class. If you want to 
  7427. have your own view be the default, then override the _wpclsQueryDefaultView 
  7428. method. 
  7429.  
  7430. Note that upon opening a view using a Presentation Manager window, an object 
  7431. should add itself to the "Use List" maintained by the Workplace Shell. If the 
  7432. view is the first view of the object to be opened, this causes the Workplace 
  7433. Shell to modify the object's icon to indicate the "in use" state. The object 
  7434. should also register the view with the Workplace Shell, which will then 
  7435. subclass the view's frame window, automatically attach the object's context 
  7436. menu to the window's system menu icon, and add the view to the Workplace 
  7437. Shell's Window List. These steps are done using the _wpAddToObjUseList and 
  7438. _wpRegisterView methods, as shown in Opening a Custom View of an Object. 
  7439.  
  7440. HWND    hView;                                  /* View window handle    */
  7441.  
  7442. typedef struct _OBJECTVIEW                      /* Object view structure */
  7443.                {
  7444.                SOMAny   *Object;                /* Object pointer        */
  7445.                USEITEM  UseItem;                /* USEITEM structure     */
  7446.                VIEWITEM ViewItem;               /* VIEWITEM structure    */
  7447.                } OBJECTVIEW;
  7448.  
  7449. OBJECTVIEW *pObjectView;                        /* Pointer to structure  */
  7450.  
  7451. <Create Window>                                 /* Get window handle     */
  7452.  
  7453. pObjectView = _wpAllocMem(somSelf,              /* Allocate memory       */
  7454.                           sizeof(OBJECTVIEW),   /* Size of mem object    */
  7455.                           NULL);
  7456. pObjectView->Record          = somSelf;         /* Initialize OBJECTVIEW */
  7457. pObjectView->UseItem.type    = USAGE_OPENVIEW;  /* structure             */
  7458. pObjectView->ViewItem.view   = OPEN_CUST;
  7459. pObjectView->ViewItem.handle = hView;
  7460.  
  7461. WinSetWindowULong(hView,                        /* Store pointer to      */
  7462.                   QWL_USER,                     /* structure in window   */
  7463.                   (ULONG)pObjectView);          /* words                 */
  7464.  
  7465. _wpAddToObjUseList(somSelf,                     /* Add to Use List       */
  7466.                    &pObjectView->UseItem);      /* USEITEM structure     */
  7467. _wpRegisterView(somSelf,                        /* Register view         */
  7468.                 hView,                          /* View window handle    */
  7469.                 "Customer Details")             /* Title of view         */
  7470. Opening a Custom View of an Object 
  7471.  
  7472. The Workplace Shell makes use of a USEITEM and a VIEWITEM structure in the 
  7473. _wpAddToObjUseList method. It assumes that these structures are contiguous in 
  7474. memory; hence they should be allocated as part of a larger data structure such 
  7475. as the OBJECTVIEW structure shown in Opening a Custom View of an Object. A 
  7476. pointer to this structure is stored in the window words of the view window, so 
  7477. that information such as the object's pointer can be accessed from the view's 
  7478. window procedure. 
  7479.  
  7480. Note that upon closing a view, the view's window procedure should invoke the 
  7481. _wpDeleteFromObjUseList method to remove the view from the Use List. If the 
  7482. view is the only open view of the object, the object's icon is modified to 
  7483. remove the "in use" emphasis. 
  7484.  
  7485.  
  7486. ΓòÉΓòÉΓòÉ 15.4.2.2. A Custom View of our pwFinanceFile ΓòÉΓòÉΓòÉ
  7487.  
  7488. This section shows how to implement a custom view of the pwFinanceFile 
  7489. Workplace Object. Not all of the code, such as the resource files, header 
  7490. files, are shown. For a full code listing please refer to Source Code for the 
  7491. PWFolder and PWFinanceFile objects 
  7492.  
  7493. _wpModifyPopupMenu .C code shows how the "Open Finance File" menu item is added 
  7494. onto the "Open" menu item, which appears on the pwFinanceFile's context menu. 
  7495. Note that we also add the "Lock Finance File" menu item. pwFinanceFile's 
  7496. Context Menu shows the resulting context menu which is provided by 
  7497. _wpModifyPopupMenu .C code. Note that the "OS/2 System Editor" menu item is 
  7498. also present. The Workplace Shell wpDataFile class has added this due to file 
  7499. type associations. In this case because this object does not have a file type, 
  7500. it is assumed by the ancestor classes to be text and the default association 
  7501. for the text type is the OS/2 System Editor. We could remove this by overriding 
  7502. the _wpclsQueryDefaultView method, thus making our view the default one. 
  7503.  
  7504. /*
  7505.  *
  7506.  *   METHOD:   wpModifyPopupMenu                           PUBLIC
  7507.  *
  7508.  *   PURPOSE:  Adds an additional "Lock" item to the object's context menu.
  7509.  *             Adds a "Open Finance File" item to the "Open" item
  7510.  *   INVOKED:  By Workplace Shell, upon instantiation of the object instance.
  7511.  *
  7512.  */
  7513.  
  7514. SOM_Scope BOOL   SOMLINK pwFinanceFile_wpModifyPopupMenu(PWFinanceFile *somSelf,
  7515.                 HWND hwndMenu,
  7516.                 HWND hwndCnr,
  7517.                 ULONG iPosition)
  7518. {
  7519.     PWFinanceFileData *somThis =                      /* Get instance data pointer */
  7520.                  PWFinanceFileGetData(somSelf);
  7521.     PWFinanceFileMethodDebug("PWFinanceFile",              /* Set debug info            */
  7522.                         "pwFinanceFile_wpModifyPopupMenu");
  7523.  
  7524.     _wpInsertPopupMenuItems(somSelf,             /* Insert menu item          */
  7525.                             hwndMenu,            /* Menu handle               */
  7526.                             iPosition,           /* Default position          */
  7527.                             hmodThisClass,       /* Module handle             */
  7528.                             ID_CXTMENU_LOCK,     /* Menu item identifier      */
  7529.                             0);                  /* No submenu identifier     */
  7530.  
  7531.     _wpInsertPopupMenuItems( somSelf,            /* Insert menu item          */
  7532.                              hwndMenu,           /* Menu handle               */
  7533.                              0,                  /* at the top!               */
  7534.                              hmodThisClass,      /* Module handle             */
  7535.                              ID_OPENFinanceFile, /* Menu item identifier      */
  7536.                              WPMENUID_OPEN);     /* Submenu identifier        */
  7537.  
  7538.  
  7539.     return(parent_wpModifyPopupMenu(somSelf,     /* Invoke default processing */
  7540.                                     hwndMenu,
  7541.                                     hwndCnr,
  7542.                                     iPosition));
  7543. }
  7544. _wpModifyPopupMenu .C code 
  7545.  
  7546. This example shows how to add two menu items to the "Open Finance File" menu 
  7547. item on the pwFinanceFile's context menu. 
  7548.  
  7549. _wpMenuItemSelected .C code, _wpOpen, pwFinanceFile's         Function and 
  7550. pwFinanceFile's Window Procedure, FinanceFileWndProc() show the additional code 
  7551. required to process the selection of the "Open Finance File" menu item. 
  7552. pwFinanceFile's Custom View shows the window view which is presented when the 
  7553. user selects the "Open Finance File" menu item. This window is empty and the 
  7554. population of the window with information from the file associated with the 
  7555. instance of the pwFinanceFile is a normal PM programming exercise which is left 
  7556. for the reader to perform. pwFinanceFile's Context Menu 
  7557. pwFinanceFile's Custom View 
  7558.  
  7559. /*
  7560.  *
  7561.  *   METHOD:   wpMenuItemSelected                          PUBLIC
  7562.  *
  7563.  *   PURPOSE:  Processes the user's selections from the context menu.  The
  7564.  *             overridden method processes the added "Lock" & "OPENFinanceFile"
  7565.  *             items, and passes all others to the parent method
  7566.  *
  7567.  *   INVOKED:  By Workplace Shell, upon selection of a menu item by the user.
  7568.  *
  7569.  */
  7570.  
  7571. SOM_Scope BOOL   SOMLINK pwFinanceFile_wpMenuItemSelected(PWFinanceFile *somSelf,
  7572.                 HWND hwndFrame,
  7573.                 ULONG ulMenuId)
  7574. {
  7575.     PWFinanceFileData *somThis =                      /* Get instance data pointer */
  7576.                  PWFinanceFileGetData(somSelf);
  7577.     PWFinanceFileMethodDebug("PWFinanceFile",         /* Set debug info            */
  7578.                         "pwFinanceFile_wpMenuItemSelected");
  7579.  
  7580.     switch( ulMenuId )                           /* Switch on item identifier      */
  7581.     {
  7582.        case IDM_LOCK:                            /* Lock item selected             */
  7583.           _LockFinanceFile(somSelf);             /* Invoke _LockFinanceFile method */
  7584.           break;
  7585.  
  7586.     /*
  7587.      *   We could call wpOpen here, but if the object is already opened
  7588.      *   the following API determines whether the object should be
  7589.      *   resurfaced or if multiple views are desired.
  7590.      *   Must call wpViewObject not wpOpen.  If you use wpOpen then multiple
  7591.      *   concurrent views won't work.  User can set object to open multiple views
  7592.      *   or switch to.
  7593.      */
  7594.  
  7595.        case IDM_OPENFinanceFile:                 /* Open a view selected      */
  7596.           _wpViewObject(somSelf, NULLHANDLE, OPEN_FinanceFile, 0);
  7597.           break;
  7598.  
  7599.  
  7600.        default:                                  /* All other items           */
  7601.           parent_wpMenuItemSelected(somSelf,     /* Invoke default processing */
  7602.                                     hwndFrame,
  7603.                                     ulMenuId);
  7604.           break;
  7605.     }
  7606. }
  7607. _wpMenuItemSelected .C code 
  7608.  
  7609. /*
  7610.  *
  7611.  *   METHOD:   wpOpen                                      PUBLIC
  7612.  *
  7613.  *   PURPOSE:  Only allows a FinanceFile to be opened if the FinanceFile is unlocked, or
  7614.  *             if the user supplies the correct password in response to the
  7615.  *             dialog.
  7616.  *
  7617.  *   INVOKED:  By Workplace Shell, upon selection of the "Open" menu item by
  7618.  *             the user.
  7619.  *
  7620.  */
  7621.  
  7622. SOM_Scope HWND   SOMLINK pwFinanceFile_wpOpen(PWFinanceFile *somSelf,
  7623.                 HWND hwndCnr,
  7624.                 ULONG ulView,
  7625.                 ULONG param)
  7626. {
  7627.     ULONG    ulResult;                           /* Return value              */
  7628.     CHAR     szTitle[100];                       /* FinanceFile title buffer       */
  7629.     PVOID    pCreateParam;
  7630.     BOOL     bAllowAccess = FALSE;               /* user is allowed in */
  7631.  
  7632.     PWFinanceFileData *somThis =                      /* Get instance data pointer */
  7633.                  PWFinanceFileGetData(somSelf);
  7634.     PWFinanceFileMethodDebug("PWFinanceFile",              /* Set debug info            */
  7635.                         "pwFinanceFile_wpOpen");
  7636.  
  7637.     if ((strcmp(_szCurrentPassword,              /* If FinanceFile is locked   */
  7638.          _szPassword)) != 0)
  7639.     {
  7640.        somPrintf("ask for a password\n");
  7641.     pCreateParam = malloc( sizeof(ULONG) );      /* Allocate memory to pass a */
  7642.                                                  /* ULONG to the dialog proc  */
  7643.     *((PULONG)pCreateParam) = (ULONG)somSelf;    /* Put the somSelf pointer   */
  7644.                                                  /* in the CreateParam memory */
  7645.  
  7646.     ulResult = WinDlgBox(HWND_DESKTOP,           /* Display password dialog   */
  7647.                          HWND_DESKTOP,           /* Desktop is owner          */
  7648.                          PasswordDlgProc,        /* Dialog procedure address  */
  7649.                          hmodThisClass,          /* Module handle             */
  7650.                          ID_DLG_PASSWORD,        /* Dialog resource id        */
  7651.                          pCreateParam );         /* Create Param holding the  */
  7652.                                                  /* pointer to this object    */
  7653.     if (ulResult == DID_OK )                     /* If user hit OK button     */
  7654.        {
  7655.        if ((strcmp(_szCurrentPassword,           /* If password is correct    */
  7656.                    _szPassword)) == 0)
  7657.           {
  7658.           strcpy(szTitle,                        /* Get title string          */
  7659.                  _wpQueryTitle(somSelf));
  7660.           szTitle[strlen(szTitle)-9] = '\0';     /* Remove <LOCKED>           */
  7661.           _wpSetTitle(somSelf,szTitle);          /* Reset title string        */
  7662.  
  7663.           _wpSetIcon(somSelf,                    /* Set icon to unlocked      */
  7664.                      hUnlockedIcon);             /* state                     */
  7665.  
  7666.           /* now we can allow the user access to the object proper ! */
  7667.           bAllowAccess = TRUE;
  7668.  
  7669.           }
  7670.        else                                      /* Password is incorrect     */
  7671.           {
  7672.           WinMessageBox(HWND_DESKTOP,            /* Display message to user   */
  7673.                         HWND_DESKTOP,
  7674.                         "Password incorrect. FinanceFile remains locked.",
  7675.                         "Password Failed",
  7676.                         0,
  7677.                         MB_OK |
  7678.                         MB_CUAWARNING );
  7679.           return((HWND)0);                       /* Return NULL handle        */
  7680.           }
  7681.        }
  7682.     } else {
  7683.       bAllowAccess = TRUE;
  7684.     }
  7685.     if (bAllowAccess) {
  7686.        switch (ulView) {
  7687.        case OPEN_FinanceFile:
  7688.          if (!_wpSwitchTo(somSelf, ulView)) {
  7689.            /* Create a basic frame and client window for this instance */
  7690.            return PWFinanceFileInit(somSelf);
  7691.          } /* endif */
  7692.          break;
  7693.  
  7694.        default:
  7695.          return(parent_wpOpen(somSelf,          /* Allow open to proceed in  */
  7696.                               hwndCnr,          /* normal way using default  */
  7697.                               ulView,           /* processing                */
  7698.                               param));
  7699.        } /* endswitch */
  7700.     } else {
  7701.     } /* endif */
  7702. }
  7703. _wpOpen
  7704.  
  7705. /***************************************************************************
  7706. *                                                                          *
  7707. *       ROUTINE:    PWFinanceFileInit()                                    *
  7708. *                                                                          *
  7709. *       DESCRIPTION:  PWFinanceFile Initialization                         *
  7710. *                                                                          *
  7711. *       RETURNS:    Handle of PWFinanceFile frame window, NULL if error    *
  7712. *                                                                          *
  7713. ***************************************************************************/
  7714. HWND PWFinanceFileInit (PWFinanceFile* somSelf)
  7715. {
  7716.  
  7717.    HAB  hab;                                       /* PM anchor block handle */
  7718.    HWND hwndFrame = NULLHANDLE;                       /* Frame window handle */
  7719.    HWND hwndClient = NULLHANDLE;
  7720.    PWINDOWDATA pWindowData;
  7721.    BOOL fSuccess;
  7722.    SWCNTRL    swcEntry;                                      /* Switch Entry */
  7723.    FRAMECDATA flFrameCtlData;                              /* Frame Ctl Data */
  7724.  
  7725.    somPrintf("PWFinanceFileInit\n");
  7726.  
  7727.    hab = WinQueryAnchorBlock(HWND_DESKTOP);
  7728.    if (!WinRegisterClass( hab , szFinanceFileWindowClass, (PFNWP)FinanceFileWndProc ,
  7729.                             CS_SIZEREDRAW | CS_SYNCPAINT, sizeof(pWindowData)))
  7730.    {
  7731.       somPrintf("FinanceFileInit Failure in WinRegisterClass\n");
  7732.       return NULLHANDLE ;
  7733.    }
  7734.  
  7735.    /*
  7736.     *   Allocate some instance specific data in Window words of Frame window.
  7737.     *   This will ensure our window procedure can use this object's methods
  7738.     *   (our window proc isn't passed a * somSelf pointer).
  7739.     */
  7740.    pWindowData = (PWINDOWDATA) _wpAllocMem(somSelf, sizeof(*pWindowData), NULL);
  7741.  
  7742.    if (!pWindowData)
  7743.    {
  7744.       somPrintf("FinanceFileInit wpAllocMem failed to allocate pWindowData\n");
  7745.       return NULLHANDLE;
  7746.    }
  7747.  
  7748.    memset((PVOID) pWindowData, 0, sizeof(*pWindowData));
  7749.    pWindowData->cb = sizeof(*pWindowData);             /* first field = size */
  7750.    pWindowData->somSelf = somSelf;
  7751.  
  7752.    /* Create a frame window
  7753.     */
  7754.    flFrameCtlData.cb            = sizeof( flFrameCtlData );
  7755.    flFrameCtlData.flCreateFlags = FCF_SIZEBORDER | FCF_TITLEBAR | FCF_SYSMENU |
  7756.                                   FCF_MINMAX ;
  7757.    flFrameCtlData.hmodResources = hmodThisClass;
  7758.    flFrameCtlData.idResources   = ID_UNLOCK;
  7759.    hwndFrame =                                        /* create frame window */
  7760.    WinCreateWindow(
  7761.       HWND_DESKTOP,               /* parent-window handle                    */
  7762.       WC_FRAME,                   /* pointer to registered class name        */
  7763.       _wpQueryTitle(somSelf),     /* pointer to window text                  */
  7764.       0,                          /* window style                            */
  7765.       0, 0, 0, 0,                 /* position of window                      */
  7766.       NULLHANDLE,                 /* owner-window handle                     */
  7767.       HWND_TOP,                   /* handle to sibling window                */
  7768.       (USHORT) ID_FRAME,          /* window identifier                       */
  7769.       (PVOID) &flFrameCtlData,    /* pointer to buffer                       */
  7770.       NULL);      ;               /* pointer to structure with pres. params. */
  7771.  
  7772.    if (!hwndFrame)
  7773.    {
  7774.       somPrintf("FinanceFileInit Failure in WinCreateWindow\n");
  7775.       return NULLHANDLE;
  7776.    }
  7777.    hwndClient =          /* use WinCreateWindow so we can pass pres params */
  7778.    WinCreateWindow(
  7779.       hwndFrame,                /* parent-window handle                    */
  7780.       szFinanceFileWindowClass, /* pointer to registered class name        */
  7781.       NULL,                     /* pointer to window text                  */
  7782.       0,                        /* window style                            */
  7783.       0, 0, 0, 0,               /* position of window                      */
  7784.       hwndFrame,                /* owner-window handle                     */
  7785.       HWND_TOP,                 /* handle to sibling window                */
  7786.       (USHORT)FID_CLIENT,       /* window identifier                       */
  7787.       pWindowData,              /* pointer to buffer                       */
  7788.       NULL);                    /* pointer to structure with pres. params. */
  7789.  
  7790.    if (!hwndClient)
  7791.    {
  7792.       WinDestroyWindow(hwndFrame);
  7793.       return NULLHANDLE;
  7794.    }
  7795.  
  7796.    WinSendMsg(hwndFrame,WM_SETICON,MPFROMP(_wpQueryIcon(somSelf)),NULL);
  7797.    WinSetWindowText(WinWindowFromID(hwndFrame,(USHORT)FID_TITLEBAR),
  7798.                                                          _wpQueryTitle(somSelf));
  7799.  
  7800.    /*
  7801.     * Restore the Window Position
  7802.     */
  7803.    fSuccess =
  7804.    WinRestoreWindowPos(
  7805.       szFinanceFileClassTitle,                                        /* class title */
  7806.       _wpQueryTitle(somSelf),                                /* object title */
  7807.       hwndFrame);
  7808.    if (!fSuccess)
  7809.    {
  7810.     SWP        swp;
  7811.  
  7812.       /* Get the dimensions and the shell's suggested
  7813.        * location for the window
  7814.        */
  7815.       WinQueryTaskSizePos(hab,0,&swp);
  7816.  
  7817.       /* Set the frame window position
  7818.        */
  7819.       swp.fl               = SWP_SIZE|SWP_MOVE|SWP_RESTORE|SWP_ZORDER;
  7820.       WinSetWindowPos(hwndFrame, HWND_TOP, swp.x, swp.y, swp.cx,
  7821.                      swp.cy, swp.fl);
  7822.    }
  7823.  
  7824.    WinShowWindow(hwndFrame,TRUE);
  7825.  
  7826.    return hwndFrame;                                              /* success */
  7827.  
  7828. }   /* end FinanceFileInit() */
  7829. pwFinanceFile's Initialization Function 
  7830.  
  7831. /******************************************************************************
  7832. *
  7833. *   FinanceFileWndProc()
  7834. *
  7835. *   DESCRIPTION: FinanceFile Window Procedure
  7836. *
  7837. ******************************************************************************/
  7838. MRESULT EXPENTRY FinanceFileWndProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
  7839. {
  7840.   ULONG         MenuId;
  7841.   PWINDOWDATA   pWindowData;
  7842.   HWND          hwndFrame;
  7843.   CHAR          acBuffer[10];
  7844.   BOOL          fSuccess;
  7845.   CHAR          szPath[CCHMAXPATH];                                            //jt 55384
  7846.   ULONG         cbPath = CCHMAXPATH;                                           //jt 55384
  7847.  
  7848.  
  7849.    hwndFrame = WinQueryWindow(hwnd, QW_PARENT);
  7850.  
  7851.    switch( msg )
  7852.    {
  7853.       case WM_CREATE:
  7854.  
  7855.         pWindowData = (PWINDOWDATA) mp1;
  7856.  
  7857.         if (pWindowData == NULL)
  7858.         {
  7859.            somPrintf("FinanceFileWndProc:WM_CREATE couldn't get window words");
  7860.            return FALSE;
  7861.         }
  7862.         /*
  7863.          *   Fill in the class view/usage details and window specific data
  7864.          *   for this instance.
  7865.          */
  7866.  
  7867.         /*
  7868.          * Must create UseItem, add it to the object's use list and register the view
  7869.          */
  7870.         pWindowData->UseItem.type    = USAGE_OPENVIEW;
  7871.         pWindowData->ViewItem.view   = OPEN_FinanceFile;
  7872.         /*
  7873.          * Must be frame.  Be careful because this procedure is for the client.
  7874.          * Must get parent and pass that as ViewItem handle.
  7875.          */
  7876.         pWindowData->ViewItem.handle = hwndFrame;
  7877.         pWindowData->x               = 10;
  7878.         pWindowData->y               = 10;
  7879.         pWindowData->xDir            = 0;
  7880.         pWindowData->yDir            = 0;
  7881.  
  7882.         /*
  7883.          *   Set window pointer with object pointer and instance view info.
  7884.          *   Then add view to the in-use list so wpSwitchTo works.
  7885.          */
  7886.         WinSetWindowPtr(hwnd, QWL_USER, pWindowData);
  7887.         /*
  7888.          * _wpAddToObjUseList will tell the shell to store the view in
  7889.          * the internal linked list for the object to enable wpSwitchTo and other
  7890.          * methods to find the view.  The shell will also subclass the view window
  7891.          * this gives you title bar context menu when you call wpRegisterView.
  7892.          * wpRegisterView also puts the view in the window list and sets up
  7893.          * the title bar like:  "Object Title - View Title"
  7894.          */
  7895.  
  7896.         _wpAddToObjUseList(pWindowData->somSelf,&pWindowData->UseItem);
  7897.         _wpRegisterView(pWindowData->somSelf, hwndFrame,
  7898.                                              _wpQueryTitle(pWindowData->somSelf));
  7899.         WinSetFocus( HWND_DESKTOP, hwndFrame);
  7900.  
  7901.         /* what is the filename of the file */
  7902.         if (_wpQueryRealName(pWindowData->somSelf,szPath,&cbPath,TRUE))
  7903.            {
  7904.               somPrintf("File name is %s, size %i \n",szPath, cbPath);
  7905.            } else {
  7906.               somPrintf("Failed to get filename\n");
  7907.            } /* endif */
  7908.  
  7909.         break;
  7910.  
  7911.       case WM_COMMAND:
  7912.  
  7913.         break;
  7914.  
  7915.       case WM_PAINT:
  7916.          pWindowData = (PWINDOWDATA) WinQueryWindowPtr(hwnd, QWL_USER);
  7917.  
  7918.          if (pWindowData == NULL)
  7919.          {
  7920.             somPrintf("FinanceFileWndProc:WM_PAINT couldn't get window words\n");
  7921.             return FALSE;
  7922.          }
  7923.          else
  7924.          {
  7925.           HPS    hps;
  7926.           RECTL  rectl;
  7927.  
  7928.            hps = WinBeginPaint( hwnd, (HPS)NULLHANDLE, &rectl);
  7929.            WinFillRect( hps, &rectl, SYSCLR_WINDOW);
  7930.            WinEndPaint( hps );
  7931.          }
  7932.          break;
  7933.       case WM_CLOSE:
  7934.          {
  7935.           HAB hab;
  7936.  
  7937.             hab = WinQueryAnchorBlock(HWND_DESKTOP);
  7938.  
  7939.             pWindowData = (PWINDOWDATA) WinQueryWindowPtr(hwnd, QWL_USER);
  7940.  
  7941.             if (pWindowData == NULL)
  7942.             {
  7943.                somPrintf("FinanceFileWndProc:WM_CLOSE couldn't get window words\n");
  7944.                return FALSE;
  7945.             }
  7946.             fSuccess =
  7947.             WinStoreWindowPos(szFinanceFileClassTitle,_wpQueryTitle(pWindowData->somSelf),
  7948.                                                                         hwndFrame);
  7949.             /*
  7950.              * Must remove from the object UseList when window is closed.  (can be done
  7951.              * on WM_DESTROY instead)
  7952.              */
  7953.             _wpDeleteFromObjUseList(pWindowData->somSelf,&pWindowData->UseItem);
  7954.             _wpFreeMem(pWindowData->somSelf,(PBYTE)pWindowData);
  7955.  
  7956.             WinDestroyWindow ( hwndFrame ) ;
  7957.          }
  7958.          break;
  7959.  
  7960.       default:
  7961.          return WinDefWindowProc( hwnd, msg, mp1, mp2 );
  7962.    }
  7963.    return FALSE;
  7964.  
  7965. }   /* end FinanceFileWndProc() */
  7966. pwFinanceFile's Window Procedure, FinanceFileWndProc()
  7967.  
  7968.  
  7969. ΓòÉΓòÉΓòÉ 15.4.2.3. Automatic Opening Upon Instantiation ΓòÉΓòÉΓòÉ
  7970.  
  7971. In many cases, it is desirable to automatically open a view of an object when 
  7972. the object is created. This may be achieved by using the OPEN= keyword in the 
  7973. setup string passed to the WinCreateObject() function. An example of this 
  7974. technique is shown in Automatically Instantiating an Object. 
  7975.  
  7976. PSZ  pszClassName   = "NewObject";              /* Class name            */
  7977. PSZ  pszObjectTitle = "My New Object";          /* Object title          */
  7978. PSZ  pszParams = "OPEN=ICON";                   /* Setup string          */
  7979. PSZ  pszLocation = "C:\\Desktop\\MyNewFolder";  /* Location for object   */
  7980.  
  7981. ULONG ulFlags = CO_UPDATEIFEXISTS;              /* Creation flags        */
  7982.  
  7983. HOBJECT hObject;                                /* Object handle         */
  7984.  
  7985. hObject = WinCreateObject(pszClassName,         /* Create object         */
  7986.                           pszObjTitle,          /* Title for icon        */
  7987.                           pszParams,            /* Setup string          */
  7988.                           pszLocation,          /* Location for object   */
  7989.                           ulFlags);             /* Creation flags        */
  7990. Automatically Instantiating an Object 
  7991.  
  7992. This example shows the use of the OPEN= keyword to automatically open a view of 
  7993. an object upon creating the object. 
  7994.  
  7995. The opening of the view specified in the OPEN= keyword is handled by the 
  7996. default processing for the _wpSetup method, as defined by the WPObject class. 
  7997. The default processing supports the icon, tree and details views, specified 
  7998. using the ICON, TREE and DETAILS values for the OPEN= keyword respectively. For 
  7999. new object classes that support additional views, the _wpSetup method must be 
  8000. overridden and the additional view types opened explicitly as windows using 
  8001. appropriate Presentation Manager functions. 
  8002.  
  8003.  
  8004. ΓòÉΓòÉΓòÉ 15.4.2.4. Closing an Object ΓòÉΓòÉΓòÉ
  8005.  
  8006. When all open views of an object are to be closed, the _wpClose method is 
  8007. invoked. This method is normally invoked when the user selects the Close option 
  8008. from a view's context menu. 
  8009.  
  8010. The _wpClose method may be overridden to perform class-specific processing for 
  8011. closing views, or to free system resources allocated during processing of the 
  8012. _wpOpen method. For example, Closing an Object shows the _wpClose method being 
  8013. overridden to automatically lock a password-protected folder whenever it is 
  8014. closed by the user. 
  8015.  
  8016. SOM_Scope BOOL SOMLINK pwfolder_wpClose(PWFolder *somSelf)
  8017. {
  8018.     PWFolderData *somThis =                     /* Get instance data     */
  8019.                  PWFolderGetData(somSelf);
  8020.     PWFolderMethodDebug("PWFolder",             /* Set debug info        */
  8021.                         "pwfolder_wpInitData");
  8022.     _LockFolder(somSelf);                       /* Lock folder           */
  8023.  
  8024.     return(parent_wpClose(somSelf));            /* Allow default proc    */
  8025. }
  8026. Closing an Object 
  8027.  
  8028. This example shows the _wpClose method being overridden in order to provide 
  8029. class-specific processing for the password-protected folder. 
  8030.  
  8031. When a view of an object is closed, the system sends a WM_DESTROY message to 
  8032. the view's frame window. This allows the object to release any allocated 
  8033. resources and save its instance data, so that the object may be reopened in its 
  8034. current state at some future time. 
  8035.  
  8036. Note that since the _wpClose method is defined by the parent class and is 
  8037. overridden, the default processing performed by the parent is called after the 
  8038. class-specific processing has completed. 
  8039.  
  8040.  
  8041. ΓòÉΓòÉΓòÉ 15.4.2.5. Saving and Restoring the Object State ΓòÉΓòÉΓòÉ
  8042.  
  8043. As already mentioned, an object is persistent; that is, it remains in existence 
  8044. even when all views of the object are closed. In order to maintain its instance 
  8045. data so that it may subsequently be opened in the same state in which it was 
  8046. closed, the object must save this data when its views are closed and restore it 
  8047. when a view is opened. The Workplace Shell provides methods that handle the 
  8048. saving and restoration of instance data on behalf of object classes; these 
  8049. methods are automatically invoked by the system at the appropriate times, and 
  8050. are described below. 
  8051.  
  8052. When an object is made dormant, the system invokes the object's _wpSaveState 
  8053. method, which allows the object to save its instance data. A number of 
  8054. predefined methods are available to the object to save its data, such as 
  8055. _wpSaveString. These methods may be called by the object during the processing 
  8056. of its _wpSaveState method, in order to save instance data. An example of the 
  8057. _wpSaveState method for the password-protected folder example is given in 
  8058. Saving an Object's State. 
  8059.  
  8060. SOM_Scope BOOL SOMLINK pwfolder_wpSaveState(PWFolder *somSelf)
  8061. {
  8062.     PWFolderData *somThis =                     /* Get instance data     */
  8063.                  PWFolderGetData(somSelf);
  8064.     PWFolderMethodDebug("PWFolder",             /* Set debug info        */
  8065.                         "pwfolder_wpSaveState");
  8066.  
  8067.     _wpSaveString(somSelf,                      /* Save folder password  */
  8068.                   "PWFolder",                   /* Class name            */
  8069.                    1L,                          /* Class-defined key     */
  8070.                    _szPassword);                /* String to be saved    */
  8071.     _wpSaveString(somSelf,                      /* Save current password */
  8072.                   "PWFolder",                   /* Class name            */
  8073.                   2L,                           /* Class-defined key     */
  8074.                   _szCurrentPassword);          /* String to be saved    */
  8075.  
  8076.     return (parent_wpSaveState(somSelf));       /* Invoke default proc   */
  8077. }
  8078. Saving an Object's State 
  8079.  
  8080. An object's instance data items are saved in different locations, depending 
  8081. upon the class of the object. Object classes that are descendants of the 
  8082. WPAbstract class store their instance data in the OS/2 initialization file 
  8083. OS2.INI. Object classes that are descendants of the WPFileSystem class store 
  8084. their instance data in extended attributes. Since the password-protected folder 
  8085. class is descended from the WPFolder class defined by the Workplace Shell, 
  8086. which in turn is a descendant of the WPFileSystem class, the instance data of 
  8087. this object class is saved as extended attributes in the OS/2 file system. 
  8088.  
  8089. The class-defined key passed to the _wpSaveString method is used to save the 
  8090. data item in a particular location, which can then be accessed, using the same 
  8091. key, to restore the item. In addition to strings, numeric data may be saved 
  8092. using the _wpSaveLong method, and other binary data such as application-defined 
  8093. data structures may be saved using the _wpSaveData method. 
  8094.  
  8095. Note that since the _wpSaveState method is defined by the object's class's 
  8096. ancestors and overridden, it must invoke the default processing supplied by the 
  8097. parent class in order to correctly save any instance data defined by ancestor 
  8098. classes. Failure to do so may cause unpredictable results upon awakening the 
  8099. object from its dormant state. 
  8100.  
  8101. An object must retrieve its instance data and restore its state whenever it is 
  8102. made awake. At this point, the system invokes an object's _wpRestoreState 
  8103. method, which allows the object to restore its state. During the processing of 
  8104. this method, the object can invoke other methods such as _wpRestoreString, 
  8105. which restore specific instance data items. An example of the _wpRestoreState 
  8106. method is given in Restoring an Object's State. 
  8107.  
  8108. SOM_Scope BOOL32   SOMLINK pwfolder_wpRestoreState(PWFolder *somSelf,
  8109.                 ULONG ulReserved)
  8110. {
  8111.     ULONG ulResStrLen;                          /* String length         */
  8112.  
  8113.     PWFolderData *somThis =                     /* Get instance data     */
  8114.                  PWFolderGetData(somSelf);
  8115.     PWFolderMethodDebug("PWFolder",             /* Set debug info        */
  8116.                         "pwfolder_wpRestoreState");
  8117.  
  8118.     _wpRestoreString(somSelf,                   /* Restore folder p'word */
  8119.                      "PWFolder",                /* Class name            */
  8120.                      1L,                        /* Class-defined key     */
  8121.                      _szPassword,               /* Target string         */
  8122.                      &ulResStrLen);             /* Length restored       */
  8123.     _wpRestoreString(somSelf,                   /* Restore curr p'word   */
  8124.                      "PWFolder",                /* Class name            */
  8125.                      2L,                        /* Class-defined key     */
  8126.                      _szCurrentPassword,        /* Target string         */
  8127.                      &ulResStrLen);             /* Length restored       */
  8128.  
  8129.     return(parent_wpRestoreState(somSelf,       /* Invoke default proc   */
  8130.                                  ulReserved));
  8131. }
  8132. Restoring an Object's State 
  8133.  
  8134. The class-defined key passed to the _wpRestoreString method is used to locate 
  8135. the required data item, and the item is restored into the specified target 
  8136. string variable. Numeric data can be restored using the _wpRestoreLong method, 
  8137. and other binary data such as application-defined structures can be restored 
  8138. using the _wpRestoreData method. 
  8139.  
  8140. Since the _wpRestoreState method is an overridden method, it is important that 
  8141. the default processing supplied by the parent class be invoked. Failure to do 
  8142. so will result in any instance data defined by ancestor classes being in an 
  8143. unknown state, with unpredictable results. 
  8144.  
  8145. Note that you are not restricted to the workplace methods to save and restore 
  8146. data. You may use any auxiliary file, OS2.INI, extended attributes or what ever 
  8147. means you wish. 
  8148.  
  8149.  
  8150. ΓòÉΓòÉΓòÉ 15.4.3. Destroying an Object ΓòÉΓòÉΓòÉ
  8151.  
  8152. A specific instance of an object class can be destroyed by the user, simply by 
  8153. dragging it over the Shredder object on the Workplace Shell desktop. If an 
  8154. object or application wishes to delete an object, it may do so using the 
  8155. WinDestroyObject() function, as shown in Destroying an Object. 
  8156.  
  8157. HOBJECT hObject;                           /* Object handle              */
  8158. BOOL    bSuccess;                          /* Success flag               */
  8159.  
  8160. bSuccess = WinDestroyObject(hObject);      /* Destroy object             */
  8161. Destroying an Object 
  8162.  
  8163. The WinDestroyObject() function uses the object handle that is returned by the 
  8164. WinCreateObject() function. The object or application that creates the object 
  8165. is responsible for storing this handle during the existence of the object. 
  8166.  
  8167. When an object is destroyed, the system invokes the object's _wpUnInitData 
  8168. method, which may be used to free any resources or instance data items that 
  8169. were allocated to that particular object. 
  8170.  
  8171.  
  8172. ΓòÉΓòÉΓòÉ 15.4.4. Deregistering an Object Class ΓòÉΓòÉΓòÉ
  8173.  
  8174. An entire object class can be deleted from the system by deregistering it from 
  8175. the Workplace Shell. This is achieved by either using the 
  8176. WinDeregisterObjectClass() function, which is shown in Deregistering an Object 
  8177. Class, or the SysDeregisterObjectClass() function, which is shown in REXX Code 
  8178. to Deregister a WPS Object. 
  8179.  
  8180. BOOL bSuccess;
  8181.  
  8182. bSuccess = WinDeregisterObjectClass(pszClassName);   /* Deregister class */
  8183. Deregistering an Object Class 
  8184.  
  8185. The WinDeregisterObjectClass() function accepts a string containing the object 
  8186. class name. Once a successful call is made to the WinDeregisterObjectClass() 
  8187. function, the object class is deleted from the system and is no longer 
  8188. available to other objects or applications. However, the DLL that contains the 
  8189. code for the object class is not automatically deleted from the system; if the 
  8190. Templates folder is subsequently opened with this DLL still resident in a 
  8191. directory in the system's LIBPATH, a template for the class will still appear 
  8192. in the folder. In order to prevent this, the DLL must be explicitly deleted 
  8193. from the system. 
  8194.  
  8195. During processing of the WinDeregisterObjectClass() call, the system invokes 
  8196. the object's _wpclsUnInitData method, to free any instance data or resources 
  8197. that were obtained when the object class was created. See Class Data for an 
  8198. example of this method. 
  8199.  
  8200. REXX Code to Deregister a WPS Object shows a sample piece of REXX code that 
  8201. deregisters a Workplace Object called pwFinanceFile. 
  8202.  
  8203. /*  */
  8204. Call RxFuncadd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
  8205. Call SysLoadFuncs
  8206.  
  8207. '@echo off'
  8208.  
  8209. RetCode = SysDeregisterObjectClass( "PWFinanceFile");
  8210.  
  8211. if RetCode then
  8212.     say 'Uninstall successfully completed for PWFinanceFile class'
  8213.  
  8214. say 'Re-boot NOW in order to release DLL'
  8215. 'pause'
  8216. REXX Code to Deregister a WPS Object 
  8217.  
  8218.  
  8219. ΓòÉΓòÉΓòÉ 15.4.5. Accessing Presentation Manager Resources From a Workplace Shell Object ΓòÉΓòÉΓòÉ
  8220.  
  8221. A Workplace Shell object may access and make use of Presentation Manager 
  8222. resources such as icons, bitmaps, strings and dialogs. These resources may 
  8223. reside in the same DLL as the object's code, or in another DLL. However, since 
  8224. the resources must reside in a DLL, the code that loads the resources must use 
  8225. the DosLoadModule or DosGetModuleHandle() functions to obtain module handles, 
  8226. as described in Loading Resources From a DLL. This is typically done by 
  8227. obtaining the module handles as part of the _wpclsInitData method, and storing 
  8228. them either in global variables or in class data until needed. Note that not 
  8229. all Workplace methods can be assumed to be called in a PM thread. You may need 
  8230. to create your own PM thread to access PM functions during Workplace 
  8231. processing. 
  8232.  
  8233.  
  8234. ΓòÉΓòÉΓòÉ 15.5. Transient Objects ΓòÉΓòÉΓòÉ
  8235.  
  8236. As mentioned earlier in this chapter, a Workplace Shell object differs from a 
  8237. Presentation Manager window in that it is persistent; that is, it continues to 
  8238. exist after a system restart. The exception to this rule is the transient 
  8239. object, which only exists during the current execution of the system, and is 
  8240. destroyed when the system is IPLed. 
  8241.  
  8242. Transient objects are useful when a programmer wishes to represent and display 
  8243. information such as records from a database. As each record is retrieved, a 
  8244. transient object is created for that record and displayed in a folder on the 
  8245. Workplace Shell desktop. These objects may be opened and manipulated by the end 
  8246. user, but will cease to exist when the system is IPLed. 
  8247.  
  8248. Creating a Transient Object shows an object window in a requester process 
  8249. which, upon receiving a completed database query from a server process, invokes 
  8250. the _wpclsNew method to create a new instance of a transient object class, 
  8251. representing the record retrieved from the database. 
  8252.  
  8253. REPLY *Reply;                                   /* Reply data structure  */
  8254.  
  8255. SOMAny *NewObj;                                 /* Object pointer        */
  8256.  
  8257. case WMP_REQUEST_COMPLETE:
  8258.      Reply = (REPLY *)mp1;                      /* Get reply data        */
  8259.  
  8260.      ClassID = SOM_IdFromString("CustClass");   /* Get class SOM ID      */
  8261.  
  8262.      TransClass = _somFindClass(SOMClassMgrObject, /* Get class pointer  */
  8263.                                 ClassID,        /* Class SOM ID          */
  8264.                                 1,1);           /* Major & minor version */
  8265.  
  8266.      NewObj = _wpclsNew(TransClass,             /* Create new object     */
  8267.                         Reply->CustName,        /* Title for object      */
  8268.                         "",                     /* No setup string       */
  8269.                         Reply->Folder,          /* Location              */
  8270.                         TRUE);                  /* Lock flag             */
  8271.  
  8272.      _SetCustInfo(NewObj,                       /* Set instance data     */
  8273.                   Reply);
  8274.      break;
  8275. Creating a Transient Object 
  8276.  
  8277. The SOM pointer to the transient object class is obtained using the 
  8278. SOMIdFromString() macro and the _somFindClass method (see Communication Between 
  8279. Objects for further information). This pointer is then used to invoke the 
  8280. _wpclsNew method to create a new instance of the class. Once the new instance 
  8281. is created, a method named _SetCustInfo, which is defined by the transient 
  8282. object class, is invoked to insert the information retrieved from the database 
  8283. into the object's instance data. 
  8284.  
  8285. Note that the technique shown in Creating a Transient Object may only be used 
  8286. when an object is created from within the Workplace Shell process. If an object 
  8287. must be created from another process in the system, the WinCreateObject() 
  8288. function must be used. 
  8289.  
  8290.  
  8291. ΓòÉΓòÉΓòÉ 15.6. Communication Between Objects ΓòÉΓòÉΓòÉ
  8292.  
  8293. Objects communicate with one another in order to convey events and initiate 
  8294. actions on the part of other objects. Such communication is typically initiated 
  8295. in one of two ways: 
  8296.  
  8297.    o  By an object to convey information to another object with which it has an 
  8298.       application-defined relationship, such as a request. This is similar to 
  8299.       the application-initiated event discussed for Presentation Manager 
  8300.       applications in OS/2 2.1 Volume 4: Writing Applications, Chapter 4 "The 
  8301.       Presentation Manager Application Model". 
  8302.  
  8303.    o  By the user directly manipulating the objects' icons. For example, 
  8304.       dropping one icon over another icon initiates a conversation between the 
  8305.       two objects.  This is similar to the user-initiated event discussed for 
  8306.       Presentation Manager applications in OS/2 2.1 Volume 4: Writing 
  8307.       Applications, Chapter 4 "The Presentation Manager Application Model". 
  8308.  
  8309.  Each of these types of communication is discussed in the following sections. 
  8310.  
  8311.  
  8312. ΓòÉΓòÉΓòÉ 15.6.1. Application-Initiated Communication ΓòÉΓòÉΓòÉ
  8313.  
  8314. The application-initiated communication is somewhat more complex then the 
  8315. user-initiated communication since the initiator of the communication typically 
  8316. has knowledge of the type of object to which the communication is being passed, 
  8317. and can usually initiate the communication by simply invoking a method in the 
  8318. receiving object, in a similar manner to that discussed in Invoking Another 
  8319. Object's Methods. 
  8320.  
  8321. However, it is often necessary to determine the identity of the object for 
  8322. which a method must be invoked. The Workplace Shell provides access to objects 
  8323. using the HOBJECT and the OBJECTID and, at a base level, system object model 
  8324. provides pointers to objects and SOM IDs. Each of these is described in the 
  8325. following sections, and some discussion is included on converting between 
  8326. identifiers. 
  8327.  
  8328.  
  8329. ΓòÉΓòÉΓòÉ 15.6.1.1. HOBJECT ΓòÉΓòÉΓòÉ
  8330.  
  8331. This identifier is the object handle, which is allocated by the Workplace Shell 
  8332. and passed as the return value from the WinCreateObject() function. It is a 
  8333. persistent object handle that remains allocated to an object for the duration 
  8334. of its existence. Object handles persist across system restarts, and may 
  8335. therefore be used by one object to refer to another object at any time. 
  8336.  
  8337. An object handle can be determined from the object's OBJECTID using the 
  8338. WinQueryObject() function, 
  8339.  
  8340. HOBJECT  hObject;                            /* Object handle         */
  8341. PSZ      szObjectID = "<OBJECTID>";          /* OBJECTID string       */
  8342.  
  8343. hObject = WinQueryObject(szObjectID);        /* Query object handle   */
  8344.  
  8345. Note that this function may be called from any process; its use is not 
  8346. restricted to objects in the Workplace Shell process. 
  8347.  
  8348.  
  8349. ΓòÉΓòÉΓòÉ 15.6.1.2. OBJECTID ΓòÉΓòÉΓòÉ
  8350.  
  8351. The OBJECTID is provided by an application or object class as part of the setup 
  8352. string parameter in the WinCreateObject() call, when an object is created. It 
  8353. is persistent in the same way as an object handle, but provides a more 
  8354. meaningful reference for an object, which can be used by other objects. 
  8355.  
  8356. HOBJECT hObject;                                /* Object handle         */
  8357.  
  8358. /*************************************************************************/
  8359. /* Create a folder on the desktop with an OBJECTID of MYFOLDER           */
  8360. /*************************************************************************/
  8361.  
  8362. hObject = WinCreateObject("WPFolder",           /* Class Name            */
  8363.                           "My Folder",          /* Title                 */
  8364.                           "OBJECTID=<MYFOLDER>", /* Setup string         */
  8365.                           "<WP_DESKTOP>",       /* Location              */
  8366.                           CO_REPLACEIFEXISTS);  /* Create option         */
  8367.  
  8368. /*************************************************************************/
  8369. /* Create a file object with an OBJECTID of MYFILE inside the folder     */
  8370. /*************************************************************************/
  8371.  
  8372. hObject = WinCreateObject("WPDataFile",         /* Class Name            */
  8373.                           "My File",            /* Title                 */
  8374.                           "OBJECTID=<MYFILE>",  /* Setup string          */
  8375.                           "<MYFOLDER>",         /* Location              */
  8376.                           CO_REPLACEIFEXISTS);  /* Create option         */
  8377.  
  8378. /*************************************************************************/
  8379. /* Create a shadow of the file object MYFILE on the desktop              */
  8380. /*************************************************************************/
  8381.  
  8382. hObject = WinCreateObject("WPShadow",           /* Class Name            */
  8383.                           "My File",            /* Title                 */
  8384.                           "SHADOWID=<MYFILE>",  /* Setup string          */
  8385.                           "<WP_DESKTOP>",       /* Location              */
  8386.                           CO_REPLACEIFEXISTS);  /* Create option         */
  8387. Referencing an Object Using OBJECTID 
  8388.  
  8389. Note that the angle brackets ("<" and ">") used within the OBJECTID are an 
  8390. important part of the syntax. 
  8391.  
  8392. Note also that the Workplace Shell provides a number of predefined OBJECTIDs 
  8393. for system-defined objects. The first and third WinCreateObject() calls in 
  8394. Referencing an Object Using OBJECTID use the <WP_DESKTOP> OBJECTID to place the 
  8395. objects on the desktop. 
  8396.  
  8397.  
  8398. ΓòÉΓòÉΓòÉ 15.6.1.3. SOM Pointer ΓòÉΓòÉΓòÉ
  8399.  
  8400. SOM pointers come in various forms, but can all be typecast to SOMAny *. From a 
  8401. Workplace Shell perspective, a SOM pointer is the return value of the _wpclsNew 
  8402. class method; this is the method used for creating objects within the Workplace 
  8403. Shell process. An object's public methods and data can be accessed using the 
  8404. object's SOM pointer. 
  8405.  
  8406. A SOM pointer for an object may be obtained from an object handle using the 
  8407. _wpclsQueryObject method provided by the WPObject class, as follows: 
  8408.  
  8409. SOMAny *Asomptr;                             /* SOM pointers          */
  8410. SOMAny *Bsomptr;
  8411.  
  8412. Asomptr = _wpclsQueryObject(_WPObject,       /* Query SOM pointer     */
  8413.                             hObject);        /* Object handle         */
  8414.  
  8415. A SOM pointer for a class may be obtained from the SOM ID for that class, using 
  8416. the _somFindClass method shown below: 
  8417.  
  8418. Asomptr = _somFindClass(SOMClassMgrObject,
  8419.                         AsomId,
  8420.                         1,
  8421.                         1);
  8422.  
  8423. A SOM pointer for a class may be obtained from the SOM pointer for any object 
  8424. within that class, using the _somGetClass method as follows: 
  8425.  
  8426. Asomptr = _somGetClass(Bsomptr);
  8427.  
  8428. The SOM pointer is typically used to invoke class methods from an object in 
  8429. another class. The _SOMDispatchL() method shown in Invoking a Method in Another 
  8430. Object Class requires a SOM pointer as a parameter. 
  8431.  
  8432.  
  8433. ΓòÉΓòÉΓòÉ 15.6.1.4. SOM ID ΓòÉΓòÉΓòÉ
  8434.  
  8435. A SOM ID is simply a way of mapping a unique number to a string. This string 
  8436. may represent the name of a method or class.  SOM IDs are integers that are 
  8437. managed by the Workplace Shell using the Atom Manager facility of Presentation 
  8438. Manager. A SOM ID is obtained using the SOM_IdFromString() function as follows: 
  8439.  
  8440. somId    AsomId;
  8441.  
  8442. AsomId = SOM_IdFromString("WPFolder");
  8443.  
  8444. The SOM ID is typically used to obtain a SOM pointer, which can then be used to 
  8445. invoke a method. 
  8446.  
  8447.  
  8448. ΓòÉΓòÉΓòÉ 15.6.2. User-Initiated Communication ΓòÉΓòÉΓòÉ
  8449.  
  8450. The user-initiated communication is somewhat more complex then the 
  8451. application-initiated communication, since the two objects may have no defined 
  8452. relationship. A conversation must be initiated between the two, whereby each 
  8453. determines the nature of the other, and whether a drop operation is valid at 
  8454. the present time. If so, each object passes the information required to carry 
  8455. out the requested action. 
  8456.  
  8457.  
  8458. ΓòÉΓòÉΓòÉ 15.6.2.1. Dragging a Workplace Object over a Workplace Object ΓòÉΓòÉΓòÉ
  8459.  
  8460. When the user begins to drag an object, this source object being dragged is 
  8461. notified by the system, by invoking the object's _wpFormatDragItem method. This 
  8462. method is used to build a DRAGITEM structure, which is passed to any object if 
  8463. this source object is dragged over it or dropped on it. The DRAGITEM structure 
  8464. contains rendering information about the source object, which is used by other 
  8465. receiving objects over which the source object is dragged, in order to 
  8466. determine whether a drop operation is valid at that point. 
  8467.  
  8468. Default information for the DRAGITEM structure is inserted by the default 
  8469. processing provided by the parent class, but an object class may override the 
  8470. method and include its own class-specific processing. The DRAGITEM structure is 
  8471. nested within a DRAGINFO structure, which is passed to any receiver object over 
  8472. which one or more source objects are dragged. In a situation where more than 
  8473. one object is being dragged simultaneously, a separate DRAGITEM structure is 
  8474. produced for each source object, and the entire set of structures is combined 
  8475. using a single DRAGINFO structure. 
  8476.  
  8477. When an object is dragged over an object the system invokes the _wpDragOver 
  8478. method in the receiving object. This method receives a DRAGINFO structure, 
  8479. which contains a variety of information including pointers to one or more 
  8480. DRAGITEM structures. Note it is the responsibility of the receiver object's 
  8481. _wpDragOver method to return whether it can accept the drop, and what operation 
  8482. to perform. 
  8483.  
  8484. The receiver object has to check the operation code it receives from the source 
  8485. object. If it is the default (DO_DEFAULT), it needs to return the operation to 
  8486. be performed, for example DO_MOVE, or DO_COPY. If it is not the default, for 
  8487. example a DO_MOVE, then the receiver object must determine if it can accept 
  8488. that operation and return accordingly. 
  8489.  
  8490.      Warning 
  8491.  
  8492.      If you have written Workplace Shell drag and drop code under OS/2 2.0, the 
  8493.      way the ancestor classes respond to the _wpDragOver method has changed for 
  8494.      OS/2 2.1. Specifically the parent_wpDragOver method will return 
  8495.      DOR_NEVERDROP if the ancestor classes cannot accept the source objects. 
  8496.  
  8497.      Consequently code must be written so that the parent_wpDragOver method is 
  8498.      called first, and if the resultant Drop Indicator is NOT DOR_NEVERDROP, 
  8499.      then the method may continue its processing, as shown in Dragging a 
  8500.      Workplace Object. 
  8501.  
  8502.  Dragging a Workplace Object shows another _wpDrop method override example for 
  8503.  the object called pwFinanceFile which is derived from the wpDataFile Workplace 
  8504.  Shell object. In this example we first invoke our objects parent _wpDragOver 
  8505.  method (that is the _wpDragOver method for wpDataFile) to see that it doesn't 
  8506.  violate any of its rules. If the parent successfully tested one or more source 
  8507.  objects, our method determines how many source objects are being dragged over 
  8508.  the target object and then searches through each of the source objects() and 
  8509.  checks that they are all Workplace Objects. If any one of these is not a 
  8510.  Workplace Object then our object will reject all of them by returning 
  8511.  DOR_NEVERDROP as the indicator and DO_UNKNOWN as the operation. Otherwise our 
  8512.  method makes sure it is being passed a DO_COPY, DO_MOVE or a DO_DEFAULT 
  8513.  operation. If it is not one of these, it will reject all of the source 
  8514.  objects. If it is one of these, DO_DROP and DO_COPY will be returned as the 
  8515.  result to the Workplace Shell. 
  8516.  
  8517.  If the receiver object wanted to allow only its tests and not any of the 
  8518.  parents, then the parent_wpDragOver method invocation can be removed, along 
  8519.  with the setting of the dropIndication and dropOperation from the returned mr 
  8520.  program variable, as well as the if statement that immediately follows. 
  8521.  
  8522.  If the _wpDragOver in Dragging a Workplace Object returns successful, and the 
  8523.  user drops the object, then the _wpDrop method is invoked for the receiver 
  8524.  object. The same checking that was performed in the _wpDragOver method needs 
  8525.  to be performed by the _wpDrop method because the receiving object may only 
  8526.  receive a _wpDrop method invocation, and not a _wpDragOver. 
  8527.  
  8528.   SOM_Scope MRESULT   SOMLINK pwFinanceFile_wpDragOver(PWFinanceFile *somSelf,
  8529.                   HWND hwndCnr,
  8530.                   PDRAGINFO pdrgInfo)
  8531.   {
  8532.       MRESULT  mr;
  8533.       USHORT   dropOperation,
  8534.                dropIndicator;
  8535.       ULONG    ulItemCount         =0;
  8536.       ULONG    ulItem              =0;
  8537.  
  8538.       PWFinanceFileData *somThis = PWFinanceFileGetData(somSelf);
  8539.       PWFinanceFileMethodDebug("PWFinanceFile","pwFinanceFile_wpDragOver");
  8540.  
  8541.       /* firstly will all the source object(s) pass my parents tests? */
  8542.       mr = parent_wpDragOver(somSelf,hwndCnr,pdrgInfo);
  8543.       dropIndicator = SHORT1FROMMR(mr);
  8544.       dropOperation = SHORT2FROMMR(mr);
  8545.  
  8546.       if (dropIndicator != DOR_NEVERDROP)
  8547.       {
  8548.         /* passed the parent's tests, so unless it fails this object's */
  8549.         /* tests we will allow the DROP                                */
  8550.         dropIndicator = DOR_DROP;
  8551.         dropOperation = DO_COPY;
  8552.  
  8553.         /* how many items are being dragged ? */
  8554.         ulItemCount = DrgQueryDragitemCount(pdrgInfo);
  8555.  
  8556.         /* search through the objects and abort if we find any that */
  8557.         /* are not WorkPlace objects                                */
  8558.  
  8559.         for (ulItem=0; ulItem<ulItemCount; ulItem++) {
  8560.           PDRAGITEM pDragItem;               /* temporary variable */
  8561.           WPObject *ObjectBeingDragged=NULL; /* temporary variable */
  8562.  
  8563.           /* get one of the one or more drag items that we are receiving */
  8564.           pDragItem = DrgQueryDragitemPtr(pdrgInfo, ulItem);
  8565.  
  8566.           /* test to see if it is a WorkPlace object, if it is use     */
  8567.           /* the OBJECT_FROM_PREC macro to get the object; otherwise   */
  8568.           /* ObjectBeingDragged will remain as a NULL as it was        */
  8569.           /* initialised when declared as NULL                         */
  8570.           if ( DrgVerifyRMF(pDragItem, "DRM_OBJECT", NULL))
  8571.              ObjectBeingDragged = OBJECT_FROM_PREC(pDragItem);
  8572.           if (!ObjectBeingDragged) {
  8573.               /* Object is NOT a WorkPlace object, so I reject all objects */
  8574.               return (MRFROM2SHORT(DOR_NEVERDROP,DO_UNKNOWN));
  8575.             } else {
  8576.               if ( (pdrgInfo->usOperation != DO_COPY   ) &&
  8577.                    (pdrgInfo->usOperation != DO_MOVE   ) &&
  8578.                    (pdrgInfo->usOperation != DO_DEFAULT) ) {
  8579.               /* this object only allows a move or copy */
  8580.               return (MRFROM2SHORT(DOR_NODROP,DO_UNKNOWN));
  8581.               } /* endif */
  8582.             } /* endif */
  8583.  
  8584.           } /* endfor */
  8585.       } /* endif */
  8586.       /* all the test have been passed, so tell this to the WorkPlace Shell */
  8587.       return (MRFROM2SHORT(dropIndicator, dropOperation));
  8588.    }
  8589.  Dragging a Workplace Object 
  8590.  
  8591.  In this figure we first see if the source's object passes this object's 
  8592.  parent's wpDragOver tests, and then apply our own. :efigdesc. 
  8593.  
  8594.  Note that DOR_NODROP is returned when rejecting the operation, and 
  8595.  DOR_NEVERDROP is returned when rejecting the drop request. This is important 
  8596.  when a user drags one object onto another (DO_MOVE) and the receiver object 
  8597.  returns a DOR_NODROP, meaning it cannot accept the operation. If the user 
  8598.  still has the object over the receiver object and now holds down the <ctrl> 
  8599.  key, then the operation is now a DO_COPY. If the receiver object had 
  8600.  previously returned a DOR_NODROP then the Workplace Shell will now reinvoke 
  8601.  the objects _wpDragOver method passing it the DO_COPY. This would not occur if 
  8602.  a DOR_NEVERDROP had been received. 
  8603.  
  8604.  How the receiver object responds with its implementation of the _wpDragOver, 
  8605.  really depends on: 
  8606.  
  8607.    o  The type of object being implemented 
  8608.  
  8609.    o  What is being dragged over it 
  8610.  
  8611.    o  What the person who designs the object really wants to achieve 
  8612.  
  8613.  For example, in Dragging a Workplace Object, simple decisions are made based 
  8614.  on the parent's _wpDragOver method. Only Workplace Objects which want to 
  8615.  perform a DO_COPY, DO_MOVE or a DO_DEFAULT operation are acceptable source 
  8616.  objects. 
  8617.  
  8618.  The designer may want to restrict what the object will accept still further. 
  8619.  For example, only allowing objects that are the same class as the 
  8620.  pwFinanceFile object, or are descended from it, as there are going to be 
  8621.  specific data types that have meaning to this object and no others can be 
  8622.  accepted. Perhaps the designer wishes to have financial account type entries 
  8623.  in the pwFinanceFile object and it would therefore not be meaningful to allow 
  8624.  the dragging and dropping of a picture or any other objects that could not be 
  8625.  understood by this specialized object. 
  8626.  
  8627.  Only Accepting pwFinanceFile Objects from Drag Operations expands on Dragging 
  8628.  a Workplace Object to now exclude any objects that are not part of the 
  8629.  pwFinanceFile class. 
  8630.  
  8631.   SOM_Scope MRESULT   SOMLINK pwFinanceFile_wpDragOver(PWFinanceFile *somSelf,
  8632.                   HWND hwndCnr,
  8633.                   PDRAGINFO pdrgInfo)
  8634.   {
  8635.       MRESULT  mr;
  8636.       USHORT   dropOperation,
  8637.                dropIndicator;
  8638.       ULONG    ulItemCount         =0;
  8639.       ULONG    ulItem              =0;
  8640.       CLASS    PWFinanceFileClass;
  8641.  
  8642.       PWFinanceFileData *somThis = PWFinanceFileGetData(somSelf);
  8643.       PWFinanceFileMethodDebug("PWFinanceFile","pwFinanceFile_wpDragOver");
  8644.  
  8645.       /* create a dummy pwFinanceFile class for comparison with the source */
  8646.       /* object(s) class                                                   */
  8647.       PWFinanceFileClass = _somClassFromId( SOMClassMgrObject,
  8648.                            SOM_IdFromString("PWFinanceFile") );
  8649.  
  8650.       /* firstly will all the source object(s) pass my parents tests? */
  8651.       mr = parent_wpDragOver(somSelf,hwndCnr,pdrgInfo);
  8652.       dropIndicator = SHORT1FROMMR(mr);
  8653.       dropOperation = SHORT2FROMMR(mr);
  8654.  
  8655.       if (dropIndicator != DOR_NEVERDROP)
  8656.       {
  8657.         /* passed the parent's tests, so unless it fails this object's */
  8658.         /* tests we will allow the DROP                                */
  8659.         dropIndicator = DOR_DROP;
  8660.         dropOperation = DO_COPY;
  8661.  
  8662.         /* how many items are being dragged ? */
  8663.         ulItemCount = DrgQueryDragitemCount(pdrgInfo);
  8664.  
  8665.         /* search through the objects and abort if we find any that */
  8666.         /* are not WorkPlace objects                                */
  8667.  
  8668.         for (ulItem=0; ulItem<ulItemCount; ulItem++) {
  8669.           PDRAGITEM pDragItem;               /* temporary variable */
  8670.           SOMAny   *ObjectBeingDragged=NULL; /* temporary variable */
  8671.  
  8672.           /* get one of the one or more drag items that we are receiving */
  8673.           pDragItem = DrgQueryDragitemPtr(pdrgInfo, ulItem);
  8674.  
  8675.           /* test to see if it is a WorkPlace object, if it is use     */
  8676.           /* the OBJECT_FROM_PREC macro to get the object; otherwise   */
  8677.           /* ObjectBeingDragged will remain as a NULL as it was        */
  8678.           /* initialised when declared as NULL                         */
  8679.  
  8680.           if ( DrgVerifyRMF(pDragItem, "DRM_OBJECT", NULL))
  8681.              ObjectBeingDragged = OBJECT_FROM_PREC(pDragItem);
  8682.  
  8683.           if (!ObjectBeingDragged) {
  8684.               /* Object is NOT a WorkPlace object, so I reject all objects */
  8685.               return (MRFROM2SHORT(DOR_NEVERDROP,DO_UNKNOWN));
  8686.             } else {
  8687.               if ( (pdrgInfo->usOperation != DO_COPY   ) &&
  8688.                    (pdrgInfo->usOperation != DO_MOVE   ) &&
  8689.                    (pdrgInfo->usOperation != DO_DEFAULT) ) {
  8690.               /* this object only allows a move or copy */
  8691.               return (MRFROM2SHORT(DOR_NODROP,DO_UNKNOWN));
  8692.               } else {
  8693.                 /* the object is all ok, but is it a pwFinanceFile object,  */
  8694.                 /* or descended from one?                                   */
  8695.                 if (!_somIsA(ObjectBeingDragged,PWFinanceFileClass)) {
  8696.                   /* reject all the objects because this one is not derived */
  8697.                   /* from PWFinanceFileClass                                */
  8698.                   return (MRFROM2SHORT(DOR_NEVERDROP,DO_UNKNOWN));
  8699.                 } /* endif */
  8700.  
  8701.               } /* endif */
  8702.  
  8703.             } /* endif */
  8704.  
  8705.           } /* endfor */
  8706.  
  8707.       } /* endif */
  8708.       /* all the test have been passed, so tell this to the WorkPlace Shell */
  8709.       return (MRFROM2SHORT(dropIndicator, dropOperation));
  8710.    }
  8711.  Only Accepting pwFinanceFile Objects from Drag Operations 
  8712.  
  8713.  
  8714. ΓòÉΓòÉΓòÉ 15.6.3. Dragging a Non-Workplace Object onto a Workplace Object ΓòÉΓòÉΓòÉ
  8715.  
  8716. Dragging a non-Workplace Object onto a Workplace Object is handled in a similar 
  8717. way to the dragging of a Workplace Object over a Workplace Object. How the 
  8718. receiver object responds in its implementation of its _wpDragOver, depends on 
  8719. the type of object being implemented, what is being dragged over it and what 
  8720. the person who designed the object wants it to do. The difficulty is to 
  8721. determine what the object should do for every possible type of non-Workplace 
  8722. Shell object (and Workplace Shell objects such as OS/2 files). 
  8723.  
  8724. If the receiver object is capable of having a file object dropped on it, and a 
  8725. file was dragged over it (the source is not a Workplace Object file object), 
  8726. the receiver object could convert the source to a file object and then process 
  8727. it. 
  8728.  
  8729. If the source of the drag operation cannot be converted to a file object, or is 
  8730. not a file in the first place, then drag and drop participation is still 
  8731. possible if the source object has a drag mechanism and operation that the 
  8732. target object can support. Dropping an Object shows an example of a _wpDrop 
  8733. method where an OS/2 file is accepted and converted to a Workplace Object. 
  8734.  
  8735.  
  8736. ΓòÉΓòÉΓòÉ 15.6.4. Dragging a Workplace Object onto a Non-Workplace Object ΓòÉΓòÉΓòÉ
  8737.  
  8738. In the same way a non-Workplace Object can participate in a drag and drop 
  8739. conversation with a Workplace Object, a Workplace Object can can also 
  8740. participate in a drag and drop conversation with a non-Workplace Object, 
  8741. provided the Workplace Object provide support for the drag mechanisms and 
  8742. operations that the receiver object supports. 
  8743.  
  8744. A Workplace Object can support multiple mechanisms and operations as shown in 
  8745. Multiple Rendering Methods. 
  8746.  
  8747.  
  8748.    MRESULT       mr;
  8749.    PDRAGTRANSFER pDragTransfer;
  8750.    BOOL          bSentOK;
  8751.       .
  8752.       .
  8753.       .
  8754.    /* allocate a drag transfer structure */
  8755.    pDragTransfer = DrgAllocDragtransfer(1);
  8756.  
  8757.    if (pDragTransfer) // was the allocate successful?
  8758.    {
  8759.       /* populate the drag structure */
  8760.       .
  8761.       .
  8762.       .
  8763.       pDragTransfer->hstrSelectedRMF  =
  8764.           DrgAddStrHandle("(DRM_OS2FILE,DRM_PRINT)x(DRF_TEXT),
  8765.                            <DRM_OBJECT,DRF_OBJECT>");
  8766.       .
  8767.       .
  8768.       .
  8769.       bSentOK = (BOOL)DrgSendTransferMsg(pDragInfo->hwndSource,
  8770.                                          DM_RENDERPREPARE,
  8771.                                          (MPARAM)pDragTransfer,
  8772.                                          (MPARAM)NULL);
  8773.       if (bSentOK)
  8774.       {
  8775.         .
  8776.         .
  8777.         .
  8778.       } else {
  8779.         mr = (MRESULT)RC_DROP_ERROR;
  8780.       }
  8781.         .
  8782.         .
  8783.         .
  8784. }
  8785. Multiple Rendering Methods 
  8786.  
  8787.  
  8788. ΓòÉΓòÉΓòÉ 15.6.5. Dropping an Object ΓòÉΓòÉΓòÉ
  8789.  
  8790. When a drop operation occurs, the receiver object is notified by the system 
  8791. which invokes the _wpDrop method for that object. This method accepts the 
  8792. DRAGINFO structure which may then be examined by the receiver object to 
  8793. determine the correct action to be taken. The rendering information contained 
  8794. in the DRAGITEM structure may be sufficient to allow the action to be 
  8795. completed, or the receiver object may initiate a conversation with the source 
  8796. object in order to gain sufficient information to complete the action. 
  8797.  
  8798. If the source object is not a Workplace Object but it is an OS/2 file, then the 
  8799. receiver object must decide whether it can handle a file. If receiver handling 
  8800. is set then the receiver object can create a Workplace Object created to 
  8801. represent the OS/2 file. This Workplace Object can then issue methods. However, 
  8802. if you do not wish to create a Workplace Object to represent the file then the 
  8803. Presentation Manager Drag and Drop messages must be handled. 
  8804.  
  8805. If neither a Workplace Object, nor an OS/2 File are being dropped, then the 
  8806. receiver object must decide what it wants to do. 
  8807.  
  8808. The rendering information provided in the DRAGITEM structure, and its use by a 
  8809. Presentation Manager or Workplace Shell object, is described in detail in OS/2 
  8810. 2.1 Volume 4: Writing Applications, Chapter 8 "Direct Manipulation." 
  8811.  
  8812. Converting a Source Drag OS/2 File to a Workplace Object 
  8813.  
  8814. /*
  8815.  *
  8816.  *   METHOD:   wpDrop                                      PUBLIC
  8817.  *
  8818.  *   PURPOSE:  To receive a dropped object.
  8819.  *
  8820.  *   INVOKED:  By Workplace Shell, when another object has been dropped on
  8821.  *             this object.
  8822.  *
  8823.  */
  8824.  
  8825. SOM_Scope MRESULT   SOMLINK pwFinanceFile_wpDrop(PWFinanceFile *somSelf,
  8826.                 HWND hwndCnr,
  8827.                 PDRAGINFO pdrgInfo,
  8828.                 PDRAGITEM pdrgItem)
  8829. {
  8830.  
  8831.     CHAR          szName[CCHMAXPATH];
  8832.     CHAR          szPath[CCHMAXPATH];
  8833.     ULONG         cbPath = CCHMAXPATH;
  8834.     ULONG         ulItemCount         =0;
  8835.     ULONG         ulItem              =0;
  8836.     CLASS         PWFinanceFileClass;
  8837.     SOMAny       *ObjectBeingDragged;
  8838.     MRESULT       mr;
  8839.     USHORT        dropOperation,
  8840.                   dropIndicator;
  8841.     BOOL          flPrepared = TRUE; // Assume we do not need to do a prepare
  8842.     BOOL          flRendering = FALSE;
  8843.     PDRAGTRANSFER pDragTransfer;
  8844.  
  8845.     PWFinanceFileData *somThis = PWFinanceFileGetData(somSelf);
  8846.     PWFinanceFileMethodDebug("PWFinanceFile","pwFinanceFile_wpDrop");
  8847.  
  8848.     if ((strcmp(_szCurrentPassword,       /* If FinanceFile is NOT locked */
  8849.                 _szPassword)) == 0)
  8850.     {
  8851.  
  8852.   /* make sure we are not dragging ourselves, and dropping onto ourselves */
  8853.      if (pdrgInfo->hwndSource != hwndCnr)
  8854.      {
  8855.  
  8856.      /* for each of the items being dropped, check to see that they are all */
  8857.      /* derived from PWFinanceFileClass                                     */
  8858.  
  8859.      PWFinanceFileClass = _somClassFromId( SOMClassMgrObject,
  8860.                           SOM_IdFromString("PWFinanceFile") );
  8861.       /* passed the parent's tests, so unless it fails this object's */
  8862.       /* tests we will allow the DROP                                */
  8863.       dropIndicator = DOR_DROP;
  8864.       dropOperation = DO_COPY;
  8865.  
  8866.       /* how many items are being dragged ? */
  8867.       ulItemCount = DrgQueryDragitemCount(pdrgInfo);
  8868.  
  8869.       /* search through the objects and abort if we find any that aren't derived */
  8870.       /* from PWFinanceFileClass                                                 */
  8871.       somPrintf("Number of Items being dropped = %i.\n",ulItemCount);
  8872.       for (ulItem=0; ulItem<ulItemCount; ulItem++) {
  8873.         PDRAGITEM pDragItem; /* temporary variable*/
  8874.  
  8875.         /* get one of the one or more drag items that we are receiving */
  8876.         pDragItem = DrgQueryDragitemPtr(pdrgInfo, ulItem);
  8877.  
  8878.         ObjectBeingDragged = queryObjectFromDragItem(pDragItem);
  8879.  
  8880.         if (ObjectBeingDragged) {
  8881.           if (!_somIsA(ObjectBeingDragged,PWFinanceFileClass)) {
  8882.             somPrintf("Object %i, is rejected for drop because it ",ulItem);
  8883.             somPrintf("is not derived from PWFinanceFileClass\n");
  8884.           } else {
  8885.             somPrintf("Object %i, is acceptable for dropping, by wpDROP\n",ulItem);
  8886.           } /* endif */
  8887.         } else {
  8888.           somPrintf("Object %i, is not a WPS object, can we render it\n",ulItem);
  8889.  
  8890.       /* start of code to render item */
  8891.  
  8892.       if( DrgVerifyRMF (pDragItem, "DRM_OS2FILE", NULL) )
  8893.       {
  8894.          somPrintf("An OS2FILE rendering method!\n");
  8895.          /* Protocol allows the source object to propose a target name...
  8896.           *
  8897.           * If it does, then try to use it, if it does not, then
  8898.           * try to use the source name, if present.  Finally, just
  8899.           * make up our own name...
  8900.           */
  8901.          if (pDragItem->hstrTargetName &&
  8902.              DrgQueryStrNameLen(pDragItem->hstrTargetName) )
  8903.          {
  8904.             DrgQueryStrName(pDragItem->hstrTargetName,
  8905.                             sizeof(szName),szName);
  8906.             somPrintf("Source proposes the target filename\n");
  8907.          }
  8908.          else
  8909.          {
  8910.             if (pDragItem->hstrSourceName &&
  8911.                DrgQueryStrNameLen(pDragItem->hstrSourceName))
  8912.             {
  8913.                DrgQueryStrName(pDragItem->hstrSourceName,
  8914.                                sizeof(szName),szName);
  8915.             somPrintf("Source proposes the source filename\n");
  8916.  
  8917.             }
  8918.             else
  8919.             {
  8920.                szName[0] = '\0';
  8921.                somPrintf("no source, nor target name\n");
  8922.             }
  8923.          }
  8924.  
  8925.          /* Allocate and initialize a drag transfer structure
  8926.           */
  8927.          somPrintf("allocating pDragtransfer structure\n");
  8928.          pDragTransfer = DrgAllocDragtransfer(1);
  8929.  
  8930.          if (pDragTransfer)
  8931.          {
  8932.             somPrintf("pDragtransfer structure allocated ok\n");
  8933.             /* create a WPDataFile object
  8934.              */
  8935.             ObjectBeingDragged = _wpclsNew( _WPDataFile,
  8936.                                 szName,
  8937.                                 NULL,
  8938.                                 _wpclsQueryFolder(_WPDataFile,"<WP_NOWHERE>",TRUE),
  8939.                                 TRUE );
  8940.  
  8941.             if (ObjectBeingDragged)
  8942.             {
  8943.                somPrintf("ObjectBeingDragged has been successfully allocated\n");
  8944.                _wpQueryRealName(ObjectBeingDragged,szPath,&cbPath,TRUE);
  8945.                somPrintf("The ObjectBeingDragged filename is %s\n",szPath);
  8946.  
  8947.                /* fill in the struct now
  8948.                 */
  8949.                pDragTransfer->cb               = sizeof(DRAGTRANSFER);
  8950.                pDragTransfer->hwndClient       = hwndCnr;
  8951.                pDragTransfer->pditem           = pDragItem;
  8952.                pDragTransfer->hstrSelectedRMF  =
  8953.                               DrgAddStrHandle("<DRM_OS2FILE,DRF_UNKNOWN>");
  8954.                pDragTransfer->hstrRenderToName = DrgAddStrHandle( szPath );
  8955.                pDragTransfer->ulTargetInfo     = 0L;
  8956.                pDragTransfer->usOperation      = pdrgInfo->usOperation;
  8957.                pDragTransfer->fsReply          = 0;
  8958.                /* Now, if the source wants prepared, do it...
  8959.                 */
  8960.                if (pDragItem->fsControl & DC_PREPARE)
  8961.                {
  8962.                   somPrintf("Source wants prepared\n");
  8963.                   flPrepared = (BOOL)DrgSendTransferMsg(pdrgInfo->hwndSource,
  8964.                                                         DM_RENDERPREPARE,
  8965.                                                         (MPARAM)pDragTransfer,
  8966.                                                         (MPARAM)NULL);
  8967.                } else {
  8968.                   somPrintf("Source does not want prepared\n");
  8969.                }
  8970.                /* See if either we did not need to send a RENDERPREPARE, or
  8971.                 * we have successfully done so...
  8972.                 */
  8973.  
  8974.                if (flPrepared)
  8975.                {
  8976.                   somPrintf("not prepared\n");
  8977.                   /* Tell the source object where to put the file.
  8978.                    */
  8979.                   flRendering = (BOOL)DrgSendTransferMsg(pDragItem->hwndItem,
  8980.                                                          DM_RENDER,
  8981.                                                          (MPARAM)pDragTransfer,
  8982.                                                          (MPARAM)NULL);
  8983.                   if (!flRendering)
  8984.                   {
  8985.                      /* The partner object did not render, so delete
  8986.                       * the object we just created.
  8987.                       * or we could add code here to directly open the source as
  8988.                       * a file and work with it, or what ever we like.
  8989.                       */
  8990.  
  8991.                      _wpFree(ObjectBeingDragged);
  8992.                      somPrintf("not rendering, we are deleting the object we just created\n");
  8993.                   } else {
  8994.                      somPrintf("rendering\n");
  8995.                   }
  8996.                }
  8997.                else
  8998.                {
  8999.                   somPrintf("Our partner wanted us to send him a prepare, and");
  9000.                   somPrintf("now has changed his mind about things..., ABORT\n");
  9001.  
  9002.                   /* Our partner wanted us to send him a prepare, and
  9003.                    * now has changed his mind about things...
  9004.                    * We cannot even send him an end conversation, as
  9005.                    * we do not know that the hwnd is any good.
  9006.                    *
  9007.                    * For now, we will treat this as an error.
  9008.                    */
  9009.                   mr = (MRESULT)RC_DROP_ERROR;
  9010.                }
  9011.             } else {
  9012.               somPrintf("ObjectBeingDragged has NOT been successfully allocated\n");
  9013.             }
  9014.             if (flRendering)
  9015.             {
  9016.                mr = RC_DROP_RENDERING;
  9017.             }
  9018.             else
  9019.             {
  9020.                DrgDeleteStrHandle( pDragTransfer->hstrRenderToName );
  9021.                DrgFreeDragtransfer( pDragTransfer );
  9022.             }
  9023.          }
  9024.       } else {
  9025.          somPrintf("Not an OS2FILE rendering method\n");
  9026.       }
  9027.  
  9028.         } /* endif */
  9029.  
  9030.       } /* for */
  9031.     } else {
  9032.        somPrintf("we are trying to drop onto ourselves, not allowed\n");
  9033.     } /* endif */
  9034.   } else {
  9035.      somPrintf("LOCKED, drop is disallowed\n");
  9036.   } /* endif */
  9037.  
  9038.   return((MRESULT) NULL);
  9039.  
  9040. }
  9041.  
  9042. A partial sample _wpDrop accepting a non-Workplace Object, specifically an OS/2 
  9043. file. :efigdesc. 
  9044.  
  9045.  
  9046. ΓòÉΓòÉΓòÉ 15.7. Building a Workplace Shell Application ΓòÉΓòÉΓòÉ
  9047.  
  9048. As already mentioned, an application that exploits the Workplace Shell consists 
  9049. of a number of objects on the desktop or in folders, which interact with one 
  9050. another to carry out operations as requested by the user. The implementation of 
  9051. the Workplace Shell under OS/2 V2.0 causes all Workplace Shell objects to run 
  9052. in a single process, under the control of the Workplace Shell itself. It is 
  9053. therefore possible for an error in a Workplace Shell to terminate the Workplace 
  9054. Shell process, and all objects currently open under the control of that 
  9055. process. While the Workplace Shell automatically restarts itself and its open 
  9056. objects, it is recommended for reasons of performance that applications 
  9057. carrying out lengthy processing such as database or remote system access should 
  9058. be implemented using multiple processes. Other processes in the system are not 
  9059. affected if the Workplace Shell process terminates, and become available to the 
  9060. user as soon as the shell restarts itself, without the need to reload 
  9061. application code, reinitialize communications links, etc. 
  9062.  
  9063. For example, a database query application that searches a database for customer 
  9064. records and displays these in a Workplace Shell folder may be composed of two 
  9065. processes, each with multiple threads, as shown in -- Reference somapp not 
  9066. found --.. 
  9067.  
  9068. Therequesterportionoftheapplication ,whichallowstheusertoenteraquery 
  9069. ,andwhichdisplaystheresultsonthescreen ,isimplementedasaWorkplaceShellobject 
  9070. ,runningunderthecontroloftheWorkplaceShellprocess 
  9071. .Theprimarythreadinthisprocesscarriesouttheinteractionwiththeenduser 
  9072. ,whileasecondarythreadiscreatedtohandlecommunicationbetweenprocesses .
  9073.  
  9074. The second process acts as a database server, and is created by the first 
  9075. process when the application is started. The server process has a primary 
  9076. thread that accepts requests from the requester in the Workplace Shell process, 
  9077. and a number of secondary threads that actually perform the database access. 
  9078.  
  9079. If an errant object or application were to cause the Workplace Shell to 
  9080. terminate, the requester threads would be terminated. However, the server 
  9081. process would not be terminated, and communication with the requester could be 
  9082. re-established simply by having the requester initiate one of the standard 
  9083. interprocess communication mechanisms described in OS/2 2.1 Volume 4: Writing 
  9084. Applications, Chapter 10, "Multitasking Considerations". 
  9085.  
  9086.  
  9087. ΓòÉΓòÉΓòÉ 15.8. Debugging ΓòÉΓòÉΓòÉ
  9088.  
  9089. SOM provides several facilities to aid in debugging SOM and WPS applications. 
  9090. These facilities are designed around a replaceable procedure called 
  9091. SOMOutCharRoutine, which normally writes output to the stdout logical device. 
  9092.  
  9093. It is not practical to capture stdout and the information that SOM and WPS is 
  9094. providing when debugging WPS objects, because objects are implemented as DLLs. 
  9095. Instead the object must replace the SOMOutCharRoutine to send the output to a 
  9096. place where you can easily deal with it. 
  9097.  
  9098. Additionally the OS/2 Programmer's Toolkit provides an interactive debugging 
  9099. tool, the Kernel Debugger. For further information on using the Toolkit Kernel 
  9100. Debugger to debug DLLs, please refer to the OS/2 Programmer's Toolkit. 
  9101.  
  9102.  
  9103. ΓòÉΓòÉΓòÉ 15.8.1. Replacing SOM's SOMOutCharRoutine ΓòÉΓòÉΓòÉ
  9104.  
  9105. Sample .CSC File Definition for Overriding the SOMOutCharRoutine shows a simple 
  9106. replacement procedure that sends the output to the COM1: serial port. To 
  9107. actually replace the SOMCharOutRoutine it is necessary to add a line of code to 
  9108. the initialization portion of your object. This is shown in Sample .C File 
  9109. Definition for Overriding the SOMOutCharRoutine. Note that it is best to add a 
  9110. command to your STARTUP.CMD file to set up the COM1: serial port. A sample 
  9111. portion of a STARTUP.CMD is shown in Sample STARTUP.CMD File Definition. 
  9112.  
  9113. You can now use another computer to view the information that is generated by 
  9114. the SOM runtime as you manipulate your object. 
  9115.  
  9116. The additional computer should be connected from its serial port, normally 
  9117. COM1:, to the first computer by means of a NULL modem cable. This is a 
  9118. specialized serial cable where the transmit and receive conductors are crossed 
  9119. over to allow the transmission from one serial port to be received by the 
  9120. other. 
  9121.  
  9122. It is then a matter of registering your object and running an ASCII terminal 
  9123. emulator program on the additional computer to view the information. 
  9124.  
  9125.     .
  9126.     .
  9127.     .
  9128. #
  9129. # Passthru a debug message box to the .ih file
  9130. # (for inclusion in the .c file)
  9131. #
  9132. passthru: C.ih, after;
  9133.  
  9134. #include <wppgm.h>
  9135. #include <wppgmf.h>
  9136. #include <stdio.h>
  9137.  
  9138. // force SOM to output all debug information to the Communications Port 1
  9139.  
  9140. int myReplacementForSOMOutCharRoutine (char c)
  9141. {
  9142. static FILE *fdebug = NULL;
  9143.  
  9144. if (!fdebug) {
  9145.   fdebug = fopen("COM1","w");
  9146.  
  9147.   if (!fdebug) return 0;     /* failed to open COM1: */
  9148.   }
  9149. fputc(c,fdebug);
  9150. fflush(fdebug);
  9151.  
  9152. return 1;
  9153. }
  9154. endpassthru;
  9155.     .
  9156.     .
  9157.     .
  9158.  
  9159. Sample .CSC File Definition for Overriding the SOMOutCharRoutine 
  9160.  
  9161.     .
  9162.     .
  9163.     .
  9164.     /* Set up the debug and tracing ... */
  9165.  
  9166.     /* Produce a message each time a method is entered */
  9167.     SOM_TraceLevel=2;
  9168.  
  9169.     /* Replace the default routine with this object's new one */
  9170.     SOMOutCharRoutine = myReplacementForSOMOutCharRoutine;
  9171.     .
  9172.     .
  9173.     .
  9174.  
  9175. Sample  . C  File  Definition  for  Overriding  the  SOMOutCharRoutine 
  9176.  
  9177. /* My STARTUP.CMD */
  9178. MODE COM1 9600,n,8,1
  9179. /* and whatever else I like to have in here */
  9180.     .
  9181.     .
  9182.     .
  9183. exit 0
  9184.  
  9185. Sample  STARTUP . CMD  File  Definition 
  9186.  
  9187.  
  9188. ΓòÉΓòÉΓòÉ 15.8.2. A Sample ASCII Terminal Emulator for Debugging Use ΓòÉΓòÉΓòÉ
  9189.  
  9190. The PM terminal program that can be found in the Productivity folder can be 
  9191. used to receive and display the information from the SOM runtime about the 
  9192. computer to be debugged. The following steps detail how to create and use a 
  9193. custom emulator session. 
  9194.  
  9195.  
  9196. ΓòÉΓòÉΓòÉ 15.8.2.1. Creating a Custom Emulator Session ΓòÉΓòÉΓòÉ
  9197.  
  9198. The following steps detail how to create a PM Terminal session suitable for 
  9199. remote debugging use. 
  9200.  
  9201.    1. Open OS/2 System and select the Productivity Folder 
  9202.    2. Select PM Terminal 
  9203.    3. From the Session pulldown, select Add 
  9204.    4. Enter a comment, for example "Remote SOM Debug Session" 
  9205.    5. You should have the default settings as shown in Parameters and Settings 
  9206.       for the Remote Terminal, on the Add Session panel 
  9207.    6. Select the ADD pushbutton to add the new session 
  9208.  
  9209.   ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
  9210.   Γöé Parameters and Settings for the Remote Terminal             Γöé
  9211.   Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  9212.   Γöé PARAMETER              Γöé SETTING              Γöé
  9213.   Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  9214.   Γöé Terminal emulation profile     Γöé ANSI 3.64             Γöé
  9215.   Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  9216.   Γöé Connection path profile       Γöé ACDI - Hardwire          Γöé
  9217.   Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  9218.   Γöé System environment profile     Γöé Default Environment        Γöé
  9219.   Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  9220.   Γöé File transfer profile        Γöé Character             Γöé
  9221.   ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
  9222.  
  9223.  
  9224. ΓòÉΓòÉΓòÉ 15.8.2.2. Using the Emulator Session ΓòÉΓòÉΓòÉ
  9225.  
  9226. After you have created an instance of your object, start the session you 
  9227. created above. If the connection is broken at any time, for example you closed 
  9228. and reopened the object, then from the File pulldown select Connect. 
  9229.  
  9230.  
  9231. ΓòÉΓòÉΓòÉ 15.8.3. SOM Provided Macros for Debugging ΓòÉΓòÉΓòÉ
  9232.  
  9233. System Object Model provides a number of macros for the purposes of debugging 
  9234. objects. These are: 
  9235.  
  9236.  SOM_TestC           Evalutes a Boolean expression. If it is true, then 
  9237.                      execution continues; otherwise SOM_Error is invoked. 
  9238.  SOM_WarnMsg         Writes out a warning message depending on the setting of 
  9239.                      the SOM_WarnLevel variable. 
  9240.  SOM_Assert          Evaluates a Boolean assertion. If this fails then 
  9241.                      SOM_Error is invoked with a user supplied error code. 
  9242.  SOM_Expect          Evaluates a Boolean assertion. If this fails then SOM_Warn 
  9243.                      is invoked. 
  9244.  somPrintf           SOM's implementation of the "C" printf function. 
  9245.  
  9246.  For more detailed information please refer to System Object Model Guide and 
  9247.  Reference. 
  9248.  
  9249.  
  9250. ΓòÉΓòÉΓòÉ 15.9. Sample Code and Application ΓòÉΓòÉΓòÉ
  9251.  
  9252. The sample Workplace Objects used as examples in this chapter are included on a 
  9253. diskette supplied with this document, as well as the main program listings 
  9254. appearing in Source Code for the PWFolder and PWFinanceFile objects. The two 
  9255. main code examples are pwFolder and pwFinanceFile. 
  9256.  
  9257.  
  9258. ΓòÉΓòÉΓòÉ 15.9.1. pwFolder ΓòÉΓòÉΓòÉ
  9259.  
  9260. The pwFolder is a Workplace Object that has been sub-classed from the Workplace 
  9261. Folder class and adds a lock feature. This lock feature prevents the user from 
  9262. accessing the folder when it is in the locked state. 
  9263.  
  9264. The pwFolder demonstrates adding a method to a context menu and writing your 
  9265. own methods, as well as drag and drop processing. 
  9266.  
  9267.  
  9268. ΓòÉΓòÉΓòÉ 15.9.2. pwFinanceFile ΓòÉΓòÉΓòÉ
  9269.  
  9270. The pwFinanceFile is a Workplace Object that has been subclassed from the 
  9271. wpDataFile class and also adds a lock feature, in a very similar manner to the 
  9272. pwFolder. 
  9273.  
  9274. The pwFinanceFile demonstrates the following: 
  9275.  
  9276.    o  Adding a method to a context menu 
  9277.  
  9278.    o  Filtering menu items in a context menu 
  9279.  
  9280.    o  Writing your own methods 
  9281.  
  9282.    o  Drag and drop progressing, including: 
  9283.  
  9284.         -  Only accepting source objects which are descended from the same 
  9285.            pwFinanceFile class 
  9286.  
  9287.         -  Accepting an OS/2 file as a source, and converting it to a Workplace 
  9288.            Object 
  9289.  
  9290.         -  Multiple rendering methods 
  9291.  
  9292.    o  Adding an object view 
  9293.  
  9294.    o  Determining the file name of a wpDataFile object 
  9295.  
  9296.  
  9297. ΓòÉΓòÉΓòÉ 15.10. Summary ΓòÉΓòÉΓòÉ
  9298.  
  9299. The OS/2 Version 2.0 Workplace Shell provides an object-oriented user interface 
  9300. to the operating system, and provides an object-oriented application layer on 
  9301. top of Presentation Manager, through its implementation of the system object 
  9302. model. An application that exploits the facilities of the Workplace Shell 
  9303. consists of a number of objects, which are manipulated on the Workplace Shell 
  9304. desktop by the user, in order to carry out the required tasks. 
  9305.  
  9306. Workplace Shell objects conform to "standard" object-oriented principles in 
  9307. that they are grouped into object classes, have instance data, and contain 
  9308. methods which perform the required tasks and operate upon the instance data. 
  9309. Workplace Shell object classes may inherit data and methods from their parent 
  9310. class, in accordance with the object-oriented concept of inheritance. A class 
  9311. may add additional data items or new methods to perform actions not handled by 
  9312. its parent class, or may override existing methods to handle actions in a 
  9313. different manner. 
  9314.  
  9315. An object class is defined using a class definition file, which defines the 
  9316. parent hierarchy for the object, its data items and its methods. The class 
  9317. definition file is used as input to the SOM Precompiler, which uses the file to 
  9318. produce a number of source code files and header files. The source code is 
  9319. edited by the programmer to add the application logic for each method. It is 
  9320. then compiled using a normal C compiler, and link edited to produce a dynamic 
  9321. link library that implements the object class. An object class may make use of 
  9322. operating system and Presentation Manager resources during its execution. 
  9323.  
  9324. Workplace Shell objects behave in a similar manner to windows under 
  9325. Presentation Manager; object classes are registered to the Workplace Shell, and 
  9326. individual instances of an object class are created, opened, closed and 
  9327. destroyed by the user or by other objects in the system. The major difference 
  9328. between a window under Presentation Manager and an object under the Workplace 
  9329. Shell is that Workplace Shell objects are persistent; that is, they exist for 
  9330. longer than a single application execution. Once created, a Workplace Shell 
  9331. object remains in existence until it is explicitly destroyed. 
  9332.  
  9333.  
  9334. ΓòÉΓòÉΓòÉ 16. Direct Manipulation ΓòÉΓòÉΓòÉ
  9335.  
  9336. Direct manipulation of icons on the Presentation Manager desktop in order to 
  9337. carry out processing tasks has been possible since the first release of 
  9338. Presentation Manager in OS/2 Version 1.1, but only in Version 1.3 was a 
  9339. standard method introduced for implementing such function.  Previously, each 
  9340. programmer needed to devise a set of protocols, and write code in every 
  9341. application to handle all the mouse messages and interaction between windows 
  9342. that may have been needed. 
  9343.  
  9344. OS/2 Version 1┬╖3 introduced some standards for coding direct manipulation 
  9345. operations, in the form of new message classes (the DM_xxxx messages), and 
  9346. standard protocols known as rendering mechanisms, which are used to communicate 
  9347. required information for commonly used direct manipulation operations. This 
  9348. support is continued in OS/2 V2.0, and is of increased importance since the 
  9349. Workplace Shell itself makes extensive use of direct manipulation. 
  9350. Applications that use direct manipulation are therefore more likely to be 
  9351. written under Version 2.0, either to interact with one another or to make use 
  9352. of Workplace Shell facilities such as printer objects or the shredder. 
  9353.  
  9354. This chapter discusses the use of direct manipulation in a program, covering 
  9355. the major messages and data structures involved, and the use of the standard 
  9356. rendering mechanisms.  Examples of the use of these messages and data 
  9357. structures are given, along with guidance on implementing a private rendering 
  9358. mechanism to meet the needs of a particular application. 
  9359.  
  9360.  
  9361. ΓòÉΓòÉΓòÉ 16.1. Direct Manipulation Basics ΓòÉΓòÉΓòÉ
  9362.  
  9363. It might appear that dragging an icon from one window and dropping it onto 
  9364. another is straightforward, but on closer consideration it proves to be 
  9365. somewhat more complex. Consider the simple action of dragging an icon 
  9366. representing a customer from one container window to another, the intention 
  9367. being to move the customer from one branch of the business (represented by the 
  9368. first container) to another (the second container window). The following steps 
  9369. are required: 
  9370.  
  9371.    1. The program owning the first container (hereafter called the source 
  9372.       program) must determine which customer the user wishes to move (hereafter 
  9373.       known as the dragitem). 
  9374.  
  9375.    2. The source program must decide on an icon or bitmap to represent the 
  9376.       customer as the user drags the customer around the screen. 
  9377.  
  9378.    3. The source program must package a number of items of information to 
  9379.       travel with the icon, so that potential target windows may decide whether 
  9380.       or not they will allow the item to be dropped on them. 
  9381.  
  9382.    4. As the icon passes outside the container to other areas, its appearance 
  9383.       must be constantly updated to indicate to the user whether a drop is 
  9384.       allowed. 
  9385.  
  9386.    5. When the icon reaches a potential target window, the program owning the 
  9387.       target window (hereafter known as the target) must access the information 
  9388.       about the dragged item to decide whether it will allow the item to be 
  9389.       dropped.  At this point, the rendering mechanism used to convey this 
  9390.       information becomes significant, since both the source and target must be 
  9391.       able to understand the mechanism. 
  9392.  
  9393.    6. Once a drop has occurred, the target window must decide the form in which 
  9394.       it wishes to receive the dropped object (if more than one form is 
  9395.       supported by both source and target), and inform the source program 
  9396.       accordingly. 
  9397.  
  9398.    7. The source program must make the data representing the customer available 
  9399.       to the target program.  Since the source and target programs may not 
  9400.       necessarily run in the same process, this may not be trivial. Again, the 
  9401.       rendering mechanism to be used becomes significant. 
  9402.  
  9403.    8. The source must inform the target that the data is ready. 
  9404.  
  9405.    9. The target must access and retrieve the data. 
  9406.  
  9407.   10. The source must delete its own copy (since the operation is a "move" 
  9408.       operation). 
  9409.  
  9410.   11. The target must display the new customer object in its own container 
  9411.       window, in the location at which it was dropped. 
  9412.  
  9413.  While this appears extremely complex, much of the necessary work is done by 
  9414.  Presentation Manager for a Presentation Manager application; for a Workplace 
  9415.  Shell object, even more of the necessary function is automated by the 
  9416.  Workplace Shell.  The remainder of this chapter will describe the steps 
  9417.  necessary for a Presentation Manager application and/or a Workplace Shell 
  9418.  object to exploit drag/drop functionality. 
  9419.  
  9420.  
  9421. ΓòÉΓòÉΓòÉ 16.2. Significant Events ΓòÉΓòÉΓòÉ
  9422.  
  9423. There are a number of significant events that occur during a direct 
  9424. manipulation operation, and which must be communicated to the source and/or 
  9425. target of the operation.  These are as follows: 
  9426.  
  9427.    o  Initiation of the drag operation, which must be communicated to the 
  9428.       source so that it can initialize data structures with information 
  9429.       relating to the dragitem. 
  9430.  
  9431.    o  Dragging the object over a potential target, which must be communicated 
  9432.       to the target so that the target can determine whether a drop operation 
  9433.       is valid. 
  9434.  
  9435.    o  Dropping the object over a target, which must be communicated to the 
  9436.       target so that it may decide the form in which it wishes the dragitem 
  9437.       data to be passed, and allocate any necessary resources to receive the 
  9438.       data. 
  9439.  
  9440.    o  Transferring the information between the source and the target to 
  9441.       complete the overall direct manipulation sequence. 
  9442.  
  9443.  Presentation Manager carries out much of the required notification of 
  9444.  drag/drop events using messages, which are passed to the source or target 
  9445.  windows as necessary during the drag/drop operation.  The required messages 
  9446.  are described in the OS/2 2.0 Programming Guide Volume II and their use is 
  9447.  discussed in Using Direct Manipulation. 
  9448.  
  9449.  In certain cases, the behavior of a Workplace Shell object participating in a 
  9450.  direct manipulation operation varies somewhat from that of a Presentation 
  9451.  Manager window.  This is due to the fact that the Workplace Shell implements 
  9452.  much of the required message handling itself, and directly invokes the 
  9453.  appropriate methods in the object.  Where the behavior of a Workplace Shell 
  9454.  object differs from that of a Presentation Manager window, this is noted in 
  9455.  the text. 
  9456.  
  9457.  
  9458. ΓòÉΓòÉΓòÉ 16.3. Rendering Mechanisms ΓòÉΓòÉΓòÉ
  9459.  
  9460. Rendering mechanisms are the means by which the source and target of a 
  9461. drag/drop operation determine the data type of the dragitem and the format of 
  9462. the information to be exchanged. 
  9463.  
  9464. While the precise sequence of events that takes place after a drop has occurred 
  9465. is dependent upon the application, a number of standard rendering mechanisms 
  9466. have been defined to enable diverse applications to engage in direct 
  9467. manipulation with one another.  These standard rendering mechanisms are used by 
  9468. various components of OS/2, as well as being available for use by applications. 
  9469.  
  9470. Three standard rendering mechanisms are provided by Presentation Manager and 
  9471. are documented in the OS/2 2.0 Programming Guide Volume II: 
  9472.  
  9473.  DRM_PRINT      This rendering mechanism is designed for applications that wish 
  9474.                 to provide printing facilities via direct manipulation, by 
  9475.                 allowing the user to drag items from the application and drop 
  9476.                 them on one of the Workplace Shell printer objects. 
  9477.  
  9478.                 It is a very simple mechanism.  When an object is dropped on a 
  9479.                 printer object, the printer object sends a DM_PRINTOBJECT 
  9480.                 message, one parameter of which gives the name of the print 
  9481.                 queue represented by that printer object.  It is then the 
  9482.                 responsibility of the source window to print the relevant data 
  9483.                 to the specified queue. 
  9484.  
  9485.                 Note that in OS/2 Version 1┬╖3, the DM_PRINT message was used 
  9486.                 for this purpose, rather than the DM_PRINTOBJECT message. 
  9487.  DRM_OS2FILE    This rendering mechanism is intended for applications that wish 
  9488.                 to allow the dragging and dropping of file objects between 
  9489.                 windows or folders on the desktop.  Such applications include 
  9490.                 the File Manager in OS/2 Version 1┬╖3, or the Drives objects in 
  9491.                 OS/2 V2.0. 
  9492.  
  9493.                 With this mechanism, all information about the source file may 
  9494.                 be contained in the fields of the DRAGITEM structure, so it is 
  9495.                 not necessary for a protracted conversation to take place 
  9496.                 between source and target windows.  In the simplest case, the 
  9497.                 target can complete the operation using only this information 
  9498.                 with no further involvement from the source window, though this 
  9499.                 rendering mechanism does allow for more interaction between the 
  9500.                 two windows should this be useful. 
  9501.  DRM_DDE        The DDE rendering mechanism is intended for applications in 
  9502.                 which drag/drop actions will be used to set up DDE links 
  9503.                 between windows.  The DDE then proceeds according to standard 
  9504.                 DDE protocols. 
  9505.  Further rendering mechanisms may be devised and documented for use by a 
  9506.  particular user's applications.  The creation and use of rendering mechanisms 
  9507.  is discussed in Using Rendering Mechanisms. 
  9508.  
  9509.  
  9510. ΓòÉΓòÉΓòÉ 16.4. Data Structures Used in Drag/Drop ΓòÉΓòÉΓòÉ
  9511.  
  9512. Three structures contain the data that travels with an item while it is being 
  9513. dragged; these are the DRAGINFO, DRAGITEM and DRAGIMAGE structures.  A further 
  9514. structure, the DRAGTRANSFER structure, is used to transfer information between 
  9515. source and target windows after a drop has occurred. 
  9516.  
  9517. Details of the fields within these structures can be found in the IBM OS/2 
  9518. Version 2.0 Presentation Manager Reference, and full descriptions will not be 
  9519. given here.  However, the following sections describe in general terms the kind 
  9520. of data the structures contain, and particularly certain critical fields. 
  9521.  
  9522.  
  9523. ΓòÉΓòÉΓòÉ 16.4.1. The DRAGINFO Structure ΓòÉΓòÉΓòÉ
  9524.  
  9525. The DRAGINFO structure contains information about the overall drag operation, 
  9526. which may consist of one or more dragitems.  Information in the DRAGINFO 
  9527. structure determines the source and type of the drag operation, and provides 
  9528. pointers to one or more DRAGITEM structures which identify individual 
  9529. dragitems. 
  9530.  
  9531. The handle of the source window for the drag operation is contained in the 
  9532. DRAGINFO structure.  This handle enables a target window which receives the 
  9533. structure to initiate a conversation with the source window if necessary, in 
  9534. order to exchange information. 
  9535.  
  9536. The other item of note in the DRAGINFO structure is a field which identifies 
  9537. the type of drag operation that the user has selected.  For example, a value of 
  9538. DO_COPY means that the user is holding the Ctrl key down, which by convention 
  9539. means that a copy operation is required.  The DO_DEFAULT value means that a 
  9540. default drag operation is to be used because the user is not holding down any 
  9541. modifier key. 
  9542.  
  9543. The DRAGINFO structure contains a counter that specifies how many dragitems are 
  9544. involved in the current operation.  This counter is then used to access an 
  9545. array of pointers, also contained within the DRAGINFO structure, which 
  9546. reference individual DRAGITEM structures for each dragitem. 
  9547.  
  9548. Note that the DRAGINFO structure must be accessible not only to the source 
  9549. window that sets it up in the first place, but also to any potential target 
  9550. windows.  Since these windows may not be owned by the same process, the 
  9551. DRAGINFO structure must be allocated in shared memory.  In order that the 
  9552. structure be correctly allocated and easily accessible by the system in order 
  9553. to provide it to potential target windows, OS/2 allocates the DRAGINFO 
  9554. structure on the application's behalf, using the DrgAllocDraginfo() function. 
  9555. This function is called by the source window when it is notified of a drag 
  9556. operation by receiving a WM_BEGINDRAG message. 
  9557.  
  9558. For Workplace Shell objects, the Workplace Shell handles the allocation and 
  9559. initialization of the DRAGINFO structure.  The object itself is not required to 
  9560. take any action with respect to this structure. 
  9561.  
  9562.  
  9563. ΓòÉΓòÉΓòÉ 16.4.2. The DRAGITEM Structure ΓòÉΓòÉΓòÉ
  9564.  
  9565. The DRAGITEM structure contains information about an individual dragitem. A 
  9566. drag operation may include one or more dragitems, and a separate DRAGITEM 
  9567. structure is used for each.  The number of dragitems, and an array of pointers 
  9568. to the DRAGITEM structures, is contained in the DRAGINFO structure.  In 
  9569. conjunction with the information contained in the DRAGINFO structure, the 
  9570. DRAGITEM structure provides the information required by a potential or actual 
  9571. target window, to determine whether a drop operation is valid for the dragitem. 
  9572.  
  9573. Several of the fields in the DRAGITEM structure are defined as being of type 
  9574. HSTR.  These fields refer to ordinary null-terminated character strings that 
  9575. are given string handles by Presentation Manager when the DrgAddStrHandle() 
  9576. function is called.  It is the string handles that are stored in the DRAGITEM 
  9577. structure; the strings themselves are stored by Presentation Manager and may be 
  9578. accessed by any other process that has access to the string handle, using the 
  9579. DrgQueryStrName() function. 
  9580.  
  9581. For Presentation Manager windows, the DRAGITEM structure is normally allocated 
  9582. by the source of the drag/drop operation as a local variable, since it only 
  9583. persists for the duration of the operation.  For Workplace Shell objects, the 
  9584. structure is allocated by the Workplace Shell and a pointer to it is passed to 
  9585. the object by the Workplace Shell when it invokes the object's 
  9586. _wpFormatDragItem method when the drag is initiated. 
  9587.  
  9588. A number of fields in the DRAGITEM structure are of primary importance; these 
  9589. fields are described in the following sections. 
  9590.  
  9591.  
  9592. ΓòÉΓòÉΓòÉ 16.4.2.1. ulItemID ΓòÉΓòÉΓòÉ
  9593.  
  9594. This field contains a value provided by the source window, which uniquely 
  9595. identifies the dragitem.  For example, the value might be a listbox index 
  9596. value, a customer number, or any other value that is unique and meaningful to 
  9597. the source window.  The reason for having this identification is that later in 
  9598. the drag/drop processing, the target window may need to ask the source window 
  9599. for more information about the dragged item.  The identifier can then be used 
  9600. to identify the item concerned. 
  9601.  
  9602.  
  9603. ΓòÉΓòÉΓòÉ 16.4.2.2. hstrType and hstrRMF ΓòÉΓòÉΓòÉ
  9604.  
  9605. These values refer to character strings containing details of the type of data 
  9606. represented by the dragitem, and the rendering mechanisms and formats that the 
  9607. source is able support for the item.  The types correspond to the file type 
  9608. extended attribute, and are identified by names of the form DRT_xxxx; for 
  9609. example, DRT_TEXT for plain text, or DRT_BITMAP for bitmap data. 
  9610.  
  9611. The rendering mechanism is specified in the hstrRMF field, and may refer to any 
  9612. of the standard mechanisms described in Rendering Mechanisms, identified by the 
  9613. names DRM_PRINT, DRM_DISCARD, DRM_OS2FILE and DRM_DDE, or to any user-defined 
  9614. rendering mechanism for which a similar name should be defined.  More than one 
  9615. rendering mechanism can be specified; for example, a program that allows the 
  9616. dragging of files may allow the file to be moved or copied to another 
  9617. directory, or to be printed by being dropped on a printer object.  In this case 
  9618. the program would include the names of both the Print and OS/2 File rendering 
  9619. mechanisms in its hstrRMF string, allowing the target window to decide which is 
  9620. more suitable. 
  9621.  
  9622. The format specifications, which are also contained in the hstrRMF field, 
  9623. inform a target window of the data formats supported by the dragitem for each 
  9624. of its supported rendering mechanisms.  Data format names use the convention 
  9625. DRF_xxxx. 
  9626.  
  9627. To illustrate the use of format specifications and rendering mechanisms, 
  9628. consider a spreadsheet program that allows the user to drag an icon 
  9629. representing a particular spreadsheet; the user may choose to drag the data 
  9630. into a word-processor, into another spreadsheet, or onto a printer object for 
  9631. printing. For dragging the file to another spreadsheet or to a word-processing 
  9632. document, the DRM_OS2FILE rendering mechanism is appropriate but for dragging 
  9633. to a printer object, the DRM_PRINT mechanism is required.  In the case where 
  9634. the target is the printer or the word-processing document, clearly the required 
  9635. format for the data is text, but in the case of a drag to another spreadsheet 
  9636. it would be more convenient to have the numerical data and the cell 
  9637. relationships transferred too, so a different data format should be used, 
  9638. perhaps SYLK. 
  9639.  
  9640. The dragitem therefore needs to indicate that it supports the following 
  9641. rendering mechanism/data format combinations: 
  9642.  
  9643.    o  DRM_OS2FILE with DRF_TEXT 
  9644.  
  9645.    o  DRM_PRINT with DRF_TEXT 
  9646.  
  9647.    o  DRM_OS2FILE with DRF_SYLK. 
  9648.  
  9649.  The hstrRMF string provides a syntax for defining this in a fairly 
  9650.  straightforward way.  Complete details are given in the OS/2 2.0 Programming 
  9651.  Guide Volume II but, for the above example, the hstrRMF string is as follows: 
  9652.  
  9653.   <DRM_OS2FILE,DRF_TEXT>,<DRM_PRINT,DRF_TEXT>,<DRM_OS2FILE,DRF_SYLK>
  9654.  
  9655.  This can be expressed slightly more concisely as: 
  9656.  
  9657.   (DRM_OS2FILE,DRM_PRINT)x(DRF_TEXT),<DRM_OS2FILE,DRF_SYLK>
  9658.  
  9659.  Here the first two bracketed items, connected with an "x", indicate that all 
  9660.  possible pairs made up of one from the first bracket and one from the second, 
  9661.  are implied.  This notation is very useful in more complex examples, where it 
  9662.  can save the programmer from having to enumerate all possible combinations in 
  9663.  the string. 
  9664.  
  9665.  
  9666. ΓòÉΓòÉΓòÉ 16.4.2.3. hstrContainerName, hstrSourceName, hstrTargetName ΓòÉΓòÉΓòÉ
  9667.  
  9668. The meaning of these three fields depends on the rendering mechanism to be 
  9669. used; with some rendering mechanisms, certain fields are not needed.  They 
  9670. apply most directly to the DRM_OS2FILE mechanism where they are used to define 
  9671. the source directory, source file name, and a suggested target filename (which 
  9672. may be overridden by the target window if it so chooses). 
  9673.  
  9674.  
  9675. ΓòÉΓòÉΓòÉ 16.4.3. The DRAGIMAGE Structure ΓòÉΓòÉΓòÉ
  9676.  
  9677. This structure, as its name suggests, contains information about the actual 
  9678. image to be displayed on the screen as the user performs the drag operation. 
  9679. In this structure, the source window specifies the icon or bitmap to be used, 
  9680. whether it is to be rescaled, and the coordinates of the hot spot. 
  9681.  
  9682.  
  9683. ΓòÉΓòÉΓòÉ 16.4.4. The DRAGTRANSFER Structure ΓòÉΓòÉΓòÉ
  9684.  
  9685. This structure is passed with a DM_RENDER message, from the target to the 
  9686. source window, after a drop has occurred.  It allows the target window to 
  9687. inform the source of several important things.  For example, where the source 
  9688. supports several different rendering mechanisms and/or formats, the target can 
  9689. specify which of these it wishes to use.  Similarly, if the source supports 
  9690. both copy and move operations, the target can specify which it will use by 
  9691. means of the usOperation field of this structure. 
  9692.  
  9693. Another important field is hstrRenderToName.  This tells the source window 
  9694. where to place the data, so that the target will know where to find it. The 
  9695. precise interpretation of this depends on the rendering mechanism; for example, 
  9696. in the case of the DRM_OS2FILE rendering mechanism, it contains the fully 
  9697. qualified name that the file is to be given at its destination. Where the 
  9698. transfer of information between source and target window is a simple memory 
  9699. transfer, this field may be used to contain the name of a named shared memory 
  9700. object into which the source is to place the data. 
  9701.  
  9702.  
  9703. ΓòÉΓòÉΓòÉ 16.5. Using Direct Manipulation ΓòÉΓòÉΓòÉ
  9704.  
  9705. The following sections use an example to illustrate the way in which direct 
  9706. manipulation can be used within a Presentation Manager application or a 
  9707. Workplace Shell  object. The example consists of a Customer program which reads 
  9708. and displays customer details.  Each customer is displayed as an object in a 
  9709. container window. 
  9710.  
  9711. The other component of the example is a Telephone program, which accepts 
  9712. customer information from the Customer program via drag/drop, and automatically 
  9713. dials the customer's telephone number.  The Telephone program communicates with 
  9714. the Customer program using a private rendering mechanism defined by the 
  9715. application.  This rendering mechanism uses shared memory, and is identified by 
  9716. the name DRM_SHAREMEM.  The rendering mechanism is explained in detail in 
  9717. Implementing a Private Rendering Mechanism. 
  9718.  
  9719. The example uses Presentation Manager windows as both the source and target for 
  9720. the drag/drop operation, since this enables a description of the complete set 
  9721. of steps required to complete the operation.  For Workplace Shell objects, 
  9722. certain steps are handled automatically by the Workplace Shell itself, and a 
  9723. Workplace Shell object class is therefore not required to carry out these 
  9724. steps.  Where a particular step is automated by the Workplace Shell, this is 
  9725. noted in the discussion. 
  9726.  
  9727.  
  9728. ΓòÉΓòÉΓòÉ 16.5.1. Initiating a Drag Operation ΓòÉΓòÉΓòÉ
  9729.  
  9730. A drag operation is initiated by the source window or object.  When the user 
  9731. starts the drag operation by pressing and holding down mouse button 2, 
  9732. Presentation Manager  passes a WM_BEGINDRAG message to the window or object 
  9733. that is currently under the mouse pointer. In the case of a Presentation 
  9734. Manager window, the window procedure for that window may process the 
  9735. WM_BEGINDRAG message in order to initialize the DRAGINFO and DRAGITEM 
  9736. structures, and start the drag operation.  A Workplace Shell object is notified 
  9737. of a drag initiation by the Workplace Shell itself, which invokes the object's 
  9738. _wpFormatDragItem method. 
  9739.  
  9740. The initialization of a drag operation from a container window is shown in Drag 
  9741. Initiation From a Container Window. 
  9742.  
  9743. PCONTRECORD  pCRec;
  9744. PCNRDRAGINIT pcnrInit;
  9745. PDRAGINFO   pDInfo;
  9746. DRAGITEM   DItem;
  9747. DRAGIMAGE   DImage;
  9748.  
  9749. APIRET    rc;
  9750.  :
  9751.  :
  9752. case WM_CONTROL:
  9753.    switch (SHORT2FROMMP(mp1))
  9754.       {
  9755.       case CN_INITDRAG:
  9756.          pcnrInit =           /* Get container data   */
  9757.           (PCNRDRAGINIT)mp2;
  9758.          pCRec = (PCONTRECORD)pcnrInit->pRecord;
  9759.  
  9760.          if (pCRec == NULL)       /* If no item selected  */
  9761.           return(0);          /* Return         */
  9762.  
  9763.          pDInfo = DrgAllocDraginfo(1);  /* Allocate DRAGINFO   */
  9764.  
  9765.          DItem.hwndItem = hWnd;     /* Initialize DRAGITEM  */
  9766.          DItem.ulItemID = (ULONG)pCRec;
  9767.          DItem.hstrType =
  9768.           DrgAddStrHandle("DRT_CUSTOMER");
  9769.          DItem.hstrRMF =
  9770.           DrgAddStrHandle("(DRM_SHAREMEM,DRM_PRINT)x(DRF_TEXT)");
  9771.          DItem.fsControl = 0;
  9772.          DItem.fsSupportedOps = DO_COPYABLE | DO_MOVEABLE;
  9773.  
  9774.          rc = DrgSetDragItem(pDInfo,   /* Set item in DRAGINFO  */
  9775.              &DItem,         /* Pointer to DRAGITEM  */
  9776.              sizeof(DItem),     /* Size of DRAGITEM    */
  9777.              0);           /* Index of DRAGITEM   */
  9778.  
  9779.          DImage.cb = sizeof(DRAGIMAGE); /* Initialize DRAGIMAGE  */
  9780.          DImage.cptl = 0;        /* Not a polygon     */
  9781.          DImage.hImage = hPostIcon;   /* Icon handle for drag  */
  9782.          DImage.fl = DRG_ICON;      /* Dragging an icon    */
  9783.          DImage.cxOffset = 0;      /* No hotspot       */
  9784.          DImage.cyOffset = 0;
  9785.  
  9786.          hDrop = DrgDrag(hWnd,      /* Initiate drag     */
  9787.               pDInfo,       /* DRAGINFO structure   */
  9788.               (PDRAGIMAGE)&DImage, /* DRAGIMAGE structure  */
  9789.               1,          /* Only one DRAGIMAGE   */
  9790.               VK_ENDDRAG,     /* End of drag indicator */
  9791.               NULL);        /* Reserved        */
  9792.  
  9793.          DrgFreeDragInfo(pDInfo);    /* Free DRAGINFO struct  */
  9794.          break;
  9795.  
  9796. Drag Initiation From a Container Window 
  9797.  
  9798. Another window class would perform these operations in response
  9799. to a WM_BEGINDRAG message, rather than a WM_CONTROL message with the
  9800. CN_INITDRAG indicator.
  9801. The code shown in Drag Initiation From a Container Window would form part of 
  9802. the window procedure for the owner of the container control, since it is this 
  9803. window that would receive the WM_CONTROL message from the container. 
  9804.  
  9805.  
  9806. ΓòÉΓòÉΓòÉ 16.5.1.1. Initializing Data Structures ΓòÉΓòÉΓòÉ
  9807.  
  9808. When a WM_CONTROL message is received from a container window, a pointer to a 
  9809. CNRDRAGINIT structure is passed in the second parameter to the WM_CONTROL 
  9810. message.  This structure contains a pointer to the item within the container 
  9811. that the user is attempting to drag.  If this pointer is NULL, the user has 
  9812. attempted a drag operation while no item in the container was selected.  In the 
  9813. current example, the drag operation is ignored and control is immediately 
  9814. returned to Presentation Manager. 
  9815.  
  9816. The source window then allocates a DRAGINFO structure using the 
  9817. DrgAllocDraginfo() function.  The DRAGITEM structure is initialized with the 
  9818. appropriate values, and its pointer is set in the DRAGINFO structure using the 
  9819. DrgSetDragItem() function. All interaction with the DRAGINFO structure is 
  9820. performed using Presentation Manager functions, avoiding the necessity for the 
  9821. source window procedure to address the DRAGINFO structure directly. 
  9822.  
  9823. The DRAGIMAGE structure is then initialized with the information relating to 
  9824. the icon that will be displayed under the mouse pointer during the drag 
  9825. operation. 
  9826.  
  9827. For a Workplace Shell object, the Workplace Shell itself performs the 
  9828. initialization of the DRAGINFO structure.  The object may perform its own 
  9829. initialization of the DRAGITEM structure during processing of the 
  9830. _wpFormatDragItem method, if class-specific processing is required.  For 
  9831. example, if the object class implements a private rendering mechanism, the 
  9832. appropriate information must be entered into the correct fields in the DRAGITEM 
  9833. structure as part of the _wpFormatDragItem method. 
  9834.  
  9835. Note that a Workplace Shell object need not allocate the DRAGITEM structure, 
  9836. since the structure is already allocated by the Workplace Shell, and a pointer 
  9837. to the structure is passed to the _wpFormatDragItem method upon invocation. 
  9838.  
  9839.  
  9840. ΓòÉΓòÉΓòÉ 16.5.1.2. DrgDrag() Processing ΓòÉΓòÉΓòÉ
  9841.  
  9842. Once all data structures are allocated and initialized, the drag operation is 
  9843. initiated using the DrgDrag() function. This function is synchronous; it does 
  9844. not return control to the source window procedure until the key or mouse button 
  9845. specified in the fifth parameter (VK_ENDDRAG in the example above) is detected, 
  9846. and any synchronous message passing has been completed. 
  9847.  
  9848. At this point, the DrgDrag() function returns a window handle.  If the dragitem 
  9849. was dropped over a window or object that was able to accept the item, the 
  9850. window handle of the target window is returned.  If a drop occurred over an 
  9851. object that was unable to accept the item, a NULL window handle is returned. 
  9852.  
  9853. Upon return of control by the DrgDrag() function, the drag operation and the 
  9854. drop operation (if any) is complete, and the DRAGINFO structure can be released 
  9855. by the source window procedure. 
  9856.  
  9857. A Workplace Shell object is not required to invoke the DrgDrag() function, 
  9858. since this is performed automatically by the Workplace Shell when the object 
  9859. completes the processing of its _wpFormatDragItem method. 
  9860.  
  9861.  
  9862. ΓòÉΓòÉΓòÉ 16.5.1.3. Synchronous Message Processing During DrgDrag() ΓòÉΓòÉΓòÉ
  9863.  
  9864. When the user drops the dragitem over another window or object that is able to 
  9865. accept the item, a DM_DROP message is passed to the target, which then 
  9866. processes the drop operation.  Note that the target's DM_DROP message 
  9867. processing must complete and return control to Presentation Manager before the 
  9868. DrgDrag() function will return control to the source window procedure.  Thus 
  9869. any processing that is performed by the target window during its processing of 
  9870. the DM_DROP message is synchronous. 
  9871.  
  9872. The synchronous nature of this processing is necessary in order to ensure that 
  9873. the drop operation, and the accompanying transfer of information, is completed 
  9874. before the user performs any other operation.  For this reason, it is 
  9875. recommended that any messages passed by the target to the source window during 
  9876. processing of the DM_DROP message should be passed synchronously using the 
  9877. DrgSendTransferMsg() function. This is a departure from the normal Presentation 
  9878. Manager guidelines, where messages are processed asynchronously, but is 
  9879. required in order to ensure data integrity. 
  9880.  
  9881. A number of synchronous messages may be sent to the source window at the 
  9882. completion of a drop, prior to the DrgDrag() call returning control to the 
  9883. source window.  For example, if the user drops an object on a Workplace Shell 
  9884. printer object with the DRM_PRINT rendering mechanism specified, the target 
  9885. object sends a DM_PRINTOBJECT message to the source window.  This message 
  9886. contains sufficient information for the source window to direct a print data 
  9887. stream to the print queue represented by the printer object.  The first 
  9888. parameter in the DM_PRINTOBJECT message contains a pointer to the DRAGITEM 
  9889. structure that identifies the item being dropped, and the second parameter 
  9890. contains the name of the print queue for the printer object. 
  9891.  
  9892. An example of the way in which the source window procedure may process the 
  9893. DM_PRINTOBJECT message is shown in Receiving a DM_PRINTOBJECT Message. 
  9894.  
  9895. case DM_PRINTOBJECT:
  9896.    WinMessageBox(HWND_DESKTOP,         /* Display message box  */
  9897.           hWnd,             /* Curr window is owner  */
  9898.           "Printing customer details", /* Message box text    */
  9899.           "Print Message Received",   /* Message box title   */
  9900.           0,              /* No identifier     */
  9901.           MB_OK);            /* Include okay button  */
  9902.  
  9903.    <Extract DRAGITEM pointer from mp1>
  9904.    <Extract print queue name from mp2>
  9905.  
  9906.    <Print item>
  9907.  
  9908.    break;
  9909.  
  9910. Receiving a DM_PRINTOBJECT Message 
  9911.  
  9912. NotethatthecodethatactuallyperformstheprintingoperationhasbeenomittedfromReceivingaDM 
  9913. _ PRINTOBJECTMessage . PrintingunderOS / 2Version2 . 
  9914. 0andPresentationManagerisdiscussedindetailinOS / 2Version2 . 0-Volume5 
  9915. : PrintSubsystem 
  9916. ,andexamplesarealsoprovidedinthePRTSAMPprogramincludedintheIBMDeveloper ' 
  9917. sToolkitforOS / 22 . 0 .
  9918.  
  9919.  
  9920. ΓòÉΓòÉΓòÉ 16.5.2. Dragging Over a Window ΓòÉΓòÉΓòÉ
  9921.  
  9922. While the dragitem is being dragged, Presentation Manager sends a succession of 
  9923. DM_DRAGOVER messages to the Presentation Manager window under the mouse 
  9924. pointer; one message is sent for every mouse movement. The DM_DRAGOVER message 
  9925. informs the target window that it is being dragged over, and allows it to 
  9926. access sufficient information to allow the window to decide whether it is able 
  9927. to accept a drop operation.  The window procedure indicates this to 
  9928. Presentation Manager by the value that it returns in response to the 
  9929. DM_DRAGOVER message. 
  9930.  
  9931. The information required by the window is contained in two data structures; the 
  9932. DRAGINFO structure, which is referenced by one of the parameters in the 
  9933. DM_DRAGOVER message, and the DRAGITEM structure, which can be accessed from the 
  9934. DRAGINFO structure.  Since multiple items may be dragged at the same time, the 
  9935. DRAGINFO structure contains an array of pointers to DRAGITEM structures, one 
  9936. for each dragitem.  The DRAGINFO structure maintains a count of the number of 
  9937. dragitems. 
  9938.  
  9939. When a potential target is a Workplace Shell object, the Workplace Shell 
  9940. notifies the object that a dragitem is being dragged over it, by invoking the 
  9941. object's _wpDragOver method. The DRAGINFO structure is passed to the object as 
  9942. a parameter to this method.  Processing of the _wpDragOver method is very 
  9943. similar to that described below for Presentation Manager window procedures.  In 
  9944. normal circumstances, however, the _wpDragOver method is not overridden by an 
  9945. object class; the default processing supplied by the parent class is allowed to 
  9946. occur unless the object class supports private rendering mechanisms that must 
  9947. be explicitly checked against those supported by the dragitem. 
  9948.  
  9949. An example of the way in which a window procedure may process the DM_DRAGOVER 
  9950. message is shown in Dropping an Object. 
  9951.  
  9952.  PDRAGITEM pDItem;               /* Pointer to DRAGITEM  */
  9953.  PDRAGINFO pDInfo;               /* Pointer to DRAGINFO  */
  9954.  
  9955.  case DM_DRAGOVER:
  9956.     pdinfo = (PDRAGINFO)mp1;         /* Get DRAGINFO pointer  */
  9957.     DrgAccessDraginfo(pdinfo);        /* Access DRAGINFO    */
  9958.     pditem = DrgQueryDragitemPtr(pdinfo,   /* Access DRAGITEM    */
  9959.                   0);     /* Index to DRAGITEM   */
  9960.     if (!DrgVerifyRMF(pditem,         /* Check valid rendering */
  9961.             "DRM_SHAREMEM",     /* mechanisms and data  */
  9962.             "DRF_TEXT"))       /* formats        */
  9963.      {
  9964.      DrgFreeDraginfo(pdinfo);        /* Free DRAGINFO     */
  9965.      return(MPFROM2SHORT(DOR_DROP,     /* Return okay to drop  */
  9966.                DO_COPY));     /* Copy operation valid  */
  9967.      }
  9968.     else
  9969.      {
  9970.      DrgFreeDraginfo(pdinfo);        /* Free DRAGINFO     */
  9971.      return(MPFROM2SHORT(DOR_NEVERDROP,   /* Drop not valid     */
  9972.                0));        /* No valid operations  */
  9973.      }
  9974.     break;
  9975.  
  9976. Handling the DM_DRAGOVER Message 
  9977.  
  9978. The code shown in Dropping an Object is quite simple; the processing of the 
  9979. DM_DRAGOVER message is intended only to determine whether a drop operation is 
  9980. valid for the specified dragitem and the target window.  First, access is 
  9981. gained to the DRAGINFO structure, which is referenced by the first parameter to 
  9982. the DM_DRGOVER message.  The DRAGINFO structure is then used to access the 
  9983. DRAGITEM structure, by means of the DrgQueryDragitemPtr() function. The window 
  9984. procedure then has access to all the information needed to determine the 
  9985. validity of a drop operation. 
  9986.  
  9987. In this particular case, the only type of dragitem that is acceptable to the 
  9988. target window is one that represents a customer object, using the specially 
  9989. defined DRM_SHAREMEM rendering mechanism.  The window procedure therefore uses 
  9990. the DrgVerifyRMF() function to check whether the dragitem supports this 
  9991. rendering mechanism and the data type required by it. 
  9992.  
  9993. According to the result returned by the DrgVerifyRMF() function, the window 
  9994. procedure returns either DOR_DROP, indicating that a drop is acceptable, or 
  9995. DOR_NEVERDROP, indicating that a drop is not acceptable and that there is no 
  9996. point in sending any more DM_DRAGOVER messages to this window.  A number of 
  9997. other valid returns are possible for the DM_DRAGOVER message; these are 
  9998. documented in the IBM OS/2 Version 2.0 Presentation Manager Reference. 
  9999. Irrespective of the return code, the DRAGINFO structure is released. 
  10000.  
  10001. If a window returns any return code other than DOR_DROP to this message, the 
  10002. icon seen by the user is automatically modified to show that a drop is not 
  10003. allowed, thereby providing instant visual feedback. 
  10004.  
  10005.  
  10006. ΓòÉΓòÉΓòÉ 16.5.3. Dropping an Object ΓòÉΓòÉΓòÉ
  10007.  
  10008. When the user drops a dragitem over a Presentation Manager window, the target 
  10009. receives a DM_DROP message.  The window procedure for the target may process 
  10010. that message in order to handle the drop operation, and may either complete the 
  10011. operation or initiate a conversation with the source window or object in order 
  10012. to do so, typically by sending it a DM_RENDER message, which ultimately will 
  10013. result in the data being transferred. 
  10014.  
  10015. When the user drops a dragitem over a Workplace Shell object, the Workplace 
  10016. Shell invokes that object's _wpDrop method. The processing of this method is 
  10017. very similar to that discussed below for the DM_DROP message.  However, object 
  10018. classes that do not implement private rendering mechanisms need not override 
  10019. the _wpDrop method; the default processing provided by the parent class may be 
  10020. allowed to occur. 
  10021.  
  10022. In the customer/phone dialler example, the only type of dragitem that the order 
  10023. program will accept is a customer object, which uses the application-defined 
  10024. DRM_SHAREMEM rendering mechanism.  The correct data type and rendering 
  10025. mechanism is verified by the target window procedure during processing of the 
  10026. DM_DRAGOVER message, so there is no need for further checking when the DM_DROP 
  10027. is processed.  Note however, that in a more sophisticated application, which 
  10028. supports multiple data types and rendering mechanisms, it may be necessary to 
  10029. perform more detailed checking. 
  10030.  
  10031. #define XFERMEM "\\SHAREMEM\\DragXfer.mem"    /* Shared mem obj name  */
  10032.  
  10033. PVOID   pCust;                 /* Customer record ptr  */
  10034.  
  10035. PDRAGITEM pDItem;                /* DRAGITEM struct ptr  */
  10036. PDRAGINFO pDInfo;                /* DRAGINFO struct ptr  */
  10037.  :
  10038. case DM_DROP:
  10039.    pDInfo = (PDRAGINFO)mp1;          /* Get DRAGINFO pointer  */
  10040.    DrgAccessDraginfo(pDInfo);         /* Access DRAGINFO    */
  10041.    pDItem = DrgQueryDragitemPtr(pdinfo,    /* Access DRAGITEM    */
  10042.                  0);      /* Index to DRAGITEM   */
  10043.  
  10044.    DosAllocSharedMem(&pCust,          /* Allocate shared mem  */
  10045.             XFERMEM,         /* Named memory object  */
  10046.             sizeof(CUSTOMER),     /* Size of memory object */
  10047.             PAG_COMMIT |       /* Commit storage now   */
  10048.             PAG_WRITE  |       /* Allow write access   */
  10049.             PAG_READ);        /* Allow read access   */
  10050.  
  10051.    pdxfer = DrgAllocDragtransfer(1);      /* Allocate DRAGTRANSFER */
  10052.    pdxfer->cb = sizeof(DRAGTRANSFER);     /* Init DRAGTRANSFER   */
  10053.    pdxfer->hwndClient = hWnd;
  10054.    pdxfer->pditem = pDItem;
  10055.    pdxfer->hstrSelectedRMF =
  10056.        DrgAddStrHandle("<DRM_CUSTOMER,DRF_TEXT>");
  10057.    pdxfer->hstrRenderToName =
  10058.        DrgAddStrHandle(XFERMEM);
  10059.    pdxfer->ulTargetInfo = 0;
  10060.    pdxfer->usOperation = DO_COPY;
  10061.  
  10062.    rc=DrgSendTransferMsg(pDInfo->hwndSource,  /* Send msg to source   */
  10063.               DM_RENDER,      /* DM_RENDER message   */
  10064.               (MPARAM)pdxfer,    /* DRAGTRANSFER pointer  */
  10065.               NULL);
  10066.    if (rc == TRUE)               /* If rendered okay    */
  10067.     {
  10068.     strcpy(msgtext, "Dialling number");   /* Build message text   */
  10069.     strncat(msgtext,
  10070.         pxfercust->phone,
  10071.         30);
  10072.     WinMessageBox(HWND_DESKTOP,       /* Display message box  */
  10073.            hWnd,           /* Curr window is owner  */
  10074.            msgtext,          /* Message text      */
  10075.            "Telephone Dialler",    /* Message title     */
  10076.            0,             /* No identifier     */
  10077.            MB_OK);          /* Include okay button  */
  10078.  
  10079.     PhoneDial(pxfercust->phone);       /* Dial number      */
  10080.     }
  10081.  
  10082.    DrgFreeDragInfo(pdinfo);          /* Release all data    */
  10083.    DrgFreeDragtransfer(pdxfer);        /* structures       */
  10084.    DosFreeMem((PVOID)pxfercust);
  10085.    break;
  10086.  
  10087. Handling the DM_DROP Message 
  10088.  
  10089. In Handling the DM_DROP Message, access must first be gained to the DRAGINFO 
  10090. and DRAGITEM structures.  This is achieved in a similar manner to that already 
  10091. described for the DM_DRAGOVER message.  Having gained access to these 
  10092. structures, a named shared memory object is then allocated, into which the 
  10093. source window will be asked to place the customer details. 
  10094.  
  10095. A DRAGTRANSFER structure is then allocated, in which information about the 
  10096. target's requirements can be passed to the source window.  This structure is 
  10097. similar to the DRAGINFO structure, in that it must be accessible from multiple 
  10098. processes.  It is therefore allocated using the DrgAllocDragtransfer() 
  10099. function, ensuring that the structure will be accessible to the source window, 
  10100. which may be in another process and therefore not have direct access to the 
  10101. target's private data areas. 
  10102.  
  10103. There are several important fields in this structure.  The target window 
  10104. procedure places a pointer to the DRAGITEM structure into the pditem field, 
  10105. thereby enabling the source to identify which item has been dropped.  The 
  10106. hstrSelectedRMF field is used to identify which rendering mechanism and data 
  10107. format is to be used for this target, from the selection offered by the source 
  10108. in the DRAGITEM structure.  The hstrRenderToName field is used in the 
  10109. DRM_SHAREMEM rendering mechanism to pass the name of the shared memory object 
  10110. to the source window. 
  10111.  
  10112. Once this structure has been completed with the necessary information, it is 
  10113. sent to the source window as part of a DM_RENDER message.  This message is 
  10114. passed to the source window using the DrgSendTransferMsg() function. This 
  10115. function should be used for drag/drop operations in preference to the 
  10116. WinSendMsg() function since, for a DM_RENDER message, it also grants access to 
  10117. the DRAGTRANSFER structure for the process that owns the window to which the 
  10118. message is being sent. 
  10119.  
  10120. In processing the DM_RENDER message, the source window copies the customer 
  10121. details into the shared memory so that when DrgSendTransferMsg() returns, the 
  10122. target window procedure may extract the data it needs.  A detailed explanation 
  10123. of the source window's processing of a DM_RENDER message is given in 
  10124. Transferring Information. 
  10125.  
  10126. Upon completion of the information transfer, the entire drag/drop operation is 
  10127. complete and the data structures allocated during the operation may be 
  10128. released.  For the DRAGINFO and DRAGTRANSFER structures, this must be carried 
  10129. out using the DrgFreeDraginfo() and DrgFreeDragtransfer() functions. 
  10130.  
  10131.  
  10132. ΓòÉΓòÉΓòÉ 16.5.4. Transferring Information ΓòÉΓòÉΓòÉ
  10133.  
  10134. As explained in Dropping an Object, a target window may send a DM_RENDER 
  10135. message to the source when it receives a DM_DROP message from Presentation 
  10136. Manager.  Similarly, a Workplace Shell object may send the same message when 
  10137. its _wpDrop method is invoked by the Workplace Shell.  This message is normally 
  10138. sent to the source when the target requires the assistance of the source in 
  10139. completing the transfer of data as part of the drop operation. 
  10140.  
  10141. The source window processes this message in its window procedure, according to 
  10142. the rendering mechanism requested by the target.  If the source is a Workplace 
  10143. Shell object, the Workplace Shell will directly invoke the object's _wpRender 
  10144. method to perform the same function.  In most cases, however, an object does 
  10145. not need to override the _wpRender method unless it wishes to implement a 
  10146. private rendering mechanism. 
  10147.  
  10148. The DM_RENDER processing from the Customer program is shown in Handling the 
  10149. DM_RENDER Message. 
  10150.  
  10151. PDRAGITEM   pDItem;              /* DRAGITEM pointer    */
  10152. PDRAGINFO   pDInfo;              /* DRAGINFO pointer    */
  10153. PDRAGTRANSFER pDXfer;              /* DRAGTRANSFER pointer  */
  10154. PCONTRECORD  pCRec;               /* Container record ptr  */
  10155. PCUSTOMER   pCust,               /* Customer record ptrs  */
  10156.        pXferData;
  10157. CHAR      xfermem[100];           /* Memory name buffer   */
  10158.  
  10159. HWND      hContainer;            /* Container handle    */
  10160.  :
  10161.  :
  10162. case DM_RENDER:
  10163.    pDXfer = (PDRAGTRANSFER)mp1;        /* Get DRAGTRANSFER ptr  */
  10164.    pDItem = pDxfer->pditem;          /* Get DRAGITEM ptr    */
  10165.    pCRec = pditem->ulItemID;          /* Get container rec ptr */
  10166.    pCust = pCRec->cust;            /* Get customer rec ptr  */
  10167.  
  10168.    DrgQueryStrName(pDXfer->hstrRenderToName,  /* Get mem object name  */
  10169.            100,            /* Size of buffer     */
  10170.            xfermem);          /* Buffer         */
  10171.  
  10172.    DosGetNamedSharedMem((PPVOID)&pXferData,  /* Get shared mem object */
  10173.              xfermem,        /* Name of mem object   */
  10174.              PAG_WRITE |      /* Allow write access   */
  10175.              PAG_READ);       /* Allow read access   */
  10176.    memcpy(pCust,                /* Copy customer record  */
  10177.       pXferData,              /* to shared mem object  */
  10178.       sizeof(CUSTOMER));          /* No. of bytes to copy  */
  10179.  
  10180.    DosFreeMem((PVOID)pCust);          /* Free shared mem obj  */
  10181.  
  10182.    if (pDXfer->usOperation == DO_MOVE)     /* If move operation   */
  10183.     {
  10184.     hContainer = WinWindowFromID(hWnd,    /* Get container window  */
  10185.             CONTAINER);       /* handle         */
  10186.     RemoveCustomer(hContainer,        /* Remove record from   */
  10187.             pCRec);          /* container       */
  10188.     }
  10189.    return((MRESULT)TRUE);           /* Return TRUE      */
  10190.    break;
  10191.  
  10192. Handling the DM_RENDER Message 
  10193.  
  10194. The first parameter to the DM_RENDER message contains a pointer to the 
  10195. DRAGTRANSFER structure, which in turn contains a pointer to the DRAGITEM 
  10196. structure in its pditem field.  For a Workplace Shell object, a pointer to the 
  10197. DRAGTRANSFER structure is passed as a parameter to the _wpRender method. 
  10198.  
  10199. In the DRM_SHAREMEM rendering mechanism, the ulItemID field in the DRAGITEM 
  10200. structure is used to hold a pointer to the customer container record (of type 
  10201. CONTRECORD), in whch the cust field is a CUSTOMER structure containing details 
  10202. of the customer object which was dragged. 
  10203.  
  10204. Next, the name of the shared memory object previously allocated by the target 
  10205. window is retrieved from the hstrRenderToName field of the DRAGTRANSFER 
  10206. structure.  This name is used to obtain access to the shared memory object. 
  10207. The customer details are copied into this memory object, after which the memory 
  10208. object is freed. 
  10209.  
  10210. The operation code in the DRAGTRANSFER structure is then checked to establish 
  10211. whether the target requires a copy or a move operation.  If a move was 
  10212. requested, the source program deletes the customer record from the contaiiner 
  10213. by calling an application subroutine named RemoveCustomer(). 
  10214.  
  10215. The window procedure then returns the value TRUE, indicating that the data was 
  10216. successfully rendered.  This value is returned to the target window procedure 
  10217. that issued the DrgSendTransferMsg() call. At this point, the target window 
  10218. procedure has access to all information required to complete the drop 
  10219. operation, and may do so without further communication. 
  10220.  
  10221. At the completion of the rendering procedure, the source may pass a 
  10222. DM_RENDERCOMPLETE message to the target, allowing the target to release any 
  10223. resources still outstanding.  A Presentation Manager window may process this 
  10224. message in its window procedure, while a Workplace Shell object is notified of 
  10225. the event by the Workplace Shell, which invokes the object's _wpRenderComplete 
  10226. method. This is usually only required in cases where complex private rendering 
  10227. mechanisms involve multiple transfers.  It is not used in the above examples. 
  10228.  
  10229.  
  10230. ΓòÉΓòÉΓòÉ 16.6. Using Rendering Mechanisms ΓòÉΓòÉΓòÉ
  10231.  
  10232. The rendering mechanism is essentially a protocol that determines the contents 
  10233. of several fields in the DRAGITEM structure.  These fields are: 
  10234.  
  10235.    o  ulItemID, which contains an application-specific value uniquely 
  10236.       identifying the item being dragged. 
  10237.  
  10238.    o  hstrType, which contains a handle to a string defining the data type of 
  10239.       the dragitem. 
  10240.  
  10241.    o  hstrRMF, which contains a handle to a string containing the names of all 
  10242.       rendering mechanisms supported by the dragitem, and the data formats 
  10243.       supported by those rendering mechanisms. 
  10244.  
  10245.    o  hstrContainerName, hstrSourceName and hstrTargetName, which contain 
  10246.       handles to strings used by the DRM_OS2FILE rendering mechanism, and may 
  10247.       be used by private rendering mechanisms to contain string data. 
  10248.  
  10249.  The content of the hstrRMF field should obey a set of syntactical rules that 
  10250.  are explained in the OS/2 2.0 Programming Guide Volume II.  Other fields in 
  10251.  the DRAGITEM structure may also be used by particular rendering mechanisms; 
  10252.  their use is dependent upon the individual rendering mechanism in use at the 
  10253.  time. Applications may use one of the standard rendering mechanisms DRM_PRINT, 
  10254.  DRM_DISCARD, DRM_OS2FILE or DRM_DDE, or may define their own rendering 
  10255.  mechanisms to support dragging and dropping of particular dragitems. 
  10256.  
  10257.  
  10258. ΓòÉΓòÉΓòÉ 16.6.1. Standard Rendering Mechanisms ΓòÉΓòÉΓòÉ
  10259.  
  10260. The following sections describe the use of two of the standard rendering 
  10261. mechanisms, DRM_PRINT and DRM_OS2FILE.  These mechanisms can be used by 
  10262. Presentation Manager applications to interact with other applications and/or 
  10263. Workplace Shell  objects. 
  10264.  
  10265.  
  10266. ΓòÉΓòÉΓòÉ 16.6.1.1. DRM_PRINT ΓòÉΓòÉΓòÉ
  10267.  
  10268. For Presentation Manager applications running on the Workplace Shell desktop 
  10269. under OS/2 Version 2.0, it may be desirable to allow the user to print from the 
  10270. program by dragging the relevant item, such as a customer record, onto a 
  10271. Workplace Shell printer object. Since all Workplace Shell printer objects are 
  10272. written to understand the DRM_PRINT rendering mechanism, a Presentation Manager 
  10273. may provide such function simply by adhering to this mechanism. 
  10274.  
  10275. With the DRM_PRINT rendering mechanism, responsibility for actually carrying 
  10276. out the printing rests within the source window.  The source window must: 
  10277.  
  10278.    1. Detect the fact that a drag is being initiated by the user 
  10279.  
  10280.    2. Allocate and fill the DRAGINFO and DRAGITEM structures 
  10281.  
  10282.    3. Start the drag operation using the DrgDrag() function 
  10283.  
  10284.    4. Process the DM_PRINTOBJECT message which is returned by the target 
  10285.       printer object. 
  10286.  
  10287.  The first three steps are handled in exactly the same way as illustrated in 
  10288.  Drag Initiation From a Container Window.  Note that a view of a Workplace 
  10289.  Shell object need not explicitly handle Presentation Manager messages in the 
  10290.  window procedures for its views.  When the user initiates a drag from within a 
  10291.  Workplace Shell object such as a folder or work area, the object is notified 
  10292.  by the Workplace Shell, which invokes the object's _wpFormatDragItem method. 
  10293.  This method is processed in an identical manner to that shown for the window 
  10294.  procedure in Drag Initiation From a Container Window. 
  10295.  
  10296.  The final step is handled by processing the DM_PRINTOBJECT message in the 
  10297.  source window procedure.  A simple example of such processing is shown in 
  10298.  Receiving a DM_PRINTOBJECT Message. 
  10299.  
  10300.  
  10301. ΓòÉΓòÉΓòÉ 16.6.1.2. DRM_DISCARD ΓòÉΓòÉΓòÉ
  10302.  
  10303. The DRM_DISCARD rendering mechanism operates in a similar fashion to the 
  10304. DRM_PRINT mechanism, and is intended for use by applications which create their 
  10305. own equivalent to the Workplace Shell Shredder object.  In this rendering 
  10306. mechanism, the target passes a DM_DISCARDOBJECT message to the source, which 
  10307. may either accept responsibility for the discard operation, abort the 
  10308. operation, or allow the system to perform the operation. 
  10309.  
  10310. Note that the system may only discard objects which are capable of being 
  10311. rendered with the DRM_OS2FILE rendering mechanism; that is, program files and 
  10312. data files.  Other objects not based upon files must be explicitly discarded by 
  10313. the source. 
  10314.  
  10315. When a Workplace Shell object is dropped on the Shredder object, the Workplace 
  10316. Shell intercepts the DM_DISCARDOBJECT message and invokes the source object's 
  10317. wpDelete method. 
  10318.  
  10319.  
  10320. ΓòÉΓòÉΓòÉ 16.6.1.3. DRM_OS2FILE ΓòÉΓòÉΓòÉ
  10321.  
  10322. The DRM_OS2FILE rendering mechanism is designed to support moving and copying 
  10323. file objects between containers.  This rendering mechanism is described in 
  10324. detail in the OS/2 2.0 Programming Guide Volume II, and an extensive example is 
  10325. provided in the IBM Developer's Toolkit for OS/2 2.0.  The details of 
  10326. programming for the DRM_OS2FILE mechanism will therefore not be described 
  10327. further in this document. 
  10328.  
  10329. Certain fields in the DRAGITEM structure are designed specifically for this 
  10330. rendering mechanism; the hstrContainer, hstrSourceName and hstrTargetName 
  10331. fields are ideally suited to holding the source directory name, source file 
  10332. name, and fully qualified target file name respectively.  This is how these 
  10333. fields are used by the DRM_OS2FILE rendering mechanism. 
  10334.  
  10335. An alternative, and even more straightforward way to implement this rendering 
  10336. mechanism, is to use the DrgDragFiles() function.  This function automatically 
  10337. allocates and fills the required data structures for the source window, 
  10338. avoiding the need for the application to perform these functions and reducing 
  10339. the risk of error. 
  10340.  
  10341.  
  10342. ΓòÉΓòÉΓòÉ 16.6.2. Implementing a Private Rendering Mechanism ΓòÉΓòÉΓòÉ
  10343.  
  10344. The OS/2 2.0 Programming Guide Volume II gives some advice on use of the 
  10345. various messages available to implement a private rendering mechanism, and also 
  10346. some guidelines on how such a rendering mechanism should be documented.  This 
  10347. section illustrates the implementation of a simple rendering mechanism, by 
  10348. explaining the definition of the DRM_SHAREMEM rendering mechanism used by the 
  10349. examples earlier in this chapter. 
  10350.  
  10351. A rendering mechanism is necessary to pass the customer record data used in the 
  10352. examples, since the CUSTOMER structure that contains this data is too large to 
  10353. be contained within the DRAGITEM structure. It is therefore necessary, after a 
  10354. drop has occurred, for the source program to make the relevant data available 
  10355. to the target, in a format which is understood by and accessible to both the 
  10356. source and the target.  In the examples, a named shared memory object is used 
  10357. to transfer the data; hence the name DRM_SHAREMEM used for the rendering 
  10358. mechanism. 
  10359.  
  10360. The DRM_SHAREMEM rendering mechanism operates as follows: 
  10361.  
  10362.    o  The source window stores a pointer to the customer record being dragged 
  10363.       in the ulItemID field of the DRAGITEM structure.  This field is defined 
  10364.       as ULONG, but it can be used in any way that is meaningful to the source 
  10365.       window to identify the item being dragged.  A pointer to the customer 
  10366.       record is a convenient way to do this. 
  10367.  
  10368.    o  The target window, on receiving a DM_DROP message, allocates a named 
  10369.       shared memory object with a name of its choice.  It then sends a 
  10370.       DM_RENDER message to the source window, passing the name of the memory 
  10371.       object in the hstrRenderToName field of the DRAGTRANSFER structure, and 
  10372.       indicating whether it requires a copy (DO_COPY) or a move (DO_MOVE) to 
  10373.       take place, using the usOperation field of the DRAGTRANSFER structure. 
  10374.  
  10375.    o  When the source window receives the DM_RENDER message, it obtains access 
  10376.       to the shared memory object and places the customer record in that 
  10377.       object.  The source window knows which customer record to copy, since the 
  10378.       DRAGITEM structure, which includes a pointer to the customer record, is 
  10379.       passed along with the DRAGTRANSFER structure. 
  10380.  
  10381.       Finally, if a move operation was requested by the target, the source 
  10382.       window deletes the customer record from its own data. 
  10383.  
  10384.    o  On receiving a TRUE return code from the DM_RENDER message, indicating 
  10385.       that the data was successfully rendered, the target window copies the 
  10386.       data out of the shared memory object, and uses it in whatever way it 
  10387.       chooses. 
  10388.  
  10389.  It should be stressed that this is a very simple rendering mechanism. However, 
  10390.  it illustrates the general structure of such mechanisms, and their impact on 
  10391.  the contents of fields in the DRAGITEM and DRAGTRANSFER structures. 
  10392.  
  10393.  
  10394. ΓòÉΓòÉΓòÉ 16.7. Summary ΓòÉΓòÉΓòÉ
  10395.  
  10396. Direct manipulation is likely to become considerably more important to 
  10397. application designers than it has been in previous releases of OS/2, because of 
  10398. its central role in the object-oriented user interface provided by the 
  10399. Workplace Shell.  Even applications that are not implemented as Workplace Shell 
  10400. objects should provide, so far as is practical, a similar style of interface. 
  10401. Direct manipulation forms an essential part of such an interface. 
  10402.  
  10403. The programming facilities for direct manipulation in OS/2 V2.0 are essentially 
  10404. the same as those introduced in OS/2 Version 1┬╖3, and consist of a set of 
  10405. message classes, functions and data structures, along with defined protocols 
  10406. known as rendering mechanisms, which define standard techniques for using these 
  10407. facilities to pass different types of information between diverse applications, 
  10408. and between user-developed applications and Workplace Shell objects such as 
  10409. printers and the shredder. 
  10410.  
  10411. User-defined rendering mechanisms may also be defined for specific purposes 
  10412. that are not covered by the standard ones.  The OS/2 2.0 Programming Guide 
  10413. Volume II gives guidance on this and on how such rendering mechanisms should be 
  10414. documented. 
  10415.  
  10416.  
  10417. ΓòÉΓòÉΓòÉ 17. Presentation Manager Resources ΓòÉΓòÉΓòÉ
  10418.  
  10419. The definition and use of Presentation Manager resources by applications was 
  10420. mentioned in The Presentation Manager Application Model.  The use of such 
  10421. resources greatly simplifies the task of the application developer in creating 
  10422. windows, menu bars, etc., and provides a powerful tool for the externalization 
  10423. of the user interface properties of an application object, thereby enabling 
  10424. easier modification of these properties during development or maintenance of 
  10425. the application.  This chapter will describe the definition of resources, and 
  10426. the ways in which resources may be used within a Presentation Manager 
  10427. application. 
  10428.  
  10429.  
  10430. ΓòÉΓòÉΓòÉ 17.1. Types of Resources ΓòÉΓòÉΓòÉ
  10431.  
  10432. A number of different types of resources may be defined for use by Presentation 
  10433. Manager applications.  These include text items such as menu bars and window 
  10434. templates, and graphical items such as graphics fonts, icons and bitmaps. 
  10435. Textual items are defined in the resource script file, which is described in 
  10436. Resource Script File.  Non-textual items are defined and saved in other files, 
  10437. and are referenced by statements in the resource script file.  The various 
  10438. types of Presentation Manager resource are described in the following sections. 
  10439.  
  10440.  
  10441. ΓòÉΓòÉΓòÉ 17.1.1. Fonts ΓòÉΓòÉΓòÉ
  10442.  
  10443. A font is a set of alphanumeric characters and other symbols.  Fonts may be 
  10444. designed interactively using the Font Editor application provided as part of 
  10445. the IBM Developer's Toolkit for OS/2 2.0.  Once a font has been designed, the 
  10446. Font Editor saves the font in a disk file with an extension .FNT.  This font 
  10447. file is referenced from the resource script file using the FONT keyword: 
  10448.  
  10449. FONT     123     MYFONT.FNT
  10450. The integer following the FONT keyword is used to identify the font resource. 
  10451. A symbolic name cannot be used to define a font resource. 
  10452.  
  10453. A font file must be link-edited along with a resource script file containing a 
  10454. FONT keyword referencing the .FNT file, and with the FONTS.OBJ and FONTS.DEF 
  10455. files provided with the OS/2 Programmer's Toolkit, to produce a file with an 
  10456. extension of .FON.  Although a font cannot be stored in a dynamic link library, 
  10457. the .FON file may be installed on the system by the user or installed 
  10458. explicitly by an application.  The font is then usable by any application in 
  10459. the system.  Alternatively, an application developer may choose not to install 
  10460. the font, but merely to access it from a particular application using the 
  10461. GpiLoadFonts() function. 
  10462.  
  10463.  
  10464. ΓòÉΓòÉΓòÉ 17.1.2. Icons, Pointers and Bitmaps ΓòÉΓòÉΓòÉ
  10465.  
  10466. As already mentioned, an icon is a graphical representation of an object on the 
  10467. screen.  For the purposes of discussion, icons, pointers and bitmaps will be 
  10468. grouped together; a pointer is a graphical image that is associated with a 
  10469. pointing device such as a mouse, and which moves on the screen as the pointing 
  10470. device is moved by the user, whereas a bitmap is a graphical image that 
  10471. typically is used to represent a general item such as a logo.  Icons, pointers 
  10472. and bitmaps may be designed interactively using the Icon Editor application 
  10473. supplied as part of the OS/2 Version 2.0 product.  Depending on which resource 
  10474. is being created, the Icon Editor saves the resulting icon, pointer or bitmap 
  10475. in a file with an extension of ICO, PTR or BMP.  These files are then 
  10476. referenced from the resource script file using the ICON, POINTER or BITMAP 
  10477. keywords: 
  10478.  
  10479. ICON     MAIN     APPLIC.ICO
  10480. POINTER  DRAW     PENCIL.PTR
  10481. BITMAP   INTRO    LOGO.BMP
  10482.  
  10483. The keyword is followed in each case by a resource identifier, which is a 
  10484. symbolic name used by the application to identify the resource.  For an icon, 
  10485. the identifier is used as a parameter to the WinCreateWindow() and 
  10486. WinCreateStdWindow() calls, and identifies the icon resource to be used when 
  10487. the FCF_ICON attribute is specified for the frame window.  In all cases, the 
  10488. symbolic name must be defined as an integer constant using a #define statement. 
  10489.  
  10490. For a pointer or bitmap, the identifier is used as a parameter to the 
  10491. WinLoadPointer() or GpiLoadBitmap() functions, which load the resource into 
  10492. memory.  WinLoadPointer() returns a pointer to the resource in memory, which 
  10493. may then be used as a parameter to the WinSetPointer() function, in order to 
  10494. set the desktop pointer to that resource. 
  10495.  
  10496. A pointer may be set to one of the system-defined pointer styles (such as an 
  10497. arrow or hourglass) using the WinSetPointer() function, by obtaining the handle 
  10498. of the required system pointer using the WinQuerySysPointer() function as 
  10499. follows: 
  10500.  
  10501. rc = WinSetPointer(HWND_DESKTOP,
  10502.                    WinQuerySysPointer(HWND_DESKTOP,
  10503.                                       SPTR_WAIT,
  10504.                                       FALSE));
  10505. This call will set the pointer for the desktop to the hourglass pointer 
  10506. (indicated by the symbolic name SPTR_WAIT).  The handle of the hourglass 
  10507. pointer is returned by the WinQuerySysPointer() call.  The symbolic names of 
  10508. the various system pointers are described along with the WinQuerySysPointer() 
  10509. function in the IBM OS/2 Version 2.0 Presentation Manager Reference. 
  10510.  
  10511. A bitmap is drawn within a window on the screen using the WinDrawBitmap() 
  10512. function.  The pointer to the bitmap, returned by GpiLoadBitmap() is passed as 
  10513. a parameter to WinDrawBitmap() in order to identify the resource. 
  10514.  
  10515.  
  10516. ΓòÉΓòÉΓòÉ 17.1.3. Menu Bars and Pulldown Menus ΓòÉΓòÉΓòÉ
  10517.  
  10518. Menu bars and their associated pulldown menus are defined within the resource 
  10519. script file, using the MENU and SUBMENU keywords.  A sample menu bar and 
  10520. pulldown menu definition is shown in Menu Bar Resource Definition. 
  10521.  
  10522. MENU MAIN    PRELOAD
  10523. BEGIN
  10524.    SUBMENU "~File",  MI_FILE, MIS_TEXT
  10525.    BEGIN
  10526.      MENUITEM "~New...",  MI_NEW, MIS_TEXT
  10527.      MENUITEM "~Open",   MI_OPEN, MIS_TEXT
  10528.      MENUITEM "~Save",   MI_SAVE, MIS_TEXT
  10529.      MENUITEM "Save ~as", MI_SAVEAS, MIS_TEXT
  10530.    END
  10531.    SUBMENU "~Edit", MI_EDIT, MIS_TEXT
  10532.    BEGIN
  10533.      MENUITEM "Cu~t",   MI_CUT, MIS_TEXT
  10534.      MENUITEM "~Copy",   MI_COPY, MIS_TEXT
  10535.      MENUITEM "~Paste",  MI_PASTE, MIS_TEXT
  10536.    END
  10537.    SUBMENU "~Window",     MI_WINDOW, MIS_TEXT
  10538.    BEGIN
  10539.      MENUITEM "~Tile",   MI_TILE, MIS_TEXT
  10540.      MENUITEM "~Cascade", MI_CASC, MIS_TEXT
  10541.    END
  10542.    MENUITEM "E~xit",     MI_EXIT, MIS_TEXT
  10543.    MENUITEM "~Help",     MI_HELP, MIS_HELP |
  10544.                     MIS_BUTTONSEPARATOR
  10545. END
  10546.  
  10547. Menu Bar Resource Definition 
  10548.  
  10549. Thesymbolicname( MAINintheexampleabove )identifiestheresource 
  10550. .ThisnameispassedasaparametertotheWinCreateWindow ( )andWinCreateStdWindow ( 
  10551. )functionsandidentifiesthemenubarresourcewhentheFCF _ 
  10552. MENUstyleframecontrolflagisspecifiedfortheframewindow 
  10553. . ThePRELOADoptionspecifiesthattheresourcewillbeincorporatedintotheapplication 
  10554. ' smain. EXEfile ,andistobeloadedimmediatelyintomemory 
  10555. ,ratherthanbeingloadedwhencalledbytheapplication .
  10556.  
  10557. The SUBMENU statement defines a menu bar entry that will be associated with a 
  10558. pulldown menu.  MENUITEM statements that are enclosed within the BEGIN and END 
  10559. markers of a SUBMENU statement define the pulldown menu items. MENUITEM 
  10560. statements that are not enclosed within the bounds of a SUBMENU statement 
  10561. define menu bar entries that do not have an associated pulldown menu. 
  10562.  
  10563. The text strings within quotation marks define the text for each menu bar or 
  10564. pulldown menu item.  The symbolic name following the text identifies the value 
  10565. (placed in the first message parameter) of the WM_COMMAND message generated 
  10566. when the item is selected.  The symbolic names following the message identifier 
  10567. define the style of the item.  In the example above, all items are simple text 
  10568. items and are defined with the style MIS_TEXT.  The sole exception is the final 
  10569. "Help" menu bar item, which is defined with the style attributes of MIS_HELP, 
  10570. which causes the item to generate a WM_HELP message rather than a WM_COMMAND 
  10571. message, and MIS_BUTTONSEPARATOR, which causes the item to be displayed on the 
  10572. right-hand side of the menu bar separated by a vertical bar, in accordance with 
  10573. SAA CUA guidelines.  The various item styles and attributes are documented in 
  10574. the IBM OS/2 Version 2.0 Presentation Manager Reference. 
  10575.  
  10576. When groups of items within a single pulldown menu are logically separate, they 
  10577. should be visually separated by a horizontal bar within the pulldown menu. 
  10578. This may be achieved using the SEPARATOR keyword in the MENUITEM statement, as 
  10579. follows: 
  10580.  
  10581. MENUITEM  SEPARATOR
  10582. The use of a separator bar in pulldown menus is particularly important when the 
  10583. pulldown menu is used to display a list of entries, comprised of multiple sets 
  10584. of mutually exclusive options, from which the user must select one option from 
  10585. each set.  In such a case, the separator bar is used to group the items within 
  10586. each set, and to visually separate the sets from one another. 
  10587.  
  10588. As already mentioned, menu bar resources are typically incorporated into a 
  10589. window by specifying their resource identifier in a WinCreateWindow() or 
  10590. WinCreateStdWindow() call, with the FCF_MENU frame creation flag set for the 
  10591. frame window.  A submenu within a menu bar resource may also be dynamically 
  10592. created using the WinCreateMenu() function, which is described in The Menu Bar. 
  10593.  
  10594.  
  10595. ΓòÉΓòÉΓòÉ 17.1.3.1. Mnemonics ΓòÉΓòÉΓòÉ
  10596.  
  10597. Mnemonics may be specified for menu bar and pulldown menu items.  A mnemonic is 
  10598. a key which, when combined with the F10 key, results in selection of the item. 
  10599. The character for the mnemonic must be part of the text for the item.  For 
  10600. example, the conventional mnemonic key for the "Exit" menu bar item is "x"; 
  10601. when the F10 key is pressed followed by the "x" key, a WM_COMMAND message with 
  10602. value MI_EXIT is generated. 
  10603.  
  10604. Mnemonics are indicated to the user by the appropriate character within the 
  10605. item text being underlined.  This is achieved by placing a tilde character (~) 
  10606. within the item text, immediately prior to the required character; for example: 
  10607.  
  10608. MENUITEM "E~xit",     MI_EXIT, MIS_TEXT
  10609. When the resource script file is compiled using the resource compiler, the menu 
  10610. bar item is created with the appropriate mnemonic. 
  10611.  
  10612.  
  10613. ΓòÉΓòÉΓòÉ 17.1.3.2. Accelerator Keys ΓòÉΓòÉΓòÉ
  10614.  
  10615. Accelerator keys or key sequences may be used to represent a pulldown menu item 
  10616. and provide a "fast path" to a particular command.  Note that accelerator keys 
  10617. are not used to represent menu bar entries, since the use of an accelerator key 
  10618. sequence is typically more complex than the use of a mouse or an F10 + single 
  10619. character operation.  The definition of accelerator keys is described in 
  10620. Accelerator Tables.  It is conventional to display an accelerator key sequence, 
  10621. along with the command represented by that sequence, in the pulldown menu, thus 
  10622. providing the user with a visual indication of the accelerator key sequence. 
  10623. This may be achieved by the use of the "\t" or "\a" control codes within the 
  10624. item text.  The "\t" code causes text to the right of the code to be 
  10625. left-justified in a new column, whereas the "\a" code causes text to the right 
  10626. of the code to be right-justified in a new column. 
  10627.  
  10628. To display an accelerator key sequence in a pulldown menu, it is conventional 
  10629. to use the "\t" control code.  For example: 
  10630.  
  10631. MENUITEM "~Tile\tShift+F5",     MI_TILE, MIS_TEXT
  10632. This would result in the item text "Tile" (with the "T" underscored to 
  10633. represent the mnemonic) being displayed in the left of the pulldown menu with 
  10634. the text "Shift+F5" being left-justified in a second column to the right of the 
  10635. item text. 
  10636.  
  10637.  
  10638. ΓòÉΓòÉΓòÉ 17.1.4. String Tables ΓòÉΓòÉΓòÉ
  10639.  
  10640. Tables of text strings may be defined within a resource script file for use by 
  10641. an application.  A string table is defined using the STRINGTABLE keyword, as 
  10642. shown in String Table Resource Definition. 
  10643.  
  10644. STRINGTABLE MAIN   PRELOAD
  10645. BEGIN
  10646.    STR_MAINTITLE,   "Application Main Window"
  10647.    STR_LIST1,     "List of Objects"
  10648.    STR_MSGTITLE1,   "Title for Message Box"
  10649. END
  10650.  
  10651. String Table Resource Definition 
  10652.  
  10653. Stringtablesmaybeusedtocontaintitles 
  10654. ,messagesandothercommontextusedbyanapplication 
  10655. . Theexternaldefinitionofthesestringsmakesiteasytochangeatitleormessagewithoutmodifyingsourcecode 
  10656. . Stringtablesmayalsobeusedtocontainmenubarorpulldownmenutextfordynamicinsertionbyanapplication 
  10657. . Specialcharacterssuchasmnemonicindicatorsandtabcharactersforcolumnatingdisplaymaybeincorporatedintothestringdefinition .
  10658.  
  10659. The symbolic name following the STRINGTABLE keyword identifies the string table 
  10660. and is used as a parameter when loading strings from the resource into 
  10661. application buffers using the WinLoadString() function.  The PRELOAD keyword 
  10662. specifies that the resource will be incorporated into the application's main 
  10663. .EXE file, and is to be loaded into memory immediately rather than being loaded 
  10664. when called by the application. 
  10665.  
  10666. Multiple string tables may be defined by an application.  Each string table 
  10667. must have its own symbolic name (note that the same name may be used for a 
  10668. string table and another type of resource such as a menu bar) and is enclosed 
  10669. within the BEGIN and END keywords of a STRINGTABLE statement. Each string has 
  10670. its own symbolic name within the string table. 
  10671.  
  10672. As mentioned above, strings are loaded from the string table into application 
  10673. buffers using the WinLoadString() function.  For example, to load the string 
  10674. STR_MAINTITLE from the string table MAIN into a buffer named szTitle, the 
  10675. function shown in Loading a Text String Resource is used. 
  10676.  
  10677. ulLength = WinLoadString(hAB,        /* Load string       */
  10678.              NULL,       /* From appl resource file */
  10679.              STR_MAINTITLE,   /* String id in resource  */
  10680.              sizeof(szTitle),  /* Number of characters   */
  10681.              szTitle);     /* Target buffer      */
  10682.  
  10683. Loading a Text String Resource 
  10684.  
  10685. TheWinLoadString ( 
  10686. )functionreturnsanunsignedintegerrepresentingthenumberofcharactersloadedintothetargetbuffer 
  10687. . Onceloaded 
  10688. ,thebuffermaythenbemanipulatedusingstandardprogramminglanguagefunctions 
  10689. ,orusedasaparametertootherPresentationManagerfunctioncalls .
  10690.  
  10691.  
  10692. ΓòÉΓòÉΓòÉ 17.1.5. Accelerator Tables ΓòÉΓòÉΓòÉ
  10693.  
  10694. Accelerator keys are single keys or key sequences that are used to represent a 
  10695. particular command (typically a pulldown menu item) within an application, and 
  10696. provide a fast path for the entry of that command.  Accelerators are defined 
  10697. for an individual window and are active whenever that window is active. 
  10698. According to Systems Application Architecture CUA conventions, accelerator keys 
  10699. should be indicated to the user by placing the accelerator key sequence 
  10700. alongside the command in the pulldown menu.  Accelerator keys are defined in 
  10701. the resource script file using the ACCELTABLE keyword, as shown in Accelerator 
  10702. Table Resource Definition. 
  10703.  
  10704. ACCELTABLE CHILD1
  10705. BEGIN
  10706.    VK_F3,   MI_EXIT, VIRTUALKEY
  10707.    VK_F5,   MI_TILE, VIRTUALKEY, SHIFT
  10708.    "D",    MI_DELETE, CHAR, CONTROL
  10709. END
  10710.  
  10711. Accelerator Table Resource Definition 
  10712.  
  10713. ThesymbolicnamefollowingtheACCELTABLEstatementidentifiestheacceleratorresource 
  10714. ,andispassedasaparametertotheWinCreateWindow ( )orWinCreateStdWindow ( 
  10715. )functionswhentheFCF _ ACCELTABLEstyleattributeisspecifiedfortheframewindow .
  10716.  
  10717. In the above example, the F3 key is defined as a virtual key that when pressed 
  10718. will generate a WM_COMMAND message with the value MI_EXIT.  This is equivalent 
  10719. to the user having selected the "Exit" option from the menu bar. The Shift+F5 
  10720. key sequence is also defined as a virtual key that will generate a WM_COMMAND 
  10721. message with the value MI_TILE.  Note that the shifted state of the key is 
  10722. indicated by use of the SHIFT option.  The Ctrl+D key sequence has also been 
  10723. defined to generate a WM_COMMAND message with the value MI_DELETE.  The Ctrl 
  10724. state of the key is indicated by the use of the CONTROL option (in a similar 
  10725. manner to the SHIFT option on the previous line).  The various options for 
  10726. defining accelerator keys are documented in the IBM OS/2 Version 2.0 
  10727. Presentation Manager Reference. 
  10728.  
  10729. As already mentioned, an accelerator table is associated with a particular 
  10730. window by specifying the resource identifier as a parameter to the 
  10731. WinCreateWindow() or WinCreateStdWindow() functions.  In addition, the 
  10732. WinLoadAccelTable() function may be used to dynamically load an accelerator 
  10733. table into memory. The WinLoadAccelTable() function returns the handle of the 
  10734. accelerator table in memory, which may then be passed as a parameter to the 
  10735. WinSetAccelTable() function to activate the accelerator table for a particular 
  10736. queue or window. 
  10737.  
  10738.  
  10739. ΓòÉΓòÉΓòÉ 17.1.6. Help Tables ΓòÉΓòÉΓòÉ
  10740.  
  10741. Help tables are used by the IPF to relate each display window, dialog box or 
  10742. control window to the help panel containing information about that window. 
  10743. Help tables and their definition are described in detail in Adding Online Help 
  10744. and Documentation. 
  10745.  
  10746.  
  10747. ΓòÉΓòÉΓòÉ 17.1.7. Window and Dialog Templates ΓòÉΓòÉΓòÉ
  10748.  
  10749. Templates defining standard windows and dialog boxes may be defined within the 
  10750. resource script file.  Typically, a window or dialog template is designed using 
  10751. the Dialog Box Editor application supplied with the IBM Developer's Toolkit for 
  10752. OS/2 2.0, and is saved in a text file with an extension .DLG which is included 
  10753. in the resource script file with an rcinclude statement.  A window or dialog 
  10754. template may also be defined directly into the resource script file.  In either 
  10755. case, the template is defined using the WINDOWTEMPLATE or DLGTEMPLATE keywords. 
  10756. These keywords are actually synonymous, and the resource compiler interprets 
  10757. either keyword in the same way. 
  10758.  
  10759. Within a single window or dialog template, there may be multiple WINDOW or 
  10760. DIALOG statements that define individual windows or dialog boxes.  The nesting 
  10761. of the statements defines the parent/child window hierarchy. Window Template 
  10762. Resource Definition shows an example of nested windows within a window 
  10763. template. 
  10764.  
  10765. WINDOWTEMPLATE WCP_0001
  10766. BEGIN
  10767.    FRAME "Window Class X", 1, 10, 10, 320, 130
  10768.    CTLDATA FCF_STANDARD
  10769.    BEGIN
  10770.      WINDOW "", FID_CLIENT, 0,0,0,0, "MyClass", 01
  10771.    END
  10772. END
  10773.  
  10774. Window Template Resource Definition 
  10775.  
  10776. ThewindowtemplateWCP _ 001containsaframewindowwiththetitle" WindowClassX 
  10777. "andwithsizeandpositionalcoordinatesasspecified 
  10778. . ThestyleattributesoftheframewindowarespecifiedusingtheCTLDATAstatement 
  10779. . TheclientwindowforthisframewindowiscreatedusingtheWINDOWkeywordnestedwithinthewindowtemplate 
  10780. ,withnowindowtitle ,theidentifierFID _ CLIENT ,nosizeorpositionalcoordinates( 
  10781. thesearedefinedbytheframewindow ) ,theclass" MyClass "andthedefaultclientstyle .
  10782.  
  10783. The use of the WINDOWTEMPLATE keyword and WINDOW statements is a useful way for 
  10784. an application developer to predefine particular window types and styles for 
  10785. use by one or more applications.  The template definitions may be used to 
  10786. create modal dialog boxes, which are loaded into memory and executed by the use 
  10787. of WinLoadDlg() and WinProcessDlg() calls.  Definitions may also be created for 
  10788. standard windows or modeless dialog boxes, which are loaded into memory using 
  10789. the WinLoadDlg() function and executed by making the window or dialog box 
  10790. visible using the WinShowWindow() function. 
  10791.  
  10792. Predefinition of windows is particularly useful when applied to dialog boxes. 
  10793. Here, the number and complexity of control window definitions is often such 
  10794. that creating such windows dynamically is a complicated task.  A dialog box is 
  10795. defined in the resource script file (or a .DLG file, which is incorporated into 
  10796. the resource script file using the rcinclude statement) using the DLGTEMPLATE 
  10797. keyword. 
  10798.  
  10799. Within a dialog template, there may be multiple dialogs defined using the 
  10800. DIALOG statement, and each dialog box may have multiple control windows defined 
  10801. using CONTROL keywords.  Dialog Template Resource Definition shows an example 
  10802. of a dialog template containing a dialog box with several control windows: 
  10803.  
  10804. DLGTEMPLATE DC_CREATE
  10805. BEGIN
  10806.    DIALOG "Create an Object", DC_CREATE, 22, 32, 260, 76,,
  10807.    FCF_TITLEBAR | FCF_DLGBORDER
  10808.    BEGIN
  10809.      CONTROL "Enter the Object Name", -1, 7, 59, 246, 8, WC_STATIC,
  10810.      SS_TEXT | DT_CENTER | DT_TOP | WS_GROUP | WS_VISIBLE
  10811.      CONTROL "", 91, 43, 149, 8, WC_ENTRYFIELD,
  10812.      ES_MARGIN | ES_LEFT | WS_TABSTOP | WS_VISIBLE
  10813.      CONTROL "Enter", DID_OK, 38, 5, 38, 12, WC_BUTTON,
  10814.      BS_PUSHBUTTON | BS_DEFAULT | WC_TABSTOP | WC_VISIBLE
  10815.      CONTROL "Cancel", DID_CANCEL, 38, 5, 38, 12, WC_BUTTON,
  10816.      BS_PUSHBUTTON | WC_TABSTOP | WC_VISIBLE
  10817.    END
  10818. END
  10819.  
  10820. Dialog Template Resource Definition 
  10821.  
  10822. Thedialogtemplateisequivalenttoaframewindow ,andisnamedDC _ CREATE 
  10823. . ThissymbolicnameisusedtoidentifythedialogresourceandispassedasaparametertotheWinDlgBox 
  10824. ( )function ,whichloadsandprocessesthedialogbox .
  10825.  
  10826. The dialog box is defined with a title bar and a dialog border, and is also 
  10827. named using the symbolic name DC_CREATE.  The dialog box contains a static text 
  10828. control window providing instructions to the user, and an entry field into 
  10829. which the user may enter text.  It also contains an "Enter" and a "Cancel" 
  10830. pushbutton. 
  10831.  
  10832. Note that the resource identifier for the static text string does not use a 
  10833. symbolic constant, but simply has the value "-1".  This is done because there 
  10834. is no need for the application to access the text string; it is merely present 
  10835. as a prompt to the user.  It is therefore conventional to omit the symbolic 
  10836. constant and use "-1" as the value.  Multiple text strings may have the same 
  10837. value. 
  10838.  
  10839.  
  10840. ΓòÉΓòÉΓòÉ 17.2. Resource Script File ΓòÉΓòÉΓòÉ
  10841.  
  10842. The resource script file is an ASCII text file in which Presentation Manager 
  10843. resources are either defined or referenced.  A sample resource script file is 
  10844. given in Resource Script File. 
  10845.  
  10846. Note that the dialog templates are not defined directly in the resource script 
  10847. file, but are incorporated at the end of the resource script file using an 
  10848. rcinclude statement for the file mydlg.dlg. This is the typical way to 
  10849. incorporate dialog templates that are created by the Dialog Box Editor and 
  10850. stored in a DLG file. 
  10851.  
  10852. #include <os2.h>
  10853. #include "myappl.h"
  10854. #include "mydlg.h"
  10855.  
  10856. ICON   MAIN   APPLIC.ICO
  10857. ICON   CHILD1  CHILD1.ICO
  10858.  
  10859. BITMAP  INTRO   LOGO.BMP
  10860.  
  10861. STRINGTABLE MAIN   PRELOAD
  10862. BEGIN
  10863.    STR_MAINTITLE,   "Application Main Window"
  10864.    STR_LIST1,     "List of Objects"
  10865.    STR_MSGTITLE1,   "Title for Message Box"
  10866. END
  10867.  
  10868. MENU MAIN    PRELOAD
  10869. BEGIN
  10870.    SUBMENU "~File",  MI_FILE, MIS_TEXT
  10871.    BEGIN
  10872.      MENUITEM "~New...",  MI_NEW, MIS_TEXT
  10873.      MENUITEM "~Open",   MI_OPEN, MIS_TEXT
  10874.      MENUITEM "~Save",   MI_SAVE, MIS_TEXT
  10875.      MENUITEM "Save ~as", MI_SAVEAS, MIS_TEXT
  10876.    END
  10877.    SUBMENU "~Edit", MI_EDIT, MIS_TEXT
  10878.    BEGIN
  10879.      MENUITEM "Cu~t",   MI_CUT, MIS_TEXT
  10880.      MENUITEM "~Copy",   MI_COPY, MIS_TEXT
  10881.      MENUITEM "~Paste",  MI_PASTE, MIS_TEXT
  10882.    END
  10883.    MENUITEM "E~xit",     MI_EXIT, MIS_TEXT
  10884.    MENUITEM "~Help",     MI_HELP, MIS_HELP |
  10885.                     MIS_BUTTONSEPARATOR
  10886. END
  10887.  
  10888. ACCELTABLE MAIN
  10889. BEGIN
  10890.    VK_F3,   MI_EXIT, VIRTUALKEY
  10891.    VK_F5,   MI_TILE, VIRTUALKEY, SHIFT
  10892.    "D",    MI_DELETE, CHAR, CONTROL
  10893. END
  10894. ACCELTABLE CHILD1
  10895. BEGIN
  10896.    VK_F1,   MI_HELP, VIRTUALKEY, HELP
  10897.    VK_F3,   MI_EXIT, VIRTUALKEY
  10898.    "D",    MI_DELETE, CHAR, CONTROL
  10899. END
  10900.  
  10901. rcinclude MYDLG.DLG
  10902.  
  10903. Resource Script File 
  10904.  
  10905. The resource script file has a number of #include statements at the start, 
  10906. similar to those typically found in C programs.  This is because the symbolic 
  10907. names used throughout the resource script file represent integer constants, and 
  10908. must be defined in the application's header file myappl.h. Other symbolic names 
  10909. may be used in the .DLG file, and must also be defined;  the header file 
  10910. mydlg.h for these symbolic names is generated by the Dialog Box Editor. 
  10911. Finally, a number of symbolic names such as DID_OK and DID_CANCEL are actually 
  10912. defined by Presentation Manager  rather than by the application, and therefore 
  10913. the file os2.h is also required. 
  10914.  
  10915. The resource script file is used as input to the resource compiler provided as 
  10916. part of the IBM Developer's Toolkit for OS/2 2.0.  For further information on 
  10917. the resource compiler and its operation, see Resource Compilation. 
  10918.  
  10919.  
  10920. ΓòÉΓòÉΓòÉ 17.3. Using Resources ΓòÉΓòÉΓòÉ
  10921.  
  10922. As mentioned throughout this chapter, resources are typically loaded and used 
  10923. in an application by specifying the symbolic name of the resource as a 
  10924. parameter to a function that requires the resource.  The resource is then 
  10925. loaded and used by that function in performing its task.  However, there are 
  10926. several ways in which the resource may be loaded, depending upon where it 
  10927. resides.  These are discussed in the following sections. 
  10928.  
  10929.  
  10930. ΓòÉΓòÉΓòÉ 17.3.1. Loading From Within the Application ΓòÉΓòÉΓòÉ
  10931.  
  10932. In the typical case, resources are incorporated into an application by passing 
  10933. the resource script file to the resource compiler.  The resource compiler 
  10934. compiles the resource definitions and incorporates them into an executable file 
  10935. that has already been created. 
  10936.  
  10937. Many of the functions that require a resource identifier, such as 
  10938. WinLoadString() and WinLoadPointer(), also accept the identifier of a resource 
  10939. file as one of their parameters.  For resources that are incorporated into the 
  10940. application's .EXE file, this parameter should be specified as NULL.  For 
  10941. example, to load a pointer from a resource defined within the .EXE file, the 
  10942. following call is used: 
  10943.  
  10944. hPointer = WinLoadPointer(hDesktop,     /* Desktop handle           */
  10945.                           NULL,         /* Within .EXE file         */
  10946.                           DRAW);        /* Resource symbolic name   */
  10947. Other Presentation Manager functions that use this convention include 
  10948. WinLoadAccelTable(), WinLoadMenu() and WinCreateStdWindow(). 
  10949.  
  10950.  
  10951. ΓòÉΓòÉΓòÉ 17.3.2. Loading Resources From a DLL ΓòÉΓòÉΓòÉ
  10952.  
  10953. Presentation Manager resources may also be defined and stored in a dynamic link 
  10954. library. The process of compiling and placing resources in a DLL is described 
  10955. in  Presentation Manager Resources in a DLL.  Once a resource is located in a 
  10956. DLL however, the DLL module must be loaded into memory by the application, and 
  10957. a module handle obtained at run time before the resource may be accessed by a 
  10958. Presentation Manager function.  This is typically achieved using the 
  10959. DosLoadModule() or DosGetModuleHandle() functions. Loading Dialogs From a DLL 
  10960. illustrates the necessary code to load a dynamic link library named MYDLL from 
  10961. a directory identified in the LIBPATH statement in CONFIG.SYS, and to load a 
  10962. string resource from this DLL. 
  10963.  
  10964. rc = DosLoadModule(NULL,          /* No object name      */
  10965.           0,           /* No object length     */
  10966.           "MYDLL",        /* DLL module name      */
  10967.           hModule);        /* DLL handle (returned)   */
  10968.  
  10969. ulLength = WinLoadString(hAB,       /* Load string        */
  10970.              hModule,     /* DLL module handle     */
  10971.              STR_TITLE,    /* Resource ID within DLL  */
  10972.              sizeof(szTitle), /* Number of bytes      */
  10973.              szTitle);     /* Target buffer       */
  10974.  
  10975. Loading Resources From a DLL 
  10976.  
  10977. TheDosLoadModule ( )functioncallloadsthedynamiclinklibrarywiththename" MYDLL "( 
  10978. thedefaultextensionof. DLLisassumed 
  10979. )intomemoryandreturnsahandlehModuleoftypeHMODULE 
  10980. . ThishandleisthenpassedastheresourcefileidentifiertotheWinLoadString ( 
  10981. )functioncall ,whichaccessestheresourceswithinthemodule 
  10982. . OtherfunctioncallssuchasWinLoadPointer ( )workinasimilarmanner .
  10983.  
  10984.  
  10985. ΓòÉΓòÉΓòÉ 17.3.3. Loading Dialogs From a DLL ΓòÉΓòÉΓòÉ
  10986.  
  10987. The WinDlgBox() function also allows a DLL module handle to be specified, and 
  10988. thus enables dialog template definitions to be loaded from a DLL. For instance, 
  10989. to load and create a dialog box from a dialog template resource DC_001 defined 
  10990. in a DLL module named WINDLL.DLL, the following call sequence is used: 
  10991.  
  10992. frame=box.
  10993. rc = DosLoadModule(NULL,                  /* No object name           */
  10994.                    0,                     /* No object length         */
  10995.                    "MYDLL",               /* DLL module name          */
  10996.                    hModule);              /* DLL handle (returned)    */
  10997.  
  10998. rc = WinDlgBox(hDesktop,                  /* Desktop is parent        */
  10999.                hFrame,                    /* Frame is owner           */
  11000.                dpProc001,                 /* Dialog procedure address */
  11001.                hModule,                   /* DLL module handle        */
  11002.                DC_001,                    /* Resource ID within DLL   */
  11003.                NULL);                     /* No create parameters     */
  11004. Note that if the dialog procedure dpProc001 to be associated with this dialog 
  11005. box is also defined within the DLL module, the address of this procedure must 
  11006. be obtained by the application before the WinDlgBox() call is issued.  This is 
  11007. achieved using the DosGetProcAddr() function, which returns the address of the 
  11008. required function, as shown in the following example: 
  11009.  
  11010. rc = DosGetProcAddr(hModule,
  11011.                     "Proc1",
  11012.                     dpProc001);
  11013. In this case, Proc1 is the name of the required entry point in the DLL module, 
  11014. and dpProc001 is a variable of type PFNWP which contains the address of the 
  11015. procedure returned by the DosGetProcAddr() call.  While the address of the 
  11016. dialog procedure could have been supplied implicitly by using load-time rather 
  11017. than run-time dynamic linking, run-time dynamic linking is necessary to load 
  11018. the dialog box resource, and it is logical to place the resource and its 
  11019. associated dialog procedure in the same DLL module.  An example of the complete 
  11020. procedure required to load a dialog box from a DLL is given in Loading a Dialog 
  11021. Resource From a DLL. 
  11022.  
  11023. BOOL CustInfoDialog()
  11024. {
  11025.    HMODULE hModule;            /* DLL module handle    */
  11026.    PFNWP  dpDlgProc;           /* Dialog procedure addr  */
  11027.    USHORT  usResult;            /* Result storage      */
  11028.  
  11029.    DosGetModuleHandle("WINDLL",      /* Get DLL module handle  */
  11030.             hModule);
  11031.  
  11032.    DosGetProcAddr(hModule,         /* Get address of dialog  */
  11033.           "dpCustDlg",       /* procedure        */
  11034.           dpDlgProc);
  11035.  
  11036.    rc = WinDlgBox(HWND_DESKTOP,      /* Load & process dialog  */
  11037.           NULL,          /* No owner         */
  11038.           dpDlgProc,        /* Dialog procedure addr  */
  11039.           hModule,         /* DLL module handle    */
  11040.           DC_CUSTDLG,       /* Dialog template id    */
  11041.           NULL);          /* No create parameters   */
  11042.  
  11043.    return(usResult);
  11044. }
  11045.  
  11046. Loading a Dialog Resource From a DLL 
  11047.  
  11048. When loading dialogs from DLL modules, it is recommended that a combination of 
  11049. load-time and run-time dynamic linking techniques be used.  A calling routine 
  11050. should be placed in the DLL which, in response to an application request, loads 
  11051. and obtains the appropriate module handle, obtains the required dialog 
  11052. procedure address and executes the dialog.  This relieves the application of 
  11053. the responsibility for loading the dynamically-linked resources and routines. 
  11054. An example of such a routine is given in Loading a Dialog Resource From a DLL. 
  11055. The calling routine CustInfoDlg is defined as an entry point within the DLL 
  11056. module, since it will be called from the application's main executable module. 
  11057. An import library is then built for the DLL, and linked with the application 
  11058. code using standard conventions for load-time dynamic linking. 
  11059.  
  11060. When CustInfoDlg is invoked by the application, it obtains a module handle for 
  11061. its own DLL module, which has already been loaded when the call to CustInfoDlg 
  11062. was made, and uses this handle to obtain the address of the required dialog 
  11063. procedure using standard run-time dynamic linking conventions.  It then issues 
  11064. a WinDlgBox() call to load and process the dialog box, and returns the result 
  11065. to the application.  This example illustrates the combination of load-time and 
  11066. run-time dynamic linking conventions. 
  11067.  
  11068.  
  11069. ΓòÉΓòÉΓòÉ 17.4. Resources and National Language Support ΓòÉΓòÉΓòÉ
  11070.  
  11071. Since Presentation Manager resources provide the ability to define all the user 
  11072. interface properties of a Presentation Manager application, externally to the 
  11073. application code, they provide a useful means for implementing national 
  11074. language support within Presentation Manager applications.  Resources may be 
  11075. used to define: 
  11076.  
  11077.    o  Window titles 
  11078.    o  Menu bar and pulldown menu entries, including mnemonics and accelerator 
  11079.       keys 
  11080.    o  Dialogs 
  11081.    o  Messages 
  11082.    o  Symbols such as icons and pointers. 
  11083.  
  11084.  In short, all of the language-specific properties of an application may be 
  11085.  defined using Presentation Manager resources.  Icons and other graphical 
  11086.  symbols used by the user interface may also be tailored to suit different 
  11087.  cultures where such symbols may have different meanings. 
  11088.  
  11089.  The set of resources for each national language may be compiled and 
  11090.  incorporated into a separate dynamic link library, which may be accessed by 
  11091.  the application in order to load the required resources, as described in 
  11092.  Loading Dialogs From a DLL.  The resource identifiers must, of course, be 
  11093.  identical in each DLL.  Upon installation of the application on a workstation, 
  11094.  an installation procedure can prompt the user to determine the required 
  11095.  language, and install the appropriate DLL for that language. 
  11096.  
  11097.  Where multiple languages must be supported in the same system, an application 
  11098.  may query the codepage currently in use by its parent process using the 
  11099.  WinQueryCp() function, and load resources from a specific DLL, depending upon 
  11100.  the result of the function call.  While this method is by no means foolproof, 
  11101.  it will suffice for many languages that use a single national codepage and 
  11102.  single-byte characters. 
  11103.  
  11104.  
  11105. ΓòÉΓòÉΓòÉ 17.5. Summary ΓòÉΓòÉΓòÉ
  11106.  
  11107. It can be seen that Presentation Manager provides the mechanism by which an 
  11108. application developer may externally define the user interface properties of 
  11109. his/her application.  This ability provides the benefit that these external 
  11110. properties may be modified, or different versions substituted, without the need 
  11111. to modify the application code itself.  In addition, standard user interface 
  11112. objects such as icons, pointers and dialog boxes, along with their associated 
  11113. dialog routines, may be defined and stored in dynamic link libraries for use by 
  11114. multiple applications. 
  11115.  
  11116. Resources are defined using a resource script file, which is an ASCII text file 
  11117. containing definitions for text-based resources and references to other files 
  11118. that contain definitions for non-textual resources such as pointers and icons. 
  11119. The resource script file is used as input to the resource compiler, which 
  11120. compiles resource definitions and incorporates them into an executable module. 
  11121.  
  11122. Resources may be incorporated into the application's main .EXE file, or may be 
  11123. stored in a dynamic link library and loaded into memory using run-time dynamic 
  11124. linking.  Application procedures such as dialog procedures, which are 
  11125. associated with such resources, may also be defined and stored in the same DLL 
  11126. module, thus providing the opportunity to create libraries of standard 
  11127. resources, including standard dialogs, which may be used by multiple 
  11128. applications. 
  11129.  
  11130.  
  11131. ΓòÉΓòÉΓòÉ 18. Multitasking Considerations ΓòÉΓòÉΓòÉ
  11132.  
  11133. Systems Application Architecture CUA guidelines recommend that an application 
  11134. should complete  the processing of a user- or system-initiated event within 0.1 
  11135. seconds  and be ready to continue interaction with the end user.  The 
  11136. particular implementation of the message handling concept under Presentation 
  11137. Manager means that  the application's primary thread must complete the 
  11138. processing of a  Presentation Manager message before any further messages can 
  11139. be passed to  applications; thus it is possible for the user to be "locked out" 
  11140. of the system if an application does not complete its processing within  a 
  11141. reasonable period of time. 
  11142.  
  11143. While the 0.1 second time period is adequate for the processing of  most 
  11144. events, it may be insufficient for those that result in lengthy  processing 
  11145. such as access to a remote system.  It is therefore  recommended that any 
  11146. window procedure performing some processing that  is likely to take longer than 
  11147. 0.1 seconds to complete should carry out  this processing using a separate 
  11148. thread of execution under OS/2.  The application's primary thread may then 
  11149. initiate the secondary thread and immediately return control to Presentation 
  11150. Manager, thereby enabling the primary thread to continue with user interaction. 
  11151.  
  11152. The separation of processing into a primary and one or more  secondary threads 
  11153. may occur in a number of ways: 
  11154.  
  11155.    o  Where the window procedure is an object window procedure, and the 
  11156.       majority of its methods may result in lengthy processing, the window 
  11157.       procedure itself may be implemented in a secondary thread. 
  11158.  
  11159.    o  Where only a single method results in lengthy processing, or where  the 
  11160.       window procedure is concerned with a display object, a single subroutine 
  11161.       containing that method may be started in a secondary thread. 
  11162.  
  11163.  In certain circumstances where the different portions of an  application's 
  11164.  task are entirely self-contained, and where it is  desirable to isolate the 
  11165.  portions from one another, the application may  be divided into separate 
  11166.  processes. Division of the application in this way means that each portion 
  11167.  resides and executes in its own address space, fully protected from other 
  11168.  portions of the application.  This approach is particularly useful for 
  11169.  applications that exploit the Workplace Shell, since the implementation of the 
  11170.  Workplace Shell in OS/2 Version 2.0 causes Workplace Shell objects to execute, 
  11171.  by default, under the  control of the Workplace Shell process.  The use of 
  11172.  multiple processes within an  application provides better protection for 
  11173.  resources used by Workplace Shell  objects. 
  11174.  
  11175.  Note that for performance reasons, the use of multiple threads  within the 
  11176.  same process is preferable to the use of multiple  processes.  This is because 
  11177.  switching between threads involves far less  system overhead than switching 
  11178.  between processes. 
  11179.  
  11180.  Processes and threads may communicate with one another in a number  of ways 
  11181.  for the purposes of exchanging information, and for  synchronizing execution 
  11182.  flow and access to data objects.  The  techniques of communication between 
  11183.  threads and processes are described  in Communicating With a Secondary Thread 
  11184.  and Communicating With Another Process. 
  11185.  
  11186.    Maintaining synchronization between threads and processes is discussed in Maintaining Synchronization.
  11187.  
  11188.  
  11189. ΓòÉΓòÉΓòÉ 18.1. Creating a Secondary Thread ΓòÉΓòÉΓòÉ
  11190.  
  11191. In Application Structure, it is mentioned that an application must  create its 
  11192. own input message queue to process messages intended for its windows.  The 
  11193. Presentation Manager  message-handling implementation creates message queues on 
  11194. a per-thread basis, and thus requires that any thread that creates a window 
  11195. (whether that window is a display window or an object window) and processes 
  11196. messages must have its own message queue. 
  11197.  
  11198. The primary thread of an application is typically a user interface  thread that 
  11199. handles processing for display windows on the screen; this  thread creates the 
  11200. application's main message queue and processes  messages caused by user 
  11201. interaction.  The primary thread may also  create a secondary thread to deal 
  11202. with messages that cause lengthy  processing to be carried out, leaving the 
  11203. primary thread free to  respond to user input.  A secondary thread may be 
  11204. created in one of two  ways: 
  11205.  
  11206.    o  The _beginthread() function provided by the C compiler should be used to 
  11207.       create secondary threads that will contain object windows, or that 
  11208.       contain code which calls C run-time library functions.  This function 
  11209.       maintains certain internal C library control data that is, by default, 
  11210.       not maintained by the DosCreateThread() function. 
  11211.  
  11212.    o  The DosCreateThread() function provided by OS/2 may be used to create 
  11213.       secondary threads that will not contain object windows, and that do not 
  11214.       call C run-time library functions.  The DosCreateThread() function offers 
  11215.       a  slight performance advantage over the _beginthread()  function. 
  11216.  
  11217.  The _beginthread() function is used since it establishes  internal semaphores 
  11218.  to serialize access to the run-time library's  global data and non-reentrant 
  11219.  library functions, transparently to the  calling application. The 
  11220.  _beginthread() function also  maintains information for each thread, such as 
  11221.  the exception handling  environment and the calling address for reentrant 
  11222.  functions.  Since  window procedures are reentrant, use of DosCreateThread() 
  11223.  in  such situations may cause execution errors. 
  11224.  
  11225.  Whenever a thread is created, a thread information block  (TIB) is created by 
  11226.  the operating system. The TIB contains information such as the thread ID, 
  11227.  priority and stack size.  This information may be accessed by the application 
  11228.  using the DosGetInfoBlocks() function.  This function also returns a pointer 
  11229.  to information on the thread's parent process, which resides in the process 
  11230.  information  block (PIB). The DosGetInfoBlocks() function is described in the 
  11231.  IBM OS/2 Version 2.0 Control Program Reference. 
  11232.  
  11233.  
  11234. ΓòÉΓòÉΓòÉ 18.1.1. Threads Containing Object Windows ΓòÉΓòÉΓòÉ
  11235.  
  11236. In the case where the processing of an event involves access to and 
  11237. manipulation of another data object, the secondary thread should create its own 
  11238. message queue and one or more object windows with window procedures to process 
  11239. any messages passed by the primary thread.  This technique preserves the 
  11240. object-oriented nature of the application by isolating data objects from one 
  11241. another. 
  11242.  
  11243. The primary thread then passes messages to the secondary thread's  object 
  11244. windows, in an identical manner to that used when passing  messages to a window 
  11245. procedure in the primary thread; it is recommended that this be achieved using 
  11246. the  WinPostMsg() function, since this call allows asynchronous processing of 
  11247. the message and preserves the correct serialization of messages in the system, 
  11248. as described in Invoking a Window Procedure. 
  11249.  
  11250. Asynchronous threads with object windows are normally created by  window 
  11251. procedures in the application's primary thread issuing a  _beginthread() 
  11252. function call.  This call is typically made  by a window procedure during its 
  11253. processing of the WM_CREATE message;  the secondary thread and its object 
  11254. window (or windows) are then  initialized and able to accept any requests 
  11255. passed to them.  An example  of the _beginthread() function is shown in 
  11256. Creating a Thread With an Object Window. 
  11257.  
  11258. #define  STACKSIZE   8192
  11259.  :
  11260.  :
  11261. case WMP_DOLONGTASK:
  11262.    _beginthread(thread,       /* Entry point of thread routine  */
  11263.          &Stack,       /* Pointer to stack memory object  */
  11264.          STACKSIZE,      /* Size of stack memory object   */
  11265.          (PVOID)hwnd);    /* Initialization data for thread  */
  11266.    break;
  11267.  
  11268. Creating a Thread With an Object Window 
  11269.  
  11270. NotethatwhenusingtheIBMCSet / 2compiler ,thesecondparameterin the_ beginthread 
  11271. ( )functioncall( thepointertothestack ) isignored ,sincethe_ beginthread ( 
  11272. )functionautomatically allocatesmemoryforthestack 
  11273. .Thisparameterisincludedmerelyto allowsourcecodecompatibilitywithapplicationswrittenforthe earlierIBMC 
  11274. / 2andMicrosoftCcompilers 
  11275. ,whichrequiredthe applicationtoexplicitlyallocatestackspaceforasecondarythread 
  11276. . Notethattheminimumrecommendedstacksizeforathreadcontaining objectwindowsis8192bytes( 
  11277. 8KB ) .
  11278.  
  11279. The handle of the window from which the secondary thread is being  created is 
  11280. passed to the thread in the _beginthread() call.  The secondary thread's main 
  11281. routine may then pass this handle to the  object window created in the thread. 
  11282. Upon successful creation, the  object window can then pass an acknowledgement 
  11283. message back to the  window that created it, containing the handle of the 
  11284. object window, in  order that the calling window may then post messages to the 
  11285. object  window.  This acknowledgement message also ensures that the object 
  11286. window is correctly created and initialized before any messages are  posted to 
  11287. it. 
  11288.  
  11289. The secondary thread's main routine is similar in structure to the  main 
  11290. routine of the primary thread in a Presentation Manager application.  The main 
  11291. routine registers the object window class, creates a window of that  class and 
  11292. enters a message processing loop. 
  11293.  
  11294. It should be noted that the secondary thread's main routine is  identical to 
  11295. that of the application's primary thread, with the  exception that a secondary 
  11296. thread need not register itself to Presentation Manager,  since this is 
  11297. typically done once per application, by the primary  thread.  However, if 
  11298. certain functions such as error processing are  required on a per-thread basis, 
  11299. a separate anchor block must be created  for the secondary thread, and hence an 
  11300. additional  WinInitialize() call must be made. 
  11301.  
  11302. Secondary Thread Creating an Object Window shows a secondary thread that 
  11303. registers an  object window class and creates a window of that class. 
  11304.  
  11305. void thread(HWND hWnd)
  11306. {
  11307.   HMQ  hMsgQ;              /* Message queue handle    */
  11308.   HWND hWindow;             /* Window handles       */
  11309.   QMSG qMsg;              /* Message queue structure  */
  11310.  
  11311.   WinRegisterClass(hAB,         /* Register window class   */
  11312.            WCP_OBJECT,     /* Class name         */
  11313.            (PFNWP)wpObject,   /* Window procedure      */
  11314.            0L,         /* No class style       */
  11315.            0);         /* No extra window words   */
  11316.  
  11317.   hObject=WinCreateWindow(HWND_OBJECT, /* Create object window    */
  11318.               WCP_OBJECT,  /* Object handle is parent  */
  11319.               (PSZ)0,    /* No window text       */
  11320.               0L,      /* No style          */
  11321.               0,0,0,0,   /* No position        */
  11322.               NULL,     /* No owner          */
  11323.               HWND_TOP,   /* On top of siblings     */
  11324.               0,      /* No window id        */
  11325.               hWnd,     /* Handle in WM_CREATE    */
  11326.               0);      /* No pres. parameters    */
  11327.  
  11328.   while (WinGetMsg(hAB,         /* Loop until WM_QUIT     */
  11329.            &qMsg,
  11330.            (ULONG)0,
  11331.            0, 0))
  11332.       WinDispatchMsg(hAB, &qMsg);
  11333.  
  11334.   WinDestroyWindow(hObject);      /* Destroy object window   */
  11335.   WinDestroyMsgQueue(hMsgQ);      /* Destroy message queue   */
  11336.   _endthread();             /* Terminate thread      */
  11337. }
  11338.  
  11339. Secondary Thread Creating an Object Window 
  11340.  
  11341. An object window is created using the normal  WinCreateWindow() call, as 
  11342. illustrated in Secondary Thread Creating an Object Window.  The window's parent 
  11343. is  specified as the conceptual object window, the handle of which is  obtained 
  11344. from the WinQueryObjectWindow() function, or using the defined constant 
  11345. HWND_OBJECT.  Note that the  handle of the window that created the thread is 
  11346. passed to the object  window in the CtlData parameter of the  WinCreateWindow() 
  11347. call, in order that the object window may  pass its handle back to the calling 
  11348. window to indicate its readiness to  receive messages. 
  11349.  
  11350. The secondary thread retrieves messages from its input queue in the 
  11351. conventional manner using WinGetMsg(), and invokes Presentation Manager  using 
  11352. WinDispatchMsg() to pass the message to its object  window procedure.  Thus a 
  11353. secondary thread has a message processing  loop similar to that of the 
  11354. application's (primary thread's) main  routine. 
  11355.  
  11356. An object window procedure is identical in structure to a  "normal" display 
  11357. window procedure.  An example of an object window  procedure is illustrated in 
  11358. Sample Object Window Procedure. 
  11359.  
  11360. MRESULT EXPENTRY wpObject(HWND hWnd,
  11361.              ULONG ulMsg,
  11362.              MPARAM mp1,
  11363.              MPARAM mp2)
  11364. {
  11365.     HWND   hNotify;
  11366.     HWND   hObject;
  11367.  
  11368.     switch (ulMsg)
  11369.         {
  11370.         case WM_CREATE:
  11371.           WinDefWindowProc(hWnd,
  11372.                    usMsg,
  11373.                    mp1,
  11374.                    mp2);
  11375.           <initialize instance data>
  11376.           <open data objects>
  11377.  
  11378.           hNotify=HWNDFROMMP(mp1);
  11379.           hObject=MPFROMHWND(hWnd);
  11380.           WinPostMsg(hNotify,
  11381.                 WMP_NOTIFY,
  11382.                 hObject,
  11383.                 0);
  11384.  
  11385.           return((MRESULT)FALSE);
  11386.           break;
  11387.         case WMP_PUTDATA:
  11388.           <put data into database>
  11389.           <post message to logging object>
  11390.           return((MRESULT)TRUE);
  11391.           break;
  11392.         case WMP_GETDATA:
  11393.           <get data from database>
  11394.           <post data to caller in message>
  11395.           return((MRESULT)TRUE);
  11396.           break;
  11397.         case WM_DESTROY:
  11398.           <close data objects>
  11399.           <free any instance data areas>
  11400.           return((MRESULT)0);
  11401.           break;
  11402.         default:
  11403.           return(WinDefWindowProc(hWnd,
  11404.                       ulMsg,
  11405.                       mp1,
  11406.                       mp2));
  11407.         }
  11408. }
  11409.  
  11410. Sample Object Window Procedure 
  11411.  
  11412. Upon creation, an object window receives a WM_CREATE message in the same way as 
  11413. a standard window.  The window may capture and explicitly process this message 
  11414. in order to open  or create data objects, initialize instance data, etc., as 
  11415. illustrated  in Sample Object Window Procedure.  Once opened, however, 
  11416.  
  11417.  an object window typically only receives a number of application-defined
  11418. messages requesting certain actions on  data objects owned by the window. 
  11419.  
  11420. The object window procedure shown in Sample Object Window Procedure  also 
  11421. extracts the handle of the window that issued the WinCreateWindow() function 
  11422. call, which is normally passed to  the object window as part of the WM_CREATE 
  11423. message.  The window  procedure then uses this handle to send an 
  11424. acknowledgement message back  to this window, containing its own window handle 
  11425. and thus enabling the  two windows to communicate with one another.  This is 
  11426. necessary when  object windows are created in secondary threads, as described 
  11427. in  Communicating With a Secondary Thread.  Note that the object window 
  11428. procedure must use  the system linkage convention; this is achieved using the 
  11429. EXPENTRY keyword. 
  11430.  
  11431. The only other system-defined message class normally received by an  object 
  11432. window is the WM_DESTROY message class passed to the window by  Presentation 
  11433. Manager when a WinDestroyWindow() call is issued by the  thread.  An object 
  11434. window should respond to the WM_DESTROY message by  closing, destroying or 
  11435. freeing any data objects to which it has  obtained access, and backing out any 
  11436. uncommitted units of work. 
  11437.  
  11438. Sample Object Window Procedure shows a number of application-defined message 
  11439. classes being processed by the object window procedure.  These message  classes 
  11440. are typically defined by the application during its  initialization.  For 
  11441. message classes that will be processed by an  object window procedure loaded 
  11442. from a DLL module, the message classes  should be defined in the include file 
  11443. for that DLL module, rather than  explicitly within the application that uses 
  11444. the DLL module.  This  further enhances the isolation of the internal workings 
  11445. of the object  window from other components of the application, and facilitates 
  11446. reusability of the code. 
  11447.  
  11448. The window procedure in the primary thread must have some way of determining 
  11449. when the object window has completed its processing, at  which point it may 
  11450. safely assume that the previous event has been  processed successfully and 
  11451. allow the user to continue operating upon  the data object, or take appropriate 
  11452. error action.  This indication may  be provided in a number of ways, which are 
  11453. discussed in  Maintaining Synchronization. 
  11454.  
  11455.  
  11456. ΓòÉΓòÉΓòÉ 18.1.2. Threads Without Object Windows ΓòÉΓòÉΓòÉ
  11457.  
  11458. When the processing to be performed within a secondary thread is  limited in 
  11459. scope to the data objects "owned" by the current application  object, an object 
  11460. window is not warranted.  A secondary thread without  an object window is 
  11461. similar in both appearance and  behavior to a  normal subroutine. However, the 
  11462. routine executing in the secondary  thread performs its tasks asynchronously to 
  11463. the primary thread,  although it still has access to the same data objects. 
  11464. Such a thread  is typically started when required by issuing a 
  11465. DosCreateThread() call from within a window procedure in the primary thread.  A 
  11466. sample invocation of such a thread is illustrated in Creating a Thread Without 
  11467. an Object Window. 
  11468.  
  11469. case WMP_THREAD:
  11470.    usReturn=DosCreateThread(ThreadID,   /* Create thread        */
  11471.          ThreadRoutine,       /* Routine to run in thread  */
  11472.          &InitData,         /* Initialization data     */
  11473.          0L,            /* Start immediately      */
  11474.          4096);           /* Stack size for thread    */
  11475.    break;
  11476.  
  11477. Creating a Thread Without an Object Window 
  11478.  
  11479. Two considerations arise when processing asynchronous threads  without the use 
  11480. of object windows: 
  11481.  
  11482.    o  The primary thread must not attempt to access a data object at the same 
  11483.       time as a secondary thread is updating that data object, since the state 
  11484.       of the data during the update is undetermined and unpredictable results 
  11485.       could occur. 
  11486.  
  11487.    o  The primary thread must have some way of determining when the secondary 
  11488.       thread has completed its processing, at which point it may then access 
  11489.       the data objects that were manipulated by the secondary thread. 
  11490.  
  11491.  These two conditions may be achieved by adopting a convention whereby a 
  11492.  secondary thread has exclusive access to its data object(s) for the duration 
  11493.  of its execution.  It is therefore only necessary for the  primary thread to 
  11494.  determine when the secondary thread has completed  processing, at which point 
  11495.  it may access the data objects. 
  11496.  
  11497.  Where this is not possible, mutex semaphores may be used to  serialize access 
  11498.  to resources such as data objects.  Each thread that  requires access must bid 
  11499.  for the semaphore.  If the semaphore is  already held by another thread, the 
  11500.  requesting thread must wait for  that thread to release the semaphore before 
  11501.  attempting to access the  resource. 
  11502.  
  11503.  A number of mechanisms for synchronizing execution and/or access to resources 
  11504.  are described in Maintaining Synchronization. 
  11505.  
  11506.  
  11507. ΓòÉΓòÉΓòÉ 18.2. Creating Another Process ΓòÉΓòÉΓòÉ
  11508.  
  11509. Each application running under OS/2 typically resides in its own  process, and 
  11510. therefore has its own address space.  Resources created by  or allocated to a 
  11511. process are normally private to that process.  If  required for application 
  11512. purposes, this process may in turn create one  or more additional processes to 
  11513. perform part of the application's processing.  Additional processes  may be 
  11514. created in either of two ways: 
  11515.  
  11516.    o  As a child process of the creating process, in which case the child 
  11517.       process will automatically terminate upon termination of the creating 
  11518.       process.  Such processes are started using the DosExecPgm()  function. 
  11519.  
  11520.    o  As a separate process, in which case the process will not automatically 
  11521.       terminate when its creator terminates, and must be explicitly terminated 
  11522.       either by its creator or by another process in the system. Such a process 
  11523.       is started using the  DosStartSession() function. 
  11524.  
  11525.  When an application uses multiple processes, it is usual for the first process 
  11526.  to be regarded as the "primary" process for the  application, and for other 
  11527.  processes to be started as children of this  process.  This is conceptually 
  11528.  similar to the use of primary and  secondary threads. 
  11529.  
  11530.  It is therefore conventional to use the DosExecPgm()  function to start a 
  11531.  child process.  This function is illustrated in  Starting a Child Process. 
  11532.  
  11533.   CHAR     szClient[7];          /* ASCII form of win handle  */
  11534.   CHAR     LoadError[100];         /* Buffer for failure reason  */
  11535.   RESULTCODES ReturnInfo;           /* Returned info from call   */
  11536.   PID     pidServer;           /* Child process id      */
  11537.   APIRET    rc;               /* Return code         */
  11538.    :
  11539.    :
  11540.   itoa(hWnd, szClient);            /* Convert handle to ASCII   */
  11541.  
  11542.   rc = DosExecPgm(LoadError,         /* Start child process     */
  11543.           sizeof(LoadError),     /* Size of buffer       */
  11544.           EXEC_ASYNCRESULT,      /* Execute asynchronously   */
  11545.           szClient,          /* Window handle in ASCII   */
  11546.           0,             /* No new environment vars   */
  11547.           &ReturnInfo,        /* Returned info address    */
  11548.           "server.exe");       /* Name of program to start  */
  11549.  
  11550.   pidServer = ReturnCodes.termcodepid;
  11551.  
  11552.   <Store pidServer in window words>
  11553.  
  11554.  Starting a Child Process 
  11555.  
  11556.   This example shows the use of the DosExecPgm() function to
  11557.   start a process from another process within the application.
  11558.  The window handle of the window from which the DosExecPgm()  call is made, is 
  11559.  passed to the child process as an argument, using the  the fourth parameter of 
  11560.  the DosExecPgm() function.  This  enables the child process to post a message 
  11561.  to its parent upon  completing its initialization, indicating the window 
  11562.  handle of its own  window.  In this way, communication via Presentation 
  11563.  Manager messages may be  established in both directions. 
  11564.  
  11565.  Note that since the fourth parameter to the DosExecPgm()  function is defined 
  11566.  as an ASCII string, the window handle is converted  to its ASCII equivalent 
  11567.  before the call is issued.  The main routine of  the child process 
  11568.  subsequently converts the handle back to its true  form. 
  11569.  
  11570.  Use of the EXEC_ASYNCRESULT flag in the DosExecPgm() call  causes the 
  11571.  operating system to save the termination codes of the child  process so that 
  11572.  they may be examined at a later point by the parent  process, using a 
  11573.  DosWaitChild() function call for  synchronization purposes (see DosWaitChild() 
  11574.  Function for further  information). 
  11575.  
  11576.  The process ID of the child process is returned by the  DosExecPgm() function 
  11577.  as part of the RESULTCODES structure  in the sixth parameter. This value 
  11578.  should be stored by the parent  process, since it is used if and when the 
  11579.  parent process needs to  terminate the child at some later point during 
  11580.  execution. 
  11581.  
  11582.  
  11583. ΓòÉΓòÉΓòÉ 18.3. Destroying a Secondary Thread ΓòÉΓòÉΓòÉ
  11584.  
  11585. Secondary threads should be terminated when they are no longer required, to 
  11586. reduce the context-switching  overhead of the operating system.  The method of 
  11587. termination depends  upon how the secondary thread was created, and whether or 
  11588. not it has  created object windows. 
  11589.  
  11590.  
  11591. ΓòÉΓòÉΓòÉ 18.3.1. Threads Containing Object Windows ΓòÉΓòÉΓòÉ
  11592.  
  11593. A secondary thread with an object window should be terminated by the window 
  11594. procedure in the primary thread that initially created the secondary thread. 
  11595. This is achieved simply by posting a WM_QUIT message to the object window, 
  11596. which will cause the message processing loop for the secondary thread to 
  11597. terminate. 
  11598.  
  11599. The thread's main routine then issues WinDestroyWindow() calls for its object 
  11600. windows.  These calls cause WM_DESTROY messages to  be posted to the object 
  11601. windows, which will process these messages in  order to close data objects, 
  11602. release any resources, etc., in accordance  with established conventions. 
  11603.  
  11604. Once all data objects and other resources have been released or  destroyed, the 
  11605. thread should terminate itself using the  _endthread() function. The use of 
  11606. this function will ensure that the semaphores and control structures used by 
  11607. the _beginthread() function are correctly  reset. 
  11608.  
  11609.  
  11610. ΓòÉΓòÉΓòÉ 18.3.2. Threads Without Object Windows ΓòÉΓòÉΓòÉ
  11611.  
  11612. Secondary threads without object windows are typically created to  perform a 
  11613. lengthy processing operation within the scope of a single  event.  A window 
  11614. procedure under the control of the primary thread  creates the secondary thread 
  11615. to process a particular subroutine, and  the secondary thread terminates 
  11616. automatically when this subroutine  reaches an exit point.  However, the 
  11617. DosExit() function should be called as the last action in the secondary thread, 
  11618. in order  to ensure that the memory allocated for the thread's stack is 
  11619. correctly released by the operating system. 
  11620.  
  11621. However, some checks may be necessary to ensure orderly termination  of a 
  11622. secondary thread, particularly where access to data objects is  involved. Upon 
  11623. termination of an application's primary thread, all  secondary threads that 
  11624. have not already been terminated by the  application are forcibly terminated by 
  11625. OS/2.  Where the secondary  thread's processing involves a critical data 
  11626. operation such as the  update of a database, the primary thread should ensure 
  11627. that the  secondary thread has completed its processing before allowing itself 
  11628. to  terminate. 
  11629.  
  11630. It is recommended that before creating a secondary thread without an object 
  11631. window, a window procedure should set an event semaphore, and  pass the handle 
  11632. of this semaphore to the secondary thread.  The event  semaphore is then 
  11633. cleared by the secondary thread as the last  action before it terminates. 
  11634.  
  11635. Upon receiving a WM_DESTROY message, the window procedure in the  primary 
  11636. thread should test the state of the event semaphore and wait  for the semaphore 
  11637. to clear before completing the WM_DESTROY message  processing (which should 
  11638. include releasing the semaphore) and returning  control to Presentation 
  11639. Manager.  This will ensure that the secondary thread  terminates in an orderly 
  11640. manner before the primary thread is terminated. 
  11641.  
  11642. The use of event semaphores is described in more detail in  Maintaining 
  11643. Synchronization. 
  11644.  
  11645.  
  11646. ΓòÉΓòÉΓòÉ 18.3.3. Forcing Termination of a Thread ΓòÉΓòÉΓòÉ
  11647.  
  11648. In certain circumstances, it may be necessary to terminate a  secondary thread 
  11649. without waiting for the thread to complete its  processing; for example, the 
  11650. user may decide to exit from the  application.  This capability is provided 
  11651. under OS/2 Version 2.0 using the  DosKillThread() function.  This function is 
  11652. illustrated in DosKillThread() Function. 
  11653.  
  11654. <Retreive thread id from window words>
  11655.  
  11656. usReturn = DosKillThread(ThreadID);  /* Destroy secondary thread     */
  11657.  
  11658. DosKillThread() Function 
  11659.  
  11660. This function allows the forced termination of a thread.
  11661. Note that the DosKillThread() function cannot be used to  terminate the current 
  11662. thread; if the application attempts to issue a  DosKillThread() function call 
  11663. for the current thread, the  function will return an error. To terminate a 
  11664. secondary thread from  within that thread, the _endthread() function should be 
  11665. used  if the thread was created with the _beginthread() function,  or the 
  11666. DosExit() function may be used if the thread was  created using the 
  11667. DosCreateThread() function. 
  11668.  
  11669.  
  11670. ΓòÉΓòÉΓòÉ 18.4. Terminating a Process ΓòÉΓòÉΓòÉ
  11671.  
  11672. A process may terminate another process running in the system, provided it has 
  11673. access to the process ID of the process it wishes to terminate.  This process 
  11674. ID is returned by the DosExecPgm() function when the process is created and 
  11675. since, in the majority of  cases, a process is terminated by the process that 
  11676. created it, this  presents no particular problem since the process ID can be 
  11677. stored as a  global variable or as instance data in window words, until it is 
  11678. needed  to terminate the process. 
  11679.  
  11680. A process is terminated using the DosKillProcess()  function.  This function 
  11681. may be used to terminate a single process, or  to terminate a process and all 
  11682. its descendants (that is, its children,  along with their children, and so on). 
  11683. An example of the  DosKillProcess() function is given in Terminating a Process. 
  11684.  
  11685. <Retrieve process id from window words>
  11686.  
  11687. rc = DosKillProcess(1,           /* Kill only this process   */
  11688.           pidServer);       /* Process ID to be killed   */
  11689.  
  11690. Terminating a Process 
  11691.  
  11692. This example shows the use of the DosKillProcess() function to
  11693. terminate a single process.
  11694. The value of "1" specified for the first parameter in the  DosKillProcess() 
  11695. call causes the function to terminate only  the specified process and not its 
  11696. descendants (if any). 
  11697.  
  11698.  
  11699. ΓòÉΓòÉΓòÉ 18.5. Communicating With a Secondary Thread ΓòÉΓòÉΓòÉ
  11700.  
  11701. The primary thread may wish to communicate with the secondary thread in order 
  11702. to initiate an event or transfer data.  The methods available  for such 
  11703. communication differ, depending upon whether the secondary  thread contains an 
  11704. object window. 
  11705.  
  11706.  
  11707. ΓòÉΓòÉΓòÉ 18.5.1. Threads Containing Object Windows ΓòÉΓòÉΓòÉ
  11708.  
  11709. When a secondary thread is created, and in turn creates an object  window as 
  11710. shown in Secondary Thread Creating an Object Window, the handle of the calling 
  11711. window  may be passed to the object window as part of the WM_CREATE message, 
  11712. and the object window procedure uses this handle to pass its own window  handle 
  11713. back to the calling window as part of an acknowledgement  message.  This 
  11714. technique is illustrated in the sample object window  procedure shown in Sample 
  11715. Object Window Procedure. 
  11716.  
  11717. Once the calling window receives this message and extracts the  object window's 
  11718. handle, it should store the handle in its own instance  data.  It may then use 
  11719. the handle at any time to pass a Presentation Manager message  to the object 
  11720. window, in order to initiate an event in the object  window. 
  11721.  
  11722. By convention, messages passed to an object window should contain  the window 
  11723. handle of the calling window, within the message  parameters.  The object 
  11724. window procedure may then use this handle to  pass an acknowledgement message 
  11725. or return data to the calling window in  the primary thread.  This technique 
  11726. allows the same object window to  process messages from multiple sources.  See 
  11727. Client-Server Applications for  additional considerations. 
  11728.  
  11729. Note that messages passed to object windows in secondary threads  should be 
  11730. posted using the WinPostMsg() function,  rather than being sent using the 
  11731. WinSendMsg() function.  This causes asynchronous processing of the message, and 
  11732. allows the  primary thread to return to Presentation Manager and continue 
  11733. interaction with the  end user. 
  11734.  
  11735. In situations where the user must be prevented from carrying out  certain 
  11736. actions while the object window processes an event, the calling  window 
  11737. procedure should disable those actions in the action bar  immediately before 
  11738. posting the message to the object window,  and re-enable those actions only 
  11739. after a completion message  has been received from the object window.  This 
  11740. prevents the user from  carrying out such actions, but does not prohibit other 
  11741. actions within  the application, or interaction with other applications on the 
  11742. desktop. 
  11743.  
  11744.  
  11745. ΓòÉΓòÉΓòÉ 18.5.2. Threads Without Object Windows ΓòÉΓòÉΓòÉ
  11746.  
  11747. Where a secondary thread is created only to process a specific  event, and 
  11748. where the thread terminates upon completion of that event,  communication 
  11749. between the primary and secondary threads is usually not  required. Necessary 
  11750. data is communicated to the secondary thread as  part of the DosCreateThread() 
  11751. function, including pointers to the data objects upon which the thread must 
  11752. operate.  The secondary thread then proceeds to process the event, 
  11753. independently of the primary thread. 
  11754.  
  11755. The only communication from the secondary thread to the primary  thread occurs 
  11756. upon completion of the event, when the secondary thread  signals this 
  11757. completion to the primary thread.  Completion may be  signalled by Presentation 
  11758. Manager messages or via semaphores; see  Maintaining Synchronization for 
  11759. further discussion. 
  11760.  
  11761.  
  11762. ΓòÉΓòÉΓòÉ 18.6. Communicating With Another Process ΓòÉΓòÉΓòÉ
  11763.  
  11764. Communication between processes must use one of the architected  methods 
  11765. provided by OS/2, since the operating system by default  prohibits different 
  11766. processes from accessing the same resources.  For  this reason, communication 
  11767. between processes is slightly more complex  than communication between threads, 
  11768. but requires less care on the part  of the programmer to ensure synchronization 
  11769. and data integrity. 
  11770.  
  11771. The mechanisms provided by OS/2 for interprocess communication are: 
  11772.  
  11773.    o  Presentation Manager messages 
  11774.    o  Shared memory 
  11775.    o  Queues 
  11776.    o  Pipes (both named and anonymous) 
  11777.    o  Atoms 
  11778.    o  Dynamic data exchange (DDE). 
  11779.  
  11780.  Each of these mechanisms is explained in detail in the  IBM OS/2 Version 2.0 
  11781.  Application Design Guide, and simple examples are given in the following 
  11782.  sections. 
  11783.  
  11784.  
  11785. ΓòÉΓòÉΓòÉ 18.6.1. Presentation Manager Messages ΓòÉΓòÉΓòÉ
  11786.  
  11787. When a child process creates its own windows, Presentation Manager messages can 
  11788. be  used to signal events and/or pass information between the parent and  child 
  11789. processes, provided the windows' handles are known to one another.  One 
  11790. technique  for passing window handles during process creation is described in 
  11791. Creating Another Process.  Even where the child process does not create its 
  11792. own windows, it may use Presentation Manager messages to indicate events and 
  11793. pass  information to its parent process. 
  11794.  
  11795. The amount of information which can be passed in a Presentation Manager message 
  11796. is somewhat limited, due to the four-byte size of each message parameter.  The 
  11797. use of Presentation Manager messages for passing information is therefore 
  11798. typically combined with other mechanisms such as shared memory or  atoms.  The 
  11799. message parameters are then used to carry pointers to  shared memory objects, 
  11800. or string handles that are then used by the  child process to access the 
  11801. required information. 
  11802.  
  11803.  
  11804. ΓòÉΓòÉΓòÉ 18.6.2. Shared Memory ΓòÉΓòÉΓòÉ
  11805.  
  11806. Shared memory objects may be allocated and used to pass information between 
  11807. specific processes.  Such memory objects may be named or anonymous. 
  11808.  
  11809. The example that follows assumes that two processes are created in  the system: 
  11810. a client process that accepts user input and displays  results, and a server 
  11811. process that accepts requests from the client,  accesses data objects and 
  11812. returns the requested data to the client.  Both of these processes create 
  11813. windows. 
  11814.  
  11815. In order to communicate a request to the server, the client must  first 
  11816. allocate a shared memory object, using the  DosAllocSharedMem() function as 
  11817. described in The Flat Memory Model.  Since the process  ID of the server 
  11818. process is known to the client, the client can provide  access to the shared 
  11819. memory object for the server process, using the  DosGiveSharedMem() function, 
  11820. which is also described in The Flat Memory Model.  This technique  is shown in 
  11821. Interprocess Communication Using Shared Memory (Part 1). 
  11822.  
  11823. REQUEST *Request;                /* Request structure   */
  11824. REPLY  *Reply;                 /* Reply structure ptr  */
  11825.  :
  11826. CASE WMP_SENDREQUEST:
  11827.    rc = DosAllocShrMem(&Request,        /* Allocate memory obj  */
  11828.              NULL,          /* Anonymous memory obj  */
  11829.              sizeof(REQUEST),    /* Size of memory obj   */
  11830.              OBJ_GIVEABLE,      /* Object is giveable   */
  11831.              PAG_WRITE |       /* Allow write access   */
  11832.              PAG_READ  |       /* Allow read access   */
  11833.              PAG_COMMIT);      /* Commit storage now   */
  11834.    rc = DosGiveSharedMem(Request,       /* Give access to object */
  11835.               pidServer,      /* Process to get access */
  11836.               PAG_WRITE |      /* Write access allowed  */
  11837.               PAG_READ);      /* Read access allowed  */
  11838.  
  11839.    rc = DosAllocShrMem(&Reply,         /* Allocate memory obj  */
  11840.              NULL,          /* Anonymous memory obj  */
  11841.              sizeof(REPLY),     /* Size of memory obj   */
  11842.              OBJ_GIVEABLE,      /* Object is giveable   */
  11843.              PAG_WRITE |       /* Allow write access   */
  11844.              PAG_READ  |       /* Allow read access   */
  11845.              PAG_COMMIT);      /* Commit storage now   */
  11846.    rc = DosGiveSharedMem(Reply,        /* Give access to object */
  11847.               pidServer,      /* Process to get access */
  11848.               PAG_WRITE |      /* Write access allowed  */
  11849.               PAG_READ);      /* Read access allowed  */
  11850.  
  11851.    Request->hRequester = hWnd;         /* Set requester handle  */
  11852.  
  11853.    <Initialize other Request structure fields>
  11854.  
  11855.    WinPostMsg(hServer,             /* Post msg to server   */
  11856.         WMP_DOREQUEST,          /* DO_REQUEST message   */
  11857.         (MPARAM)Request,         /* Ptr to request object */
  11858.         (MPARAM)Reply);         /* Ptr to reply object  */
  11859.  
  11860.    DosFreeMem(Request);            /* Release request obj  */
  11861.    break;
  11862.     :
  11863. case WMP_REQUESTCOMPLETE:
  11864.    Reply=(PVOID)mp1;
  11865.  
  11866.    <Copy contents of Reply to private memory>
  11867.  
  11868.    DosFreeMem(Reply);             /* Release reply object  */
  11869.    break;
  11870.  
  11871. Interprocess Communication Using Shared Memory (Part 1) 
  11872.  
  11873. This example shows a "requester" window procedure issuing
  11874. requests and receiving replies by way of Presentation Manager messages.
  11875. If the technique described in Creating Another Process is followed, and the 
  11876. server process has posted a message to the client at the completion of  server 
  11877. initialization, containing the window handle of the server's  object window, 
  11878. the client can dispatch the request as an  application-defined Presentation 
  11879. Manager message to the server's object window, with  a pointer to the memory 
  11880. object as a message parameter.  The server process then obtains access to the 
  11881. object using the  DosGetSharedMem() function, as shown in Interprocess 
  11882. Communication Using Shared Memory (Part 2). 
  11883.  
  11884. CASE WMP_DOREQUEST:
  11885.    Request = (REQUEST *)mp1;          /* Get memory obj ptrs  */
  11886.    Reply = (REPLY *)mp2;
  11887.    DosGetSharedMem(&Request,          /* Obtain access to obj  */
  11888.            PAG_READ);         /* Allow read access   */
  11889.    DosGetSharedMem(&Reply,           /* Obtain access to obj  */
  11890.            PAG_WRITE |         /* Allow write access   */
  11891.            PAG_READ);         /* Allow read access   */
  11892.  
  11893.    ServiceRequest(Request,Reply);       /* Complete request    */
  11894.  
  11895.    WinPostMsg(Request->hRequester,       /* Post msg to requester */
  11896.         WMP_REQUESTCOMPLETE,       /* Message class     */
  11897.         (MPARAM)Reply,          /* Ptr to reply struct  */
  11898.         (MPARAM)0);
  11899.  
  11900.    DosFreeMem(Request);            /* Free request object  */
  11901.    DosFreeMem(Reply);             /* Free reply object   */
  11902.    break;
  11903.  
  11904. Interprocess Communication Using Shared Memory (Part 2) 
  11905.  
  11906. This example shows a "server" window procedure receiving and
  11907. processing Presentation Manager messages.
  11908.  
  11909. In the simplest case where the client process has only one window,  the handle 
  11910. of this window is passed to the server process when it is  created, as part of 
  11911. the DosExecPgm() call, as shown in  Starting a Child Process.  Hence the server 
  11912. has access to the client's  window handle and can pass the return data to the 
  11913. client.  In a more  complex situation where the client process has several 
  11914. windows and  where a request can come from any of these, the handle can be 
  11915. passed as  part of the request structure, as shown in Interprocess 
  11916. Communication Using Shared Memory (Part 1) and  Interprocess Communication 
  11917. Using Shared Memory (Part 2). 
  11918.  
  11919. Another issue that arises when using shared memory to communicate  between 
  11920. processes is that of freeing the shared memory object.  When a  process issues 
  11921. a DosGiveSharedMem() or  DosGetSharedMem() call, the operating system 
  11922. increments a usage counter for the shared memory object, and will not release 
  11923. the memory until all processes  using the object have issued a DosFreeMem() 
  11924. call. 
  11925.  
  11926. For the server process that receives access to the shared memory  object, the 
  11927. DosFreeMem() call is simply made whenever the server process has finished with 
  11928. the contents of the memory object.  For the client process that initially 
  11929. creates the memory object, the DosFreeMem() call can be made  at either of two 
  11930. points: 
  11931.  
  11932.    o  If the client process does not care whether the request is  correctly 
  11933.       received by the server process, the DosFreeMem()  call can be made 
  11934.       immediately after passing the message to the server,  as shown in 
  11935.       Interprocess Communication Using Shared Memory (Part 1). 
  11936.  
  11937.    o  If the client wishes to guarantee delivery of the request, it must pass 
  11938.       the message, wait for an acknowledgement of receipt from the server, and 
  11939.       then issue the DosFreeMem() call.  This  acknowledgement may simply be an 
  11940.       indication of receipt, prior to the  server processing the request, or 
  11941.       may be the returned data from the  request. 
  11942.  
  11943.  Note that it is common for returned data from a request to be passed  using 
  11944.  the same memory object as was used to contain the original  request.  In such 
  11945.  cases, the memory object cannot be freed by the  client process until the 
  11946.  returned data is received and processed. 
  11947.  
  11948.  
  11949. ΓòÉΓòÉΓòÉ 18.6.3. Atoms ΓòÉΓòÉΓòÉ
  11950.  
  11951. This example assumes that the two processes described in the  previous example 
  11952. require only to pass character strings, perhaps  containing the request and the 
  11953. returned information.  In this case, the  requester obtains the handle to the 
  11954. system atom table using the WinQuerySystemAtomTable() function. It may then add 
  11955. the request string to this table using the  WinAddAtom() function, and obtain 
  11956. an atom that represents the string in the table.  This atom  may then be passed 
  11957. to the server process in an application-defined  Presentation Manager message. 
  11958. An example of this technique is shown in  Interprocess Communication Using 
  11959. Atoms (Part 1). 
  11960.  
  11961. CASE WMP_SENDREQUEST:
  11962.    hSysAtomTable = WinQuerySystemAtomTable(); /* Get atom table handle */
  11963.    ReqAtom = WinAddAtom(hSysAtomTable,     /* Add string to table  */
  11964.              szRequest);      /* String to be added   */
  11965.    WinPostMsg(hServer,             /* Post msg to server   */
  11966.         WMP_DOREQUEST,          /* DO_REQUEST message   */
  11967.         (MPARAM)ReqAtom,         /* Atom to access string */
  11968.         (MPARAM)hWnd);          /* Return window handle  */
  11969.  
  11970.    <Store ReqAtom in window words>
  11971.  
  11972.    return((MRESULT)0);             /* Return zero      */
  11973.    break;
  11974.     :
  11975.     :
  11976. case WMP_REQUESTCOMPLETE:
  11977.    hSysAtomTable = WinQuerySystemAtomTable(); /* Get atom table handle */
  11978.    ReplyAtom = (ATOM)mp1;           /* Get atom for reply   */
  11979.    WinQueryAtomName(hSysAtomTable,       /* Get string from atom  */
  11980.            ReplyAtom,         /* Atom          */
  11981.            szReply,          /* Buffer for string   */
  11982.            sizeof(szReply));     /* Size of buffer     */
  11983.  
  11984.    <Verify reply is correct>
  11985.  
  11986.    WinDeleteAtom(hSysAtomTable,        /* Delete atoms      */
  11987.           ReqAtom);
  11988.    WinDeleteAtom(hSysAtomTable,
  11989.           ReplyAtom);
  11990.    return(TRUE);
  11991.    break;
  11992.  
  11993. Interprocess Communication Using Atoms (Part 1) 
  11994.  
  11995. This example shows a "requester" window procedure issuing
  11996. requests and receiving replies by way of Presentation Manager messages.
  11997.  
  11998. When the server process receives this message, it may also obtain  the handle 
  11999. to the system atom table, and retrieve the string using the  atom supplied in 
  12000. the message.  If the string is of a predefined length,  the server may simply 
  12001. retrieve the string using the  WinQueryAtomName() function. If the string is of 
  12002. variable length, the server may need to obtain the length of the string using 
  12003. the WinQueryAtomLength() function, and allocate a buffer for the string.  This 
  12004. is illustrated in  Interprocess Communication Using Atoms (Part 2). 
  12005.  
  12006. CASE WMP_DOREQUEST:
  12007.    hAtomTable = WinQuerySystemAtomTable();   /* Get atom table handle */
  12008.    ReqAtom = (ATOM)mp1;            /* Get atom for request  */
  12009.    hRequester = (HWND)mp2;           /* Get requester handle  */
  12010.  
  12011.    ulLength = WinQueryAtomLength(hAtomTable,  /* Get size of string   */
  12012.                   ReqAtom);
  12013.    szRequest = malloc(ulLength);        /* Allocate buffer    */
  12014.  
  12015.    WinQueryAtomName(hSysAtomTable,       /* Get string from atom  */
  12016.            ReqAtom,          /* Atom          */
  12017.            szRequest,         /* Buffer for string   */
  12018.            sizeof(szRequest));    /* Size of buffer     */
  12019.  
  12020.    ServiceRequest(szRequest,szReply);     /* Complete request    */
  12021.  
  12022.    ReplyAtom = WinAddAtom(hSysAtomTable,    /* Add string to table  */
  12023.               szReply);      /* String to be added   */
  12024.  
  12025.    WinPostMsg(hRequester,           /* Post msg to requester */
  12026.         WMP_REQUESTCOMPLETE,       /* Message class     */
  12027.         (MPARAM)ReplyAtom,        /* Atom to access string */
  12028.         (MPARAM)0);           /* Return window handle  */
  12029.  
  12030.    free(szRequest);              /* Free request buffer  */
  12031.    return((MRESULT)0);             /* Return zero      */
  12032.    break;
  12033.  
  12034. Interprocess Communication Using Atoms (Part 2) 
  12035.  
  12036. This example shows a "server" window procedure receiving and
  12037. processing Presentation Manager messages.
  12038.  
  12039. The server may return information to the requester using the system  atom 
  12040. table.  The WinAddAtom() function is used by the server  to add the result 
  12041. string to the atom table, and the  WinQueryAtomLength() and WinQueryAtomName() 
  12042. functions are used by the requester to retrieve the string.  In the  example 
  12043. shown in Interprocess Communication Using Atoms (Part 1), it is assumed that 
  12044. the reply  string returned to the requester is of a predefined length, and the 
  12045. WinQueryAtomLength() function is thus not required. 
  12046.  
  12047. Note that the request string is not removed from the atom table  until the 
  12048. server process has returned the result to the requester.  Once the result is 
  12049. obtained and verified, the requester removes both  the request and the result 
  12050. using the WinDeleteAtom()  function. 
  12051.  
  12052. The functions used to manipulate atoms and atom tables are described  in detail 
  12053. in the IBM OS/2 Version 2.0 Presentation Manager Reference. 
  12054.  
  12055.  
  12056. ΓòÉΓòÉΓòÉ 18.6.4. Queues ΓòÉΓòÉΓòÉ
  12057.  
  12058. A queue can be used to pass information between the process that created it and 
  12059. other processes in the system.  The process that creates the queue is known as 
  12060. the owner of the queue, and is the only process that can read  and remove 
  12061. elements from the queue.  Other processes may only add  elements to the queue. 
  12062.  
  12063. In a client-server environment, a queue is typically created by the  server 
  12064. process.  If a requester wishes to receive returned data from  the server 
  12065. process, it must therefore create its own queue.  Interprocess Communication 
  12066. Using Queues (Part 1) shows a requester process using the  DosCreateQueue() 
  12067. function to create its own queue, as well as using a queue owned by a server 
  12068. process. 
  12069.  
  12070. #define SRVQUEUENAME = "\\QUEUES\\SRV_QUEUE"   /* Server queue name   */
  12071. #define REQQUEUENAME = "\\QUEUES\\REQ_QUEUE"   /* Requester queue name  */
  12072.  
  12073. HQUEUE    hReqQueue, hSrvQueue;        /* Queue handles     */
  12074. REQUESTDATA Server;               /* Control information  */
  12075. REQUEST   *Request;              /* Request data buffer  */
  12076. REPLY    *Reply;               /* Reply data buffer   */
  12077. BYTE     Priority;              /* Priority information  */
  12078. ULONG    ulBytes;               /* Bytes read/written   */
  12079. APIRET    rc;                 /* Return code      */
  12080.  
  12081. case WMP_SENDREQUEST:
  12082.    rc = DosCreateQueue(&hReqQueue,       /* Create req queue    */
  12083.              QUE_FIFO  |       /* First-in, first-out  */
  12084.              QUE_CONVERT_ADDRESS,  /* Convert addresses   */
  12085.              REQQUEUENAME);     /* Name of queue     */
  12086.  
  12087.    rc = DosOpenQueue(&pidServer,        /* Open srv queue     */
  12088.             &hSrvQueue,        /* Queue handle      */
  12089.             SRVQUEUENAME);      /* Server queue name   */
  12090.  
  12091.    rc = DosAllocSharedMem(&Request,      /* Allocate shared mem  */
  12092.               NULL,        /* object for request   */
  12093.               sizeof(REQUEST),   /* Size of memory object */
  12094.               PAG_WRITE |     /* Allow write access   */
  12095.               PAG_READ  |     /* Allow read access   */
  12096.               PAG_COMMIT);     /* Commit storage now   */
  12097.    rc = DosGiveSharedMem(Request,       /* Give mem to server   */
  12098.               pidServer,      /* Server process id   */
  12099.               PAG_READ);      /* Allow read only    */
  12100.  
  12101.    rc = DosWriteQueue(hSrvQueue,        /* Add request to queue  */
  12102.             (ULONG)hWnd,       /* Requester win handle  */
  12103.             sizeof(REQUEST),     /* Size of request    */
  12104.             Request,         /* Request buffer     */
  12105.             0);           /* No priority      */
  12106.    rc = DosCloseQueue(hSrvQueue);       /* Close srv queue    */
  12107.    DosFreeMem(Request);            /* Free request buffer  */
  12108.    break;
  12109.  
  12110. Interprocess Communication Using Queues (Part 1) 
  12111.  
  12112. This example shows elements being added to a queue by a
  12113. "requester" process.
  12114. Queues may be created with a number of different ordering mechanisms.  The 
  12115. order of elements in a queue is determined when the queue is  created, and may 
  12116. be specified as FIFO, LIFO, or priority-based.  When  adding an element to a 
  12117. priority-based queue, a process must specify a  priority (from 0 to 15 with 0 
  12118. being lowest and 15 being highest) for  the element. 
  12119.  
  12120. Processes other than a queue's owner may gain write access to the  queue using 
  12121. the DosOpenQueue() function to obtain a queue handle.  Once this handle is 
  12122. obtained, the process  may use the DosWriteQueue() function to add elements to 
  12123. the queue.  The example in Interprocess Communication Using Queues (Part 1) 
  12124. shows  a requester process that passes a request to a server process using a 
  12125. queue created by that server process. 
  12126.  
  12127. The requester process first creates its own queue for returned data,  using the 
  12128. DosCreateQueue() function.  This queue will be  accessed by the server to write 
  12129. the returned data from the completed  request, which can then be read by the 
  12130. requester.  The example shown in  Interprocess Communication Using Queues (Part 
  12131. 2) creates a FIFO queue with the name specified in the  string constant 
  12132. REQQUENAME, and specifies that the addresses of any  elements placed in the 
  12133. queue by 16-bit processes are to be  automatically converted to 32-bit 
  12134. addresses by the operating system.  This conversion, specified using the 
  12135. QUE_CONVERT_ADDRESS flag, is used  by 32-bit queue owners to avoid the need for 
  12136. the queue owner to  explicitly convert addresses. 
  12137.  
  12138. The requester obtains access to the server's queue using the DosOpenQueue() 
  12139. function, passing the queue name as a  parameter.  This function returns both a 
  12140. queue handle and the process  identifier of the server process that owns the 
  12141. queue. 
  12142.  
  12143. The requester must allocate a shared memory object to contain the  request; the 
  12144. actual queue element contains only a pointer to that  memory object. The 
  12145. requester then invokes the  DosGiveSharedMem() function to provide read-only 
  12146. access (by  specifying only the PAG_READ flag) to that object for the server 
  12147. process, using the process identifier returned by the DosOpenQueue() function. 
  12148.  
  12149. The requester adds its request as a element in the queue, using the 
  12150. DosWriteQueue() function.  Note that the second parameter to  the function is 
  12151. an unsigned long integer, which may be used to pass application-specific 
  12152. information.  The value specified in this  parameter is passed to the queue 
  12153. owner as the ulData field  of a REQUESTDATA structure, which is returned by the 
  12154. DosReadQueue() function.  In this example, the parameter is  used to pass the 
  12155. window handle of the requester's object window to the  server process, so that 
  12156. a notification message can be passed to the  requester when the request has 
  12157. been completed. 
  12158.  
  12159. Once the element has been written to the queue, the requester  immediately 
  12160. relinquishes access to the server's queue by issuing a  DosCloseQueue() 
  12161. function call.  The shared memory object allocated for the request buffer is 
  12162. then released by the requester using the DosFreeMem()  function. 
  12163.  
  12164. The server process is very similar in structure to the requester, in  that it 
  12165. creates its own queue, then awaits and services requests.  The  server process 
  12166. is illustrated in Interprocess Communication Using Queues (Part 2). 
  12167.  
  12168. #define SRVQUEUENAME = "\\QUEUES\\SRV_QUEUE"   /* Server queue name   */
  12169. #define REQQUEUENAME = "\\QUEUES\\REQ_QUEUE"   /* Requester queue name  */
  12170.  
  12171. HQUEUE    hSrvQueue, hReqQueue;        /* Queue handles     */
  12172. REQUESTDATA Requester;              /* Requester win handle  */
  12173. REQUEST   *Request;              /* Request data buffer  */
  12174. REPLY    *Reply;               /* Reply data buffer   */
  12175. BYTE     Priority;              /* Element priority    */
  12176. ULONG    ulBytes;               /* Bytes read/written   */
  12177. APIRET    rc;                 /* Return code      */
  12178.  
  12179. rc = DosCreateQueue(&hSrvQueue,         /* Create queue      */
  12180.           QUE_FIFO  |         /* First-in, first-out  */
  12181.           QUE_CONVERT_ADDRESS,     /* Convert addresses   */
  12182.           SRVQUEUENAME);        /* Name of queue     */
  12183. while (!ProcessEnded)              /* Until process ends   */
  12184.    {
  12185.    rc = DosReadQueue(hSrvQueue,        /* Read queue       */
  12186.             &Requester,       /* Control information  */
  12187.             &ulBytes,        /* Bytes read       */
  12188.             &Request,        /* Data buffer pointer  */
  12189.             0,            /* Get first element   */
  12190.             DCWW_WAIT,        /* Wait synchronously   */
  12191.             &Priority,        /* Priority of element  */
  12192.             0);           /* No event semaphore   */
  12193.  
  12194.    ServiceRequest(Request);          /* Process request    */
  12195.  
  12196.    rc = DosOpenQueue(&Requester.idpid,    /* Open queue       */
  12197.             &hReqQueue,       /* Queue handle      */
  12198.             REQQUEUENAME);      /* Server queue name   */
  12199.    rc = DosAllocSharedMem(&Reply,       /* Allocate shared mem  */
  12200.                NULL,        /* object for request   */
  12201.                sizeof(REPLY),   /* Size of memory object */
  12202.                PAG_WRITE |     /* Allow write access   */
  12203.                PAG_READ  |     /* Allow read access   */
  12204.                PAG_COMMIT);    /* Commit storage now   */
  12205.    rc = DosGiveSharedMem(Reply,        /* Give mem to requester */
  12206.               &Requester.idpid,  /* Req process id     */
  12207.               PAG_READ);      /* Allow read only    */
  12208.    rc = DosWriteQueue(hReqQueue,       /* Add request to queue  */
  12209.              0L,           /* No control info    */
  12210.              sizeof(REPLY),     /* Size of reply     */
  12211.              Reply,         /* Reply buffer      */
  12212.              0);           /* No priority      */
  12213.    rc = DosCloseQueue(hReqQueue);       /* Close queue      */
  12214.  
  12215.    DosFreeMem(Request);            /* Free request buffer  */
  12216.    WinPostMsg((HWND)Requester.ulData,     /* Post notification msg */
  12217.          WMP_REQUESTCOMPLETE,      /* to requester window  */
  12218.          (MPARAM)Reply,         /* Reply buffer pointer  */
  12219.          0);
  12220.    DosFreeMem(Reply);             /* Free reply buffer   */
  12221.    }
  12222.  
  12223. Interprocess Communication Using Queues (Part 2) 
  12224.  
  12225. This example shows the creation of a queue and the processing
  12226. of items from the queue by a "server" process.
  12227. Note that the server process does not use an object window.  It simply accepts 
  12228. requests from its own queue, using the DCWW_WAIT flag  to suspend itself in the 
  12229. DosReadQueue() call until an  element becomes available in the queue.  Once a 
  12230. request is complete,  the server places the returned data on the requester's 
  12231. queue, extracts  the window handle of the requester from the REQUESTDATA 
  12232. structure  provided by the DosReadQueue() call, and posts a message to  the 
  12233. requester indicating that the request is complete. This message is  processed 
  12234. by the requester to retrieve the returned data from the queue. 
  12235.  
  12236. After adding the request to the server's queue, the requester is  notified by 
  12237. the server when the request has been serviced.  This is  done using a 
  12238. Presentation Manager message, since the requester's window handle is  passed to 
  12239. the server in the second parameter to the  DosWriteQueue() function.  The 
  12240. operating system imbeds this  value as the second doubleword of a REQUESTDATA 
  12241. structure which is  passed to the server by the DosReadQueue() function. 
  12242.  
  12243. Once notification is received from the server process, the requester  uses the 
  12244. DosReadQueue() function to retrieve the returned  data from its own queue, as 
  12245. shown in Interprocess Communication Using Queues (Part 3). 
  12246.  
  12247. case WMP_REQUESTCOMPLETE:
  12248.    rc = DosReadQueue(hReqQueue,        /* Read req queue     */
  12249.          &Server,            /* Control information  */
  12250.          &ulBytes,           /* Bytes read       */
  12251.          &Reply,            /* Data buffer pointer  */
  12252.          0,               /* Get first element   */
  12253.          DCWW_WAIT,           /* Wait synchronously   */
  12254.          &Priority,           /* Priority of element  */
  12255.          0);              /* No event semaphore   */
  12256.  
  12257.    < Process reply>
  12258.  
  12259.    DosFreeMem(Reply);
  12260.    break;
  12261.  
  12262. Interprocess Communication Using Queues (Part 3) 
  12263.  
  12264. This example shows returned data being read from a queue by a
  12265. "requester" process.
  12266. The DCWW_WAIT flag causes the DosReadQueue() function to  wait until an element 
  12267. is available in the queue before returning  control to the application.  If the 
  12268. process merely wishes to check  whether a queue element is available, the 
  12269. DCWW_NOWAIT flag may be  specified, in which case an event semaphore must be 
  12270. created and its  handle passed to the DosReadQueue() function.  This  semaphore 
  12271. is immediately set by the operating system, and is posted  when an element is 
  12272. added to the queue.  If the queue is shared between  processes (as in the 
  12273. examples given herein), the semaphore must be  shared, either by creating it as 
  12274. a named semaphore or by setting the  DC_SEM_SHARED flag in the 
  12275. DosCreateEventSem() call. 
  12276.  
  12277. It will be noted that the use of queues is very similar to that of  shared 
  12278. memory, except that the queue is used to pass a pointer to a  shared memory 
  12279. object, rather than a Presentation Manager message.  However, queues  have an 
  12280. advantage in that they may be FIFO, LIFO or priority-based,  without the need 
  12281. for the application to handle the querying and sorting  of elements. 
  12282.  
  12283.  
  12284. ΓòÉΓòÉΓòÉ 18.6.5. Pipes ΓòÉΓòÉΓòÉ
  12285.  
  12286. While a queue may only be read by its owner, a pipe may be used for either read 
  12287. access, write access or both.  Pipes  function in a similar way to files, and 
  12288. once created, are accessed  using the OS/2 file system programming functions 
  12289. such as the  DosRead() and DosWrite() functions. This means that pipes can be 
  12290. accessed by other applications in the  system that support file system 
  12291. operations, including applications  executing in virtual DOS machines.  In this 
  12292. way, interprocess communication can be  supported between an OS/2 application 
  12293. and a DOS or Windows application. 
  12294.  
  12295. Pipes may be either named or anonymous.  Communication via an  anonymous pipe 
  12296. requires that the read and write handles for the pipe  are known to both 
  12297. processes involved in the communication.  Since these  handles are not shared 
  12298. by default, another means of passing the  handles, such as Presentation Manager 
  12299. messages or shared memory, must be used.  For  this reason, anonymous pipes are 
  12300. typically less useful than named pipes  for interprocess communication, and are 
  12301. therefore used mainly for  "streaming" communication between threads in the 
  12302. same process. 
  12303.  
  12304. Named pipes are even more similar to files than anonymous pipes,  since they 
  12305. are initially accessed using predefined names rather than  requiring handles. 
  12306. Hence a process may easily obtain access to a named  pipe, provided it knows 
  12307. the name of the pipe.  Once the pipe has been  created or opened, the process 
  12308. uses a pipe handle, which is similar to  a file handle, to access the pipe via 
  12309. DosRead() and  DosWrite() function calls. 
  12310.  
  12311. OS/2 V2.0 introduces a number of new functions for accessing named  pipes, 
  12312. which simplify programming in the client-server environment.  These are the 
  12313. DosCallNPipe() function and the  DosTransactNPipe() function, both of which are 
  12314. explained in  the following text. 
  12315.  
  12316. Note that while queues allow many processes to access and write to  the queue, 
  12317. a named pipe is typically a one-to-one connection; the  creator of the pipe may 
  12318. interact with only one other process at a time,  and that process must 
  12319. relinquish access to the pipe before another  process may gain access.  For 
  12320. this reason, pipes have some limitations  when used in a client-server 
  12321. environment with many requesters being  serviced by a single server, as will 
  12322. become evident from the following  examples. 
  12323.  
  12324. A named pipe is normally created by the server process, using the 
  12325. DosCreateNPipe() function. During creation of the pipe, the server specifies 
  12326. the type of access  that is allowed for the pipe.  The following types of 
  12327. access are valid: 
  12328.  
  12329.    o  Inbound access (client to server) 
  12330.    o  Outbound access (server to client) 
  12331.    o  Duplex (both). 
  12332.  
  12333.  Since only one client process may have access to a named pipe at any  given 
  12334.  time, the requester must wait for the named pipe to become  available, using 
  12335.  the DosWaitNPipe() function. 
  12336.  
  12337.  Interprocess Communication Using Named Pipes (Part 1) shows a secondary thread 
  12338.  routine in a requester  process, which is dispatched to make a request to a 
  12339.  server process. 
  12340.  
  12341.   #define  NPIPE_NAME  "\\PIPE\\SRVPIPE"     /* Pipe name       */
  12342.  
  12343.   void RequestThread(TRANS *Trans)         /* Requester thread    */
  12344.   {
  12345.      ULONG    ulBytes;             /* Bytes read/written   */
  12346.      APIRET   rc;               /* Return code      */
  12347.  
  12348.      rc = DosWaitNPipe(NPIPE_NAME,        /* Wait on named pipe   */
  12349.               NP_WAIT_INDEFINITELY);  /* Wait indefinitely   */
  12350.  
  12351.      rc = DosCallNPipe(NPIPE_NAME,        /* Pipe name       */
  12352.               Trans->Request,      /* Request buffer ptr   */
  12353.               sizeof(REQUEST),     /* Size of buffer     */
  12354.               Trans->Reply,       /* Reply buffer ptr    */
  12355.               sizeof(REPLY),      /* Size of buffer     */
  12356.               &ulBytes,         /* No. of bytes read   */
  12357.               10000);          /* Timeout period     */
  12358.  
  12359.      WinPostMsg(Trans->hReturn,         /* Notify calling window */
  12360.           WMP_REQUESTCOMPLETE,       /* Request is complete  */
  12361.           (MPARAM)Trans,          /* Transaction structure */
  12362.           0);
  12363.      DosExit(0);
  12364.   }
  12365.  
  12366.  Interprocess Communication Using Named Pipes (Part 1) 
  12367.  
  12368.   This example shows a secondary thread in a "requester" process,
  12369.   writing to and reading from a named pipe.
  12370.  In the example shown in Interprocess Communication Using Named Pipes (Part 1), 
  12371.  the requester dispatches  a secondary thread that waits synchronously for the 
  12372.  named pipe to  become available.  This thread accepts a pointer to a data 
  12373.  structure  that contains the request and reply buffers along with the window 
  12374.  handle of the window that initiated the thread. This window handle is 
  12375.  included so that a notification message can be posted to the window  when the 
  12376.  request is complete.  Since a separate thread is dispatched  for each request, 
  12377.  the thread terminates when the reply is returned by  the server.  Hence no 
  12378.  object window is necessary. 
  12379.  
  12380.  When the pipe becomes available, the requester opens the pipe,  writes the 
  12381.  request, reads the reply and then closes the pipe.  These  functions are all 
  12382.  performed by a single call to the  DosCallNPipe() function. This function 
  12383.  actually opens the pipe using a DosOpen()  function call, and writes the 
  12384.  request to the pipe using the  DosWrite() function. The reply is read using 
  12385.  the DosRead() function and the pipe is closed using the DosClose() function. 
  12386.  Use of the DosCallNPipe() function simplifies the  application code by 
  12387.  allowing the programmer to combine these operations  into a single function 
  12388.  call. 
  12389.  
  12390.  Once the reply is received from the server and the  DosCallNPipe() function 
  12391.  returns, the requester thread  notifies the window from which the request was 
  12392.  made, by posting a  Presentation Manager message to it.  The pointer to the 
  12393.  transaction data structure  initially passed to the thread is returned with 
  12394.  the message, enabling  the window procedure to easily differentiate this 
  12395.  request from any  others that may currently be active. 
  12396.  
  12397.  The server process creates the named pipe, as shown in  Interprocess 
  12398.  Communication Using Named Pipes (Part 2), using the DosCreateNPipe() function. 
  12399.  
  12400.   #define  NPIPE_NAME  "\\PIPE\\SRVPIPE"     /* Pipe name       */
  12401.  
  12402.   HFILE    hPipe;                /* Pipe handle      */
  12403.   REQUEST   *Request;               /* Request buffer     */
  12404.   REPLY    *Reply;                /* Reply buffer      */
  12405.   ULONG    ulAction;               /* Open action      */
  12406.   ULONG    ulBytes;               /* Bytes read/written   */
  12407.   APIRET   rc;                  /* Return code      */
  12408.  
  12409.   rc = DosCreateNPipe(NPIPE_NAME,         /* Create named pipe   */
  12410.             &hPipe,           /* Pipe handle      */
  12411.             NP_ACCESS_DUPLEX,      /* Allow duplex access  */
  12412.             NP_WAIT     |      /* Blocking mode     */
  12413.             NP_TYPE_MESSAGE |      /* Msg oriented pipe   */
  12414.             NP_READMODE_MESSAGE,     /* Msg oriented read   */
  12415.             0x01,            /* Single instance only  */
  12416.             sizeof(REPLY),        /* Outbound buffer size  */
  12417.             sizeof(REQUEST),       /* Inbound buffer size  */
  12418.             0);             /* Default timeout value */
  12419.  
  12420.   while (!ProcessEnded)              /* Until process ends   */
  12421.      {
  12422.      rc = DosConnectNPipe(hPipe);        /* Connect to requester  */
  12423.      rc = DosRead(hPipe,            /* Read request      */
  12424.             Request,           /* Request buffer     */
  12425.             sizeof(REQUEST),       /* Size of buffer     */
  12426.             &ulBytes);          /* No. of bytes read   */
  12427.  
  12428.      ServiceRequest(Request, Reply);      /* Complete request    */
  12429.  
  12430.      rc = DosWrite(hPipe,            /* Write reply to pipe  */
  12431.             Reply,            /* Reply buffer      */
  12432.             sizeof(REPLY),        /* Size of buffer     */
  12433.             &ulBytes);          /* No. of bytes written  */
  12434.      rc = DosDisConnectNPipe(hPipe);      /* Disconnect from req  */
  12435.      }
  12436.  
  12437.  Interprocess Communication Using Named Pipes (Part 2) 
  12438.  
  12439.   This example shows a "server" process creating and reading from a
  12440.   duplex named pipe.
  12441.  Once the pipe is created, the server process makes the pipe available  to a 
  12442.  requester process by issuing a DosConnectNPipe()  function call.  This enables 
  12443.  any requester processes currently waiting for the  pipe to contend for 
  12444.  ownership.  The requester that claims ownership  returns from its 
  12445.  DosWaitNPipe() call, while other requesters  continue to wait. 
  12446.  
  12447.  The server then uses the DosRead() function to retrieve a  request from the 
  12448.  pipe.  Since blocking mode is selected in the  DosCreateNPipe() call by 
  12449.  specifying the NP_WAIT flag, the  DosRead() call does not return until a 
  12450.  request becomes  available. 
  12451.  
  12452.  Once the read operation completes, the server process services the  request 
  12453.  and writes the returned data back to the pipe using the  DosWrite() function. 
  12454.  It then informs the requester that the  request has completed, using a 
  12455.  Presentation Manager message, and obtaining the window  handle of the 
  12456.  requester from the Request structure. 
  12457.  
  12458.  Note that the server process cannot make the pipe available to other 
  12459.  requesters by issuing a DosDisconnectNPipe() call, until the current requester 
  12460.  has completed retrieval of the information from the pipe.  If this call is 
  12461.  issued before the requester retrieves  its returned data, the requester's 
  12462.  DosRead() call will  fail.  The server ensures that correct synchronization is 
  12463.  maintained by  passing the completion message synchronously using the 
  12464.  WinSendMsg() function.  For this reason, and in order to  ensure that user 
  12465.  responsiveness is maintained, it is recommended that  requesters interacting 
  12466.  with named pipes should do so from within object  windows created in secondary 
  12467.  threads under the control of the  application's primary process. 
  12468.  
  12469.  Once the pipe is made available once more, this cycle of operations continues 
  12470.  for each request issued to the server.  The server process is suspended within 
  12471.  the DosConnectNPipe() call until a request  is issued by a requester process. 
  12472.  
  12473.  Note that where a one-to-one relationship exists between the server  and 
  12474.  requester processes, the requester need not relinquish access to  the named 
  12475.  pipe between requests.  In such situations, the named pipe  would be opened by 
  12476.  the requester using the DosOpen()  function directly, and accessed using the 
  12477.  DosTransactNPipe()  function. This function combines the DosWrite() and 
  12478.  DosRead() functions.  When the secondary thread is  terminated, it can 
  12479.  relinquish access to the pipe using the  DosClose() function. 
  12480.  
  12481.  
  12482. ΓòÉΓòÉΓòÉ 18.7. Maintaining Synchronization ΓòÉΓòÉΓòÉ
  12483.  
  12484. It is the responsibility of the application to ensure the  appropriate level of 
  12485. synchronization between threads or process accessing resources.  Assuming the 
  12486. convention suggested in Threads Without Object Windows, it is only necessary to 
  12487. indicate when a secondary thread or process has completed processing a 
  12488. particular unit of work.  This may be achieved in a number of ways: 
  12489.  
  12490.    o  By having the secondary thread or process post a completion message  to 
  12491.       the calling window procedure before terminating 
  12492.  
  12493.    o  By using an event semaphore in conjunction with the Presentation Manager 
  12494.       timer facility 
  12495.  
  12496.    o  By using the DosWaitThread() function in the case of  threads 
  12497.  
  12498.    o  By using the DosWaitChild() function in the case of  processes. 
  12499.  
  12500.  While it is possible, when using object windows in secondary threads or 
  12501.  separate processes, to ensure synchronization by using the  WinSendMsg() call 
  12502.  for synchronous processing of the target  window procedure, this method is not 
  12503.  recommended since it  prevents the calling window procedure from processing 
  12504.  additional user  input, and is thus potentially in violation of SAA CUA 
  12505.  guidelines.  In addition, immediate invocation of a window procedure in this 
  12506.  way may  disturb the natural sequence of message processing and compromise the 
  12507.  user's intention. 
  12508.  
  12509.  
  12510. ΓòÉΓòÉΓòÉ 18.7.1. Presentation Manager Messages ΓòÉΓòÉΓòÉ
  12511.  
  12512. Since a process in OS/2 owns data resources, window handles are  available to 
  12513. any threads under the control of that process.  It is  therefore possible for a 
  12514. secondary thread to post a message to the  window procedure that invoked it, 
  12515. advising that the secondary thread  has completed its processing.  The window 
  12516. procedure may then process  the message and take appropriate action. 
  12517.  
  12518. This technique may be used by secondary threads that use object  windows and 
  12519. those which do not.  It requires only that the secondary  thread have 
  12520. addressability to the window handle of the window procedure  that invoked it. 
  12521. This handle may be obtained directly from Presentation Manager, but  it is 
  12522. recommended that the handle of the invoking window procedure is  passed to the 
  12523. secondary thread upon invocation.  This may be done in  one of two ways: 
  12524.  
  12525.    o  By including the handle in the CtrlData parameter of the 
  12526.       WinCreateWindow() call if the secondary thread is using an  object 
  12527.       window.  This also requires passing the handle as a parameter to  the 
  12528.       _beginthread() call used to create the secondary  thread's main 
  12529.       processing routine. 
  12530.  
  12531.    o  By including the handle as a parameter to the  DosCreateThread() call if 
  12532.       using a secondary thread without  an object window. 
  12533.  
  12534.  The second method described above is illustrated in  Synchronization Using 
  12535.  Presentation Manager Messages. 
  12536.  
  12537.       :
  12538.   case WMP_THREAD:             /* Start secondary thread    */
  12539.      DosCreateThread(ThreadID,      /* Thread ID           */
  12540.              Thread,       /* Entry point for thread    */
  12541.              (PVOID)hwnd,    /* Invoking window handle    */
  12542.              0L,         /* Start immediately       */
  12543.              4096);       /* Stack size for thread     */
  12544.      break;
  12545.  
  12546.   case WMP_ENDOFTHREAD:          /* Thread has completed     */
  12547.  
  12548.      <perform end-of-thread processing>
  12549.  
  12550.      break;
  12551.       :
  12552.       :
  12553.   int cdecl thread(hReturn)        /* Thread routine        */
  12554.     HWND hReturn;            /* Handle of calling window   */
  12555.   {
  12556.     <Perform lengthy processing task>
  12557.  
  12558.     WinPostMsg(hReturn,         /* Post message to caller    */
  12559.           WMP_ENDOFTHREAD,     /* Message class         */
  12560.           0,0);           /* No parameters         */
  12561.     DosExit(EXIT_THREAD,         /* Terminate thread       */
  12562.         0L);
  12563.   }
  12564.  
  12565.  Synchronization Using Presentation Manager Messages 
  12566.  
  12567.  Where the two communicating windows are under the control of  different 
  12568.  processes, the window handles must be explicitly communicated  from one to the 
  12569.  other since by default, the window handle of a window  in one process is not 
  12570.  available to a window in another process.  One  technique for achieving this 
  12571.  communication involves passing the window  handle of the first window when the 
  12572.  second process is created, and  having the second window return a message to 
  12573.  the first window after  initialization, containing the window handle of the 
  12574.  second window.  This technique allows both communication and synchronization 
  12575.  between  windows.  An example is given in Creating Another Process. 
  12576.  
  12577.  
  12578. ΓòÉΓòÉΓòÉ 18.7.2. Timers and Semaphores ΓòÉΓòÉΓòÉ
  12579.  
  12580. Another method of achieving synchronization between threads or  processes 
  12581. involves the use of an event semaphore and the Presentation Manager timer 
  12582. facility. The timer facility may be used from within a window procedure to 
  12583. create and start a timer that periodically sends messages of class WM_TIMER to 
  12584. the window, at intervals specified by the window procedure when the  timer is 
  12585. created. 
  12586.  
  12587. In this case, the WM_TIMER message is used by the window procedure  in the 
  12588. primary thread or process, to periodically check the state of an  event 
  12589. semaphore that indicates whether the secondary thread or process  has completed 
  12590. its processing.  The secondary thread or process sets the  event semaphore upon 
  12591. commencing its processing, and releases (posts) it  upon completion.  The 
  12592. primary thread or process queries the state of  the semaphore to determine when 
  12593. the secondary thread or process has  completed its processing. 
  12594.  
  12595. Note that when using this technique for synchronization between  processes 
  12596. (rather than between threads within the same process), the  event semaphore 
  12597. must be created as a shared semaphore, either by giving  it a name or by 
  12598. specifying the DC_SEM_SHARED flag when invoking the  DosCreateEventSem() 
  12599. function. 
  12600.  
  12601. An example of a secondary thread using this technique is shown in 
  12602. Synchronization Using an Event Semaphore (Part 1). 
  12603.  
  12604. int cdecl thread()
  12605. {
  12606.   ulResult = DosCreateEventSem("\SEM32\THREAD", /* Name of semaphore  */
  12607.                  hSem,       /* Semaphore handle  */
  12608.                  NULL,       /* Not used      */
  12609.                  FALSE);      /* Set immediately   */
  12610.  
  12611.   <Perform lengthy processing task>
  12612.  
  12613.   usResult = DosPostEventSem(hSem);       /* Release semaphore  */
  12614.   DosExit(0);                  /* Terminate thread  */
  12615. }
  12616.  
  12617. Synchronization Using an Event Semaphore (Part 1) 
  12618.  
  12619. This example shows the routine executing in the secondary
  12620. thread.
  12621. Note that the event semaphore is created as a shared semaphore and named.  A 
  12622. named semaphore is recommended since, if the secondary thread routine is placed 
  12623. in a  dynamic link library for subsequent use by other applications, or the 
  12624. secondary thread executes in a separate process, the name of the  semaphore may 
  12625. be included in the documentation for that library,  enabling calling window 
  12626. procedures to access the semaphore using the  DosOpenEventSem() function (see 
  12627. Synchronization Using an Event Semaphore (Part 2)).  Using this technique 
  12628. promotes code reusability. 
  12629.  
  12630. Synchronization Using an Event Semaphore (Part 2) shows a window procedure 
  12631. using the  WinStartTimer() function to start a timer, immediately after 
  12632. dispatching a secondary thread such  as the one shown in Synchronization Using 
  12633. an Event Semaphore (Part 1).  This timer in this example  will cause a WM_TIMER 
  12634. message to be passed to the window every 0.5  seconds (500 milliseconds). 
  12635.  
  12636. case WMP_THREAD:
  12637.    usReturn = DosCreateThread(ThreadID,    /* Create thread      */
  12638.                 Thread,     /* Entry point for thread */
  12639.                 NULL,      /* No initialization data */
  12640.                 0L,       /* Start immediately    */
  12641.                 4096);     /* Stack size for thread  */
  12642.    WinStartTimer(hAB,             /* Start timer       */
  12643.           hwnd,            /* Window to get WM_TIMER */
  12644.           TID_THREAD,         /* ID of timer       */
  12645.           500);            /* Period in milliseconds */
  12646.    break;
  12647.     :
  12648. case WM_TIMER:
  12649.    ulResult=DosOpenEventSem("\SEM32\THREAD", /* Get semaphore handle  */
  12650.                hSem);      /* Semaphore handle    */
  12651.  
  12652.    ulResult=DosWaitEventSem(hSem,       /* Check semaphore state  */
  12653.                0);        /* Immediate timeout    */
  12654.  
  12655.    if (ulResult!=ERROR_TIMEOUT)        /* Semaphore not set    */
  12656.     {
  12657.     <perform end-of-thread processing>   /* Thread has completed  */
  12658.     }
  12659.  
  12660.    ulResult=DosCloseEventSem(hSem);      /* Close semaphore     */
  12661.    break;
  12662.  
  12663. Synchronization Using an Event Semaphore (Part 2) 
  12664.  
  12665. This example shows the window procedure in the primary thread,
  12666. periodically testing to determine whether the event semaphore has been
  12667. released.
  12668.  
  12669. Since the primary thread or process must remain responsive to the  end user and 
  12670. thus cannot wait indefinitely for the semaphore to be  released, the 
  12671. Presentation Manager timer facility is used to generate periodic  WM_TIMER 
  12672. messages to the invoking window procedure in the primary  thread or process. 
  12673. Upon receipt of each WM_TIMER message, the window  procedure checks the state 
  12674. of the semaphore, timing out immediately if  the semaphore has not yet been 
  12675. released by the secondary thread or  process.  This technique is illustrated in 
  12676. Synchronization Using an Event Semaphore (Part 2). 
  12677.  
  12678. Note once again the use of a named shared semaphore, in order to  reduce the 
  12679. level of interdependence between the primary and secondary threads/processes, 
  12680. thus facilitating the inclusion of the secondary routine into a dynamic link 
  12681. library for subsequent use by other applications. 
  12682.  
  12683.  
  12684. ΓòÉΓòÉΓòÉ 18.7.3. DosWaitThread() Function ΓòÉΓòÉΓòÉ
  12685.  
  12686. Where a secondary thread must complete its processing and  terminate before the 
  12687. primary thread can continue, the primary  thread may use the DosWaitThread() 
  12688. function to determine whether the secondary thread has terminated.  This 
  12689. function is used in conjunction with the Presentation Manager timer facility, 
  12690. to periodically check whether the secondary thread has issued a  DosExit() 
  12691. function call.  An example of a secondary thread  using this technique is given 
  12692. in Synchronization Using the DosWaitThread() Function (Part 1). 
  12693.  
  12694. int cdecl thread()
  12695. {
  12696.   <Perform lengthy processing task>
  12697.  
  12698.   DosExit(EXIT_THREAD,              /* Terminate thread  */
  12699.       0L);                  /* Return code     */
  12700. }
  12701.  
  12702. Synchronization Using the DosWaitThread() Function (Part 1) 
  12703.  
  12704. This example shows the routine executing in the secondary
  12705. thread.
  12706.  
  12707. When the secondary thread has been started, the window procedure in the primary 
  12708. thread stores the thread identifier in its instance data area (typically using 
  12709. window words), and uses the Presentation Manager timer facility to send 
  12710. periodic WM_TIMER messages to itself, as shown in Synchronization Using the 
  12711. DosWaitThread() Function (Part 2). 
  12712.  
  12713. case WMP_THREAD:
  12714.    usReturn = DosCreateThread(ThreadID,    /* Create thread      */
  12715.                 Thread,     /* Entry point for thread */
  12716.                 NULL,      /* No initialization data */
  12717.                 0L,       /* Start immediately    */
  12718.                 4096);     /* Stack size for thread  */
  12719.  
  12720.    <Store ThreadID in instance data block>
  12721.  
  12722.    WinStartTimer(hAB,             /* Start timer       */
  12723.           hwnd,            /* Window to get WM_TIMER */
  12724.           TID_THREAD,         /* ID of timer       */
  12725.           50);             /* Period in milliseconds */
  12726.    break;
  12727.     :
  12728. case WM_TIMER:
  12729.  
  12730.    <Get ThreadID from instance data block>
  12731.  
  12732.    ulReturn=DosWaitThread(ThreadID,      /* Check thread status  */
  12733.               DCWW_NOWAIT);    /* Immediate timeout   */
  12734.    if (ulReturn==ERROR_THREAD_NOT_TERMINATED) /* Thread still running  */
  12735.     break;                  /* Continue waiting    */
  12736.    else                    /* else          */
  12737.     <perform end-of-thread processing>    /* Thread has completed  */
  12738.    break;
  12739.  
  12740. Synchronization Using the DosWaitThread() Function (Part 2) 
  12741.  
  12742. This example shows the window procedure in the primary thread,
  12743. periodically testing to determine whether the secondary thread has
  12744. terminated.
  12745.  
  12746. Whenever it receives a WM_TIMER message, the window procedure retrieves the 
  12747. thread identifier from its instance data area and uses the DosWaitThread() 
  12748. function to determine whether the thread has terminated.  If so, it performs 
  12749. the required processing.  If the thread has not yet terminated, it immediately 
  12750. returns control to Presentation Manager.  Note the use of the DosExit() 
  12751. function in  Synchronization Using the DosWaitThread() Function (Part 1).  This 
  12752. assumes that the processing  performed by the routine does not use an object 
  12753. window, and does not  call C run-time library functions. As mentioned earlier 
  12754. in this  chapter, secondary threads without object windows are typically used 
  12755. to  perform a single, lengthy task, and terminate upon completion of this 
  12756. task.  Since they are able to use the DosExit() function and  the completion of 
  12757. their task causes the termination of the thread, such  threads are ideal 
  12758. candidates for use of the DosWaitThread()  function.  For situations where the 
  12759. progress of execution must be  indicated to the primary thread, an event 
  12760. semaphore is more suitable. 
  12761.  
  12762. As already mentioned, there is very little difference between the  use of the 
  12763. DosWaitThread() function and the use of an event  semaphore.  Both are used in 
  12764. conjunction with the Presentation Manager timer facility  and in fact, both use 
  12765. an event semaphore.  The  DosWaitThread() function avoids the need for the 
  12766. application  to explicitly open and check the semaphore, since the 
  12767. DosWaitThread() function performs these operations  transparently. However, 
  12768. while an event semaphore may be used to  indicate any significant event during 
  12769. execution of a secondary thread,  while the DosWaitThread() function can only 
  12770. signal  termination of the thread.  Hence the DosWaitThread()  function is 
  12771. slightly less flexible than the explicit use of an event  semaphore with the 
  12772. Presentation Manager timer facility. 
  12773.  
  12774.  
  12775. ΓòÉΓòÉΓòÉ 18.7.4. DosWaitChild() Function ΓòÉΓòÉΓòÉ
  12776.  
  12777. The DosWaitChild() function allows a thread within a process to wait upon the 
  12778. termination of an asynchronous child process, in a similar manner to the 
  12779. DosWaitThread() function.  The DosWaitChild()  function allows a thread to wait 
  12780. for the termination of a single child  process, or the termination of an entire 
  12781. process tree (that is, a  process and all of its descendants). 
  12782.  
  12783. Note that only the calling thread in the parent process is suspended during a 
  12784. DosWaitChild() call.  If the parent process has  other threads, they will 
  12785. continue to be dispatched. 
  12786.  
  12787. The DosWaitChild() function can also be used to check the  termination status 
  12788. of a child process that has already terminated,  provided that process was 
  12789. started with the EXEC_ASYNCRESULT flag  specified in the DosExecPgm() call. 
  12790. The use of this flag  causes OS/2 to store the result code from the child 
  12791. process, for future  reference by a DosWaitChild() call. 
  12792.  
  12793. An example of the DosWaitChild() function is given in  DosWaitChild() Function. 
  12794.  
  12795. rc = DosWaitChild(DCWA_PROCESS,       /* Wait for this process only */
  12796.          DCWW_WAIT,        /* Wait until termination   */
  12797.          &ReturnInfo,       /* Returned info        */
  12798.          &pidServer,        /* Returned process ID     */
  12799.          pidServer);        /* Process id to wait on    */
  12800.  
  12801. DosWaitChild() Function 
  12802.  
  12803. This example assumes that the DosExecPgm() call shown in Starting a Child Process has already been executed.
  12804. Specifying the DCWA_PROCESS flag in the first parameter of the DosWaitChild() 
  12805. call causes the calling thread to wait only  upon the specified process, and 
  12806. not upon its children (if any).  If a  thread is to wait upon the entire 
  12807. process tree, the DCWA_PROCESSTREE  flag must be specified. 
  12808.  
  12809. The DCWW_WAIT flag in the second parameter causes the calling thread  to wait 
  12810. until the specified process has terminated.  The DCWW_NOWAIT  flag would cause 
  12811. the DosWaitChild() call to return  immediately, without waiting for a child 
  12812. process to end.  The  DCWW_NOWAIT flag is typically used when checking the 
  12813. termination status  of a child process that has already ended. 
  12814.  
  12815.  
  12816. ΓòÉΓòÉΓòÉ 18.8. Preserving Data Integrity ΓòÉΓòÉΓòÉ
  12817.  
  12818. Since data resources are owned by a process, rather than by threads  within the 
  12819. process, multiple threads may have addressability to the same static data 
  12820. storage areas, and potential problems arise  with regard to serialization of 
  12821. data access and maintenance of data  integrity. Similarly when multiple 
  12822. processes have access to a shared  memory object, it is the responsibility of 
  12823. the application to ensure  the integrity of shared resources; neither OS/2 nor 
  12824. Presentation Manager provide any  automatic methods of avoiding such problems. 
  12825. However, mechanisms are  provided whereby the application developer may prevent 
  12826. problems from  occurring.  Some suggested techniques for private data are as 
  12827. follows: 
  12828.  
  12829.    1. For any data that is private to a thread, use local variables  defined 
  12830.       within the thread, or automatic storage assigned from the stack (because 
  12831.       each thread has its own stack memory object, this data is automatically 
  12832.       protected since no other thread has addressability to this area of 
  12833.       memory). 
  12834.  
  12835.    2. For any data that is private a particular window (as distinct from  the 
  12836.       window class), create a memory object to store this data and place  a 
  12837.       pointer in the window words, as described in Instance Data and Window 
  12838.       Words. 
  12839.  
  12840.    3. Specific data areas may be used to  contain data that is passed between 
  12841.       threads or processes.  If this data is only accessed in response to 
  12842.       particular messages passed between the threads or processes, and if these 
  12843.       messages are only generated at predefined points in the application's 
  12844.       execution (such as on entry to and exit from a window procedure), it is 
  12845.       relatively simple for an application to control access to these data 
  12846.       areas. 
  12847.  
  12848.       Static allocation of such data areas is permissible where the accessing 
  12849.       routines reside and execute solely under the control of a single 
  12850.       application.  However, where such routines are placed in a library and 
  12851.       accessed by multiple applications, the potential for data corruption 
  12852.       through application error increases significantly, and dynamic data 
  12853.       allocation prior to invoking a secondary thread or passing a request to 
  12854.       another process should be considered to ensure the integrity of data 
  12855.       areas. 
  12856.  
  12857.    4. For any code that will be placed in a DLL, it is important that a 
  12858.       separate set of memory objects is created for the data of each process 
  12859.       that will access the DLL.  In order to ensure this, a DATA NONSHARED 
  12860.       statement should be specified in the module definition file (see Module 
  12861.       Definition File). 
  12862.  
  12863.  Note that the above techniques apply to data shared between threads  within a 
  12864.  process; OS/2 provides a variety of mechanisms for dealing  with data and 
  12865.  memory areas that are shared between processes.  These  techniques are 
  12866.  described in the IBM OS/2 Version 2.0 Control Program Reference. 
  12867.  
  12868.  
  12869. ΓòÉΓòÉΓòÉ 18.9. Client-Server Applications ΓòÉΓòÉΓòÉ
  12870.  
  12871. In situations where an object window is created in a secondary  thread to 
  12872. manipulate a data object such as a database, or to handle  access to a remote 
  12873. device or system, it is often desirable to have a  single object window 
  12874. performing the requested actions, in response to  requests from multiple 
  12875. display windows.  This follows the basic  architecture of a client-server 
  12876. application, in accordance with the object-oriented rule of allowing access to 
  12877. a  data object only from a single application object, and  therefore implements 
  12878. the concept of encapsulation. 
  12879.  
  12880. For example, a user may use different display windows to access  different 
  12881. views of the same database.  However, for reasons of  efficiency and data 
  12882. integrity, the actual database access should be  coordinated by a single object 
  12883. window, preferably in a secondary thread  in case a database access request 
  12884. causes a lengthy search. 
  12885.  
  12886. The question then arises of how the handle of the object window may  be made 
  12887. available to multiple display windows.  A number of options are available: 
  12888.  
  12889.    o  The handle may be stored as a global variable.  This is not recommended 
  12890.       however, since global variables are open to inadvertent modification, and 
  12891.       their use imposes programming restrictions with respect to variable 
  12892.       names. 
  12893.  
  12894.    o  Immediately after the object window is created, its handle may be passed 
  12895.       to all display windows that require communication with the object window. 
  12896.       However, if subsequent modification of the application introduces a new 
  12897.       display window, additional modifications would be required to the module 
  12898.       that created the object window.  This increases the interdependence 
  12899.       between application objects, and is therefore not recommended. 
  12900.  
  12901.    o  The handle of the object window may be stored in the window words  of the 
  12902.       application's main window.  The handle of this window is  available to 
  12903.       all windows in the application, by querying the  application's switch 
  12904.       entry (as shown in Identifying the Destination Window).  If the  window 
  12905.       words of the application's main window are used to store a  pointer to a 
  12906.       data structure, which in turn contains the handles of  object windows and 
  12907.       other items of a global nature, these items may be  retrieved by window 
  12908.       procedures when required. 
  12909.  
  12910.  The final method described above is therefore the recommended  solution. 
  12911.  Object windows that will perform "server" tasks on  behalf of a number of 
  12912.  display window "clients" should be created  by the window procedure for the 
  12913.  application's main window, immediately  upon creation of the main window, and 
  12914.  the handles of the object windows  stored in a data structure accessed via the 
  12915.  window words of the main  window. 
  12916.  
  12917.  
  12918. ΓòÉΓòÉΓòÉ 18.10. Summary ΓòÉΓòÉΓòÉ
  12919.  
  12920. OS/2 allows multiple threads of execution to be initiated within an 
  12921. application.  Each thread is regarded as a distinct unit by the  operating 
  12922. system, and is scheduled independently of other threads and  processes in the 
  12923. system.  Each application has a primary thread,  created when the application 
  12924. is started.  An application may optionally  create one or more additional 
  12925. threads, known as secondary threads. 
  12926.  
  12927. In certain circumstances, an application may also create additional processes 
  12928. to perform some portion of the application's processing.  The use of additional 
  12929. processes may be necessary where different portions  of the application's 
  12930. processing must be isolated from one another.  It  is also useful for 
  12931. applications that exploit the Workplace Shell since by  default, all Workplace 
  12932. Shell objects share the same process and are hence  unprotected from one 
  12933. another. The use of multiple processes has  performance implications due to 
  12934. additional system overhead and should  thus be implemented with care. 
  12935.  
  12936. Secondary threads and processes may contain object windows, which do  not 
  12937. appear on the display screen but act as addresses to which messages  may be 
  12938. sent in order to initiate application processing.  An object  window typically 
  12939. "owns" a data object such as a database or  controls access to an external 
  12940. entity such as a remote system.  Where  the processing in response to an 
  12941. application event requires access to  another data object, the use of object 
  12942. windows in a secondary thread is  recommended. 
  12943.  
  12944. Communication with an object window is performed in the normal way  using 
  12945. Presentation Manager messages.  With suitable programming  conventions, the 
  12946. handle of the object window may easily be made  available to the calling window 
  12947. in order for such messages to be posted. 
  12948.  
  12949. A single object window may receive messages from multiple windows,  and perform 
  12950. actions on its data object on behalf of those windows.  This approach allows 
  12951. easy coordination of requests for access to a data  object, enhancing data 
  12952. integrity and efficiency of access.  Applications that use this technique 
  12953. follow the basic client-server  architecture, within the boundaries of the 
  12954. Presentation Manager application model. 
  12955.  
  12956. Where the scope of a long-running event is restricted to a single  method 
  12957. within the current application object, a secondary thread or  process may be 
  12958. initiated without an object window.  In such cases, a  subroutine is initiated 
  12959. in the secondary thread, and the thread  terminates immediately upon exiting 
  12960. that subroutine. 
  12961.  
  12962. Presentation Manager provides a number of methods by which an application can 
  12963. synchronize access to data objects and determine whether a secondary thread or 
  12964. process has completed processing an event.  These methods involve the use of 
  12965. functions such as DosWaitThread() or  DosWaitChild(), Presentation Manager 
  12966. messages and/or event semaphores. 
  12967.  
  12968. The multitasking capabilities of OS/2 allow greater application responsiveness 
  12969. since lengthy application processing may be performed in  an asynchronous 
  12970. manner, leaving the application's primary thread free  to continue interaction 
  12971. with the end user.  This also facilitates  conformance with the Systems 
  12972. Application Architecture CUA guideline stipulating that an  application should 
  12973. complete the processing of an event and be ready to  handle further user input 
  12974. within 0.1 seconds. 
  12975.  
  12976.  
  12977. ΓòÉΓòÉΓòÉ 19. Systems Application Architecture CUA Considerations ΓòÉΓòÉΓòÉ
  12978.  
  12979. The Presentation Manager environment provides the application developer with a 
  12980. rich set of functions that enable tasks to be performed in a variety of ways. 
  12981. However, within the general Presentation Manager application model, there are a 
  12982. number of considerations which, if observed, enable the design and  development 
  12983. of applications that comply more closely with the guidelines and emerging 
  12984. conventions of the Systems Application Architecture CUA component.  This 
  12985. chapter will discuss some of the considerations involved in designing  an 
  12986. object-oriented, CUA-conforming Presentation Manager application. 
  12987.  
  12988. The Presentation Manager programming interface enables the creation and 
  12989. manipulation of windows in a variety of ways by an application developer. 
  12990. However, there is considerable value in adopting a series of standard practices 
  12991. for developing Presentation Manager applications, from the viewpoint of 
  12992. consistency and ease of maintenance, and to enhance the degree of conformance 
  12993. to SAA CUA guidelines.  The following points provide some guidelines on the 
  12994. interpretation of CUA specifications, and outline some emerging trends in the 
  12995. development of applications that use the Presentation Manager user interface. 
  12996.  
  12997.  
  12998. ΓòÉΓòÉΓòÉ 19.1. Standard Windows ΓòÉΓòÉΓòÉ
  12999.  
  13000. Standard windows are used to display the contents of data objects. The contents 
  13001. of a data object may, in turn, be comprised of other objects.  For example, if 
  13002. the data object is a directory on a workstation's fixed disk, its contents are 
  13003. files, which are themselves objects.  Alternatively, a data object may contain 
  13004. information in the form of text or formatted data.  Note that  an object may be 
  13005. defined by the user during execution; for example, if  the user is editing a 
  13006. text file and selects a block of text to be  operated upon, then that block of 
  13007. text becomes the scope of the  following series of actions, and is thus defined 
  13008. as an object. 
  13009.  
  13010. By convention, the nature of a user's interaction with a standard window should 
  13011. be unformatted and modeless; a standard window is used to  display objects or 
  13012. their contents, from which the user selects an object upon which to perform one 
  13013. or more actions.  The exact sequence of actions performed by the user in the 
  13014. window should not be of concern  to the application.  If a modal or otherwise 
  13015. structured dialog with the  user is required, the application developer should 
  13016. implement this  dialog as a dialog box.  For this reason, it is recommended 
  13017. that the  use of control windows be confined wherever possible to dialog boxes 
  13018. only.  An allowable exception to this rule is the instance where a standard 
  13019. window displays a list of objects;  in this case, the client window may be 
  13020. created as a container window or listbox. 
  13021.  
  13022. This is relatively simple for normal listboxes; however, for a listbox with 
  13023. special display requirements and which is therefore created with the style 
  13024. LS_OWNERDRAW, the application must subclass the frame window in order to 
  13025. intercept and process the WM_DRAWITEM messages  which are sent to the listbox's 
  13026. owner (the frame) whenever a listbox item must be redrawn on the screen. 
  13027.  
  13028. A standard window should normally be both sizable and movable on the screen, 
  13029. allowing the user to configure the visual appearance of the desktop to suit the 
  13030. tasks being performed.  A standard window should therefore be created with the 
  13031. FCF_SIZEBORDER style attribute in order to generate a sizing border for the 
  13032. window.  Similarly, the user should be able to maximize and minimize the window 
  13033. in order to more clearly display information, unless the logical requirements 
  13034. of the application scenario dictate otherwise; the standard window should thus 
  13035. also be created with the FCF_MINMAX style attribute.  A window that is neither 
  13036. sizable nor able  to be minimized or maximized is by definition an optimized 
  13037. window, and should be implemented using a dialog box. 
  13038.  
  13039. A standard window should always possess a title bar, to indicate the nature of 
  13040. the window's contents, and to provide a "handle" for moving the window on the 
  13041. screen; the frame window should therefore be created with the FCF_TITLEBAR 
  13042. style attribute.  For  an application's main window, the text displayed in the 
  13043. title bar should be the same as that displayed in the OS/2 Window List entry 
  13044. for the application, and should follow the convention "Object Name - View". 
  13045.  
  13046. For child windows containing objects or their contents, the window title should 
  13047. be the same as the name or identifier of the item in the parent window that 
  13048. caused the child window to be created.  For instance, the selection of a 
  13049. "Customer List" entry in the main window of an "Address Book" application might 
  13050. cause the display of a child window containing a list of customers' names; the 
  13051. title of this window  would be "Customer List - Details View".  Since a 
  13052. standard window represents an  object or group of objects, the title should 
  13053. always be a noun rather  than a verb. 
  13054.  
  13055. A standard window is created using the WinCreateWindow() or 
  13056. WinCreateStdWindow() functions.  WinCreateWindow() creates the frame and client 
  13057. windows in separate steps, whereas WinCreateStdWindow() creates both in a 
  13058. single step. A standard window is typically created with the FCF_SIZEBORDER, 
  13059. FCF_SYSMENU, FCF_TITLEBAR, FCF_MINMAX and FCF_MENU style attributes specified 
  13060. for the frame window.  See Sample Application Main Routine (Part 2) - Window 
  13061. Creation for an illustration of the use of these style attributes. 
  13062.  
  13063. If an icon and/or accelerator table will be associated with the window, the 
  13064. FCF_ICON and FCF_ACCELTABLE style attributes should be specified.  The icon and 
  13065. accelerator table definitions will then be loaded from the specified resource 
  13066. file when the window is created. 
  13067.  
  13068. If the application does not wish to explicitly size and position a frame window 
  13069. on the desktop, the FCF_SHELLPOSITION style attribute may be specified. 
  13070. Presentation Manager will then determine a default size and position for the 
  13071. window. 
  13072.  
  13073. As an alternative to specifying all of the above attributes, the FCF_STANDARD 
  13074. attribute may be specified.  This attribute is assumed if the 
  13075. WinCreateStdWindow() call or the WinCreateWindow() call for a frame window 
  13076. contains no control data. 
  13077.  
  13078.  
  13079. ΓòÉΓòÉΓòÉ 19.2. The Menu Bar ΓòÉΓòÉΓòÉ
  13080.  
  13081. The menu bar is a menu which, in conjunction with its associated pulldown 
  13082. menus, enables the user to select an action from a list of valid actions,  to 
  13083. be applied to a selected object or group of objects displayed in a  window. The 
  13084. following guidelines should be followed in the design and  layout of the menu 
  13085. bar, for the purpose of consistency and ergonomic behavior: 
  13086.  
  13087.    o  A menu bar is not required for fewer than six actions, unless these are 
  13088.       actions specifically defined by CUA. 
  13089.  
  13090.    o  The number of entries within an menu bar should be kept to a minimum; it 
  13091.       is better to have a "deep" pulldown menu with many choices than to have a 
  13092.       "broad" menu bar.  This reduces the number of options displayed to the 
  13093.       user at any one time. 
  13094.  
  13095.    o  A menu bar must have a pulldown menu associated with it. 
  13096.  
  13097.    o  A pulldown menu item always represents an action, and therefore should 
  13098.       always be a verb. 
  13099.  
  13100.    o  Where selection of a menu bar entry results in the display of a pulldown 
  13101.       menu, the menu bar entry should indicate the generic nature of the group 
  13102.       of actions contained in the pulldown menu.  If these actions pertain to a 
  13103.       particular object or object class, the name of the object or class may be 
  13104.       used as part of the menu bar entry.  In such a case, the menu bar entry 
  13105.       may be either a verb or a noun. 
  13106.  
  13107.    o  If multiple distinct groups of actions, pertaining to a single object or 
  13108.       class, are contained within the same pulldown menu, they should be 
  13109.       separated by a horizontal separator bar within the pulldown menu. 
  13110.  
  13111.    o  A pulldown menu item that when selected, results in the display of  a 
  13112.       dialog box, [Note that a dialog box is known as an action window under 
  13113.       CUA'91.  However, the term dialog box is used in most Presentation 
  13114.       Manager documentation, and will be used throughout this document for 
  13115.       consistency. ] should have its text succeeded in the pulldown menu by an 
  13116.       ellipsis (...) to indicate that the dialog continues. 
  13117.  
  13118.  The SAA CUA guidelines stipulate that each standard window has a menu bar, 
  13119.  which contains actions specific to the object represented by that window. 
  13120.  However, certain actions may be inapplicable at certain points during 
  13121.  application execution.  If an action is not necessarily applicable at all 
  13122.  stages of processing or for all data objects displayed within a window, that 
  13123.  action should remain in the menu bar or pulldown menu, but should be disabled 
  13124.  (that is, made non-selectable) until the point at which the action is valid. 
  13125.  
  13126.  Selection of a valid menu bar or pulldown menu item should result in the 
  13127.  immediate performance of the action, or the display of a dialog box  to obtain 
  13128.  necessary information before performance of the requested  action may take 
  13129.  place.  Selection of an invalid menu bar or pulldown  menu item will result in 
  13130.  a "beep" and the continued display of the  pulldown.  The menu bar and 
  13131.  pulldown menus are discussed in the IBM Systems Application Architecture CUA 
  13132.  Advanced Guide to User Interface Design and the IBM Systems Application 
  13133.  Architecture CUA Advanced Interface Design Reference. 
  13134.  
  13135.  Presentation Manager provides mechanisms to achieve the insertion/deletion and 
  13136.  enabling/disabling of menu bar items, as explained in the following sections. 
  13137.  
  13138.  
  13139. ΓòÉΓòÉΓòÉ 19.2.1. Inserting/Deleting Menu Bar Items ΓòÉΓòÉΓòÉ
  13140.  
  13141. The insertion of an item is achieved by sending a message of class 
  13142. MM_INSERTITEM to the system menu (or to the menu bar or appropriate pulldown 
  13143. menu) using the WinSendDlgItemMsg() function.  The menu item information is 
  13144. placed into a data structure of type MENUITEM, as shown in Dynamically 
  13145. Inserting a Menu Bar Item. 
  13146.  
  13147. hFrame = WinQueryWindow(hwnd,         /* Current Window   */
  13148.             QW_PARENT);      /* Parent       */
  13149.  
  13150. hMenu = WinWindowFromID(hFrame,        /* Get handle of   */
  13151.             FID_MENU);       /* menu bar      */
  13152.  
  13153. MenuItem.iPosition = MIT_END;         /* Item position   */
  13154. MenuItem.afStyle = MIS_TEXT;          /* Item style     */
  13155. MenuItem.afAttribute = 0;           /* No attributes   */
  13156. MenuItem.id = MI_OPENOBJECT;          /* Item identifier  */
  13157. MenuItem.hItem = 0;              /* No handle     */
  13158. MenuItem.hwndSubmenu = 0;           /* No p'down handle  */
  13159.  
  13160. rc = WinSendDlgItemMsg(hMenu,         /* Send message    */
  13161.             MI_FILE,        /* to File pulldown  */
  13162.             MM_INSERTITEM,     /* Message class   */
  13163.             &MenuItem,       /* Pointer to item  */
  13164.             szItemText);      /* Text of menu item */
  13165.  
  13166. Dynamically Inserting a Menu Bar Item 
  13167.  
  13168. In the example shown above, an item is to be inserted into a standard "File" 
  13169. pulldown menu.  The menu item information is placed  into the data structure 
  13170. MenuItem, and the text to appear in  the pulldown menu is contained in the 
  13171. string variable szItemText. 
  13172.  
  13173. Note however, that the menu bar is a child of the frame window, and the 
  13174. pulldown menu is a child of the menu bar.  In order to successfully pass the 
  13175. message, the handle of the frame window must be obtained, and used to obtain 
  13176. the handle of the menu bar window.  This  handle is then used in the 
  13177. WinSendDlgItemMsg() call, along  with the window identifier MN_FILE, to send 
  13178. the MM_INSERTITEM message  to the pulldown menu.  The frame window handle is 
  13179. obtained using the  WinQueryWindow() function, and the QW_PARENT attribute 
  13180. causes the function to return the handle of the client's parent (that is, the 
  13181. frame window). 
  13182.  
  13183. Once the frame window's handle is obtained, the various attributes of the 
  13184. MenuItem structure are initialized.  An MM_INSERTITEM  message is then sent 
  13185. directly to the pulldown menu. 
  13186.  
  13187. Deletion of an item is accomplished in a similar fashion using a message of 
  13188. class MM_DELETEITEM.  Both message classes and the MENUITEM data structure are 
  13189. described in the IBM OS/2 Version 2.0 Presentation Manager Reference. 
  13190.  
  13191.  
  13192. ΓòÉΓòÉΓòÉ 19.2.1.1. Inserting/Deleting Separators ΓòÉΓòÉΓòÉ
  13193.  
  13194. Where more than one logical group of items is contained within a single 
  13195. pulldown menu, these groups should be divided by a separator, which is a 
  13196. horizontal bar appearing between the last item of one group and the first item 
  13197. of the next, in order to provide a visual indication of the group's distinct 
  13198. identities.  A separator may be defined within the resource script file (see 
  13199. Presentation Manager Resources) or may be inserted and deleted dynamically by 
  13200. the application. This dynamic insertion/deletion is carried out in a similar 
  13201. manner to that already described for "normal" pulldown menu items.  However, 
  13202. the afStyle field in the MENUITEM structure is specified as MIS_SEPARATOR, and 
  13203. the text of the item is set to NULL.  In such  cases, an item identifier is not 
  13204. required for the separator, although  it is recommended since an identifier 
  13205. must be specified in order to  delete the separator from the pulldown menu 
  13206. should this be necessary at  a later time. 
  13207.  
  13208. Deletion of a separator is achieved in exactly the same manner as that 
  13209. described for a normal pulldown menu item, using a message of class 
  13210. MM_DELETEITEM and specifying the identifier of the separator to be deleted. 
  13211.  
  13212.  
  13213. ΓòÉΓòÉΓòÉ 19.2.1.2. Inserting/Deleting Pulldown Menus ΓòÉΓòÉΓòÉ
  13214.  
  13215. The technique for dynamically inserting a pulldown menu or cascade pulldown 
  13216. into the menu bar is basically similar to that already described for inserting 
  13217. a menu bar or pulldown menu item. An example is given in Dynamically Inserting 
  13218. a Pulldown Menu. 
  13219.  
  13220. HWND hPulldown;
  13221.  :
  13222. hPulldown = WinCreateMenu(hFrame,       /* Create empty menu */
  13223.              NULL);        /* template      */
  13224.  
  13225. MenuItem.iPosition = MIT_END;         /* Item position   */
  13226. MenuItem.afStyle = MIS_TEXT;          /* Item style     */
  13227. MenuItem.afAttribute = 0;           /* No attributes   */
  13228. MenuItem.id = MN_OPENOBJECT;          /* Item identifier  */
  13229. MenuItem.hItem = 0;              /* No handle     */
  13230. MenuItem.hwndSubmenu = hPulldown;       /* No p'down handle  */
  13231.  
  13232. rc = WinSendDlgItemMsg(hMenu,         /* Send message    */
  13233.             MN_FILE,        /* to File pulldown  */
  13234.             MM_INSERTITEM,     /* Message class   */
  13235.             &MenuItem,       /* Pointer to item  */
  13236.             szItemText);      /* Text of menu item */
  13237.  
  13238. Dynamically Inserting a Pulldown Menu 
  13239.  
  13240. Thedifferenceliesinthefactthatapulldownmenuorcascadepulldownrequiresamenutemplatetobereservedinmemoryinordertocontaintheitemsthatwillsubsequentlybeinsertedintothepulldown 
  13241. . ThistemplateiscreatedusingtheWinCreateMenu ( )function 
  13242. ,whichreturnsahandletothemenutemplate 
  13243. . ThishandleisthenusedinthehwndSubmenufieldoftheMENUITEMstructure .
  13244.  
  13245.  
  13246. ΓòÉΓòÉΓòÉ 19.2.2. Enabling/Disabling Items ΓòÉΓòÉΓòÉ
  13247.  
  13248. Disabling an item is achieved using the WinEnableMenuItem() function. 
  13249.  
  13250. hMenu = WinWindowFromID(hFrame,       /* Get menu bar handle    */
  13251.            FID_MENU);
  13252.  
  13253. rc = WinEnableMenuItem(hMenu,        /* Menu bar handle      */
  13254.             MI_VIEW,       /* Menu item identifier    */
  13255.             TRUE);        /* Enable menu item      */
  13256.  
  13257. Disabling an Menu Bar/Pulldown Menu Item 
  13258.  
  13259. Enabling an item is achieved with the same message class, but FALSE is 
  13260. specified as the last attribute in the WinEnableMenuItem() function call. 
  13261.  
  13262. Note that the WinEnableMenuItem() function is new in OS/2 Version 2.0; previous 
  13263. versions of OS/2 required use of the WinSendDlgItemMsg() function to send an 
  13264. MM_SETITEMATTR message to the menu. 
  13265.  
  13266.  
  13267. ΓòÉΓòÉΓòÉ 19.2.3. Indicating Selected Items ΓòÉΓòÉΓòÉ
  13268.  
  13269. A pulldown menu may be used to display a list of options from which one or more 
  13270. items may currently be selected; for example, a pulldown menu might provide a 
  13271. list of fonts to be used by a word-processing or desktop publishing 
  13272. application.  SAA CUA guidelines stipulate that in such a case, the currently 
  13273. selected item or items within the pulldown menu should be indicated by a check 
  13274. mark next to the item.  Presentation Manager provides support for this 
  13275. convention by allowing a check mark to be displayed within the pulldown menu. 
  13276. This is achieved using the WinCheckMenuItem() function; Placing a Check Mark on 
  13277. a Pulldown Menu Item shows how to place a check mark next to  the item 
  13278. MI_OPTION1. 
  13279.  
  13280. hMenu = WinWindowFromID(hFrame,       /* Get menu bar handle    */
  13281.              FID_MENU);
  13282.  
  13283. rc = WinCheckMenuItem(hMenu,        /* Menu bar handle      */
  13284.            MI_OPTION1,      /* Menu item identifier    */
  13285.            TRUE);        /* Set check mark       */
  13286.  
  13287. Placing a Check Mark on a Pulldown Menu Item 
  13288.  
  13289. NotethattheWinCheckMenuItem ( )functionisnewinOS / 2Version2 . 0 
  13290. ; previousversionsofOS / 2requiredtheuseofaWinSendDlgItemMsg ( 
  13291. )functioncalltosendanMM _ SETITEMATTRmessagetothemenu .
  13292.  
  13293. If a checked item is selected for a second time, the check mark should be 
  13294. removed by the application.  This is achieved by sending the same message to 
  13295. the menu bar, with FALSE specified for the last attribute in the function call. 
  13296.  
  13297. Note that the use of a check mark in a pulldown menu provides an alternative to 
  13298. the use of radio buttons or check boxes in simple dialogs. See Use of Control 
  13299. Windows for further information.  When a pulldown menu with a check mark is 
  13300. used to display more than one set of  mutually exclusive items, each set should 
  13301. be separated by a horizontal  bar in the pulldown menu.  See Presentation 
  13302. Manager Resources. 
  13303.  
  13304.  
  13305. ΓòÉΓòÉΓòÉ 19.3. Action Windows ΓòÉΓòÉΓòÉ
  13306.  
  13307. Under the guidelines provided by CUA'91, a dialog box is known as an action 
  13308. window.  Since this chapter discusses CUA guidelines, this term will be used 
  13309. herein when referring to the provisions made by CUA.  The term "dialog box" 
  13310. will be used when referring to the implementation of these concepts under 
  13311. Presentation Manager. 
  13312.  
  13313. Action windows used by an application may be either modal or modeless, although 
  13314. modeless windows are preferred under CUA. Both types of action window are 
  13315. defined as optimized windows; that is, they are created at a predefined optimal 
  13316. size for their function, and may not be resized by the user.  However, the use 
  13317. of each type of action window is different, as explained below. 
  13318.  
  13319. A dialog box is typically created using the Dialog Box Editor application 
  13320. supplied as part of the IBM Developer's Toolkit for OS/2 2.0, and is defined in 
  13321. a dialog template which is stored in a .DLG file and referenced from  the 
  13322. application's resource script file.  Dialog templates are fully  described in 
  13323. the IBM OS/2 Version 2.0 Application Design Guide. 
  13324.  
  13325. It is recommended that wherever possible, action windows should be created with 
  13326. a title bar.  Since action windows typically appear as the result of a menu bar 
  13327. item being selected, the title bar should contain the name of the parent 
  13328. object, plus the same text as the menu bar item.  This provides the user with a 
  13329. visual indication of the action which led to the action window being displayed. 
  13330.  
  13331. As already mentioned, an action window should not be sizable by the user, 
  13332. although it may be movable.  Similarly, a modal action window should not 
  13333. include minimize or maximize icons, since the user must complete the 
  13334. interaction with the action window at its optimal size prior to continuing with 
  13335. execution.  In the case of a modeless action window, there is no point in 
  13336. providing a maximize icon since the window is created at an optimal size for 
  13337. the information it will contain. However, since a user may wish to suspend the 
  13338. dialog in order to interact with other windows, the user may wish to remove the 
  13339. action window from the desktop.  In such cases, a modeless action window should 
  13340. include a minimize icon. 
  13341.  
  13342.  
  13343. ΓòÉΓòÉΓòÉ 19.3.1. Modeless Action Windows ΓòÉΓòÉΓòÉ
  13344.  
  13345. A modeless action window is preferred in situations where the dialog with the 
  13346. user need not be completed before other user interaction with the application 
  13347. may occur.  For instance, in an application object that performs an 
  13348. administrative procedure, data entry would typically be performed by the use of 
  13349. control windows.  Since the control windows should remain displayed at all 
  13350. times, their parent window should not be  sizable.  By definition, the parent 
  13351. window is an optimized window, and  should therefore be created as a dialog 
  13352. box.  However, it may not be  mandatory for the user to complete the dialog 
  13353. before interacting with  other windows, and the dialog box should therefore be 
  13354. modeless. 
  13355.  
  13356. Since the WinDlgBox() function automatically creates and executes a modal 
  13357. dialog box, a modeless dialog box must be created in one of two alternative 
  13358. ways: 
  13359.  
  13360.    o  Using the standard WinCreateWindow() function, with the FCF_BORDER frame 
  13361.       creation flag set.  Control windows such as entry fields and buttons may 
  13362.       then be created as children of the dialog box window. 
  13363.  
  13364.    o  Using a WinLoadDlg() call to load the dialog template from a resource 
  13365.       into memory, and then using the WinShowWindow() or WinSetWindowPos() 
  13366.       functions to make the dialog box visible.  The dialog template should 
  13367.       have the FCF_BORDER attribute set.  Control windows within the dialog box 
  13368.       are defined in the dialog template. 
  13369.  
  13370.  The latter method is recommended for reasons of simplicity, since the dialog 
  13371.  box and its control windows may be defined and stored in a resource file (see 
  13372.  Presentation Manager Resources), making the definition of  the dialog box 
  13373.  easier for the application developer. 
  13374.  
  13375.  The dialog box may be explicitly positioned on the screen, regardless of the 
  13376.  method used.  With the former method using the WinCreateWindow() function, the 
  13377.  dialog box is positioned at the time it is created.  With the latter method, 
  13378.  the dialog box is positioned during its processing of the WM_INITDLG message. 
  13379.  
  13380.  The FCF_BORDER attribute results in the dialog box being displayed with a thin 
  13381.  blue line as the dialog border.  This is in accordance with  the SAA CUA 
  13382.  guidelines for modeless action windows. 
  13383.  
  13384.  Note that the two methods described above will result in different 
  13385.  initialization messages being received.  When created with the 
  13386.  WinCreateWindow() function, the dialog box is regarded as a "normal" window, 
  13387.  and a WM_CREATE message is passed to it.  When created with the WinLoadDlg() 
  13388.  function however, a WM_INITDLG  message is passed instead. The application 
  13389.  developer must bear this in  mind when creating the dialog procedures for such 
  13390.  dialog boxes. 
  13391.  
  13392.  
  13393. ΓòÉΓòÉΓòÉ 19.3.2. Modal Action Windows ΓòÉΓòÉΓòÉ
  13394.  
  13395. Modal action windows are used to carry out a dialog with the user in order to 
  13396. define or qualify the properties of a data object upon which the user is 
  13397. operating or wishes to operate.  It is important to differentiate the 
  13398. properties of a data object from its contents; for instance, the properties of 
  13399. a text file might be its name, parent directory, archive/hidden/read-only 
  13400. attributes etc, whereas its contents would be the text within the file.  Under 
  13401. Presentation Manager, manipulation of an object's contents is typically carried 
  13402. out in a standard window, whereas definition or alteration of attributes is 
  13403. done using a dialog box. 
  13404.  
  13405. Note that where the dialog with the user is limited to a simple decision, a 
  13406. Presentation Manager message box should be used in preference to a dialog box 
  13407. for the implementation of an action window, since the coding effort and 
  13408. processing overhead associated with a message box is much less than that 
  13409. associated with loading and processing a dialog box.  See Message Boxes for 
  13410. more information  on the use of message boxes. 
  13411.  
  13412. A modal dialog box is typically loaded and processed in a single step using the 
  13413. WinDlgBox() call.  The modal nature of the dialog box is indicated to the user 
  13414. by a double blue line as the border for the dialog box, rather than the 
  13415. standard window border.  The different border indicates that the dialog box is 
  13416. modal, and also indicates that it may not be sized by the user.  This border is 
  13417. specified in the dialog template using the FCF_DLGBORDER attribute. 
  13418.  
  13419. By default, a modal dialog box is application-modal;  that  is, the user must 
  13420. complete interaction with the dialog box before any  further interaction may 
  13421. take place with windows in the current application.  A dialog box may also be 
  13422. system-modal, in which case the user must complete interaction with the dialog 
  13423. box before interacting with any other window in the system.  A system-modal 
  13424. dialog box is created in the same way as an application-modal dialog box, but 
  13425. with  the additional attribute FS_SYSMODAL specified in the dialog template. 
  13426.  
  13427.  
  13428. ΓòÉΓòÉΓòÉ 19.3.3. Standard Dialogs ΓòÉΓòÉΓòÉ
  13429.  
  13430. OS/2 Version 2.0 provides standard dialog boxes for handling the selection of 
  13431. files and fonts.  These dialogs conform to SAA CUA guidelines, and are 
  13432. implemented within Presentation Manager.  Applications are therefore not 
  13433. required to explicitly design and code such dialog functions, nor to modify 
  13434. them should the CUA guidelines change in the future. 
  13435.  
  13436. The standard dialogs are displayed using two Presentation Manager functions new 
  13437. to OS/2 Version 2.0; these are the WinFileDlg() and WinFontDlg() functions. 
  13438.  
  13439.  
  13440. ΓòÉΓòÉΓòÉ 19.3.3.1. File Dialog ΓòÉΓòÉΓòÉ
  13441.  
  13442. The standard file dialog enables a user to specify a file to be opened or a 
  13443. file name under which current work is to be saved, including  the ability to 
  13444. switch directories and logical drives.  The file dialog  provides basic 
  13445. capabilities, and is designed in such a way that it may  be modified if 
  13446. additional function is required. 
  13447.  
  13448. The file dialog is displayed using the WinFileDlg() function.  The dialog may 
  13449. be displayed as either an "Open" dialog or a "Save as" dialog, depending upon 
  13450. the value of control flags specified in a FILEDLG structure passed as a 
  13451. parameter to the function call.  The WinFileDlg() function is shown in Standard 
  13452. Dialogs - WinFileDlg() Function. 
  13453.  
  13454. USHORT OpenFile(HWND hOwner)
  13455. {
  13456.   extern PFNWP   WinFileDlg();      /* Function prototype      */
  13457.   extern FILEDLG  fild;          /* File dlg control structure  */
  13458.   extern HFILE   hFileToOpen;      /* File handle         */
  13459.   extern USHORT  usAction;        /* Action indicator       */
  13460.   static BOOL   fFirstTime = TRUE;   /* Flag             */
  13461.   USHORT usReturn;            /* Return code         */
  13462.  
  13463.   if (fFirstTime)             /* If invoked for first time  */
  13464.    {                  /* build control structure   */
  13465.    fild.cbSize = sizeof(FILEDLG);    /* Set size of control struct  */
  13466.    fild.fl   = FDS_OPEN_DIALOG Γòæ   /* Set dialog type to "Open"  */
  13467.           FDS_CENTER    Γòæ   /* Centered in parent window  */
  13468.           FDS_HELP_BUTTON;    /* Include help button     */
  13469.    fild.pszTitle    = NULL;     /* Use default title bar text  */
  13470.    fild.pszOKButton   = NULL;     /* Use default button text   */
  13471.    fild.pfnDlgProc   = NULL;     /* Use standard dlg proc    */
  13472.    fild.hmod      = NULL;     /*  "   "    "   "     */
  13473.    fild.idDlg      = 0;       /*  "   "    "   "     */
  13474.    fild.pszIType    = NULL;     /* No initial type setting   */
  13475.    fild.ppszITypeList  = NULL;     /* No list of types       */
  13476.    fild.pszIDrive    = NULL;     /* No initial drive setting   */
  13477.    fild.ppszIDriveList = NULL;     /* No list of drivers      */
  13478.    fFirstTime = FALSE;         /* Set flag to false      */
  13479.    }
  13480.   WinFileDlg(hOwner,           /* Invoke file dialog      */
  13481.        &fild);           /* Control structure pointer  */
  13482.  
  13483.   rc = DosOpen(fild.szFullFile,      /* Open returned file name   */
  13484.         &hFileToOpen,       /* File handle         */
  13485.         &usAction,         /* Action indicator       */
  13486.         0L,            /* File size not applicable   */
  13487.         0,             /* File attribute ignored    */
  13488.         0x0001,          /* Open file if it exists    */
  13489.         0x00C2,          /* Non-shared, read-write    */
  13490.         0L);            /* No sharing mode       */
  13491.   return(rc);               /* Return            */
  13492. }
  13493.  
  13494. Standard Dialogs - WinFileDlg() Function 
  13495.  
  13496. The appearance of the file dialog is controlled by the FDS_* style flags 
  13497. specified in the fl field in the FILEDLG structure.  The fields in this 
  13498. structure are: 
  13499.  
  13500.  Field               Usage 
  13501.  cbSize              Defines the size of the FILEDLG structure, and should be 
  13502.                      initialized using the sizeof() function. 
  13503.  fl                  Style flags of the form FDS_*, which control the 
  13504.                      attributes of the dialog.  These flags are described in 
  13505.                      the IBM OS/2 Version 2.0 Presentation Manager Reference. 
  13506.  IUser               Used by applications to store their own state information 
  13507.                      if subclassing the dialog in order to modify its 
  13508.                      appearance or behavior. 
  13509.  IReturn             Identifier of the button used to dismiss the dialog.  This 
  13510.                      is typically DID_OK or DID_CANCEL, unless the application 
  13511.                      has subclassed the dialog and added its own buttons. 
  13512.  ISRC                System return code which indicates the reason for dialog 
  13513.                      failure, if a failure has occurred.  This field is used to 
  13514.                      assist in debugging. 
  13515.  pszTitle            Dialog title text.  If set to NULL, the text will default 
  13516.                      to "Open"  or "Save As", depending upon the FDS_* flags 
  13517.                      selected. 
  13518.  pszOKButton         Text used for the OK pushbutton on the dialog.  If set to 
  13519.                      NULL, the text defaults to "OK". 
  13520.  pfnDlgProc          Pointer to custom dialog procedure, for custom dialogs 
  13521.                      with the FDS_CUSTOM style flag set. 
  13522.  pszIType            String pointer to a string defining the initial Extended 
  13523.                      Attribute type filter to be applied to the file name field 
  13524.                      in the dialog. 
  13525.  pszITypeList        Pointer to a table of string pointers.  Each points to a 
  13526.                      null terminated string defining an Extended Attribute type 
  13527.                      filter.  The filters are displayed in ascending order in 
  13528.                      the Type pull-down box. 
  13529.  pszIDrive           Pointer to a string specifying the initial logical drive 
  13530.                      to be applied in the dialog. 
  13531.  ppszIDriveList      Pointer to a table of string pointers.  Each points to a 
  13532.                      null terminated string defining a valid logical drive. 
  13533.  hMod                If the FDS_CUSTOM style flag is set, this field defines 
  13534.                      the DLL module handle that contains the file dialog 
  13535.                      template to be used.  If set to NULL, the dialog template 
  13536.                      is loaded from the application's EXE file. 
  13537.  szFullFile          On initialization, this field contains the initial fully 
  13538.                      qualified path and file name, and on completion of the 
  13539.                      dialog, contains the selected or user-specified fully 
  13540.                      qualified file name.  Upon invocation of the dialog, all 
  13541.                      drive and path data is stripped from the name, and moved 
  13542.                      to the appropriate fields in the dialog box. 
  13543.  ppszFQFilename      Pointer to a table of pointers.  Each points to a null 
  13544.                      terminated string containing a fully qualified file name. 
  13545.                      This table is used by applications that require multiple 
  13546.                      files to be selected from within the file dialog 
  13547.                      (indicated by specifying FDS_MULTIPLESEL).  The storage is 
  13548.                      allocated by the file dialog procedure, and must be freed 
  13549.                      after dialog completion using the WinFileFreeFileList() 
  13550.                      function. 
  13551.  IFQFCount           Number of file names selected in the file dialog, for 
  13552.                      dialogs with multiple selection enabled. 
  13553.  idDlg               Window identifier of the dialog window.  If the FDS_CUSTOM 
  13554.                      style flag is set, this is also the resource identifier of 
  13555.                      the dialog template. 
  13556.  x,y                 Position of the dialog, relative to its parent.  These 
  13557.                      fields are automatically updated by the dialog procedure 
  13558.                      when the dialog is moved by the user, so that if the same 
  13559.                      FILEDLG procedure is used on subsequent invocations, the 
  13560.                      dialog will appear in the same location.  The FDS_CENTER 
  13561.                      style flag overrides any settings specified. 
  13562.  sEAType             Extended Attribute file type to be be assigned to the 
  13563.                      file.  This field contains the returned value specified in 
  13564.                      the Type field in the dialog.  This field is valid only 
  13565.                      for a "Save As" dialog; the value -1 is returned for an 
  13566.                      "Open" dialog. 
  13567.  For applications with specialized file handling requirements, the standard 
  13568.  file dialog may be subclassed, allowing these requirements to be handled while 
  13569.  retaining standard processing for the majority of events.  This subclassing is 
  13570.  invoked by specifying the address of an application-defined dialog procedure 
  13571.  in the pfnDlgProc field  in the FILEDLG structure, and by specifying the 
  13572.  resource identifier of  an application-defined dialog template if controls are 
  13573.  to be added or  removed from the dialog. 
  13574.  
  13575.  Note that application-defined dialog procedures should invoke the 
  13576.  WinFileDlgProc() function as their default case for message processing, to 
  13577.  ensure that messages not explicitly processed by the application are passed to 
  13578.  the standard file dialog procedure for correct default processing. 
  13579.  
  13580.  
  13581. ΓòÉΓòÉΓòÉ 19.3.3.2. Font Dialog ΓòÉΓòÉΓòÉ
  13582.  
  13583. The standard font dialog enables a user to specify a choice of font names, 
  13584. styles, and sizes from the range available within a given application.  The 
  13585. font dialog is intended to fit basic application needs, and is designed in such 
  13586. a way that additional function may be added by subclassing the dialog 
  13587. procedure. 
  13588.  
  13589. The font dialog is displayed using the WinFontDlg() function, specifying the 
  13590. owner window for the dialog box, and a FONTDLG control structure.  The use of 
  13591. the WinFontDlg() function is shown in WinFontDlg() Function - Sample Code. 
  13592.  
  13593. void SetFont(HWND hOwner, HPS hpsScreen, USHORT usCodePage)
  13594. {
  13595.    extern PFNWP  WinFontDlg();       /* Function prototype    */
  13596.    extern FONTDLG fntd;           /* Dialog control struct  */
  13597.    static BOOL   fFirstTime = TRUE;     /* Flag           */
  13598.    CHARBUNDLE   cbnd;           /* Attributes        */
  13599.  
  13600. if (FirstTime)                 /* If invoked for 1st time */
  13601.   {                      /* build control structure */
  13602.   fntd.cbSize       = sizeof(FONTDLG);  /* Set size of structure  */
  13603.   fntd.fl         = FNTS_CENTER Γòæ   /* Specify centered dlg   */
  13604.               FNTS_HELPBUTTON;  /* Include help button   */
  13605.   fntd.hpsPrinter     = NULL;       /* No printer font     */
  13606.   fntd.pszTitle      = "Fonts";      /* Dialog title text    */
  13607.   fntd.pfnDlgProc     = NULL;       /* Use standard dlg proc  */
  13608.   fntd.hmod        = NULL;       /*  "   "    "   "   */
  13609.   fntd.idDlg       = 0;         /*  "   "    "   "   */
  13610.   fntd.pszPreview     = NULL        /* Default preview string  */
  13611.   fntd.pszPtSizeList   = NULL;       /* Default point sizes   */
  13612.   fntd.flFlags      = 0L;        /* Default flags      */
  13613.   fntd.szFamilyname[]   = '\0';       /* System default      */
  13614.   fntd.fxPointSize    = MAKEFIXED(12,0);  /* 12-point vertical size  */
  13615.   fntd.usWeight      = FWEIGHT_NORMAL;  /* Weight or thickness   */
  13616.   fntd.usWidth      = FWIDTH_NORMAL;   /* Character width     */
  13617.   fntd.flType       = 0L;        /* No additional attribs  */
  13618.   fntd.flStyle      = 0L;        /* No additional styles   */
  13619.   fntd.flCHSOptions    = 0L;        /* No additional options  */
  13620.   fntd.clrFore      = CLR_BLACK;     /* Black characters     */
  13621.   fntd.clrBack      = CLR_WHITE;     /* White background     */
  13622.   fntd.fAttrs.usCodePage = usCodePage;    /* Specified code page   */
  13623.   fFirstTime=FALSE;              /* Reset flag        */
  13624.   }
  13625. fntd.hpsScreen=hpsScreen;           /* Set presentation space  */
  13626.  
  13627. WinFontDlg(hOwner,               /* Invoke font dialog    */
  13628.       &fntd);               /* Control structure ptr  */
  13629.  
  13630. GpiCreateLogFront(hpsScreen,          /* Create logical font   */
  13631.          "Name   ",         /* Name of font       */
  13632.          0,              /* Local font identifier  */
  13633.          fntd.fAttrs);        /* Returned attributes   */
  13634. cbnd.lColor = fntd.clrFore;          /* Set foreground color   */
  13635. cbnd.lBackColor = fntd.clrBack;        /* Set background color   */
  13636. GpiSetAttrs(hpsScreen,             /* Set attributes      */
  13637.       PRIM_CHAR,             /* Character attributes   */
  13638.       CBB_COLOR Γòæ CBB_BACK_COLOR,    /* Attributes to be set   */
  13639.       0L,                /* Defaults mask      */
  13640.       (PBUNDLE)&cbnd);          /* Attribute structure   */
  13641. GpiCharStringPos(hpsScreen,          /* Write character string  */
  13642.          NULL,             /* No rectangle       */
  13643.          fntd.flCHSOptions,      /* Options         */
  13644.          4,              /* Number of bytes     */
  13645.          "Text",            /* Text string       */
  13646.          NULL);            /* Increment values     */
  13647. }
  13648.  
  13649. WinFontDlg() Function - Sample Code 
  13650.  
  13651. The appearance of the dialog is determined by the FNTS_* flags specified in the 
  13652. fl field of the FONTDLG structure, and by the other fields in this structure. 
  13653. The fields in the FONTDLG structure are: 
  13654.  
  13655.  Field          Usage 
  13656.  cbSize         Defines the size of the structure, and should be initialized 
  13657.                 using the sizeof() function. 
  13658.  hpsScreen      If not NULL, this field specifies the screen presentation 
  13659.                 space, which the dialog procedure queries for available fonts. 
  13660.  hpsPrinter     If not NULL, this field specifies the printer presentation 
  13661.                 space, which the dialog procedure queries for available fonts. 
  13662.  pszTitle       Title text for the dialog box.  If set to NULL, the default 
  13663.                 text "Font" is used. 
  13664.  pszPreview     Text to be displayed in the Preview field in the dialog box. 
  13665.                 If set to NULL, the default text "abcdABCD" is used. 
  13666.  pszPtSizeList  String containing a list of numeric point sizes, to be 
  13667.                 displayed in  the Point Size drop-down list in the dialog box. 
  13668.                 Point sizes within the string must be separated by spaces.  If 
  13669.                 set to NULL, the defaults of 8, 10, 12, 14, 18, and 24 are 
  13670.                 used. 
  13671.  pfnDlgProc     Pointer to custom dialog procedure, for dialogs with the 
  13672.                 FNTS_CUSTOM flag set. 
  13673.  szFamilyname   Font family name to be used by an application to select a font. 
  13674.                 If  set to NULL, the system default is used. 
  13675.  fxPointSize    Vertical point size of the font. 
  13676.  fl             Flags which specify the characteristics of the dialog box; 
  13677.                 these may be any combination of FNTS_CENTERED, FNTS_CUSTOM, 
  13678.                 FNTS_HELPBUTTON, FNTS_MULTIFONTSELECTION, and FNTS_MODELESS. 
  13679.                 Flags are  combined using the "or" operator. 
  13680.  flFlags        Flags; specifying FNTF_VIEWPRINTERFONTS specifies whether 
  13681.                 printer fonts should be included if both hpsScreen and 
  13682.                 hpsPrinter are non-NULL.  FNTF_PRINTERFONTSELECTED is set upon 
  13683.                 return, if the user selects a printer font. 
  13684.  flType         Specifies additional font attributes specified by the user, and 
  13685.                 may  be used as the options field in a QFSATTRS structure for 
  13686.                 the GpiQueryFaceString() function. 
  13687.  flTypeMask     Specifies which flags in the flType field are required to 
  13688.                 change.  This is only relevant where selections may be for 
  13689.                 different  types and styles when multiple fonts are being 
  13690.                 selected. 
  13691.  flStyle        Specifies any additional selections, and may be used for the 
  13692.                 selection indicators in a FATTRS structure supplied to the 
  13693.                 GpiCreateLogFont() function. 
  13694.  flStyleMask    Specifies which flags in the flStyle field are required to 
  13695.                 change.  This is only relevant where selections may be for 
  13696.                 different  types and styles when multiple fonts are being 
  13697.                 selected. 
  13698.  flCHSOptions   These are equivalent to the CHS_* option flags used by the 
  13699.                 GpiCharStringPos() and GpiCharStringPosAt() functions. 
  13700.  flCHSMask      Similar to flStyleMask. 
  13701.  clrFore        Foreground color for the font. 
  13702.  clrBack        Background color for the font. 
  13703.  lUser          May be used by applications to pass information if subclassing 
  13704.                 the font dialog. 
  13705.  lReturn        Identifier of the button used to dismiss the dialog.  This is 
  13706.                 typically DID_OK or DID_CANCEL, unless the application has 
  13707.                 subclassed the dialog and added its own buttons. 
  13708.  ISRC           System return code that indicates the reason for dialog 
  13709.                 failure, if a failure has occurred.  This field is used to 
  13710.                 assist in debugging. 
  13711.  lEmHeight      Value that may be used within a FONTMETRICS structure by 
  13712.                 applications. 
  13713.  IXHeight       As above. 
  13714.  iExternalLeading As above. 
  13715.  fAttrs         Complete font attribute (FATTRS) structure for the selected 
  13716.                 font.  Only the codepage field may be modified by the 
  13717.                 application prior to invoking the dialog. 
  13718.  sNominalPointSize Nominal point size of selected font. 
  13719.  usWeight       Character thickness (for example, normal or bold).  The 
  13720.                 returned value may be used in the weightclass field in the 
  13721.                 QFSATTRS structure for the GpiQueryFaceString() function. 
  13722.  usWidth        Character width.  The returned value may be used in the 
  13723.                 widthclass field in the QFSATTRS structure for the 
  13724.                 GpiQueryFaceString() function. 
  13725.  x,y            Position of the dialog relative to its parent.  These fields 
  13726.                 are automatically updated by the dialog procedure when the 
  13727.                 dialog is moved by the user, so that if the same FONTDLG 
  13728.                 structure is used on subsequent invocations, the dialog will 
  13729.                 appear in the same location.  The FNTS_CENTERED style flag 
  13730.                 overrides any settings specified. 
  13731.  idDlg          Window identifier of the dialog window.  If the FNTS_CUSTOM 
  13732.                 style flag is set, this is also the resource identifier of the 
  13733.                 dialog template. 
  13734.  hmod           If the FNTS_CUSTOM style flag is set, this field defines the 
  13735.                 DLL module handle that contains the file dialog template to be 
  13736.                 used.  If set to NULL, the dialog template is loaded from the 
  13737.                 application's EXE file. 
  13738.  
  13739.  Applications may customize the font dialog through subclassing, by specifying 
  13740.  the FNTS_CUSTOM style flag, giving the resource identifier and module handle 
  13741.  of the application's customized font dialog template,  and the address of an 
  13742.  application-defined dialog procedure, in the FONTDLG structure.  The 
  13743.  WinFontDlg() function then performs the subclassing operation on the 
  13744.  application's behalf. 
  13745.  
  13746.  Note that application-defined dialog procedures should invoke the 
  13747.  WinFontDlgProc() function as their default case for message processing, to 
  13748.  ensure that messages not explicitly processed by the application are passed to 
  13749.  the standard font dialog procedure for correct default processing. 
  13750.  
  13751.  An application that uses its own dialog template must include all of the 
  13752.  standard controls within the dialog box, in addition  to its own customized 
  13753.  controls.  Those controls, which are not  required, may be rendered invisible 
  13754.  in order to provide the correct  appearance. 
  13755.  
  13756.  Control window identifiers in the range 0x0000 to 0x0FFF are reserved for use 
  13757.  by standard controls.  The application's own controls should therefore use 
  13758.  window identifiers greater than 0x0FFF. 
  13759.  
  13760.  
  13761. ΓòÉΓòÉΓòÉ 19.3.4. Use of Control Windows ΓòÉΓòÉΓòÉ
  13762.  
  13763. A number of control window classes are provided by Presentation Manager.  Under 
  13764. CUA guidelines, these control windows should be displayed  in standard windows, 
  13765. although their use is more typically in dialog  boxes.  This is in accordance 
  13766. with the convention that windows display objects  or the contents of objects, 
  13767. and other more structured information such  as object attributes is displayed 
  13768. in a dialog box.  See also the proviso  regarding listboxes under Standard 
  13769. Windows.  The use of control  windows is defined in the IBM Systems Application 
  13770. Architecture CUA Advanced Guide to User Interface Design.  However , there are 
  13771. some  emerging conventions as to the exact interpretation of the CUA 
  13772. guidelines, and these are discussed in the following sections. 
  13773.  
  13774.  
  13775. ΓòÉΓòÉΓòÉ 19.3.4.1. Entry Field ΓòÉΓòÉΓòÉ
  13776.  
  13777. Entry fields are used where textual or numeric data is required from the user, 
  13778. and where the set of possible entries is open-ended.  Examples of such data 
  13779. items include file names, object descriptions etc. 
  13780.  
  13781.  
  13782. ΓòÉΓòÉΓòÉ 19.3.4.2. List Box ΓòÉΓòÉΓòÉ
  13783.  
  13784. A listbox is used to display a list of objects, where the contents of that list 
  13785. may change from one execution to the next, based upon various external or 
  13786. user-specified criteria.  One or more items may be selected from a listbox. The 
  13787. listbox is typically created with a size sufficient to display a certain number 
  13788. of items, and a scroll bar is provided if the number of items increases such 
  13789. that not all items may be displayed at once. 
  13790.  
  13791. Note that a listbox should not be used to display a set of choices where that 
  13792. set is finite and unchanging.  In such a case, radio buttons  may be used where 
  13793. the choices are mutually exclusive, or check boxes  used where more than one 
  13794. choice may be made concurrently. 
  13795.  
  13796.  
  13797. ΓòÉΓòÉΓòÉ 19.3.4.3. Combo Box ΓòÉΓòÉΓòÉ
  13798.  
  13799. A combo box, also known as a prompted entry field is a combination of the 
  13800. entry field and listbox control window styles, and is supported by 
  13801. Presentation Manager in OS/2 Version 1.2 and above.  A combo box is used where 
  13802. textual or numeric data is required from a user, where the set of possible 
  13803. entries is finite, and where the application wishes to prompt the user for a 
  13804. valid entry.  A combo box may be of three distinct types: 
  13805.  
  13806.    o  A simple combo box is displayed as an entry field with a  listbox 
  13807.       directly below it.  The user may enter textual or numeric data  into the 
  13808.       entry field in the same way as for a normal entry field, or  may select 
  13809.       an item from the listbox.  The selected item will then appear in the 
  13810.       entry field.  The simple combo box provides a similar function to that of 
  13811.       a single-selection listbox. 
  13812.  
  13813.    o  A drop-down combo box is displayed as an entry field with an icon to its 
  13814.       immediate right.  The user may enter textual or numeric data into the 
  13815.       entry field, or may select the icon.  When selected, the icon causes a 
  13816.       listbox to appear below the entry field, containing a list of valid 
  13817.       entries for the entry field.  When selected,  an item appears in the 
  13818.       listbox.  The drop-down combo box is  recommended where the set of valid 
  13819.       entries is finite and limited, but  where the user may already know the 
  13820.       required entry and may wish to save  time by entering it him/herself. 
  13821.  
  13822.    o  A drop-down list combo box is displayed in a similar manner to a 
  13823.       drop-down combo box, as an entry field with an icon to its immediate 
  13824.       right.  However, the user may not enter data directly into the entry 
  13825.       field, but must select an item from the listbox.  A drop-down list combo 
  13826.       box is recommended in situations where a number of  control windows are 
  13827.       located in a dialog box, where the optimization of  space is of primary 
  13828.       importance, and where the default entry is likely  to be used. 
  13829.  
  13830.  The use of a combo box is typically recommended in place of a listbox in order 
  13831.  to save room within a dialog box, or in place of an entry field where the 
  13832.  application wishes to prompt a user with a list of valid entries. 
  13833.  
  13834.  
  13835. ΓòÉΓòÉΓòÉ 19.3.4.4. Radio Button ΓòÉΓòÉΓòÉ
  13836.  
  13837. Radio buttons are used to indicate a group of mutually exclusive options;  that 
  13838. is, only one of the items in the group is selectable at any one time, and 
  13839. selecting one item automatically deselects any previously selected item. 
  13840. Selecting a radio button does not complete the dialog; a user may revise 
  13841. his/her selection any number of times during the dialog.  Once a final decision 
  13842. is made, the user completes the dialog using a push button (see below). 
  13843.  
  13844. Radio buttons are always displayed in groups; it makes no sense to have a 
  13845. single mutually exclusive selection item.  Text is displayed along with the 
  13846. buttons to indicate the choice represented by each button.  If multiple groups 
  13847. of radio buttons are present within a dialog box or window, or if radio buttons 
  13848. are combined with other types  of control window, it is recommended for reasons 
  13849. of clarity that the  radio buttons be placed within a group box, and that this 
  13850. group box be  named to indicate the nature or purpose of the group as a whole. 
  13851.  
  13852. As described above, radio buttons should be used to denote a set of mutually 
  13853. exclusive options in the creation or manipulation of an object, as part of a 
  13854. more complex dialog.  They should not be used to present a set of options in 
  13855. response to an application or system event,  where this set of options is the 
  13856. sole purpose of the dialog.  In such  cases, a message box is the preferred 
  13857. mechanism to achieve this type of communication with the user, since the 
  13858. processing overhead associated  with a message box is less than that associated 
  13859. with a dialog box.  For example, a warning that the user is about to exit the 
  13860. application  without saving his/her latest set of changes would be presented 
  13861. using a  message box rather than a dialog box with radio buttons. 
  13862.  
  13863. The equivalent function of a group of radio buttons may also be provided by a 
  13864. pulldown menu displaying a set of options, only one of which may be selected at 
  13865. any one time, with the selected item indicated by a check mark.  The use of  a 
  13866. pulldown menu is the recommended option in situations where the selection of an 
  13867. option is the only action to be performed.  The use of radio buttons is 
  13868. recommended where the selection of an option indicated  by the radio buttons is 
  13869. part of a more complex dialog. 
  13870.  
  13871. Note that from a programming viewpoint, "auto" radio buttons should be used in 
  13872. preference to standard radio buttons since these buttons are drawn and 
  13873. maintained by Presentation Manager.  The application need not concern itself 
  13874. with redrawing the buttons when their state changes, thereby allowing simpler 
  13875. programming. 
  13876.  
  13877.  
  13878. ΓòÉΓòÉΓòÉ 19.3.4.5. Check Box ΓòÉΓòÉΓòÉ
  13879.  
  13880. A check box is used to indicate a single option that may be toggled on or off 
  13881. by the user.  Multiple check boxes may appear in a single dialog box or window, 
  13882. and may refer to different attributes of the same object.  However, these 
  13883. attributes are related to each other only by their application to that same 
  13884. object, and should not be mutually exclusive. 
  13885.  
  13886. A 3-state button is a special type of check box that, in  addition to being 
  13887. marked selected or non-selected, may be "grayed  out" to indicate that a choice 
  13888. is non-selectable in the current  dialog.  A 3-state button should be used 
  13889. whenever a dialog box is  applicable to a range of objects, but where certain 
  13890. options within the  dialog box are not valid for all objects dealt with by that 
  13891. dialog  box.  A 3-state button may be enabled or disabled using the 
  13892. WinEnableWindow() function, obtaining the window handle of the button from a 
  13893. WinWindowFromID() call. 
  13894.  
  13895. The equivalent function to a check box may be provided by a pulldown  menu 
  13896. displaying a list of options, from which multiple items may be selected  at any 
  13897. one time, with the selected items indicated by check marks.  The  use of a 
  13898. pulldown menu is recommended where the selection of such an  option is the only 
  13899. action to be performed.  The use of a check box or  3-state button is the 
  13900. preferred solution where the selection is part of  a more complex dialog. 
  13901.  
  13902. Note that the "auto" versions of check boxes and 3-state buttons should be used 
  13903. in preference to the standard versions, since the auto versions are maintained 
  13904. by Presentation Manager, and the application need not concern itself with 
  13905. redrawing these buttons when their state changes. 
  13906.  
  13907.  
  13908. ΓòÉΓòÉΓòÉ 19.3.4.6. Push Button ΓòÉΓòÉΓòÉ
  13909.  
  13910. Push buttons are used to initiate an immediate action by the application.  If 
  13911. desired, push buttons can be used in conjunction with the menu bar and context 
  13912. menu, to provide easy access to commonly used functions in both primary windows 
  13913. and action windows. 
  13914.  
  13915. Push buttons should not be used to form menus of selectable options that cause 
  13916. child windows to appear when a push button is selected.  Such a practice 
  13917. effectively forms a hierarchical user interface, which is in violation of 
  13918. object-oriented user interface principles. 
  13919.  
  13920. An exception to this rule is a "Help" push button, which immediately displays a 
  13921. window containing help information, while maintaining the previous window or 
  13922. dialog on the screen.  Dismissing the help window returns the user to the 
  13923. original window in which the "Help" push button was displayed. 
  13924.  
  13925.  
  13926. ΓòÉΓòÉΓòÉ 19.3.4.7. Slider ΓòÉΓòÉΓòÉ
  13927.  
  13928. The slider is used where a single value must be selected from a continuous 
  13929. range of options.  For example, the brightness of the screen, the saturation of 
  13930. a color or the speed of the mouse cursor on the screen are all values selected 
  13931. from a continuous, though finite, range of options. 
  13932.  
  13933. Under previous versions of OS/2, scroll bars were often used to provide a 
  13934. portion of the slider's functionality.  The provision of the slider control 
  13935. under OS/2 Version 2.0 allows the scroll bar to be used only for its intended 
  13936. purpose of scrolling information within a window; this improves the consistency 
  13937. of the user interface and removes a potential source of user confusion. 
  13938.  
  13939.  
  13940. ΓòÉΓòÉΓòÉ 19.3.4.8. Value Set ΓòÉΓòÉΓòÉ
  13941.  
  13942. The value set control is used in a similar way to a set of radio buttons, to 
  13943. indicate a group of mutually exclusive options.  Many of the comments made for 
  13944. radio buttons apply equally to value sets. 
  13945.  
  13946. However, while the use of radio buttons is effectively limited to text items, a 
  13947. value set allows the use of text or graphical items, as well as color patches. 
  13948. Thus a value set provides additional flexibility where a selection must be made 
  13949. from a set of mutually exclusive options, providing a mechanism for the display 
  13950. of those options to the user, and allowing the user to directly select the 
  13951. required choice. 
  13952.  
  13953.  
  13954. ΓòÉΓòÉΓòÉ 19.3.5. Message Boxes ΓòÉΓòÉΓòÉ
  13955.  
  13956. By convention, message boxes are used to inform the user of an event, and to 
  13957. carry out a dialog with the user in the following circumstances: 
  13958.  
  13959.    o  Where the information to be conveyed to the user is simple and limited to 
  13960.       no more than a few lines of text 
  13961.  
  13962.    o  Where the input to be gained from the user is limited to a single 
  13963.       decision from a limited list of mutually exclusive options. 
  13964.  
  13965.  The type of decision available to the user from a message box is also limited 
  13966.  to simple choices such as "Yes/No", "OK/Cancel", or "Yes/No/Help".  Since the 
  13967.  buttons displayed in the message box are  push buttons, selecting any button 
  13968.  will result in the removal of the  message box from the screen and immediate 
  13969.  action on the part of the  application.  An exception to this rule is the 
  13970.  "Help" button, which should result in the message box being left on the 
  13971.  screen, and the simultaneous display of a window containing help information. 
  13972.  This help window should be a child of the message box, so that it is dismissed 
  13973.  when the message box is closed, and the input focus should return to the 
  13974.  message box when the help window is dismissed. 
  13975.  
  13976.  A message box is created and processed using the WinMessageBox() function as 
  13977.  follows: 
  13978.  
  13979.   rc = WinMessageBox(hDesktop,                 /* Desktop is parent     */
  13980.                      hwnd,                     /* Curr. window is owner */
  13981.                      szMessageText,            /* Message text          */
  13982.                      "Warning",                /* Title of message box  */
  13983.                      0,                        /* No message box ident. */
  13984.                      MB_YESNO |                /* Yes/No choices        */
  13985.                      MB_DEFBUTTON1 |           /* Yes is default choice */
  13986.                      MB_CUAWARNING);           /* Warning style         */
  13987.  
  13988.  Message boxes may be of three types: 
  13989.  
  13990.    o  Notification message boxes inform the user of a system event that 
  13991.       requires his/her attention, but does not signify an error or potential 
  13992.       error condition.  Such message boxes are created with the message style 
  13993.       MB_CUANOTIFICATION. 
  13994.  
  13995.    o  Warning message boxes inform the user of a potential error condition that 
  13996.       may affect the integrity of the application or its data; for example, the 
  13997.       user may try to exit the application without  saving the latest set of 
  13998.       changes to a data object.  Such message boxes  are created with the 
  13999.       message style MB_CUAWARNING. 
  14000.  
  14001.    o  Critical message boxes inform the user of an error condition that 
  14002.       requires his/her immediate attention; for example, a diskette may be 
  14003.       unreadable.  Such message boxes are created with the message style 
  14004.       MB_CUACRITICAL. 
  14005.  
  14006.  These message box styles may be combined with other style identifiers that 
  14007.  determine the buttons to be displayed in the message box, the default action 
  14008.  and the modality of the message box (that is, system- or application-modal). 
  14009.  These identifiers are described, along with the WinMessageBox() function, in 
  14010.  the IBM OS/2 Version 2.0 Presentation Manager Reference. 
  14011.  
  14012.  A message box should always be created with a title; while Presentation 
  14013.  Manager  provides a default message title if a null title string is specified 
  14014.  in  the WinMessageBox() function, the use of this feature is not  recommended. 
  14015.  A message box title should identify the object or action  from which the 
  14016.  message originated; for example, a message originating  from a "Parts List" 
  14017.  object would have the title "Parts  List", whereas a message occurring as a 
  14018.  result of an incorrectly completed dialog during an "Open File" action would 
  14019.  have a title of "Open File". 
  14020.  
  14021.  A message box is created as an optimized window, and by default is neither 
  14022.  moveable nor sizable.  However, the situation may arise where the message is 
  14023.  related to some information displayed in a window, and the decision to be made 
  14024.  by the user is dependent upon the nature and context of that information.  The 
  14025.  user must therefore be able to view the information in order to make the 
  14026.  decision required by the message box, and the information may be hidden by the 
  14027.  message box itself.  To avoid this situation, a message box may be specified 
  14028.  with the style identifier MB_MOVEABLE, which allows the message box to be 
  14029.  moved (although not sized) by clicking the mouse on its title in a similar 
  14030.  fashion to that used for a standard window. 
  14031.  
  14032.  
  14033. ΓòÉΓòÉΓòÉ 19.4. Maintaining User Responsiveness ΓòÉΓòÉΓòÉ
  14034.  
  14035. The particular implementation of the message handling concept under 
  14036. Presentation Manager means that it is possible for a user to be "locked out" of 
  14037. the system if a window procedure does not return from processing a message 
  14038. within a reasonable period of time, since Presentation Manager only dispatches 
  14039. messages from the system queue to other applications when the currently active 
  14040. application attempts to retrieve  a message from its queue. 
  14041.  
  14042. The "reasonable" period of time is defined under Presentation Manager 
  14043. guidelines to be 0.1 seconds; a window procedure should complete the processing 
  14044. of a message within this period and return control to the application's main 
  14045. routine in order that the main routine may issue its next WinGetMsg() call. 
  14046. While this time period is adequate for processing of most messages, it may be 
  14047. insufficient for some messages; for examples, those that involve lengthy 
  14048. operations such as access to a remote system. 
  14049.  
  14050. In order to avoid the situation where an application or the entire Presentation 
  14051. Manager environment is unresponsive to the end user, OS/2 allows applications 
  14052. to create secondary threads of execution to handle lengthy  processing, thus 
  14053. enabling the application's primary thread to continue  responding to user 
  14054. interaction.  Presentation Manager  also provides a number of methods by which 
  14055. synchronization between threads may be achieved in order to ensure the 
  14056. integrity of the user's intention and of data resources manipulated by the 
  14057. application.  The use of secondary threads, and techniques for synchronizing 
  14058. execution between threads and processes, are discussed in Multitasking 
  14059. Considerations. 
  14060.  
  14061.  
  14062. ΓòÉΓòÉΓòÉ 19.5. Summary ΓòÉΓòÉΓòÉ
  14063.  
  14064. It can be seen that there are emergent programming conventions governing the 
  14065. use of Presentation Manager and operating system constructs to implement 
  14066. CUA-conforming, object-oriented applications under the Presentation Manager 
  14067. application architecture.  These principles facilitate the achievement of the 
  14068. many benefits attributable to the use of an object-oriented design approach, 
  14069. while remaining within the framework of Systems Application Architecture. 
  14070.  
  14071. Guidelines have been established, in accordance with emerging conventions, with 
  14072. regard to the use of standard and control windows, dialog boxes and message 
  14073. boxes, and the nature of their interaction with the user.  Each type of window 
  14074. has its own particular role in the interaction between the application and the 
  14075. end user; adherence to these conventions will provide a greater level of 
  14076. consistency between applications, within the parameters of the CUA 
  14077. specifications. 
  14078.  
  14079. The CUA guidelines specify that an application should have a response time of 
  14080. no more than 0.1 seconds, after which time the application should be ready to 
  14081. process the next user interaction.  However, the situation may arise where a 
  14082. unit of processing takes longer than the allowed time period. A number of ways 
  14083. exist by which the application may overcome this problem, typically involving 
  14084. the use of asynchronous threads, either with or without object windows. 
  14085.  
  14086. The embodiment of these principles into Presentation Manager applications at 
  14087. the design stage results in closer conformance to Systems Application 
  14088. Architecture guidelines.  The enterprise may thereby achieve the benefits of a 
  14089. consistent and intuitive approach to the human-machine interface between users 
  14090. and applications. 
  14091.  
  14092.  
  14093. ΓòÉΓòÉΓòÉ 20. Application Migration ΓòÉΓòÉΓòÉ
  14094.  
  14095. OS/2 Version 2.0 provides application compatibility at the executable code 
  14096. level for applications written to run under previous versions of OS/2.  Hence 
  14097. no modification is necessary to enable such applications to run under Version 
  14098. 2.0. However, in order to take full advantage of the enhanced capabilities of 
  14099. OS/2 Version 2.0, such as the 32-bit flat memory model and the additional 
  14100. features implemented by Presentation Manager, applications will require 
  14101. modification of their source code. 
  14102.  
  14103. Application developers who wish to migrate their code to the 32-bit programming 
  14104. environment under OS/2 Version 2.0 should experience little difficulty. Changes 
  14105. between the OS/2 Version 2.0 programming environment and that provided under 
  14106. previous versions of OS/2 fall into the following basic categories: 
  14107.  
  14108.    o  Data types 
  14109.  
  14110.    o  Function name changes 
  14111.  
  14112.    o  Function enhancements 
  14113.  
  14114.    o  Memory management 
  14115.  
  14116.    o  New Presentation Manager functions. 
  14117.  
  14118.  The remainder of this chapter will describe each of these categories in 
  14119.  detail, and suggest methods by which the required changes may be made. 
  14120.  
  14121.  Note that it is not mandatory for an application to migrate all its modules 
  14122.  and resources to the 32-bit programming environment.  OS/2 Version 2.0 allows 
  14123.  mixed model programming, where 32-bit applications may make use of existing 
  14124.  16-bit modules and resources.  The subject of mixed model programming is 
  14125.  discussed in Mixing 16-Bit and 32-Bit Application Modules. 
  14126.  
  14127.  
  14128. ΓòÉΓòÉΓòÉ 20.1. Data Types ΓòÉΓòÉΓòÉ
  14129.  
  14130. A number of the function type declarations and data type definitions used by 
  14131. Presentation Manager map into different "standard" C language type definitions 
  14132. under OS/2 Version 2.0.  This is due to the differences between the 16-bit 
  14133. architecture of previous versions and the 32-bit architecture of Version 2.0. 
  14134.  
  14135. For example, the Presentation Manager data type EXPENTRY, used to declare 
  14136. exportable entry points, is defined under OS/2 Version 1┬╖3 in the following 
  14137. way: 
  14138.  
  14139. #define EXPENTRY     pascal far
  14140.  
  14141. However, the pascal linkage convention is not used in the 32-bit OS/2 Version 
  14142. 2.0  programming environment, since all function calls use the standard C 
  14143. calling convention.  The only exception is when creating applications that 
  14144. access 16-bit functions; see Mixing 16-Bit and 32-Bit Application Modules. 
  14145.  
  14146. In addition, far memory references are not used, since the 32-bit flat memory 
  14147. model allows addressability to all locations in the process address space.  In 
  14148. the 32-bit programming environment therefore, the EXPENTRY type is defined as 
  14149. blanks; 32-bit applications are not required to use the EXPENTRY keyword. 
  14150.  
  14151. The OS/2 header file os2.h provided with the IBM Developer's Toolkit for OS/2 
  14152. 2.0 provides transparent remapping of the Presentation Manager type definitions 
  14153. to their new C language equivalents, and thus no modification is required to 
  14154. existing functions and data definitions that use the Presentation Manager 
  14155. types.  However, applications that have used standard C language type 
  14156. definitions in place of the Presentation Manager types will require 
  14157. modification.  For this reason, it is recommended that all Presentation Manager 
  14158. applications should use the Presentation Manager function and data type 
  14159. definitions. 
  14160.  
  14161.  
  14162. ΓòÉΓòÉΓòÉ 20.2. Function Name Changes ΓòÉΓòÉΓòÉ
  14163.  
  14164. Under OS/2 Version 2.0, certain function names for operating system kernel 
  14165. functions and Presentation Manager functions have been changed to provide 
  14166. improved consistency.  These changes obey the following rules: 
  14167.  
  14168.    o  The use of the terms Create, Get, Set and Query in function names is in 
  14169.       accordance with SAA conventions, as follows: 
  14170.  
  14171.         -  Create implies that a new resource is created as the result of a 
  14172.            function call. 
  14173.  
  14174.         -  Get implies that a resource is made available to the application as 
  14175.            the result of a function call. 
  14176.  
  14177.         -  Set implies that a system value is changed as a result of a function 
  14178.            call. 
  14179.  
  14180.         -  Query implies that a system value or handle to an existing function 
  14181.            is returned as the result of a function call. 
  14182.  
  14183.    o  Verbs are placed before nouns in function calls. 
  14184.  
  14185.    o  Similar actions have similar semantics, although they may operate on 
  14186.       different types of resources. 
  14187.  
  14188.  These changes have been made in order to provide improved consistency in 
  14189.  function names, simplifying the task of learning the various function names. 
  14190.  
  14191.  Applications that use operating system functions should be checked and 
  14192.  function names altered where necessary.  A list of corresponding function 
  14193.  names in OS/2 Version 1.3 and OS/2 Version 2.0 is given in OS/2 Version 2.0 - 
  14194.  Volume 1:  Control Program. 
  14195.  
  14196.  
  14197. ΓòÉΓòÉΓòÉ 20.3. 32-Bit Interface Constraints ΓòÉΓòÉΓòÉ
  14198.  
  14199. The following subsystems, present in OS/2 Version 1┬╖3, have no 32-bit 
  14200. equivalents, since they are not portable and are device-dependent. 
  14201.  
  14202.  VIO         Video subsystem; these function calls should be replaced with 
  14203.              Presentation Manager GPI calls or AVIO (advanced video) calls. 
  14204.  KBD         Keyboard subsystem; these function calls should be replaced by 
  14205.              processing WM_CHAR messages from a Presentation Manager 
  14206.              application. 
  14207.  MOU         Mouse subsystem; these function calls should be replaced by 
  14208.              processing WM_MOUSEMOVE and WM_BUTTON messages. 
  14209.  MON         Device monitor subsystem; these function calls should be replaced 
  14210.              by using appropriate message queue hooks in a Presentation Manager 
  14211.              application. 
  14212.  Note that these subsystems are supported under OS/2 Version 2.0 as 16-bit 
  14213.  service layers, for access by existing applications.  However, OS/2 Version 
  14214.  2.0 does not provide thunk layers to enable 32-bit applications to access 
  14215.  these service layers.  32-bit applications that use these subsystems must 
  14216.  employ mixed model programming techniques to access the 16-bit services; see 
  14217.  Mixing 16-Bit and 32-Bit Application Modules for further discussion. 
  14218.  
  14219.  Only two forms of input/output are supported in the 32-bit environment; the 
  14220.  stdin/stdout C interface (producing command line-based applications that can 
  14221.  be run in a text window) and Presentation Manager applications.  Programs 
  14222.  wishing to perform graphics, handle keyboard or mouse input, or intercept and 
  14223.  modify device information should do so using Presentation Manager functions. 
  14224.  
  14225.  Certain other functions have also been removed from the 32-bit programming 
  14226.  interface.  These are primarily concerned with the management of memory in the 
  14227.  segmented memory model.  Therefore functions such as DosSizeSeg(), 
  14228.  DosLockSeg() and DosUnlockSeg(), DosR2StackRealloc() etc are not implemented 
  14229.  in the 32-bit programming interface, although the 16-bit entry points are 
  14230.  still supported for compatibility purposes. 
  14231.  
  14232.  
  14233. ΓòÉΓòÉΓòÉ 20.4. Function Enhancements ΓòÉΓòÉΓòÉ
  14234.  
  14235. A number of enhancements have been made to existing operating system functions 
  14236. in OS/2 Version 2.0.  These include the semaphore functions for synchronization 
  14237. between threads and processes, and the DosCreateThread() function for 
  14238. initiating secondary threads. 
  14239.  
  14240.  
  14241. ΓòÉΓòÉΓòÉ 20.4.1. Semaphore Functions ΓòÉΓòÉΓòÉ
  14242.  
  14243. The enhanced semaphore functions available under OS/2 Version 2.0 were 
  14244. described in Operating System/2.  Previous versions of OS/2 provided only basic 
  14245. semaphore facilities with limited capability to handle multiple events.  Where 
  14246. these semaphores were used in applications under previous versions of OS/2, 
  14247. they may be updated to the new OS/2 Version 2.0 semaphore facilities using the 
  14248. following guidelines: 
  14249.  
  14250.    o  Where a semaphore is used to serialize the access to a particular data 
  14251.       object or system resource from multiple threads, a mutex semaphore should 
  14252.       be used. 
  14253.  
  14254.    o  Where a semaphore is used to signal an event occurring in one thread to 
  14255.       other threads having an interest in this event, an event semaphore should 
  14256.       be used. 
  14257.  
  14258.    o  Where an application waits upon the clearing of one semaphore from a 
  14259.       range of semaphores using the DosMuxWaitSem() function, this function may 
  14260.       be replaced by the use of a muxwait semaphore. 
  14261.  
  14262.       The muxwait semaphore has additional flexibility over the use of the 
  14263.       DosMuxWaitSem() function with normal semaphores under previous versions 
  14264.       of OS/2, since with a muxwait semaphore, a thread may wait for any one of 
  14265.       a list of mutex semaphores or event semaphores to be cleared (as with 
  14266.       previous versions), or may wait for all of the semaphores to be cleared. 
  14267.       This latter capability is not available under OS/2 Version 1┬╖3. 
  14268.  
  14269.  The enhanced semaphore functions available under OS/2 Version 2.0 are 
  14270.  described in the IBM OS/2 Version 2.0 Control Program Reference. 
  14271.  
  14272.  
  14273. ΓòÉΓòÉΓòÉ 20.4.2. Thread Management ΓòÉΓòÉΓòÉ
  14274.  
  14275. The DosCreateThread() function has been enhanced in OS/2 Version 2.0 to 
  14276. facilitate the creation of secondary threads.  Under previous versions of OS/2, 
  14277. an application was required to explicitly allocate a memory segment for the 
  14278. stack to be used by a secondary thread.  Under OS/2 Version 2.0 however, stack 
  14279. allocation is performed as a built-in part of the DosCreateThread() function, 
  14280. and deallocation is performed automatically by the operating system upon 
  14281. termination of a thread. 
  14282.  
  14283. Applications that use the DosCreateThread() function should be modified to use 
  14284. the new form of the function call, as shown in DosCreateThread() Function. 
  14285.  
  14286. APIRET   rc;               /* Return code          */
  14287. PTID    ThreadID;            /* Thread identifier       */
  14288. MYSTRUCT  *ParmBlock;           /* Initialization data      */
  14289.  
  14290. rc = DosCreateThread(ThreadID,      /* Create thread         */
  14291.            Thread,       /* Entry point for thread    */
  14292.            ParmBlock,      /* Parameters for thread     */
  14293.            0L,         /* Start immediately       */
  14294.            8192);        /* Stack size for thread     */
  14295.  
  14296. DosCreateThread() Function 
  14297.  
  14298. This example shows the enhanced form of this function as
  14299. implemented under OS/2 Version 2.0.
  14300. Note that the DosCreateThread() function under OS/2 Version 2.0 also allows 
  14301. parameters to be passed to the thread as part of the DosCreateThread() 
  14302. function.  The third parameter to the function is a 32-bit pointer, which may 
  14303. be used to pass the address of an application-defined data structure containing 
  14304. the required parameter data. 
  14305.  
  14306. The DosCreateThread() function and its implementation under OS/2 Version 2.0 
  14307. are described in greater detail in IBM OS/2 Version 2.0 Control Program 
  14308. Reference. 
  14309.  
  14310. OS/2 Version 2.0 also allows an application to forcibly terminate a thread 
  14311. using the DosKillThread() function. This function allows an application's 
  14312. primary thread to terminate any secondary threads prior to its own shutdown, in 
  14313. a more elegant manner than was possible under previous versions of OS/2. 
  14314.  
  14315.  
  14316. ΓòÉΓòÉΓòÉ 20.5. Memory Management ΓòÉΓòÉΓòÉ
  14317.  
  14318. The 64KB segment size limitation imposed by the Intel 80286 processor 
  14319. architecture has been eliminated in OS/2 Version 2.0, avoiding the need for 
  14320. applications to allocate large data structures in individual units of 64KB. The 
  14321. flat memory model implemented under OS/2 Version 2.0 allows applications to 
  14322. request the allocation of individual memory objects up to 512MB in size, using 
  14323. the DosAllocMem() function, an example of which is shown in DosAllocMem() 
  14324. Function. 
  14325.  
  14326. APIRET   rc;              /* Return code           */
  14327. PVOID   pObject;           /* Pointer to memory object    */
  14328.  
  14329. rc = DosAllocMem(&pObject,       /* Allocate memory object     */
  14330.          73727,         /* Size of memory object      */
  14331.          PAG_COMMIT |      /* Commit memory immediately    */
  14332.          PAG_READ  |      /* Allow read access        */
  14333.          PAG_WRITE);      /* Allow write access       */
  14334.  
  14335. DosAllocMem() Function 
  14336.  
  14337. This function replaces the DosAllocSeg() function implemented
  14338. in previous versions of OS/2.
  14339. The above example shows the allocation of 73KB of memory as a single memory 
  14340. object, with read and write access permitted.  The PAG_COMMIT flag is set in 
  14341. the DosAllocMem() function call, in order to commit the storage immediately. 
  14342.  
  14343.  
  14344. ΓòÉΓòÉΓòÉ 20.6. New Presentation Manager Functions ΓòÉΓòÉΓòÉ
  14345.  
  14346. A number of new functions have been added to Presentation Manager under OS/2 
  14347. Version 2.0.  While these functions do not add new capabilities to the 
  14348. Presentation Manager interface, they simplify application development by 
  14349. combining operations that previously required multiple steps into a single 
  14350. Presentation Manager function call. 
  14351.  
  14352. ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
  14353. Γöé      New Presentation Manager Functions in OS/2 Version 2.0        Γöé
  14354. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  14355. Γöé FUNCTION           Γöé DESCRIPTION               Γöé
  14356. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  14357. Γöé WinInsertLboxItem()      Γöé Inserts a listbox item          Γöé
  14358. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  14359. Γöé WinDeleteLboxItem()      Γöé Deletes a listbox item          Γöé
  14360. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  14361. Γöé WinSetLboxItemText()     Γöé Sets the text of a specified listbox   Γöé
  14362. Γöé                Γöé item                   Γöé
  14363. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  14364. Γöé WinQueryLboxCount()      Γöé Returns the number of items in a listboxΓöé
  14365. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  14366. Γöé WinQueryLboxSelectedItem()  Γöé Returns the offset (item number) of the Γöé
  14367. Γöé                Γöé selected item in a listbox        Γöé
  14368. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  14369. Γöé WinQueryLboxItemText()    Γöé Returns the text of a specified listbox Γöé
  14370. Γöé                Γöé item                   Γöé
  14371. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  14372. Γöé WinQueryLboxItemTextLength() Γöé Returns the length of the text of a   Γöé
  14373. Γöé                Γöé specified listbox item          Γöé
  14374. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  14375. Γöé WinPopupMenu()        Γöé Creates and presents a context (popup)  Γöé
  14376. Γöé                Γöé menu                   Γöé
  14377. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  14378. Γöé WinCheckMenuItem()      Γöé Sets a check mark against a pulldown   Γöé
  14379. Γöé                Γöé menu item                Γöé
  14380. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  14381. Γöé WinIsMenuItemChecked()    Γöé Determines whether a menu item is    Γöé
  14382. Γöé                Γöé currently checked            Γöé
  14383. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  14384. Γöé WinEnableMenuItem()      Γöé Enables or disables a menu bar or    Γöé
  14385. Γöé                Γöé pulldown menu item            Γöé
  14386. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  14387. Γöé WinIsMenuItemEnabled()    Γöé Determines whether a menu bar or     Γöé
  14388. Γöé                Γöé pulldown menu item is currently enabled Γöé
  14389. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  14390. Γöé WinSetMenuItemText()     Γöé Sets the text of a specified menu bar  Γöé
  14391. Γöé                Γöé or pulldown menu item          Γöé
  14392. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  14393. Γöé WinFileDlg()         Γöé Displays the standard SAA-conforming   Γöé
  14394. Γöé                Γöé file dialog box             Γöé
  14395. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  14396. Γöé WinDefFileDlgProc()      Γöé Default processing function for     Γöé
  14397. Γöé                Γöé subclassing file dialog box       Γöé
  14398. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  14399. Γöé WinFontDlg()         Γöé Displays the standard SAA-conforming   Γöé
  14400. Γöé                Γöé font dialog box             Γöé
  14401. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  14402. Γöé WinDefFontDlgProc()      Γöé Default processing function for     Γöé
  14403. Γöé                Γöé subclassing font dialog box       Γöé
  14404. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  14405. Γöé WinQueryButtonCheckstate()  Γöé Determines the current check state of a Γöé
  14406. Γöé                Γöé check box or 3-state button.       Γöé
  14407. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  14408. Γöé WinSetDesktopBkgnd()     Γöé Sets the current desktop background   Γöé
  14409. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  14410. Γöé WinQueryDesktopBackground()  Γöé Queries information about the current  Γöé
  14411. Γöé                Γöé desktop background            Γöé
  14412. ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
  14413. A number of other functions are also added in OS/2 Version 2.0, and are used to 
  14414. deal with the passing of messages between 16-bit and 32-bit modules in 
  14415. Presentation Manager applications.  These functions are discussed in Mixing 
  14416. 16-Bit and 32-Bit Application Modules. 
  14417.  
  14418. These functions are described in more detail in the IBM OS/2 Version 2.0 
  14419. Presentation Manager Reference. 
  14420.  
  14421.  
  14422. ΓòÉΓòÉΓòÉ 20.7. Summary ΓòÉΓòÉΓòÉ
  14423.  
  14424. Existing 16-bit applications written for OS/2 Version 1┬╖3 may execute under 
  14425. OS/2 Version 2.0 without modification.  However, significant enhancements to 
  14426. performance and functionality are possible by taking advantage of additional 
  14427. features provided by the 32-bit OS/2 Version 2.0 environment.  In order to take 
  14428. full advantage of the 32-bit environment, applications must be modified to use 
  14429. the new features. 
  14430.  
  14431. In addition, a number of changes have been made in the 32-bit programming 
  14432. environment to provide improved consistency and ease of use, simplifying the 
  14433. task of learning the operating system interfaces and reducing the amount of 
  14434. coding required by application developers.  The incorporation of these changes 
  14435. into applications will also require source code modification. 
  14436.  
  14437. It is not necessary for applications to migrate all their modules and resources 
  14438. to the 32-bit environment, since OS/2 Version 2.0 allows mixing of 16-bit and 
  14439. 32-bit code and resources within the same application.  However, 32-bit modules 
  14440. that make calls to 16-bit modules or resources must be aware of the differences 
  14441. in addressing schemes between the the 16-bit and 32-bit environments. 
  14442.  
  14443.  
  14444. ΓòÉΓòÉΓòÉ 21. Mixing 16-Bit and 32-Bit Application Modules ΓòÉΓòÉΓòÉ
  14445.  
  14446. Under OS/2 Version 2.0, 32-bit applications may make use of existing 16-bit 
  14447. application code and resources; this practice is known as mixed model 
  14448. programming. For example, a 32-bit Presentation Manager application may access 
  14449. an object window procedure contained in a 16-bit DLL created for OS/2 Version 
  14450. 1┬╖3.  This capability allows 32-bit applications to make use of existing 
  14451. application objects, avoiding the necessity to rewrite existing object 
  14452. libraries to accommodate the 32-bit programming environment. 
  14453.  
  14454. Applications that make use of 16-bit modules and resources must be aware of the 
  14455. particular characteristics of the 16-bit environment, which affect the way that 
  14456. application modules interface with one another and pass parameters or messages. 
  14457. Such characteristics include: 
  14458.  
  14459.    o  Pointers in the 16-bit environment are made up of a segment selector and 
  14460.       an offset; this addressing scheme is therefore known as 16. Pointers in 
  14461.       the 32-bit environment are composed of a linear offset only; hence the 
  14462.       addressing scheme is known as 0.  Note that this difference in 
  14463.       representation applies not only to memory pointers, but also to window 
  14464.       and resource handles under Presentation Manager. 
  14465.  
  14466.    o  Memory objects passed as parameters between 16-bit and 32-bit routines 
  14467.       must not be greater than 64KB in size, in order to avoid problems with 
  14468.       the 16-bit segmented memory model. 
  14469.  
  14470.    o  Memory objects passed as parameters from 32-bit applications to 16-bit 
  14471.       routines must not lie across a segment boundary. 
  14472.  
  14473.  Obviously, conversion of pointers and possible realignment of memory objects 
  14474.  is required when passing control between 16-bit and 32-bit modules. This 
  14475.  conversion between addressing schemes is known under OS/2 Version 2.0 as 
  14476.  thunking. Thunking is performed using a simple algorithm known as the 
  14477.  Compatibility Region Mapping Algorithm (CRMA).  This algorithm, along with 
  14478.  sample code, is described in OS/2 Version 2.0 - Volume 1:  Control Program. 
  14479.  
  14480.  
  14481. ΓòÉΓòÉΓòÉ 21.1. Function Calls to 16-Bit Modules ΓòÉΓòÉΓòÉ
  14482.  
  14483. Thunking considerations affect the way in which a 16-bit function must be 
  14484. declared within the 32-bit module, and the way in which parameters to be passed 
  14485. to the 16-bit function are defined.  Such functions and parameters must be 
  14486. declared using the #pragma linkage directive and the far16 keyword, as shown in 
  14487. Declaring a 16-Bit Function in 32-Bit Code. 
  14488.  
  14489. #pragma stack16(8192)
  14490.  
  14491. USHORT MyFunction(USHORT FirstNum, HWND _Seg16 hWnd);
  14492.  
  14493. #pragma linkage (MyFunction, far16 pascal)
  14494.  
  14495. Declaring a 16-Bit Function in 32-Bit Code 
  14496.  
  14497. Notetheuseofthe# pragmastack16directivetosetthestacksizeforall16 - 
  14498. bitfunctioncallsmadefromthe32 - bitmodule .
  14499.  
  14500. Declaring a 16-bit function in this manner will cause the operating system to 
  14501. automatically perform thunking for all "value" parameters (that is, those other 
  14502. than pointers).  Pointers passed as parameters must be explicitly defined using 
  14503. the _Seg16 keyword, as shown in Declaring a 16-Bit Function in 32-Bit Code. 
  14504.  
  14505. The #pragma linkage and #pragma stack16 directives are discussed in more detail 
  14506. in the IBM C Set/2 User's Guide. 
  14507.  
  14508.  
  14509. ΓòÉΓòÉΓòÉ 21.2. Using 16-Bit Window Procedures ΓòÉΓòÉΓòÉ
  14510.  
  14511. A 32-bit application may access window procedures that reside in 16-bit 
  14512. modules, either statically linked or as DLLs.  However, the differences between 
  14513. addressing schemes require some consideration on the part of the developer, 
  14514. since both the window handles and any pointers passed as message parameters 
  14515. will differ in their representation. 
  14516.  
  14517.  
  14518. ΓòÉΓòÉΓòÉ 21.2.1. Creating a Window ΓòÉΓòÉΓòÉ
  14519.  
  14520. When a 32-bit application module creates a window, and the window procedure for 
  14521. that window resides in a 16-bit module (either statically linked or in a DLL), 
  14522. the calling routine must explicitly declare the 16-bit nature of the window 
  14523. procedure's entry point when registering the window class.  This may become 
  14524. rather complex, since it involves invoking a 32-bit entry point from a 32-bit 
  14525. module, but passing a 16-bit entry point as a parameter. 
  14526.  
  14527. A simpler solution is to build a registration routine within the 16-bit module, 
  14528. which registers the window class and creates the window.  The 32-bit module 
  14529. then need only invoke this routine, and allow for the resulting 16-bit window 
  14530. handle.  This technique has the added advantage that Presentation Manager 
  14531. records the fact that the window was registered from a 16-bit module, and will 
  14532. automatically perform thunking for system-defined message classes.  The 
  14533. technique is illustrated in Creating a 16-bit Window From Within a 32-bit 
  14534. Module. 
  14535.  
  14536. Since the 16-bit module would typically be a DLL, the registration routine is 
  14537. declared in the 16-bit module as an exportable entry point using the EXPENTRY 
  14538. keyword. 
  14539.  
  14540. The 32-bit module declares the registration routine MakeMyWindow() as a 16-bit 
  14541. function using the #pragma linkage directive with the far16 keyword. Since in 
  14542. 16-bit code, the EXPENTRY keyword forces use of the pascal calling convention, 
  14543. the directive also specifies this calling convention.  Note that if the 
  14544. registration routine and the window procedure were to reside in a DLL, this 
  14545. declaration would typically take place within a header file provided by the 
  14546. developer of the DLL. 
  14547.  
  14548. The 32-bit module invokes the registration routine that registers the window 
  14549. class and creates the window.  The registration routine then returns the window 
  14550. handle to the 32-bit module, which stores it in 16:16 format. Note that the 
  14551. registration routine in the 16-bit module is not aware that it is being called 
  14552. from a 32-bit module. 
  14553.  
  14554. 32-bit Module
  14555.  
  14556. #pragma stack16(8192)
  14557.  
  14558. HWND MakeMyWindow(void);          /* 16-bit function prototype  */
  14559. #pragma linkage (MakeMyWindow, far16 pascal)
  14560.  
  14561. HWND _Seg16 hWindow;            /* 16:16 window handle     */
  14562.  :
  14563.  :
  14564. hWindow = MakeMyWindow();          /* Call registration routine  */
  14565.  
  14566. 16-bit Module
  14567.  
  14568. HWND EXPENTRY MakeMyWindow(void)      /* Registration routine    */
  14569. {
  14570.    HWND hCurrWindow;           /* 16:16 window handle     */
  14571.  
  14572.    WinRegisterClass(...);         /* Register window class    */
  14573.    hCurrWindow = WinCreateWindow(...);  /* Create window        */
  14574.  
  14575.    return(hCurrWindow);          /* Return 16:16 window handle */
  14576. }
  14577.  
  14578. Creating a 16-bit Window From Within a 32-bit Module 
  14579.  
  14580. ThisapproachallowsthesameDLLtobeaccessedbyboth16 - bitand32 - 
  14581. bitapplicationsconcurrently 
  14582. . ThedeveloperoftheDLLsimplyprovidestwoseparateheaderfilescontainingdeclarationsoftheDLL 
  14583. ' sentrypoints ,intheappropriateformatforeachprogrammingenvironment .
  14584.  
  14585.  
  14586. ΓòÉΓòÉΓòÉ 21.2.2. Passing Messages to 16-Bit Windows ΓòÉΓòÉΓòÉ
  14587.  
  14588. Passing data between 16-bit and 32-bit window procedures via message parameters 
  14589. also requires consideration of the internal representations of the data types 
  14590. passed within the parameter.  For system-defined message classes, this is 
  14591. handled automatically by OS/2 Version 2.0, but for application-defined message 
  14592. classes the conversion between addressing schemes must be handled by the 
  14593. application, since the operating system has no way of determining the intended 
  14594. contents of each parameter. 
  14595.  
  14596. Simple "value" parameters (such as integers, characters, etc.) may be passed 
  14597. without the need for translation.  It is recommended that message parameters be 
  14598. constructed using the standard Presentation Manager  macros described in 
  14599. Creating Message Parameters. 
  14600.  
  14601. When a pointer or handle is passed in a message parameter to a 16-bit window 
  14602. procedure, the pointer or handle must be translated to the 16:16 addressing 
  14603. scheme by the application.  Since the 16-bit module is unlikely to have been 
  14604. written with code to achieve this conversion, it is the responsibility of the 
  14605. 32-bit module. 
  14606.  
  14607. Conversion may be achieved using the _Seg16 keyword to explicitly define a 
  14608. 16:16 pointer or handle, which is then placed in a message parameter using the 
  14609. MPFROMP macro.  This is illustrated in Passing a 16:16 Pointer as a Message 
  14610. Parameter. 
  14611.  
  14612. typedef struct mystruct {          /* Define data structure    */
  14613.             CHAR * _Seg16 Name;
  14614.             ULONG     ulA;
  14615.             ULONG     ulB;
  14616.             USHORT     usC;
  14617.             } MYSTRUCT;
  14618.  
  14619. pragma seg16(MYSTRUCT)           /* Define pragma directive   */
  14620.  
  14621. MYSTRUCT * _Seg16 MyStruct;         /* 16:16 pointer        */
  14622.  
  14623. APIRET  rc;                /* Return code         */
  14624.  
  14625. MPARAM  mp1;                /* Message parameter      */
  14626.  
  14627. rc = DosAllocMem(&MyStruct,         /* Allocate data structure   */
  14628.          4096,           /* Size of data structure   */
  14629.          PAG_READ  |        /* Allow read access      */
  14630.          PAG_WRITE |        /* Allow write access     */
  14631.          PAG_COMMIT);        /* Commit storage immediately */
  14632.  
  14633. <Initialize structure if required>
  14634.  
  14635. mp1 = MPFROMP(MyStruct);          /* Set message parameter    */
  14636.  
  14637. Passing a 16:16 Pointer as a Message Parameter 
  14638.  
  14639. This example shows the 32-bit code necessary to define and
  14640. initialize a 16:16 pointer to be passed to a 16-bit window procedure.
  14641. The resulting message parameter may then be passed to a window in a 16-bit 
  14642. module using the normal WinPostMsg() or WinSendMsg() functions, using a 16:16 
  14643. window handle obtained in the manner shown in Creating a 16-bit Window From 
  14644. Within a 32-bit Module.  Note that the data structure referenced by the pointer 
  14645. may not be greater than 64 KB in size, and must not cross a segment boundary. 
  14646. This is ensured in Passing a 16:16 Pointer as a Message Parameter by using the 
  14647. #pragma seg16 directive, since a structure defined using this pragma will 
  14648. automatically be aligned on a segment boundary by the C Set/2 compiler. 
  14649.  
  14650. Note also that defining a structure with the #pragma seg16 directive does not 
  14651. implicitly qualify pointers within the structure with the _Seg16 keyword.  Such 
  14652. pointers must be explicitly qualified, as shown in Creating a 16-bit Window 
  14653. From Within a 32-bit Module.  Further information on the #pragma seg16 
  14654. directive can be found in the IBM C Set/2 User's Guide. 
  14655.  
  14656. A 0:32 pointer may also be converted to a 16:16 pointer using the 
  14657. DosFlattoSel() function provided by OS/2 Version 2.0.  This function provides 
  14658. the correct remapping of pointer formats from the 32-bit flat memory model to 
  14659. the 16-bit segmented memory model. 
  14660.  
  14661.  
  14662. ΓòÉΓòÉΓòÉ 21.2.3. Passing Messages to 32-Bit Windows ΓòÉΓòÉΓòÉ
  14663.  
  14664. The technique described above handles messages passed to a window in a 16-bit 
  14665. module.  However, messages passed from that window to the 32-bit module may 
  14666. also require thunking.  In order to perform this thunking, the 32-bit 
  14667. application may define a thunk procedure and register this procedure to 
  14668. Presentation Manager, which then invokes the thunk procedure whenever a message 
  14669. is passed from within the window. 
  14670.  
  14671. This registration is achieved using the WinSetWindowThunkProc() function, which 
  14672. is illustrated in Mixed Model Programming - WinSetWindowThunkProc() Function. 
  14673.  
  14674. WinSetWindowThunkProc(hWindow,        /* Window handle       */
  14675.            (PFN)ThunkProc16to32); /* Thunk proc entry point  */
  14676.  
  14677. Mixed Model Programming - WinSetWindowThunkProc() Function 
  14678.  
  14679. TheWinSetWindowThunkProc ( )functioncallismadefromthe32 - bitmodule 
  14680. .Sincethewindowclassforthewindowhasbeenregisteredinthe16 - bitmodule 
  14681. ,PresentationManagerrecognizesthatthethunkprocedureistohandle16 - bitto32 - 
  14682. bitconversion .
  14683.  
  14684. A thunk procedure may be deregistered, by issuing a WinSetWindowThunkProc() 
  14685. function call with the thunk procedure entry point address set to NULL. 
  14686.  
  14687. Whenever Presentation Manager invokes a thunk procedure for a message, it 
  14688. passes the normal four parameters accepted by a window procedure, along with 
  14689. the entry point address of the window procedure to which the message was to be 
  14690. passed.  This may be the window procedure defined for the destination window 
  14691. when its class was registered, or a subclass window procedure defined by the 
  14692. application.  Thus thunking may take place, irrespective of whether a window 
  14693. has been subclassed. 
  14694.  
  14695. A sample thunk procedure is shown in Mixed Model Programming - Thunk Procedure. 
  14696.  
  14697. MRESULT EXPENTRY ThunkProc16to32(HWND hwnd,    /* Window handle    */
  14698.                  ULONG ulMsg,   /* Message identifier  */
  14699.                  MPARAM mp1,    /* Message parameters  */
  14700.                  MPARAM mp2,
  14701.                  PFNWP wpWindow); /* Window procedure   */
  14702. {
  14703.     switch (ulMsg)
  14704.         {
  14705.         case WMP_MSG1:
  14706.           mp1=DosSeltoFlat(mp1);     /* Thunk parameters   */
  14707.           mp2=DosSeltoFlat(mp2);
  14708.           break;
  14709.         case WMP_MSG2:
  14710.           mp1=DosSeltoFlat(mp1);     /* Thunk 1st parameter */
  14711.           break;
  14712.         }
  14713.     return((*wpWindow)(hwnd,          /* Call window proc   */
  14714.               ulMsg,
  14715.               mp1,
  14716.               mp2));
  14717. }
  14718.  
  14719. Mixed Model Programming - Thunk Procedure 
  14720.  
  14721. Thethunkprocedureisinvokedwheneveramessageispassedbythewindowinthe16 - 
  14722. bitmoduletoawindowinthe32 - bitmodule 
  14723. . Thethunkprocedureissimilarinstructuretoa" normal "windowprocedure 
  14724. ,butneedcontaincasesonlyforapplication - definedmessageclasses 
  14725. ,sincethunkingforsystem - definedmessageclassesisperformedbyPresentationManager .
  14726.  
  14727. Note that since the thunk procedure is invoked by Presentation Manager, it must 
  14728. use the system linkage convention, and is thus declared using the EXPENTRY 
  14729. keyword. 
  14730.  
  14731. In Mixed Model Programming - Thunk Procedure, the 16-bit window contains two 
  14732. application-defined message classes, WMP_MSG1 and WMP_MSG2.  The first of these 
  14733. contains pointers in both parameters, and thus both parameters are thunked by 
  14734. the thunk procedure.  The second message class contains a pointer in the first 
  14735. message paramater only; the second may contain an integer or some simple value 
  14736. parameter which does not require explicit thunking.  Thunking is performed 
  14737. using the DosSeltoFlat() function provided by OS/2 Version 2.0. 
  14738.  
  14739. After performing the necessary thunking, the thunk procedure directly calls the 
  14740. window procedure entry point supplied by Presentation Manager when the thunk 
  14741. procedure is invoked.  Note that this is one of the few instances where direct 
  14742. invocation of a window procedure should be used.  The correct sequence of 
  14743. message processing is preserved in this case because the thunk procedure itself 
  14744. is invoked either synchronously or asynchronously by Presentation Manager, 
  14745. depending upon whether the message was sent or posted by the 16-bit window. 
  14746.  
  14747. An alternative to the use of the DosSeltoFlat() function is the explicit use of 
  14748. the Compability Region Mapping Algorithm discussed in OS/2 Version 2.0 - Volume 
  14749. 1:  Control Program.  This algorithm is implemented in the subroutine 
  14750. CRMA16to32 shown in 16:16 to 0:32 Address Conversion. 
  14751.  
  14752. PVOID CRMA16to32(PVOID pPointer)          /* Perform conversion  */
  14753. {
  14754.    USHORT usTemp;                /* Temporary variable  */
  14755.  
  14756.    if (pPointer)                /* If not NULL     */
  14757.      {
  14758.      usTemp=HIUSHORT(pPointer) >> 3;      /* Shift right 3 bits  */
  14759.      return(MAKEP(uTemp,            /* Swap hi & lo words  */
  14760.            LOUSHORT(pPointer)));
  14761.      }
  14762.    else
  14763.      return(NULL);
  14764. }
  14765.  
  14766. 16:16 to 0:32 Address Conversion 
  14767.  
  14768. TheuseoftheDosSeltoFlat ( )functionshouldbethepreferredoption 
  14769. ,sincetheCRMAroutinesmayfailundercertaincircumstances 
  14770. . ExplicituseofCRMAshouldberestrictedtothosesituationswherespecialprocessingmustbeperformedontheparametersbeingpassed .
  14771.  
  14772.  
  14773. ΓòÉΓòÉΓòÉ 21.3. Summary ΓòÉΓòÉΓòÉ
  14774.  
  14775. OS/2 Version 2.0 allows applications and resources from both 16-bit and 32-bit 
  14776. environments to coexist and communicate.  A 32-bit application may make 
  14777. function calls to 16-bit code, and 16-bit and 32-bit window procedures may pass 
  14778. messages between one another. 
  14779.  
  14780. Conversion between the 16:16 and 0:32 addressing schemes is achieved using 
  14781. thunks, which implement an algorithm known as the Compatibility Region Mapping 
  14782. Algorithm.  The IBM C Set/2 compiler provides transparent thunking for most 
  14783. function calls and parameters, using the #pragma linkage directive in 
  14784. conjunction with the _Seg16 keyword. 
  14785.  
  14786. For threads that will make calls to 16-bit code, the stack must also be aligned 
  14787. on a 64KB segment boundary, to avoid possible problems with stack overflow in 
  14788. the 16-bit code.  Again, the IBM C Set/2 compiler facilitates this alignment 
  14789. through use of the #pragma stack16 directive, which causes the thread's stack 
  14790. to be automatically aligned on a 64KB boundary. 
  14791.  
  14792. Thunking becomes slightly more complex when communicating between 16-bit and 
  14793. 32-bit window procedures, since pointers passed in message parameters must be 
  14794. thunked.  While Presentation Manager provides transparent thunking for all 
  14795. system-defined message classes, application-defined messages must be thunked 
  14796. explicitly by the application. 
  14797.  
  14798. Presentation Manager provides some assistance to the application developer by 
  14799. allowing thunk procedures to be registered for a window.  Presentation Manager 
  14800. automatically invokes the thunk procedure whenever a message to passed to that 
  14801. window from a window of another memory model. 
  14802.  
  14803. The ability to mix 16-bit and 32-bit code in the same application provides 
  14804. considerable flexibility and protects investment in existing application 
  14805. functions and resources.  This in turn eases the task of migrating the 
  14806. organizational development environment from the 16-bit to the 32-bit 
  14807. environment, since the transition need not be accomplished in a single step. 
  14808.  
  14809.  
  14810. ΓòÉΓòÉΓòÉ 22. Compiling and Link Editing an Application ΓòÉΓòÉΓòÉ
  14811.  
  14812. A Presentation Manager application, written in a high-level language such as C, 
  14813. is compiled and link-edited in a similar fashion to a regular OS/2 or DOS 
  14814. application.  System Object Model object classes are created in a similar way. 
  14815. However, additional steps are required for the creation of a Workplace Shell 
  14816. object class, prior to compilation of the C source code. 
  14817.  
  14818. This chapter describes the process of creating an executable Presentation 
  14819. Manager application or system object model object class.  The chapter describes 
  14820. the process of precompilation for system object model object classes, and the 
  14821. compilation, link edit and resource compilation stages for both system object 
  14822. model object classes and Presentation Manager applications. 
  14823.  
  14824. The following diagram shows the overall process used to create a new class in 
  14825. the Workplace Shell: 
  14826.  
  14827. The starting point for a system object model class is the class definition file 
  14828. which, for classes written using the C language, has an extension of .CSC.  The 
  14829. class definition file is used as input to the SOM Precompiler, which will 
  14830. generate a number of files from the class definition file: 
  14831.  
  14832.  .H     A public header file for programs that use the class. 
  14833.  .PH    A private header file, which provides usage bindings to any private 
  14834.         methods implemented by the class. 
  14835.  .IH    An implementation header file, which provides macros, etc., to support 
  14836.         the implementation of the class. 
  14837.  .C     A template C file, to which code may be added to implement the class. 
  14838.  .SC    A language-neutral class definition. 
  14839.  .PSC   A private language-neutral core file, which contains private parts of 
  14840.         the interface for the class. 
  14841.  .DEF   An OS/2 DLL module definition file containing the relevant exports 
  14842.         needed to implement the class. 
  14843.  
  14844.  
  14845. ΓòÉΓòÉΓòÉ 22.1. Running the SOM Precompiler ΓòÉΓòÉΓòÉ
  14846.  
  14847. Once the class definition file has been created, the SOM Precompiler is used to 
  14848. generate the source files for the class.  The options for the SOM Precompiler 
  14849. are described in detail in the IBM SOM Programming Reference; however, a brief 
  14850. description of the options used to create the folder example is given below. 
  14851.  
  14852.  
  14853. ΓòÉΓòÉΓòÉ 22.1.1. The Makefile ΓòÉΓòÉΓòÉ
  14854.  
  14855. The instructions to be used are placed into a makefile.  The new make facility 
  14856. NMAKE, provided with the IBM Developer's Toolkit for OS/2 2.0 is extremely 
  14857. flexible and rich in function.  It is recommended that programmers read the 
  14858. NMAKE section of the IBM OS/2 Version 2.0 Programming Tools Reference if 
  14859. unfamiliar with makefiles. 
  14860.  
  14861. The SOM Precompiler environment variables are set as follows: 
  14862.  
  14863. !if [set SMINCLUDE=.;$(SCPATH);] || \
  14864.     [set SMTMP=$(SOMTEMP)] || \
  14865.     [set SMEMIT=ih;h;ph;psc;sc;c;def]
  14866. !endif
  14867.  
  14868. The use of the !if directive is somewhat confusing, as the statement has 
  14869. nothing to do with a conditional command.  In fact, the OS/2 SET command is 
  14870. being executed to initialize the environment variables.  The NMAKE utility 
  14871. executes any OS/2 command placed within square brackets in a !if directive. 
  14872.  
  14873. The SMEMIT environment variable tells the SOM Precompiler  which C source files 
  14874. are to be generated; the suffixes correspond to the file types described 
  14875. earlier in this chapter. 
  14876.  
  14877. The SMINCLUDE and SMTMP environment variables are set from two NMAKE macros, 
  14878. which are defined at the top of the makefile: 
  14879.  
  14880.    SCPATH  = D:\toolkt20\sc
  14881.    SOMTEMP = .\somtemp
  14882.  
  14883. The SMINCLUDE variable tells the SOM Precompiler where to find the class 
  14884. definition (.SC) include files. 
  14885.  
  14886. The SMTMP variable locates the SOM Precompiler temporary workspace directory. 
  14887.  
  14888. This brings us to the next part of the makefile that is responsible for 
  14889. ensuring the existence of the temporary directory. 
  14890.  
  14891. !if [cd $(SOMTEMP)]
  14892. !  if [md $(SOMTEMP)]
  14893. !    error Error creating $(SOMTEMP) directory
  14894. !  endif
  14895. !else
  14896. !  if [cd ..]
  14897. !    error Error could not cd .. from $(SOMTEMP) directory
  14898. !  endif
  14899. !endif
  14900.  
  14901. This code checks for the existence of the directory and if it cannot be found, 
  14902. attempts to create it. 
  14903.  
  14904.  
  14905. ΓòÉΓòÉΓòÉ 22.1.2. SOM Precompiler Invocation ΓòÉΓòÉΓòÉ
  14906.  
  14907. The SOM Precompiler is invoked as a consequence of the following NMAKE 
  14908. inference rule: 
  14909.  
  14910.    .csc.c:
  14911.         sc $<
  14912.  
  14913. This infers that to go from a .CSC file to a ".C" file the SOM Precompiler 
  14914. (sc.exe) will be invoked on the .CSC file ("$<"). 
  14915.  
  14916. Note that for the folder example, many default SOM Precompiler options are 
  14917. used. Readers may wish to investigate some of the other options that are 
  14918. available, by checking the IBM SOM Programming Reference. 
  14919.  
  14920.  
  14921. ΓòÉΓòÉΓòÉ 22.2. Compiling C Source Code ΓòÉΓòÉΓòÉ
  14922.  
  14923. The following files are required to generate a system object model object class 
  14924. or Presentation Manager application from "C" source code: 
  14925.  
  14926.  Source         An application may contain one or more source modules; multiple 
  14927.                 source modules are normally bound at link-edit time.  However, 
  14928.                 application routines may be compiled and placed in a DLL for 
  14929.                 binding at execution time. 
  14930.  H              An application may use a header file that contains data type 
  14931.                 definitions, constants and macro definitions for use by the 
  14932.                 application. 
  14933.  DEF            A module definition file, while not required for all 
  14934.                 Presentation Manager  applications, is definitely recommended. 
  14935.                 This file contains information for input to the link editor, as 
  14936.                 described in Module Definition File. 
  14937.  RC             A resource script file contains definitions for Presentation 
  14938.                 Manager resources, and/or statements that include resources 
  14939.                 from other files. 
  14940.  DLG            If an application uses a dialog box, a dialog file is normally 
  14941.                 created containing a definition for the dialog box and its 
  14942.                 control windows.  This file is normally included into the 
  14943.                 resource script file using an appropriate statement. 
  14944.  The role of these files in the development of a Presentation Manager 
  14945.  application is illustrated in Compiling and Linking an OS/2 Presentation 
  14946.  Manager Application. 
  14947.  
  14948.  Compiling and Linking an OS/2 Presentation Manager Application 
  14949.  
  14950.  NotethatcertainadditionalheaderfilesaregeneratedbytheSOMPrecompilerandusedincompilingasystemobjectmodelobjectclass 
  14951.  . Thesefilesaretypicallyheaderfilesusedtolinktheclasswithitsparent 
  14952.  ,andhavenodirectbearingonthecompilationprocess .
  14953.  
  14954.  The following steps are required to compile and link-edit a Presentation 
  14955.  Manager application: 
  14956.  
  14957.    1. Compile the source file using a high-level language compiler, to produce 
  14958.       an object file (usually with an extension of .OBJ). 
  14959.  
  14960.    2. Link-edit the object file with any other required object files, and 
  14961.       possibly one or more run-time libraries, to create an executable file 
  14962.       (usually with an extension of .EXE). 
  14963.  
  14964.    3. Compile any Presentation Manager resources using the resource compiler, 
  14965.       and incorporate these resources into the application's executable code or 
  14966.       place them in a DLL module. 
  14967.  
  14968.  A number of compiler and link editor options are specified for Presentation 
  14969.  Manager applications; these are shown in the example below.  The executable 
  14970.  file may then be run as a Presentation Manager application under OS/2. 
  14971.  
  14972.  Note that the third step above is not required if Presentation Manager 
  14973.  resources are not used by the application.  However, it is envisaged that 
  14974.  virtually all Presentation Manager  applications will make some use of 
  14975.  resources, due to the benefits to be gained through externalization of 
  14976.  logic-independent or language-specific application components. 
  14977.  
  14978.  Note that the command sequences for compiling and link editing an application 
  14979.  may be combined and placed in a parameterized OS/2 command file for automated 
  14980.  execution.  Alternatively, a makefile may be created and the NMAKE utility 
  14981.  used to compile and link edit the application. 
  14982.  
  14983.  
  14984. ΓòÉΓòÉΓòÉ 22.2.1. Module Definition File ΓòÉΓòÉΓòÉ
  14985.  
  14986. The module definition file is a simple text file required by most Presentation 
  14987. Manager applications.  Module definition files are used when link editing both 
  14988. programs and dynamic link libraries.  By convention, the module definition file 
  14989. has the same name as the program or library source file, but with an extension 
  14990. of DEF. 
  14991.  
  14992. A sample module definition file for a simple Presentation Manager application 
  14993. is shown Sample Module Definition File for Presentation Manager: 
  14994.  
  14995. ; Sample Presentation Manager Module Definition File
  14996.  
  14997. NAME        MYPROG  WINDOWAPI
  14998. DESCRIPTION    'Sample PM Application (C) IBM Corporation 1991'
  14999. PROTMODE
  15000.  
  15001. STUB        'OS2STUB.EXE'
  15002.  
  15003. STACKSIZE     8192
  15004. HEAPSIZE      1024
  15005.  
  15006. EXPORTS      ThisWindowProc
  15007.          ThatWindowProc
  15008.          TheOtherWindowProc
  15009.  
  15010. Sample Module Definition File for Presentation Manager 
  15011.  
  15012. A module definition file normally begins with a NAME or LIBRARY statement, 
  15013. which identifies the module as a program or DLL respectively, and assigns it a 
  15014. module name.  The keyword WINDOWCOMPAT may be used to specify a full-screen 
  15015. application that may be run in a Presentation Manager text window, or WINDOWAPI 
  15016. may be used to specify a full Presentation Manager application. 
  15017.  
  15018. The module definition file also contains a DESCRIPTION entry, containing text 
  15019. that is embedded by the link editor into the header of the executable module. 
  15020. This text may contain information such as a copyright notice or author 
  15021. information concerning the module. 
  15022.  
  15023. The PROTMODE keyword should be used to indicate that the application will be 
  15024. run only in protect mode under OS/2 (note that this is a standard provision; 
  15025. all Presentation Manager applications must run in protect mode).  This allows 
  15026. the link editor to shorten the header in the executable module. 
  15027.  
  15028. The STUB keyword instructs the link editor to set up a stub file that generates 
  15029. an error message if the user attempts to execute the application in a DOS 
  15030. environment.  OS2STUB.EXE is a DOS executable file that performs this function, 
  15031. and is provided with the IBM Developer's Toolkit for OS/2 2.0. 
  15032.  
  15033. A DATA statement may be used in the module definition file to indicate the 
  15034. disposition of data segments created by the module.  Data segments may be 
  15035. specified as SHARED, NONSHARED or NONE.  If SHARED is specified, different 
  15036. processes using the code segments of a dynamic link library will share the same 
  15037. data segments; if NONSHARED is specified, the operating system will create a 
  15038. new set of data segments for each process using a DLL.  NONSHARED is 
  15039. recommended. 
  15040.  
  15041. The STACKSIZE and HEAPSIZE statements specify the size of the memory areas to 
  15042. be reserved for the application's stack and for the local heap in the program's 
  15043. automatic data segment.  Note that the recommended minimum stack size for 
  15044. Presentation Manager applications is 8 KB.  Note also that STACKSIZE is not 
  15045. used for dynamic link library modules, since a DLL has no stack (see Creating a 
  15046. DLL). 
  15047.  
  15048. The module definition file may also contain an EXPORTS statement for all 
  15049. exportable entry points (such as window procedures) window procedures contained 
  15050. in the module.  This statement causes the entry points for window procedures to 
  15051. be defined in the header of an executable module, so that they may later be 
  15052. called from outside the current executable module (since window procedures are 
  15053. actually invoked by Presentation Manager on behalf of the application, rather 
  15054. than directly by the application itself). 
  15055.  
  15056. An IMPORTS statement may be used to define the entry points for those functions 
  15057. and/or resource definitions that will be imported from a dynamic link library. 
  15058. However, an IMPORTS statement is not required if an import library is being 
  15059. link edited with the application (see Using a DLL). 
  15060.  
  15061. The module definition file, and the statements it may contain, are described 
  15062. fully in the IBM OS/2 Version 2.0 Application Design Guide. 
  15063.  
  15064.  
  15065. ΓòÉΓòÉΓòÉ 22.2.2. Compiler Options ΓòÉΓòÉΓòÉ
  15066.  
  15067. Using the IBM C Set/2 compiler, the following command sequence is recommended: 
  15068.  
  15069. cc /C+ /L+ /G3 /Ti+ MYPROG
  15070.  
  15071. The /C+ option indicates that only the compile step should be run, and not the 
  15072. link-edit step, which is then performed explicitly at a later point using the 
  15073. LINK386 utility.  The /L+ option causes the compiler to produce a source 
  15074. listing file. 
  15075.  
  15076. The /G3 option optimizes the code for execution on an Intel 80386 processor. 
  15077. The code will also execute on an 80486 processor.  However, for code that will 
  15078. mainly be executed on 80486 hardware, use of the /G4 option is recommended. 
  15079. See the IBM C Set/2 User's Guide for further information. 
  15080.  
  15081. The /Ti+ option instructs the compiler to generate symbolic debugging 
  15082. information which may then be used when debugging the application with the IBM 
  15083. C Set/2 debugging tool. 
  15084.  
  15085.  
  15086. ΓòÉΓòÉΓòÉ 22.3. Link Edit ΓòÉΓòÉΓòÉ
  15087.  
  15088. When using the IBM C Set/2 compiler, an application may be compiled and 
  15089. link-edited in a single operation.  The following command sequence is used to 
  15090. compile and link edit a program for Presentation Manager under OS/2 Version 
  15091. 2.0: 
  15092.  
  15093. CC /L- /G3 /Ti+ /Gm+ MYPROG OS2386.LIB MYPROG.DEF
  15094.  
  15095. This command sequence directs the linkage editor to compile the file MYPROG.C 
  15096. to produce an object file named MYPROG.OBJ, and to link this file to produce an 
  15097. executable file named MYPROG.EXE, without creating a list file, to use the 
  15098. run-time library named OS2386.LIB and the module definition file named 
  15099. MYPROG.DEF. 
  15100.  
  15101. Note the use of the /Gm+ option.  This option causes the multithreading "C" 
  15102. run-time libraries to be used in linking, thereby enabling multithreadingin the 
  15103. resulting application code. 
  15104.  
  15105.  
  15106. ΓòÉΓòÉΓòÉ 22.4. Resource Compilation ΓòÉΓòÉΓòÉ
  15107.  
  15108. Presentation Manager resources used by the application and defined in a 
  15109. resource script file are compiled using the resource compiler provided in the 
  15110. IBM Developer's Toolkit for OS/2 2.0.  The command sequence used to invoke the 
  15111. resource compiler is as follows: 
  15112.  
  15113. rc MYPROG.RC MYPROG.EXE
  15114.  
  15115. This command sequence causes the resource compiler to read the resource 
  15116. definitions from the resource script file MYPROG.RC and compile them to produce 
  15117. an intermediate resource file MYPROG.RES, which is then incorporated into the 
  15118. executable module MYPROG.EXE. 
  15119.  
  15120. Resources may also be compiled and incorporated into dynamic link libraries, 
  15121. simply by specifying the name of the DLL rather than the EXE file when invoking 
  15122. the resource compiler.  Note that certain additional considerations may apply; 
  15123. see Presentation Manager Resources in a DLL for further information. 
  15124.  
  15125. Note that under OS/2 Version 2.0, 32-bit applications may use existing 16-bit 
  15126. application modules and resources.  This concept is known as mixed model 
  15127. programming, and is discussed in Mixing 16-Bit and 32-Bit Application Modules. 
  15128.  
  15129.  
  15130. ΓòÉΓòÉΓòÉ 22.5. Dynamic Link Libraries ΓòÉΓòÉΓòÉ
  15131.  
  15132. Since window procedures that communicate using the standard Presentation 
  15133. Manager  message conventions have no exterior interfaces aside from these 
  15134. messages, window procedures are essentially "black boxes" and are invisible to 
  15135. the application.  It is thus possible to produce a number of window procedures 
  15136. to perform standard or often-used functions, and to store these window 
  15137. procedures in a library from which they may be accessed by a number of 
  15138. applications. 
  15139.  
  15140. The recommended way to achieve this capability is to place such window 
  15141. procedures in an OS/2 dynamic link library. [See Dynamic Linking for an 
  15142. explanation of the concept of dynamic linking. ] Applications using these 
  15143. window procedures then reap the benefits of DLLs; namely that changes to window 
  15144. procedures contained in the DLLs do not require the applications to be 
  15145. re-linked and that multiple applications may use the same memory-resident copy 
  15146. of the window procedure code, since DLLs are re-entrant.  The use of DLLs 
  15147. therefore maximizes the potential for code reuse, and facilitates the 
  15148. containment of change within a single application module. 
  15149.  
  15150. Note that where existing 16-bit DLLs contain application objects, functions or 
  15151. resources required by 32-bit applications under OS/2 Version 2.0, these 
  15152. applications may access the 16-bit DLLs.  This technique, known as mixed model 
  15153. programming, is discussed in Mixing 16-Bit and 32-Bit Application Modules. 
  15154.  
  15155.  
  15156. ΓòÉΓòÉΓòÉ 22.5.1. Creating a DLL ΓòÉΓòÉΓòÉ
  15157.  
  15158. To build a DLL from a particular source code module, the code is compiled in a 
  15159. similar manner to that used for any other Presentation Manager application 
  15160. code.  However, use of the /Ge- option will cause the C Set/2 compiler to 
  15161. produce a DLL module. 
  15162.  
  15163. CC /L- /G3 /Ti+ /Gm+ /Ge- MYDLL OS2386.LIB MYDLL.DEF
  15164.  
  15165. This command sequence instructs the compiler to take the file MYPROG.C, to 
  15166. compile and link edit it to produce a dynamic link library named MYPROG.DLL, 
  15167. and to use the file named MYPROG.DEF as input to the linking process.  Use of 
  15168. the /Gm+ option enables multithreading, and use of the /Ge- option directs C 
  15169. Set/2 to produce a DLL module. 
  15170.  
  15171. A sample module definition file for use when creating a DLL is shown in Sample 
  15172. Module Definition File to Create a DLL: 
  15173.  
  15174. ; Sample PM Module Definition File for Creating a DLL
  15175.  
  15176. LIBRARY      MYDLL INITINSTANCE TERMINSTANCE
  15177. DESCRIPTION    'Sample PM Dynamic Link Library (c) IBM 1991'
  15178. PROTMODE
  15179. DATA        MULTIPLE
  15180.  
  15181. EXPORTS      RoutineNumberOne
  15182.          RoutineNumberTwo
  15183.          RoutineNumberThree
  15184.  
  15185. Sample Module Definition File to Create a DLL 
  15186.  
  15187. The following rules apply to module definition files when used to create 
  15188. dynamic link libraries: 
  15189.  
  15190.    o  The LIBRARY statement must be used, and the module name declared must be 
  15191.       the same as the file name of the DLL.  The keywords INITINSTANCE and 
  15192.       TERMINSTANCE may be used to indicate that any initialization code should 
  15193.       be executed for each process which accesses the DLL. 
  15194.  
  15195.    o  If the DLL will be accessed by separate processes within the system, 
  15196.       separate data segments should be created for each process; this is 
  15197.       achieved by specifying DATA MULTIPLE in the module definition file 
  15198.  
  15199.    o  The STACKSIZE statement must not be used since a DLL does not use a 
  15200.       stack. 
  15201.  
  15202.    o  An EXPORTS statement must be included, defining each function that will 
  15203.       be exported from the DLL. 
  15204.  
  15205.  The DLL module must be copied to a directory referenced by the LIBPATH 
  15206.  statement in CONFIG.SYS. This is typically the C:\OS2\DLL directory, although 
  15207.  another directory may be used if so desired. 
  15208.  
  15209.  
  15210. ΓòÉΓòÉΓòÉ 22.5.2. Using a DLL ΓòÉΓòÉΓòÉ
  15211.  
  15212. When an application is to use functions contained in a DLL, these functions 
  15213. must first be declared at compilation time.  This is typically achieved by the 
  15214. use of an include file containing function prototypes for all exportable entry 
  15215. points within the DLL; such an include file is normally created along with the 
  15216. DLL and supplied to all application developers who will use the DLL. 
  15217.  
  15218. Once the functions are declared within the application's source code, the 
  15219. external references must be resolved at the time the program is link edited. 
  15220. This may be performed in one of two ways: 
  15221.  
  15222.    o  The functions may be identified in the application's module definition 
  15223.       file using an IMPORTS statement, as described in Module Definition File. 
  15224.       For example, the statement: 
  15225.  
  15226.             IMPORTS MYPROG.func1
  15227.  
  15228.       defines the function func1, which will be imported from a DLL named 
  15229.       MYPROG.DLL. 
  15230.  
  15231.    o  The functions may be included in an import library, which is a library 
  15232.       specified at link edit time.  An import library is created using the 
  15233.       IMPLIB utility provided with the IBM Developer's Toolkit for OS/2 2.0. 
  15234.       For example, the command: 
  15235.  
  15236.             implib MYLIB.LIB MYLIB.DEF
  15237.  
  15238.       causes IMPLIB to create an import library named MYLIB.LIB, using 
  15239.       information contained in a module definition file named MYLIB.DEF.  The 
  15240.       import library file should be placed in a directory referenced by the 
  15241.       INCLUDE environment variable. 
  15242.  
  15243.  Note that the file OS2.LIB, used when link editing OS/2 application programs, 
  15244.  is in fact an import library containing definitions for OS/2 system functions 
  15245.  that are themselves implemented using DLLs. 
  15246.  
  15247.  
  15248. ΓòÉΓòÉΓòÉ 22.5.3. Presentation Manager Resources in a DLL ΓòÉΓòÉΓòÉ
  15249.  
  15250. As noted in Dynamic Linking, Presentation Manager resources may be defined and 
  15251. stored in a DLL for use by multiple applications.  However, the implementation 
  15252. of dynamic linking under OS/2 requires that each DLL must contain an executable 
  15253. module, and resources are not executable modules in their own right.  If a DLL 
  15254. will contain only resources and will not contain an executable routine such as 
  15255. a dialog procedure, a dummy executable module must be provided for the DLL by 
  15256. the application developer, as shown below: 
  15257.  
  15258. int ARCTUSED = 1;
  15259.  
  15260. void EXPENTRY dummy()
  15261. {
  15262. }
  15263.  
  15264. The declaration for the variable ARCTUSED is provided in order to avoid an 
  15265. error generated by the IBM C/2 compiler when it cannot find a module named main 
  15266. within the source file. 
  15267.  
  15268.      Editor's Note 
  15269.  
  15270.      The above statement may not be true for the C Set/2 compiler.  This must 
  15271.      be determined. 
  15272.  
  15273.  This dummy module is compiled and link-edited into an executable file in the 
  15274.  normal way.  The resource compiler is then used to compile and incorporate the 
  15275.  resource definitions into the executable file. 
  15276.  
  15277.  
  15278. ΓòÉΓòÉΓòÉ 22.5.4. Using Dialogs in System Object Model Objects ΓòÉΓòÉΓòÉ
  15279.  
  15280. In the folder example, a dialog box is used to prompt the user for the folder's 
  15281. password, and for the user to enter the password.  Creating and invoking the 
  15282. dialog is done in the normal way.  However, invoking an object's methods from 
  15283. within a dialog procedure requires that the dialog procedure know the pointer 
  15284. to the object that invokes the method (that is, somSelf).  This is done through 
  15285. the use of the pCreateParams parameter of the WinDialogBox() function.  In this 
  15286. way, the pointer to somSelf is passed to the dialog procedure as follows: 
  15287.  
  15288.    pCreateParams = (PVOID)somSelf;
  15289.  
  15290. The dialog procedure may then store the pointer in the reserved window word 
  15291. QWL_USER: 
  15292.  
  15293.     case WM_INITDLG:
  15294.          WinSetWindowULong(hwndDlg,      /* Set window word           */
  15295.                            QWL_USER,     /* Offset of window word     */
  15296.                            (ULONG) mp2); /* Value to be stored        */
  15297.         break;
  15298.  
  15299. When an instance method must be invoked from the dialog procedure, the object 
  15300. pointer may easily be retrieved from the window words and used to invoke the 
  15301. method. 
  15302.  
  15303.    {
  15304.       PWFolder *aPWF;                         /* Object pointer       */
  15305.  
  15306.       PWF_INFO pwfolderInfo;                  /* Folder info struct   */
  15307.  
  15308.       aPWF = (PWFolder *)WinQueryWindowULong( /* Get object pointer   */
  15309.                             hwndDlg,          /* Dialog box handle    */
  15310.                             QWL_USER);        /* Offset of win word   */
  15311.  
  15312.       _QueryInfo(                             /* Invoke method        */
  15313.                  aPWF,                        /* Object pointer       */
  15314.                  &pwfolderInfo);              /* Folder info struct   */
  15315.    }
  15316.  
  15317. In the above example, a WinQueryWindowULong() call is used to retrieve the 
  15318. object pointer from the window word, and store it in aPWF.  This variable is 
  15319. then used as the first parameter when invoking the method _QueryInfo. 
  15320.  
  15321. Note that the method name _QueryInfo is in fact fully defined as 
  15322. pwfolder_QueryInfo.  However, as noted in C Implementation of an Object Class, 
  15323. the SOM Precompiler automatically generates a macro to define the abbreviated 
  15324. form of the function name, in order to avoid the necessity for the programmer 
  15325. to type the full name. 
  15326.  
  15327.  
  15328. ΓòÉΓòÉΓòÉ 22.6. Summary ΓòÉΓòÉΓòÉ
  15329.  
  15330. The steps required in compiling and link-editing a Presentation Manager 
  15331. application are generally similar to those required to generate any other OS/2 
  15332. application. Some files are required in addition to those used by a 
  15333. "conventional" application, due to Presentation Manager's use of externalized 
  15334. definitions for application resources such as menus, string tables and dialog 
  15335. boxes. 
  15336.  
  15337. The module definition file provides a mechanism whereby various attributes of 
  15338. an application or dynamic link library may be specified.  The module definition 
  15339. file also allows the developer to specify copyright information that is 
  15340. imbedded in the executable code. 
  15341.  
  15342. The creation of dynamic link libraries, while essentially similar to that of 
  15343. normal application code, requires certain special considerations, notably with 
  15344. regard to the module definition file and the options that are specified at 
  15345. link-edit time.  Code modules and Presentation Manager resources that are 
  15346. likely to be subject to change, or are of a potentially reusable nature may be 
  15347. placed in dynamic link libraries and thus isolated from the remainder of the 
  15348. application.  The remainder of the application code is thus protected from 
  15349. changes that may be necessary to these dynamic link libraries in order to 
  15350. accommodate changes in such areas as organizational procedures or government 
  15351. legislation.  Dynamic link libraries may also be used by multiple applications 
  15352. concurrently, by virtue of their reentrant nature. 
  15353.  
  15354.  
  15355. ΓòÉΓòÉΓòÉ 23. Adding Online Help and Documentation ΓòÉΓòÉΓòÉ
  15356.  
  15357. In line with the philosophy of making applications easy to use through the 
  15358. provision of an intuitive, graphical user interface, it is extremely useful to 
  15359. have an application provide online, context-sensitive help and tutorial 
  15360. facilities to the end user.  Such facilities further encourage learning by 
  15361. exploration. 
  15362.  
  15363. Presentation Manager provides such capabilities in the form of the Information 
  15364. Presentation Facility (IPF), which allows help panels to be generated and 
  15365. displayed in help windows under Presentation Manager.  These help windows are 
  15366. linked with the normal application windows in such a way that when the user 
  15367. presses the "Help" key, selects a "Help" item from the menu bar or presses a 
  15368. "Help" button in a dialog box, the appropriate help window is displayed. 
  15369.  
  15370. In addition to providing online help for Presentation Manager applications, IPF 
  15371. can also be used in a stand-alone mode, to provide online documentation for 
  15372. applications, or for business procedures that are independent of any single 
  15373. application.  Using capabilities provided by IPF, an online procedure manual 
  15374. may initiate appropriate applications, thus providing a "real-life" tutorial 
  15375. capability for new or inexperienced users. 
  15376.  
  15377. This chapter will describe the use of IPF for creating help libraries and 
  15378. online documents, and examine some ways in which IPF  may improve the 
  15379. ease-of-use of Presentation Manager applications. 
  15380.  
  15381.  
  15382. ΓòÉΓòÉΓòÉ 23.1. Creating Help Information ΓòÉΓòÉΓòÉ
  15383.  
  15384. Help information is created in ASCII source files using an IPF tag language, 
  15385. which embeds formatting tags in the text.  These tags define the formatting 
  15386. characteristics of the text which appears in help windows, and the appearance 
  15387. of the windows themselves.  Once the source files are created, the IPF compiler 
  15388. is then used to translate the source files into an IPF library format.  The IPF 
  15389. compiler can generate a table of contents and an index for help information. 
  15390.  
  15391.  
  15392. ΓòÉΓòÉΓòÉ 23.1.1. IPF Tag Language ΓòÉΓòÉΓòÉ
  15393.  
  15394. The IPF tag language is similar in structure and syntax to the Generalized 
  15395. Markup Language (GML) used by IBM's Document Composition Facility* (DCF*) 
  15396. product.  Source files are simple ASCII text files, and can be created using 
  15397. any normal text editor. 
  15398.  
  15399. Tags are embedded in the files simply by inserting the tag into the text at the 
  15400. required point.  For example, this document was created and formatted using GML 
  15401. tags, and the opening sentences of this chapter were created using the format 
  15402. shown in IPF Tag Language Example. 
  15403.  
  15404. :h1.Adding Online Help and Documentation
  15405. :p.In line with the philosophy of making applications easy to use
  15406. through the provision of an intuitive, graphical user interface,
  15407. it is extremely useful to have an application provide online,
  15408. context-sensitive help and tutorial facilities to the end user.
  15409. Such...
  15410.  
  15411. IPF Tag Language Example 
  15412.  
  15413. Notethatthechapterheadingisprecededbya" headerlevel1 
  15414. "tagwhichcausestheheadertexttobeformattedinaparticularmanner . Similarly 
  15415. ,theheaderisfollowedbya" paragraph "tagwhichcausedanewparagraphtobegin 
  15416. . Theformattingofthetextwithinthesourcefileisnotsignificant 
  15417. ;thereisnorequirementforatagtobeginattheleftmargin 
  15418. ,orforeachtagtobeginonaseparateline 
  15419. . Adevelopermayorganizethesourcefilesinthemostappropriatemannerforreadability .
  15420.  
  15421. The first statement in a source file must be a :userdoc tag, and the last 
  15422. statement must be a :euserdoc tag.  These tags are required by IPF.  Comments 
  15423. may also be imbedded within a source file using the :* tag; comments are 
  15424. ignored by the IPF  compiler, and do not appear in the formatted text. 
  15425.  
  15426. A complete description of the formatting tags available under the IPF tag 
  15427. language is beyond the scope of this document.  Some examples are given in the 
  15428. remainder of this chapter, and each tag is described in detail in the IBM OS/2 
  15429. Version 2.0 Information Presentation Reference. 
  15430.  
  15431.  
  15432. ΓòÉΓòÉΓòÉ 23.1.2. Defining Help Panels ΓòÉΓòÉΓòÉ
  15433.  
  15434. The IPF tag language contains "header" tags with levels from 1 to 6; by 
  15435. default, levels 1 to 3 define the start of a new help panel, and are 
  15436. automatically included in the table of contents for online documentation. Each 
  15437. help panel therefore begins with one of these header tags, followed by the help 
  15438. text to be displayed within that panel. 
  15439.  
  15440. :h2 res=12345 x=left y=bottom cx=50% cy=25%.Help Window Heading
  15441. :p.The sequence of operations you have performed was never
  15442. envisaged by the person who wrote this program, and no help
  15443. information has been written into these panels to deal with
  15444. this contingency. You are therefore totally beyond help.
  15445. Exciting, isn't it?
  15446.  
  15447. Simple Help Panel Source 
  15448.  
  15449. Theres =attributespecifiedinthe: h1through: 
  15450. h6tagsisusedbyIPFtouniquelyidentifythehelppanel 
  15451. ,andtoenableanapplicationtolinktothatpanelwhentheuserrequestshelp 
  15452. . SeeLinkingHelpWindowsWithApplicationsforfurtherinformation .
  15453.  
  15454. The x=, y=, cx= and cy= attributes define the position and size of the window 
  15455. within its parent.  In the case of a help window, the parent is the application 
  15456. window from which the help window was invoked. 
  15457.  
  15458. The header levels 1 to 3 are used when organizing help panels within the table 
  15459. of contents.  Panels defined with header level 3 are grouped under the last 
  15460. defined header level 2, and those defined with header level 2 are similarly 
  15461. grouped under the last defined header level 1.  Thus the order of definition 
  15462. within the source file is significant. 
  15463.  
  15464. Note that multiple help panels may be placed within a single source file, 
  15465. simply by including additional header tags.  By default, header levels 4 to 6 
  15466. will not cause the display of a new help window, but will appear as formatted 
  15467. subject headings within a help panel. 
  15468.  
  15469.  
  15470. ΓòÉΓòÉΓòÉ 23.1.3. Displaying Graphics ΓòÉΓòÉΓòÉ
  15471.  
  15472. In addition to text information, graphics may also be displayed in help panels. 
  15473. Either character graphics or bitmaps may be used.  Character graphics are 
  15474. embedded directly within the help text, using the :xmp tag to ensure correct 
  15475. formatting.  Bitmaps are referenced from within the help text using the 
  15476. :artwork tag.  An example of this tag is shown in Displaying a Bitmap in a Help 
  15477. Window. 
  15478.  
  15479. :h2 res=223.Bitmap Help Example
  15480. :p.This example shows how to display a bitmap in a help window
  15481. using the :artwork tag.
  15482. :artwork name='BITMAP.BMP' align=left.
  15483.  
  15484. Displaying a Bitmap in a Help Window 
  15485.  
  15486. Thealign =attributeonthe: artworktagallowsabitmaptobealignedeitherleft - 
  15487. justified ,right - justifiedorcenteredinthewindow 
  15488. . Insituationswherethebitmapmustfilltheentirewindow 
  15489. ,thefitattributemaybespecified 
  15490. ,whichcausesthebitmaptobescaledtofitthewindowsize .
  15491.  
  15492.  
  15493. ΓòÉΓòÉΓòÉ 23.1.4. Hypertext and Hypergraphics ΓòÉΓòÉΓòÉ
  15494.  
  15495. Help windows may be nested through the use of links embedded within the help 
  15496. information.  Both text and graphics may be defined as selectable; selection of 
  15497. these items can then be used to trigger events such as: 
  15498.  
  15499.    o  Display of another help window with supporting help text 
  15500.  
  15501.    o  Dispatch of message to the application window which invoked the help 
  15502.       window 
  15503.  
  15504.    o  Initiation of a new application. 
  15505.  
  15506.  Selectable items are known as links; text items are hypertext links, and 
  15507.  graphical items are hypergraphic links.  Each of these link types is described 
  15508.  in the following sections. 
  15509.  
  15510.  
  15511. ΓòÉΓòÉΓòÉ 23.1.4.1. Hypertext Links ΓòÉΓòÉΓòÉ
  15512.  
  15513. Text items are defined using the :link tag, which defines the type of event 
  15514. triggered by the link operation, and details of the target object activated by 
  15515. the link.  An example of a :link tag is shown in Hypertext Link. 
  15516.  
  15517. :h2 res=004.Hypertext Example
  15518. :p.This example shows the use of a
  15519. :link reftype=hd res=1013.hypertext link:elink.
  15520. to display another help window when the user selects the
  15521. hypertext item.
  15522.  
  15523. Hypertext Link 
  15524.  
  15525. The: linktagshownintheexampleaboveusesthereftype 
  15526. =attributetoidentifythetypeofeventtobetriggered( inthiscase 
  15527. ,thedisplayofanotherhelpwindow ) . Theres 
  15528. =attributeidentifiesthehelpwindowtobedisplayedwhenthehypertextitemisselected .
  15529.  
  15530. Different values for the reftype= attribute will trigger different types of 
  15531. events: 
  15532.  
  15533.    o  Specifying reftype=hd causes the display of another help window, as shown 
  15534.       in Hypertext Link.  The res= attribute must also be specified in order to 
  15535.       identify the help window to be displayed. 
  15536.  
  15537.    o  Specifying reftype=fn causes the display of a popup window containing a 
  15538.       footnote.  The refid= attribute must also be specified in order to 
  15539.       identify the footnote. 
  15540.  
  15541.    o  Specifying reftype=inform causes a message to be sent to the application 
  15542.       window which invoked the help window.  The res= attribute must also be 
  15543.       specified, and its value is passed back to the application. 
  15544.  
  15545.    o  Specifying reftype=launch causes another application to be started by the 
  15546.       operating system.  The name of the program to be started is specified in 
  15547.       the object= attribute, and parameters may be passed to the program in the 
  15548.       data= attribute. 
  15549.  
  15550.  The use of hypertext links provides a powerful means to develop sophisticated 
  15551.  help text and online documentation, and to implement tutorials and 
  15552.  "self-teaching" applications.  This subject is discussed further in 
  15553.  Self-Teaching Applications. 
  15554.  
  15555.  
  15556. ΓòÉΓòÉΓòÉ 23.1.4.2. Hypergraphic Links ΓòÉΓòÉΓòÉ
  15557.  
  15558. Bitmapped graphic items are defined in a slightly different manner to text 
  15559. items, using the :artlink tag.  The :artlink tag is specified on the line 
  15560. immediately following the :artwork tag in the source file. 
  15561.  
  15562. Multiple :artlink tags may be defined for the same bitmap, in order that the 
  15563. user may select different portions of the bitmap to trigger different events. 
  15564. If multiple :artlink tags are specified however, they must be placed in a link 
  15565. file, which is referenced using the linkfile= attribute to the :artwork tag. 
  15566.  
  15567. Both techniques are illustrated in Hypergraphic Link. 
  15568.  
  15569. :h2 res=0005.Hypergraphic Example
  15570. :p.This example shows how to define hypergraphic links in a
  15571. bitmap.
  15572. :p.The first item shows a single hypergraphic link.
  15573. :artwork name='BITMAP.BMP' align=left.
  15574. :artlink.
  15575. :link reftype=hd res=0107.
  15576. :eartlink.
  15577. :p.The next item shows multiple hypergraphic links in the same
  15578. bitmap.
  15579. :artwork name='BITMAP2.BMP' align=center linkfile='BMP2'.
  15580.  
  15581. Hypergraphic Link 
  15582.  
  15583. Theuseofalinkfileismandatorywheremultiplehypergraphiclinksexistforthesamebitmap 
  15584. . TheformatofalinkfileisshowninLinkFileWithMultipleHypergraphicLinks .
  15585.  
  15586. :artlink.
  15587. :link reftype=hd res=0110 x=0 y=0 cx=30 cy=20.
  15588. :link reftype=hd res=0111 x=31 y=21 cx=30 cy=20.
  15589. :link reftype=launch object='C:\APPLS\APPL1.EXE'
  15590.    x=61 y=41 cx=20 cy=10.
  15591. :eartlink.
  15592.  
  15593. Link File With Multiple Hypergraphic Links 
  15594.  
  15595. Multiple: linktagsarenestedwithinasingle: artlinktag 
  15596. ,anddefinevariousselectableareasofthebitmap 
  15597. ,eachofwhichtriggersaspecificeventwhenselectedbytheuser 
  15598. . Anyofthetypesofeventsnormallytriggeredbya: 
  15599. linktagmaybeinitiatedfromahypergraphiclink .
  15600.  
  15601.  
  15602. ΓòÉΓòÉΓòÉ 23.1.5. Viewports ΓòÉΓòÉΓòÉ
  15603.  
  15604. Information within help windows is displayed in viewports. In the default case, 
  15605. a single viewport is defined that occupies the entire help window and contains 
  15606. the text.  This is known as a simple viewport. However, multiple viewports may 
  15607. be defined within the same help window, and handled separately.  For example, 
  15608. two viewports may be defined in a help window;  the first may be used to 
  15609. display a graphical diagram, while the second may contain a text narrative 
  15610. relating to the diagram.  The user may scroll the text in the window, but the 
  15611. diagram remains displayed since it lies in a separate viewport.  This type of 
  15612. definition is known as a complex viewport. 
  15613.  
  15614. Multiple viewports are normally defined within a help window using :link tags 
  15615. which are known as automatic links.  These operate in a similar manner to 
  15616. hypertext links, but are invoked automatically when the help window is 
  15617. displayed.  An example of a help window containing such links is shown in 
  15618. Multiple Viewports Using Automatic Links. 
  15619.  
  15620. :h2 res=0120
  15621.    x=center y=center width=50% height=50%.
  15622.    Multiple Viewports Example
  15623. :link reftype=hd res=0121
  15624.    auto dependent
  15625.    vpx=left vpy=bottom vpcx=50% vpcy=100%
  15626.    scroll=none titlebar=none rules=none.
  15627. :link reftype=hd res=0122
  15628.    auto dependent
  15629.    vpx=right vpy=bottom vpcx=50% vpcy=100%
  15630.    scroll=vertical titlebar=none rules=none.
  15631.  
  15632. Multiple Viewports Using Automatic Links 
  15633.  
  15634. Theautoattributespecifiesthattheviewportistobeopenedautomaticallywhenitsparenthelpwindowisopened 
  15635. . Thedependentattributespecifiesthattheviewportistobeclosedwhenitsparentisclosed 
  15636. . Thevpx = ,vpy = ,vpcx =andvpcy 
  15637. =attributesspecifythepositionandsizeoftheviewportwithintheparentwindow 
  15638. . InMultipleViewportsUsingAutomaticLinks ,twoviewportsareopened ,positionedside 
  15639. - by - sidewithintheparentwindow .
  15640.  
  15641. The scroll=, titlebar= and rules= attributes determine whether each viewport 
  15642. possesses its own scroll bars, title bar and sizing borders.  In Multiple 
  15643. Viewports Using Automatic Links, neither viewport contains a title bar or 
  15644. sizing border (both make use of the parent's title bar and border), but the 
  15645. right-hand viewport contains its own scroll bar.  This allows the right-hand 
  15646. viewport to be scrolled while the left-hand viewport remains unchanged. 
  15647.  
  15648.  
  15649. ΓòÉΓòÉΓòÉ 23.1.5.1. IPF-Controlled Viewports ΓòÉΓòÉΓòÉ
  15650.  
  15651. By default, the presentation of information in viewports is under the control 
  15652. of IPF, using instructions defined in the source files.  Such viewports are 
  15653. known as IPF-controlled viewports. When an IPF-controlled viewport is used, 
  15654. text is automatically formatted within the viewport by IPF, and presented in 
  15655. the help window. 
  15656.  
  15657.  
  15658. ΓòÉΓòÉΓòÉ 23.1.5.2. Application-Controlled Viewports ΓòÉΓòÉΓòÉ
  15659.  
  15660. A viewport may also be defined as an application-controlled viewport, using the 
  15661. :acviewport tag.  This tag allows an application to take direct control of a 
  15662. viewport, and to present information in this viewport in a manner determined by 
  15663. that application.  For example, a full-motion video application could be used 
  15664. to display information in video format. 
  15665.  
  15666. The :acviewport tag is shown in Application-Controlled Viewport. 
  15667.  
  15668. :h1 res=0101
  15669.    x=center y=center width=50% height=50%.
  15670.    scroll=none.Application-Controlled Viewport Example
  15671. :acviewport dll='SAMPLES' objectname='flight' objectid=1
  15672.    vpx=left vpy=bottom vpcx=50% vpcy=50%.
  15673.  
  15674. Application-Controlled Viewport 
  15675.  
  15676. The: acviewporttagcausesIPFtoloadadynamiclinklibraryasspecifiedinthedll 
  15677. =attribute ,andtopasscontroltotheentrypointidentifiedbytheobjectname =attribute .
  15678.  
  15679.  
  15680. ΓòÉΓòÉΓòÉ 23.2. Compiling Source Files ΓòÉΓòÉΓòÉ
  15681.  
  15682. Once the text has been generated in source files, it must be compiled in order 
  15683. to produce a help library.  By default, source files have an extension of IPF. 
  15684. The IPF compiler does not require this extension, but if the compiler finds two 
  15685. files with the same name, the file with the IPF extension is used in the 
  15686. compilation. 
  15687.  
  15688. For source files that will be used to produce online documents rather than help 
  15689. libraries, the extension INF should be used.  See Stand-Alone Online 
  15690. Documentation for further information. 
  15691.  
  15692.  
  15693. ΓòÉΓòÉΓòÉ 23.2.1. The IPFC Command ΓòÉΓòÉΓòÉ
  15694.  
  15695. The IPF compiler is invoked using the IPFC command, as follows: 
  15696.  
  15697. IPFC SOURCE.IPF /X /W3 >ERRORS.TXT
  15698.  
  15699. The above command invokes the IPF compiler with the input file SOURCE.IPF.  The 
  15700. /X parameter instructs the compiler to produce a cross-reference listing for 
  15701. all headings, diagrams, etc.  The /Wn command specifies the level of 
  15702. error-reporting to be performed; valid levels are 1 (/W1) to 3 (/W3).  The 
  15703. final parameter pipes any error messages to the file ERRORS.TXT in order that 
  15704. they may be examined later.  The IPFC command is fully documented in the IBM 
  15705. OS/2 Version 2.0 Information Presentation Reference. 
  15706.  
  15707. When creating online documentation that will function in a stand-alone format 
  15708. rather than as help associated with an application, the /INF parameter is 
  15709. specified.  This causes the IPF compiler to search for source files with the 
  15710. INF extension, and to format the output for use with the online viewing utility 
  15711. VIEW.EXE. 
  15712.  
  15713.  
  15714. ΓòÉΓòÉΓòÉ 23.2.2. National Language Support ΓòÉΓòÉΓòÉ
  15715.  
  15716. Support for languages other than U.S. English may be provided in help files by 
  15717. specifying the /COUNTRY, /CODEPAGE and /LANGUAGE parameters in the IPFC 
  15718. command.  These parameters affect the collating sequence used when creating a 
  15719. table of contents or index, and the titles displayed for note (:nt), warning 
  15720. (:warning) and caution (:caution) tags. 
  15721.  
  15722. These parameters and the use of national languages in help windows and online 
  15723. documentation is described in more detail in the IBM OS/2 Version 2.0 
  15724. Information Presentation Reference. 
  15725.  
  15726.  
  15727. ΓòÉΓòÉΓòÉ 23.3. Linking Help Windows With Applications ΓòÉΓòÉΓòÉ
  15728.  
  15729. In order for an application to display help information using IPF, a number of 
  15730. steps must be performed to link the application's windows with the 
  15731. corresponding help windows.  Each of these steps is described in the following 
  15732. sections. 
  15733.  
  15734.  
  15735. ΓòÉΓòÉΓòÉ 23.3.1. Creating a Help Table ΓòÉΓòÉΓòÉ
  15736.  
  15737. A help table is a Presentation Manager resource, and is defined in a resource 
  15738. script file using the HELPTABLE resource.  An example of a help table is shown 
  15739. in Help Table Resource Definition. 
  15740.  
  15741. HELPTABLE MAINHELP
  15742. BEGIN
  15743.    HELPITEM MAIN,   SUBTABLE_MAIN,   EXTHELP_MAIN
  15744.    HELPITEM DIALOG1, SUBTABLE_DIALOG1, EXTHELP_DIALOG1
  15745. END
  15746.  
  15747. HELPSUBTABLE SUBTABLE_MAIN
  15748. BEGIN
  15749.    HELPSUBITEM MI_FILE, 0010
  15750.    HELPSUBITEM MI_EDIT, 0020
  15751.    HELPSUBITEM MI_VIEW, 0030
  15752.    HELPSUBITEM MI_EXIT, 0040
  15753. END
  15754.  
  15755. HELPSUBTABLE SUBTABLE_DIALOG1
  15756. BEGIN
  15757.    HELPSUBITEM EF_ITEM1, 0101
  15758.    HELPSUBITEM EF_ITEM2, 0102
  15759.    HELPSUBITEM CK_ITEM3, 0103
  15760.    HELPSUBITEM PB_ITEM4, 0104
  15761.    HELPSUBITEM PB_ITEM5, 0105
  15762. END
  15763.  
  15764. Help Table Resource Definition 
  15765.  
  15766. TheHELPITEMresourceswithinthehelptabledefineeachapplicationwindowforwhichhelpistobeprovided 
  15767. ,andpointtoaHELPSUBTABLEresource 
  15768. .EachHELPITEMresourcealsodefinesthepanelidentifieroftheoptionalextendedhelppanelforthatwindow .
  15769.  
  15770. A HELPSUBTABLE resource is defined for each window, and contains HELPSUBITEM 
  15771. resources that identify each item within the window for which help is to be 
  15772. provided, and the panel identifier of the help panel for that item. 
  15773.  
  15774. For example, Help Table Resource Definition shows a main window with the window 
  15775. identifier MAIN, and a dialog box with the identifier DIALOG1.  A subtable is 
  15776. defined for MAIN, which defines the menu bar items within that window, and 
  15777. identifies a help panel for each of these items.  For DIALOG1, the subtable 
  15778. specifies the identifiers of the control windows within the dialog box, and 
  15779. identifies a help panel for each control window.  The identifiers of the help 
  15780. panels must correspond to the identifiers specified in the res= attribute of 
  15781. the header tags. 
  15782.  
  15783.  
  15784. ΓòÉΓòÉΓòÉ 23.3.2. Creating a Help Instance ΓòÉΓòÉΓòÉ
  15785.  
  15786. Once the help table for an application has been created, the application must 
  15787. pass this help table to IPF and create a help instance, using the 
  15788. WinCreateHelpInstance() function.  This function is shown in 
  15789. WinCreateHelpInstance() Function. 
  15790.  
  15791. PHELPINIT HelpInit;
  15792. HWND    hHelp;
  15793.  
  15794. HelpInit=DosAllocMem(HelpInit,         /* Allocate memory object  */
  15795.            sizeof(HELPINIT),     /* Size of HELPINIT struct */
  15796.            PAG_READ  |       /* Allow read access    */
  15797.            PAG_WRITE  |       /* Allow write access    */
  15798.            PAG_COMMIT;        /* Commit storage now    */
  15799.  
  15800. HelpInit->cb=sizeof(HELPINIT);         /* Specify size of struct  */
  15801. HelpInit->pszTutorialName=NULL;        /* No tutorial       */
  15802. HelpInit->phtHelpTable=MAINHELP;        /* Help table identifier  */
  15803. HelpInit->phtHelpTableModule=NULL;       /* Help table in EXE file  */
  15804. HelpInit->hmodAccelActionBarModule=NULL;    /* Resource in EXE file   */
  15805. HelpInit->idAccelTable=0;           /* Resource in EXE file   */
  15806. HelpInit->idActionBar=0;            /* Default used       */
  15807. HelpInit->pszHelpWindowTitle="Help";      /* Help window title    */
  15808. HelpInit->usShowPanelID=CMIC_HIDE_PANEL_ID;  /* Do not show panel ids  */
  15809. HelpInit->pszHelpLibraryName="APPLHELP";    /* Name of help library   */
  15810.  
  15811. hHelp = WinCreateHelpInstance(hAB,       /* Create help instance   */
  15812.                HelpInit);    /* HELPINIT structure    */
  15813.  
  15814. WinCreateHelpInstance() Function 
  15815.  
  15816. TheWinCreateHelpInstance ( )functionisnormallycalledfromanapplication ' 
  15817. smainroutine ,immediatelyaftercreatingtheapplication ' smainwindow 
  15818. ,butbeforeenteringthemessageprocessingloop .
  15819.  
  15820. The WinCreateHelpInstance() function creates the application's main help 
  15821. window, which is initially invisible, and passes appropriate information to 
  15822. that window to enable the specified help library to be loaded and access to be 
  15823. obtained to required resources.  See Main Help Window. 
  15824.  
  15825.  
  15826. ΓòÉΓòÉΓòÉ 23.3.3. Associating a Help Instance ΓòÉΓòÉΓòÉ
  15827.  
  15828. Once the help instance has been created, it must be associated with an 
  15829. application window.  The help instance is normally associated with the 
  15830. application's main frame window, and help may therefore be provided for any 
  15831. children of the frame window, including the menu bar and client window.  The 
  15832. WinAssociateHelpInstance() function is used to associate a help instance with 
  15833. an application window; an example of this function is shown in 
  15834. WinAssociateHelpInstance() Function. 
  15835.  
  15836. rc = WinAssociateHelpInstance(hHelp,      /* Help instance handle   */
  15837.                hFrame);     /* Frame window handle   */
  15838.  
  15839. WinAssociateHelpInstance() Function 
  15840.  
  15841. TheWinAssociateHelpInstance ( )functionisnormallycalledfromtheapplication ' 
  15842. smainroutine ,immediatelyfollowingtheWinCreateHelpInstance ( )functioncall .
  15843.  
  15844.  
  15845. ΓòÉΓòÉΓòÉ 23.3.4. Ending a Help Instance ΓòÉΓòÉΓòÉ
  15846.  
  15847. Upon termination of the application, the help instance should be ended using a 
  15848. WinDestroyHelpInstance() function call, as shown in WinDestroyHelpInstance() 
  15849. Function. 
  15850.  
  15851. rc = WinDestroyHelpInstance(hHelp);      /* Destroy help instance  */
  15852.  
  15853. WinDestroyHelpInstance() Function 
  15854.  
  15855. Thisfunctionisinvokedimmediatelyafterterminationoftheapplication ' 
  15856. smessageprocessingroutine ,andpriortodestroyingtheapplication ' smainwindow .
  15857.  
  15858.  
  15859. ΓòÉΓòÉΓòÉ 23.4. Displaying Help Panels ΓòÉΓòÉΓòÉ
  15860.  
  15861. Help panels are displayed in help windows by IPF as a result of user 
  15862. interaction.  A user may cause a help panel to be displayed in one of three 
  15863. ways: 
  15864.  
  15865.    o  Hitting the F1 key 
  15866.  
  15867.    o  Selecting a "Help" item on the menu bar or a pulldown menu 
  15868.  
  15869.    o  Pressing a Help pushbutton in a dialog box. 
  15870.  
  15871.  Each of these actions normally results in a WM_HELP message being generated. 
  15872.  This message is trapped by IPF, which then determines the active application 
  15873.  window and uses the current help table to identify the help panel for that 
  15874.  window. 
  15875.  
  15876.  
  15877. ΓòÉΓòÉΓòÉ 23.4.1. F1 Key ΓòÉΓòÉΓòÉ
  15878.  
  15879. Under the default accelerator table maintained by Presentation Manager for all 
  15880. windows, the F1 key causes a WM_HELP message to be generated and posted to the 
  15881. queue for the window that possessed the input focus when the key was pressed. 
  15882. Explicit definition of the accelerator key by the application is not required. 
  15883.  
  15884.  
  15885. ΓòÉΓòÉΓòÉ 23.4.2. Help Menu Bar Item ΓòÉΓòÉΓòÉ
  15886.  
  15887. A "Help" menu bar item, whether it is defined on the menu bar or in a "Help" 
  15888. pulldown menu, should be defined using the MIS_HELP style.  This will cause the 
  15889. item to generate a WM_HELP message, rather than a WM_COMMAND message.  The 
  15890. definition of such an item is shown in Resource Script File. 
  15891.  
  15892.  
  15893. ΓòÉΓòÉΓòÉ 23.4.3. Help Pushbutton ΓòÉΓòÉΓòÉ
  15894.  
  15895. A "Help" pushbutton in a dialog box should be defined using the BS_HELP and 
  15896. BS_NOPOINTERFOCUS styles.  The WM_HELP message is passed to IPF, which then 
  15897. determines the control window within the dialog box that currently possesses 
  15898. the input focus, and displays the help panel for that control window. 
  15899.  
  15900.  
  15901. ΓòÉΓòÉΓòÉ 23.5. Main Help Window ΓòÉΓòÉΓòÉ
  15902.  
  15903. The WinCreateHelpInstance() function returns a window handle.  This is the 
  15904. handle of the application's main help window.  The main help window is created 
  15905. by IPF, with a standard format and with a window procedure supplied by 
  15906. Presentation Manager.  Whenever a help panel is displayed, it appears as a 
  15907. child window of the main help window. 
  15908.  
  15909. The main help window has a title bar, which contains a title specified by the 
  15910. application.  The application passes this title in the pszHelpWindowTitle 
  15911. parameter to the WinCreateHelpInstance() function. 
  15912.  
  15913. The main help window contains a menu bar with several pulldown menus allowing 
  15914. the user to perform text searches, view the index, etc.  An application 
  15915. developer may modify this menu bar using the resource definitions contained in 
  15916. the hmtailor.rc file provided with IPF.  This file includes an hmtailor.h file, 
  15917. which contains the integer constant definitions for the menu bar and pulldown 
  15918. menu items.  Additional items may be defined within the help pulldown menu, but 
  15919. their resource identifiers should be between 7F00 and 7FFF to avoid conflicts 
  15920. with identifiers already defined. 
  15921.  
  15922. When the menu bar of the main help window has been modified, it must be 
  15923. resource-compiled in the normal way, and combined with the application's 
  15924. executable file or with a DLL.  Its resource identifier must then be specified 
  15925. in the idActionBar parameter of the WinCreateHelpInstance() function call.  If 
  15926. additional accelerator keys have been defined, the identifier of the 
  15927. accelerator table must also be defined in the idAccelTable parameter. 
  15928.  
  15929. If the menu bar and accelerator table definitions have been combined with a 
  15930. DLL, the module handle of this DLL must be specified in the 
  15931. hmodAccellActionBarModule parameter.  The module handle must first be obtained 
  15932. using the DosLoadModule() or DosGetModuleHandle() functions.  These functions 
  15933. are described in Loading Resources From a DLL. 
  15934.  
  15935.  
  15936. ΓòÉΓòÉΓòÉ 23.5.1. The Help Pulldown Menu ΓòÉΓòÉΓòÉ
  15937.  
  15938. The menu bar of the main help window contains a "Help" pulldown menu which in 
  15939. turn contains a number of options.  The resource definition for this pulldown 
  15940. menu is included in the hmtailor.rc file provided with IPF, and illustrated in 
  15941. Help Pulldown Menu Definition. 
  15942.  
  15943.   :
  15944.   :
  15945. SUBMENU   "~Help",       ID_HELP
  15946. BEGIN
  15947.   MENUITEM "~Help for help...", ID_HELP_FOR_HELP
  15948.   MENUITEM "~Extended help...", SC_HELPEXTENDED, MIS_SYSCOMMAND
  15949.   MENUITEM "~Keys help...",   SC_HELPKEYS, MIS_SYSCOMMAND
  15950.   MENUITEM "Help ~index...",   SC_HELPINDEX, MIS_SYSCOMMAND
  15951. END
  15952.   :
  15953.   :
  15954.  
  15955. Help Pulldown Menu Definition 
  15956.  
  15957. This example shows the "Help" pulldown menu included in the
  15958. menu bar of the default main help window used by IPF.
  15959.  
  15960. When the user selects an item from the help pulldown menu, a message is 
  15961. generated, and is trapped by IPF and processed.  Typically, this message causes 
  15962. IPF to query the application for the correct help panel.  The message generated 
  15963. is dependent upon the pulldown menu item selected by the user. 
  15964.  
  15965.  
  15966. ΓòÉΓòÉΓòÉ 23.5.1.1. Help For Help ΓòÉΓòÉΓòÉ
  15967.  
  15968. When the user selects this item, IPF sends a WM_COMMAND message to the active 
  15969. application window, with the first parameter containing the ID_HELP_FOR_HELP 
  15970. identifier.  The application's window procedure should process this message by 
  15971. sending an HM_REPLACE_HELP_FOR_HELP message containing the panel identifier of 
  15972. its own "Help for help" panel if one exists, or by sending an HM_DISPLAY_PANEL 
  15973. message with both parameters set to zero in order to display the default panel. 
  15974.  
  15975.  
  15976. ΓòÉΓòÉΓòÉ 23.5.1.2. Extended Help ΓòÉΓòÉΓòÉ
  15977.  
  15978. When the user selects this item, IPF responds by displaying the "Extended help" 
  15979. panel defined for the active application window in the help table.  If no such 
  15980. help panel is defined for that window, IPF sends an HM_EXT_HELP_UNDEFINED 
  15981. message to the application (see HM_EXT_HELP_UNDEFINED). 
  15982.  
  15983.  
  15984. ΓòÉΓòÉΓòÉ 23.5.1.3. Keys Help ΓòÉΓòÉΓòÉ
  15985.  
  15986. When the user selects this item, IPF sends an HM_QUERY_KEYS_HELP message to the 
  15987. active application window.  The application's window procedure should process 
  15988. this message by returning the panel identifier of its own "Keys help" panel in 
  15989. the return code to Presentation Manager. 
  15990.  
  15991.  
  15992. ΓòÉΓòÉΓòÉ 23.5.1.4. Help Index ΓòÉΓòÉΓòÉ
  15993.  
  15994. Selecting this item causes IPF to display the index of the current help 
  15995. library. 
  15996.  
  15997.  
  15998. ΓòÉΓòÉΓòÉ 23.5.2. Communication Between IPF and Applications ΓòÉΓòÉΓòÉ
  15999.  
  16000. Information may be communicated from IPF to an application in response to user 
  16001. interaction in a help window.  This information may be in the form of 
  16002. application events or errors, and is communicated to the application in the 
  16003. form of a message passed to the application window specified in the 
  16004. WinCreateHelpInstance() function.  Such messages originate from the main help 
  16005. window, as part of the window procedure supplied by Presentation Manager for 
  16006. that window. 
  16007.  
  16008.  
  16009. ΓòÉΓòÉΓòÉ 23.5.2.1. HM_INFORM Message ΓòÉΓòÉΓòÉ
  16010.  
  16011. This message is passed to the application when the user selects a hypertext or 
  16012. hypergraphic item in a help window, for which the reftype=inform attribute has 
  16013. been specified.  The first parameter of the HM_INFORM message contains the 
  16014. identifier specified by the res= attribute in the hypertext or hypergraphic 
  16015. link definition. 
  16016.  
  16017. An application window typically processes the HM_INFORM message by examining 
  16018. the identifier in the first message parameter, and dispatching a message of the 
  16019. appropriate class to itself or another application window, in order to initiate 
  16020. the action requested by the HM_INFORM message. 
  16021.  
  16022.  
  16023. ΓòÉΓòÉΓòÉ 23.5.2.2. HM_ERROR ΓòÉΓòÉΓòÉ
  16024.  
  16025. This message is passed to the application when an error occurs during a user 
  16026. interaction with a help window.  This message allows the application to display 
  16027. its own error message in such cases, thereby providing a consistent appearance 
  16028. for error messages.  The first parameter of the message indicates the reason 
  16029. for the error.  These reasons are documented in the IBM OS/2 Version 2.0 
  16030. Information Presentation Reference. 
  16031.  
  16032. An application typically processes the HM_ERROR message by displaying an 
  16033. appropriate message box and returning zero to Presentation Manager.  If the 
  16034. application does not process the message, Presentation Manager takes no action. 
  16035.  
  16036.  
  16037. ΓòÉΓòÉΓòÉ 23.5.2.3. HM_EXT_HELP_UNDEFINED ΓòÉΓòÉΓòÉ
  16038.  
  16039. This message indicates that the user selected the "Extended help" item on the 
  16040. "Help" pulldown menu, and that no such help panel was defined for the active 
  16041. application window. 
  16042.  
  16043. An application may process this message in one of three ways: 
  16044.  
  16045.    o  Display a message box indicating that no help is available 
  16046.  
  16047.    o  Display its own help window by explicitly creating and displaying the 
  16048.       window on the screen 
  16049.  
  16050.    o  Pass a HM_DISPLAY_HELP message back to IPF, instructing IPF to display a 
  16051.       particular help panel. 
  16052.  
  16053.  If the application does not process this message, no panel is displayed and 
  16054.  the user's request is simply ignored. 
  16055.  
  16056.  
  16057. ΓòÉΓòÉΓòÉ 23.5.2.4. HM_SUBITEM_NOT_FOUND ΓòÉΓòÉΓòÉ
  16058.  
  16059. This message indicates that the user issued a help request on an item for which 
  16060. no help panel is defined in the current help table.  The application may 
  16061. process this message in one of three ways, as described in 
  16062. HM_EXT_HELP_UNDEFINED.  The application should then return TRUE to Presentation 
  16063. Manager. 
  16064.  
  16065. If the application does not process this message, the extended help panel for 
  16066. the currently active window is displayed by IPF. 
  16067.  
  16068.  
  16069. ΓòÉΓòÉΓòÉ 23.6. Stand-Alone Online Documentation ΓòÉΓòÉΓòÉ
  16070.  
  16071. Panels containing text produced using IPF need not be called from an 
  16072. application; IPF can be used to produce "stand-alone" online documentation, 
  16073. which is viewed using the VIEW.EXE utility provided with OS/2 Version 2.0. 
  16074. Online documents have similar capabilities to help libraries; both text and 
  16075. graphics may be included, and hypertext and hypergraphic links are supported. 
  16076.  
  16077. Online documents also have a number of differences from help libraries: 
  16078.  
  16079.    o  In an online document, a panel may be identified by using the name= or 
  16080.       id= attributes in the heading, rather than the res= attribute.  These 
  16081.       attributes allow the use of alphanumeric characters, where the res= 
  16082.       attribute must specify an integer identifier.  Links are then defined 
  16083.       using the refid= attribute in the :link tag. 
  16084.  
  16085.       Note that the name= or id= attributes may not be used if files will be 
  16086.       concatenated and hypertext or hypergraphic links are required between 
  16087.       files. 
  16088.  
  16089.    o  Online documents may not use hypertext or hypergraphic links with 
  16090.       reftype=inform, since there is no associated application for the help 
  16091.       instance, and IPF cannot determine the window to which the message should 
  16092.       be directed. 
  16093.  
  16094.    o  An online document has a main window created by IPF, which contains the 
  16095.       table of contents for the document.  The title of this main window is 
  16096.       determined by a :title tag. 
  16097.  
  16098.       Note that the :title tag may only be used for online documents, and not 
  16099.       for help libraries.  The title of an application's main help window is 
  16100.       specified in the WinCreateHelpInstance() function call. 
  16101.  
  16102.  The ability to include hypertext and hypergraphics in online documents allows 
  16103.  the creation of online procedure manuals that automatically invoke the 
  16104.  appropriate application or applications for each step of the procedure. This 
  16105.  is achieved by defining the hypertext or hypergraphic items with 
  16106.  reftype=launch, specifying the name of the executable file for the required 
  16107.  application.  See Self-Teaching Applications for further discussion of such 
  16108.  applications. 
  16109.  
  16110.  
  16111. ΓòÉΓòÉΓòÉ 23.6.1. Compiling Online Documents ΓòÉΓòÉΓòÉ
  16112.  
  16113. Source files that will be used for online documents are created in an identical 
  16114. manner to those used for help text.  When the IPFC command is invoked to 
  16115. compile the source files, the /INF parameter should be specified, as follows: 
  16116.  
  16117. IPFC SOURCE.IPF /X /W3 /INF >ERRORS.TXT
  16118.  
  16119. The IPF compiler will then include the necessary hooks to enable VIEW.EXE to 
  16120. display the online document.  Note that online documents compiled with the /INF 
  16121. parameter have a default extension of .INF, rather than the normal extension of 
  16122. .HLP for help libraries. 
  16123.  
  16124.  
  16125. ΓòÉΓòÉΓòÉ 23.6.2. Concatenating Source Files ΓòÉΓòÉΓòÉ
  16126.  
  16127. Multiple document files may be concatenated to produce a single online 
  16128. document.  Concatenation is achieved by creating an OS/2 environment variable 
  16129. that contains the names of the concatenated files.  For example: 
  16130.  
  16131. SET BIGDOC=DOC1.INF+DOC2.INF+DOC3.INF+DOC4.INF
  16132.  
  16133. This environment variable is typically set from within a batch file, which also 
  16134. contains the command VIEW BIGDOC to view the resulting concatenated document. 
  16135.  
  16136. Hypertext links are permitted between panels in different files, but a panel 
  16137. must use the res= attribute in the heading tag to identify itself, rather than 
  16138. the name= or id= attributes.  The global attribute must also be specified in 
  16139. the panel heading. 
  16140.  
  16141.  
  16142. ΓòÉΓòÉΓòÉ 23.7. Application Tutorials ΓòÉΓòÉΓòÉ
  16143.  
  16144. For any application, the developer or developers may supply a tutorial, which 
  16145. is effectively another Presentation Manager program which provides step-by-step 
  16146. guidance to the user.  IPF enables tutorials to be started from within help 
  16147. windows, in a number of ways: 
  16148.  
  16149.    o  Within a help panel, a hypertext or hypergraphic link may be defined with 
  16150.       reftype=launch, and with the objectname= attribute specifying the name of 
  16151.       the tutorial program.  When the user selects the hypertext or 
  16152.       hypergraphic item, the tutorial is started automatically. 
  16153.  
  16154.    o  A "Tutorial" item may be included in the "Help" pulldown menu in the 
  16155.       application's main help window.  This is done automatically by IPF if any 
  16156.       help panel heading tag (:h1 through :h6) contains the tutorial attribute. 
  16157.  
  16158.       In this case, the name of a tutorial program must be specified in the 
  16159.       pszTutorialName parameter of the WinCreateHelpInstance() function call. 
  16160.  
  16161.  When the user selects the "Tutorial" item from the "Help" pulldown menu, an 
  16162.  HM_TUTORIAL message is sent to the active application window, with the first 
  16163.  parameter containing the name of the tutorial program.  The application 
  16164.  typically processes this message by calling the DosExecPgm() function to start 
  16165.  the tutorial program. 
  16166.  
  16167.  
  16168. ΓòÉΓòÉΓòÉ 23.8. Self-Teaching Applications ΓòÉΓòÉΓòÉ
  16169.  
  16170. An extension of the tutorial concept is possible, where the user invokes an 
  16171. online procedure manual that describes a business process; hypertext and 
  16172. hypergraphic links can be imbedded in this manual to start the application or 
  16173. applications that support the business process.  This can be performed in 
  16174. either of two ways: 
  16175.  
  16176.    o  Where the steps in the business process are largely independent of one 
  16177.       another, a separate application may be used for each step. 
  16178.  
  16179.    o  Where the steps are interdependent, a single application can be used, 
  16180.       with links triggering application events by way of messages. 
  16181.  
  16182.  Note that this is an extension of the procedural entity concept originally 
  16183.  discussed in Object-Oriented Applications. 
  16184.  
  16185.  
  16186. ΓòÉΓòÉΓòÉ 23.8.1. Loosely Coupled Applications ΓòÉΓòÉΓòÉ
  16187.  
  16188. Where the steps in a business process are independent of one another and do not 
  16189. require any great coordination between supporting application functions, 
  16190. separate programs may be used to carry out each step.  In this case, the 
  16191. procedure manual is created as an online document with links for each step. 
  16192. Each link is specified with reftype=launch. 
  16193.  
  16194.  
  16195. ΓòÉΓòÉΓòÉ 23.8.2. Tightly Coupled Applications ΓòÉΓòÉΓòÉ
  16196.  
  16197. Where interdependencies exist between the steps in a business process, and 
  16198. where the application functions that support these steps must therefore 
  16199. interact closely with one another, a single application is used.  In this case, 
  16200. the procedure manual is created as a help library, and execution is handled as 
  16201. follows: 
  16202.  
  16203.    1. The application creates a help instance for the help library in the 
  16204.       normal manner, creates its own main window but does not make this window 
  16205.       visible. 
  16206.  
  16207.    2. The application's main window makes itself the active window, and sends 
  16208.       an HM_DISPLAY_HELP message to the main help window to cause the initial 
  16209.       help panel to be displayed. 
  16210.  
  16211.    3. Each step in the business is defined using hypertext or hypergraphic 
  16212.       links with reftype=inform.  When such an item is selected, it causes an 
  16213.       HM_INFORM message to be posted to the application's main window (the 
  16214.       active window). 
  16215.  
  16216.    4. When the application's main window receives the HM_INFORM message, it 
  16217.       examines the message parameters to determine the required action, then 
  16218.       creates one or more additional display windows or dialog boxes and makes 
  16219.       these visible, allowing the user to complete the required step. 
  16220.  
  16221.    5. When the current step is complete, the user selects an appropriate menu 
  16222.       bar item or pushbutton, and returns to the procedure manual. 
  16223.  
  16224.  Using this technique, the application's main window retains overall control of 
  16225.  the application, and can ensure coordination between steps and impose a 
  16226.  sequence of execution if this is required. 
  16227.  
  16228.  
  16229. ΓòÉΓòÉΓòÉ 23.9. Summary ΓòÉΓòÉΓòÉ
  16230.  
  16231. The Information Presentation Facility allows an application developer to create 
  16232. online context-sensitive help panels and stand-alone online documentation for 
  16233. Presentation Manager applications.  The ability to link between panels and 
  16234. between a panel and applications provides a flexible and powerful tool for 
  16235. developing: 
  16236.  
  16237.    o  Presentation Manager applications that contain comprehensive help 
  16238.       information 
  16239.  
  16240.    o  Online manuals both for applications and for business processes 
  16241.  
  16242.    o  Interactive tutorials for applications and business processes 
  16243.  
  16244.    o  "Self-teaching" business processes where the online manual automatically 
  16245.       starts the required applications and leads the novice user through the 
  16246.       process. 
  16247.  
  16248.  The flexibility of IPF and the high level of interaction between a help 
  16249.  instance and its controlling application allows the application to exercise 
  16250.  significant control over the way in which help information is displayed to the 
  16251.  end user.  The ability to combine multiple viewports in a single help window 
  16252.  allows the simultaneous use of text, graphics and other technologies such as 
  16253.  image or full-motion video to provide help, documentation and tutorial 
  16254.  information. 
  16255.  
  16256.  
  16257. ΓòÉΓòÉΓòÉ 24. Problem Determination ΓòÉΓòÉΓòÉ
  16258.  
  16259. The steps required for identification and resolution of application errors and 
  16260. "bugs" in the Presentation Manager application environment are basically 
  16261. similar to those required for conventional programming environments.  However, 
  16262. the event-driven nature of the Presentation Manager application model often 
  16263. causes unnecessary confusion when developers attempt to test and debug their 
  16264. applications.  This chapter describes a simple approach to problem 
  16265. determination and resolution under Presentation Manager, which will help in 
  16266. locating and removing the majority of application problems. 
  16267.  
  16268. Successful problem determination in the Presentation Manager environment, as in 
  16269. any programming environment, requires some basic ingredients: 
  16270.  
  16271.    o  Effective problem documentation 
  16272.  
  16273.    o  A methodical approach to problem resolution 
  16274.  
  16275.    o  Knowledge and experience of the application environment 
  16276.  
  16277.    o  A symbolic debugging tool such as CodeView or Multiscope** 
  16278.  
  16279.    o  A measure of luck (!) 
  16280.  
  16281.  When these requirements are satisfied, problem determination may proceed 
  16282.  through the following three phases: 
  16283.  
  16284.    1. Documentation 
  16285.  
  16286.    2. Isolation 
  16287.  
  16288.    3. Diagnosis and resolution. 
  16289.  
  16290.  The remainder of this chapter describes each of these phases in detail, 
  16291.  discussing each step in the resolution process, and also describes the 
  16292.  symptoms and likely solutions for some common application problems. 
  16293.  
  16294.  
  16295. ΓòÉΓòÉΓòÉ 24.1. Problem Documentation ΓòÉΓòÉΓòÉ
  16296.  
  16297. Problems in Presentation Manager applications typically occur within window 
  16298. procedures, or in subroutines invoked from within window procedures.  This is 
  16299. not surprising, since all processing within a Presentation Manager application 
  16300. takes place as a result of messages, which are received and processed by window 
  16301. procedures.  However, the event-driven nature of the Presentation Manager 
  16302. application model provides a built-in means of narrowing down the location of a 
  16303. problem, provided the event that caused the problem can be determined. 
  16304.  
  16305. The initial documentation of an error may be performed by whoever is 
  16306. responsible for application testing, since no great level of technical 
  16307. expertise is required at this stage.  It is important that the error is 
  16308. effectively documented in writing, at the time it occurs, along with relevant 
  16309. supporting information.  Effective documentation greatly eases the task of 
  16310. recreating the error and identifying the underlying problem. 
  16311.  
  16312. A worksheet that may be used for problem documentation, and that records the 
  16313. information required by the guidelines given in this chapter, is contained in 
  16314. Problem Reporting Worksheet. 
  16315.  
  16316.  
  16317. ΓòÉΓòÉΓòÉ 24.1.1. Window ΓòÉΓòÉΓòÉ
  16318.  
  16319. In order to narrow down the location of the problem, it is first necessary to 
  16320. identify the window that was active when the error occurred.  This is usually 
  16321. self-evident when the window is a display window, but may be less so if the 
  16322. window is an object window.  However, an object window is activated upon 
  16323. receiving a message that typically originates from a display window, and 
  16324. therefore the problem may be effectively tracked down by beginning the search 
  16325. with the display window. 
  16326.  
  16327. The first step is therefore to determine the display window with which the user 
  16328. was interacting when the error occurred.  For documentation purposes, the 
  16329. window's title may be used to identify the window. 
  16330.  
  16331.      Step #1 
  16332.  
  16333.      Identify the window with which the user was interacting when the error 
  16334.      occurred, and note its title. Identification of the active window allows 
  16335.  the search for the problem to be focused on the window procedure for that 
  16336.  window.  It is likely that the problem lies within that window procedure or a 
  16337.  subroutine invoked from that window procedure.  If not, the active window 
  16338.  usually passes a message to another window which in turn causes the problem; 
  16339.  this may be determined in the isolation phase (see Problem Isolation). 
  16340.  
  16341.  
  16342. ΓòÉΓòÉΓòÉ 24.1.2. Event/Action ΓòÉΓòÉΓòÉ
  16343.  
  16344. Once the active window has been identified, it is necessary to determine the 
  16345. last user action before the error occurred.  The name of the last menu bar or 
  16346. pulldown menu item, button or icon selected should be noted for documentation 
  16347. of the problem. 
  16348.  
  16349.      Step #2 
  16350.  
  16351.      Identify the last user action before the error occurred, and record the 
  16352.      name of the menu bar or pulldown menu item, button or icon. 
  16353.  
  16354.  Identification of the last user action provides the initial location, within 
  16355.  the window procedure for the active window, at which to begin searching for 
  16356.  the problem.  The problem is likely to be within the scope of processing for 
  16357.  the message resulting from this action, or within that of another message 
  16358.  generated during the processing of this action. 
  16359.  
  16360.  
  16361. ΓòÉΓòÉΓòÉ 24.1.3. First Time vs Repetitive Actions ΓòÉΓòÉΓòÉ
  16362.  
  16363. The third important step in documenting a problem is to determine whether the 
  16364. error occurs every time a particular action is performed, or if it only occurs 
  16365. after the action has been performed a number of times. 
  16366.  
  16367.      Step #3 
  16368.  
  16369.      Note whether the problem occurred when the action was performed for the 
  16370.      first time, or only when the action had been repeated a number of times. 
  16371.  
  16372.  Problems that occur after a number of repetitions of an action typically 
  16373.  indicate a resource limitation being exceeded, and provide a short-cut to 
  16374.  problem resolution; see Repetitive Action Problems. 
  16375.  
  16376.  
  16377. ΓòÉΓòÉΓòÉ 24.2. Problem Isolation ΓòÉΓòÉΓòÉ
  16378.  
  16379. Once the problem has been documented and narrowed down to a specific event 
  16380. within a particular window, the developer must determine the Presentation 
  16381. Manager message that results from that event, or the first such message if 
  16382. multiple messages are generated. 
  16383.  
  16384. A symbolic debugging tool is then applied to the application code, and a 
  16385. breakpoint is set at the commencement of processing for that message class. The 
  16386. program is then single-stepped to determine the operation or function call at 
  16387. which the error occurs. 
  16388.  
  16389.      Step #4 
  16390.  
  16391.      Single-step with a symbolic debugging tool to determine the code statement 
  16392.      at which the error occurs. It is important during this stage to note any 
  16393.  WinPostMsg(), WinSendMsg() or WinBroadcastMsg() function calls performed by 
  16394.  the program, which will generate additional Presentation Manager messages in 
  16395.  the system.  If the initial pass through the processing for the current 
  16396.  message does not reveal the error, the same process must be performed for each 
  16397.  of these messages and the window procedures that process them. 
  16398.  
  16399.  Note that this single-stepping process is most useful in situations where the 
  16400.  error occurs every time a particular action is performed.  In cases where the 
  16401.  error only appears after a large number of repetitions, single-stepping will 
  16402.  be time-consuming and unproductive.  In such cases, the problem resolution 
  16403.  process may be expedited by omitting the isolation phase and immediately 
  16404.  checking the logic of the processing for the failing message, to ensure that 
  16405.  all resources allocated during processing are subsequently released.  See 
  16406.  Repetitive Action Problems for more details. 
  16407.  
  16408.  
  16409. ΓòÉΓòÉΓòÉ 24.3. Problem Diagnosis ΓòÉΓòÉΓòÉ
  16410.  
  16411. Once the cause of the error is narrowed down to a single statement within the 
  16412. source code, the problem with that statement must then be identified. 
  16413. Syntactical errors can generally be ruled out as a cause of failure during run 
  16414. time, since such errors are almost always identified during compilation of the 
  16415. application code.  However, the items listed below are common causes of 
  16416. run-time errors, and should be checked for failing program statements: 
  16417.  
  16418.    o  Logic:  is the sequence of operations performed during the processing of 
  16419.       a message in accordance with the application design?  Have any steps been 
  16420.       accidentally omitted? 
  16421.  
  16422.    o  Parameters:  are the correct variable names being used for parameters in 
  16423.       the program statement?  Do the parameter definitions in the program 
  16424.       statement directly match those given in the function declaration? 
  16425.  
  16426.    o  Pointers:  do they contain valid references, and/or have they been 
  16427.       correctly initialized prior to the program statement? 
  16428.  
  16429.    o  Operating system or Presentation Manager resources:  have they been 
  16430.       successfully allocated prior to the program statement?  Are resources 
  16431.       released at the completion of processing for the event and if not, is 
  16432.       there a valid reason for retaining them? 
  16433.  
  16434.      Step #5 
  16435.  
  16436.      Diagnose the cause of the problem by carefully checking the program 
  16437.      statement, and correct the error. 
  16438.  
  16439.  The following sections provide descriptions of some common application 
  16440.  problems against which failing programs may be checked. 
  16441.  
  16442.  
  16443. ΓòÉΓòÉΓòÉ 24.3.1. First Time Problems ΓòÉΓòÉΓòÉ
  16444.  
  16445. Problems that occur whenever a program statement is executed indicate an error 
  16446. in that statement or in a parameter used by that statement.  These errors may 
  16447. often be indicated by the nature of the error.  Some common errors are given 
  16448. below. 
  16449.  
  16450.  
  16451. ΓòÉΓòÉΓòÉ 24.3.1.1. Trap 000D ΓòÉΓòÉΓòÉ
  16452.  
  16453. This error indicates that the program attempted to access a location in memory 
  16454. that was not within the area allocated to its parent process.  Since such 
  16455. access might violate the integrity of other applications or of the operating 
  16456. system itself, OS/2 disallows the access.  Note that the pointer may directly 
  16457. reference a memory location, or may be the handle to a resource such as a 
  16458. window, presentation space etc. 
  16459.  
  16460. The usual cause of such an error is that a pointer passed as a parameter in a 
  16461. function call is incorrect.  The pointer may not have been initialized, or may 
  16462. have been set to an incorrect value as a result of a failed allocation request 
  16463. or incorrect pointer arithmetic. 
  16464.  
  16465. Resolution actions are typically as follows: 
  16466.  
  16467.    o  Check that the function call which allocated the resource referenced by 
  16468.       the pointer completed without error, and that a valid pointer was 
  16469.       returned. 
  16470.  
  16471.    o  Ensure that any pointer arithmetic carried out on the pointer between 
  16472.       allocation and the failing program statement is error-free. 
  16473.  
  16474.    o  If the pointer is stored in an instance data area (that is, a data block 
  16475.       normally stored in the window words), ensure that the pointer to the 
  16476.       instance data area itself has been correctly read from the window words 
  16477.       at the start of processing for the current message. 
  16478.  
  16479.  The allocation of a Presentation Manager resource may also fail for reasons 
  16480.  associated with its parent window.  See Failure to Allocate Resources. 
  16481.  
  16482.  One additional cause of this error is the application releasing an instance 
  16483.  data block too early in the processing of a WM_DESTROY message.  If the memory 
  16484.  object containing this data block is released, and the application then 
  16485.  attempts to release other resources whose handles are contained within the 
  16486.  data block, OS/2 will not allow access to the memory.  This problem is easily 
  16487.  resolved by releasing the instance data block after other resources. 
  16488.  
  16489.  
  16490. ΓòÉΓòÉΓòÉ 24.3.1.2. Trap 000E ΓòÉΓòÉΓòÉ
  16491.  
  16492. This error indicates that an application under OS/2 Version 2.0 attempted to 
  16493. access an area in memory for which an address range had been allocated, but no 
  16494. storage committed.  This error typically occurs when writing data objects into 
  16495. application data areas, since most operating system and Presentation Manager 
  16496. resources are automatically committed upon allocation. 
  16497.  
  16498. The usual cause of such an error is that the application failed to include the 
  16499. PAG_COMMIT flag in the DosAllocMem() function call that allocated the resource, 
  16500. or failed to issue a DosSetMem() call when increasing the size of a memory 
  16501. object.  The problem may be easily resolved simply by including the PAG_COMMIT 
  16502. flag or including a DosSetMem() call to ensure that sufficient storage is 
  16503. available before writing to a memory object. 
  16504.  
  16505.  
  16506. ΓòÉΓòÉΓòÉ 24.3.1.3. Failure to Allocate Resources ΓòÉΓòÉΓòÉ
  16507.  
  16508. A common error shows itself when Presentation Manager resources cannot be 
  16509. allocated correctly by an application.  This occurs most frequently with 
  16510. resources allocated upon creation of a window, during processing of the 
  16511. WM_CREATE message. 
  16512.  
  16513. The cause of the error is a failure, on the part of the application, to 
  16514. complete the default processing of the WM_CREATE message, before carrying out 
  16515. application-specific processing.  Part of this default processing involves the 
  16516. allocation of a Presentation Manager control block for the window, allocation 
  16517. of a window handle etc.  If this processing is not performed, via a 
  16518. WinDefWindowProc() function call, at the commencement of processing for the 
  16519. WM_CREATE message, function calls which use parameters such as the window 
  16520. handle will fail. 
  16521.  
  16522. The problem may be easily resolved by placing a WinDefWindowProc() function 
  16523. call as the first statement in the processing for the WM_CREATE message. 
  16524.  
  16525.  
  16526. ΓòÉΓòÉΓòÉ 24.3.1.4. Stack Space Exceeded ΓòÉΓòÉΓòÉ
  16527.  
  16528. This error may appear in either of two places: 
  16529.  
  16530.    o  If it appears during a call to an application subroutine, it usually 
  16531.       indicates that the space reserved for the application's stack is 
  16532.       insufficient for the number of nested function calls, local variables, 
  16533.       etc., being used by the application. 
  16534.  
  16535.    o  If it appears during a call to an operating system or Presentation 
  16536.       Manager function, it may indicate the same cause as above, or that the 
  16537.       limit of the application's Ring 2 stack, used by system-level code 
  16538.       invoked by the application, has been exceeded. 
  16539.  
  16540.  The application's stack size may be exceeded in situations where the 
  16541.  application makes a large number of nested subroutine calls, particularly 
  16542.  where extensive recursion is used, and/or where large numbers of local 
  16543.  variables are defined.  In such cases, the stack may be need to be increased 
  16544.  beyond the recommended minimum of 8KB, using the STACKSIZE statement in 
  16545.  application's module definition file. 
  16546.  
  16547.  The Ring 2 stack limit is normally exceeded only in situations where a 
  16548.  system-level function attempts to retrieve more items from the stack than were 
  16549.  originally placed there.  This can occur where an application passes an 
  16550.  incorrect parameter to a function; for example, if a parameter is declared by 
  16551.  the function as an array of eight elements, but the application passes an 
  16552.  array containing only seven elements, an error may occur when the function 
  16553.  attempts to retrieve eight elements from the Ring 2 stack for processing. 
  16554.  
  16555.  While such an error may reveal itself during compilation, certain C 
  16556.  typecasting conventions may mask the problem until run time.  Where this error 
  16557.  occurs during execution, careful checking of parameters is recommended. 
  16558.  
  16559.  
  16560. ΓòÉΓòÉΓòÉ 24.3.1.5. Window Fails to Appear ΓòÉΓòÉΓòÉ
  16561.  
  16562. This error occurs when an application issues a WinCreateWindow() or 
  16563. WinCreateStdWindow() function call to create a display window, but the window 
  16564. fails to appear on the desktop, even though the function returns a valid window 
  16565. handle.  This error may result from either of two causes: 
  16566.  
  16567.    o  The WS_VISIBLE flag may not be set in the frame creation flags for the 
  16568.       window. 
  16569.  
  16570.    o  The application may include the FCF_ICON or FCF_ACCELTABLE frame creation 
  16571.       flags, but no icon or accelerator table resources are defined with 
  16572.       resource identifiers which match the window identifier. 
  16573.  
  16574.  In both cases, the WinCreateWindow or WinCreateStdWindow() function will 
  16575.  return a valid window handle, since the window has been created. 
  16576.  
  16577.  In the first case, the problem may be rectified by including the WS_VISIBLE 
  16578.  flag in the frame creation flags, or by using the WinShowWindow() function to 
  16579.  explicitly make the window visible. 
  16580.  
  16581.  In the second case, resources should be defined in the application's resource 
  16582.  script file to match the FCF_ICON and FCF_ACCELTABLE frame creation flags. 
  16583.  These resources must have identifiers that match the window identifier given 
  16584.  in the WinCreateWindow() or WinCreateStdWindow() calls, since Presentation 
  16585.  Manager uses this identifier to load the resources. 
  16586.  
  16587.  
  16588. ΓòÉΓòÉΓòÉ 24.3.2. Repetitive Action Problems ΓòÉΓòÉΓòÉ
  16589.  
  16590. Application errors that only reveal themselves after an action has been 
  16591. performed many times typically result from the application exceeding an 
  16592. operating system or Presentation Manager resource constraint.  Resources such 
  16593. as window handles, presentation spaces, memory objects and so on, have finite 
  16594. limits. If an application repeatedly requests allocation of such resources 
  16595. without releasing them, these limits may be exceeded, in which case the 
  16596. resource will not be allocated and the application may fail when attempting to 
  16597. use the resource. 
  16598.  
  16599. Such problems may manifest themselves as Trap 000D errors that will result in 
  16600. application termination, or may simply corrupt execution of the application. 
  16601. The effect is dependent upon the (invalid) contents of the resource handle when 
  16602. the application issues a function call that uses the resources.  In certain 
  16603. cases, a function call may cause the application to enter an endless loop 
  16604. within the processing of one message, in which case the entire Presentation 
  16605. Manager desktop may "lock up". 
  16606.  
  16607. This problem may be avoided by ensuring that all resource requests (DosGet...() 
  16608. and WinGet...() function calls) in the code are matched by corresponding 
  16609. DosRelease...() and WinRelease() function calls.  In accordance with the 
  16610. principle of encapsulating function, resources required for processing a 
  16611. particular message should be allocated, used and released during the processing 
  16612. of that message. 
  16613.  
  16614. An exception to this rule occurs in the case of resources such as control 
  16615. blocks, presentation spaces for display windows, etc.  These are typically 
  16616. allocated during processing of the WM_CREATE message, and persist throughout 
  16617. the life of the window, until released during processing of the WM_DESTROY 
  16618. message. 
  16619.  
  16620.  
  16621. ΓòÉΓòÉΓòÉ 24.4. Post-Resolution Action ΓòÉΓòÉΓòÉ
  16622.  
  16623. Once a problem has been identified and corrections made to the application, the 
  16624. resolution of the problem should be documented and placed, along with the 
  16625. original problem documentation, in some form of log.  In this way, similar 
  16626. problems encountered at a later date may be more easily identified and resolved 
  16627. by reference to the log. 
  16628.  
  16629.      Step #6 
  16630.  
  16631.      After resolving the problem, document the resolution for future reference. 
  16632.  
  16633.  Logging systems for such information may range widely in complexity and 
  16634.  sophistication, from simple paper files to automated database systems with 
  16635.  keyword search capabilities.  The level of system implemented by a development 
  16636.  organization is dependent upon cost and the perceived productivity benefit to 
  16637.  be gained from such information; organizations with an ongoing involvement in 
  16638.  the development of complex Presentation Manager applications will derive 
  16639.  greater benefits than those with only a single development project. 
  16640.  
  16641.  
  16642. ΓòÉΓòÉΓòÉ 24.5. Summary ΓòÉΓòÉΓòÉ
  16643.  
  16644. Problem determination in the Presentation Manager environment is similar to 
  16645. that for other application environments, and proceeds through a number of 
  16646. phases: 
  16647.  
  16648.    1. Documentation 
  16649.  
  16650.         a. Failing window 
  16651.  
  16652.         b. User action which caused the failure 
  16653.  
  16654.         c. Whether the failure occurs upon first performing the action, or only 
  16655.            upon repetitive actions 
  16656.  
  16657.    2. Isolation 
  16658.  
  16659.    3. Identification and resolution. 
  16660.  
  16661.  The documentation phase is normally part of the application testing cycle, and 
  16662.  is performed by those responsible for such testing.  No particular technical 
  16663.  or programming skills are required for this phase. 
  16664.  
  16665.  Proper documentation of the failure usually allows a developer to determine 
  16666.  the window procedure and message which caused the failure.  This provides a 
  16667.  useful starting point at which to search for the underlying problem. 
  16668.  
  16669.  The isolation phase is normally employed only for those failures that occur 
  16670.  every time a particular action is performed, and involves the use of a 
  16671.  symbolic debugging tool to single-step through the processing of the failing 
  16672.  message, in order to determine the statement in the source code at which the 
  16673.  error occurs. 
  16674.  
  16675.  Problems that occur only after many repetitions of a particular user action 
  16676.  normally indicate that an operating system or Presentation Manager resource 
  16677.  limit has been exceeded.  This is usually the result of an application 
  16678.  acquiring resources and failing to release them.  In such cases, the 
  16679.  resolution process may be expedited by immediately checking the processing of 
  16680.  the offending message for resource allocation statements, and ensuring that 
  16681.  each of these is matched by a corresponding statement that releases the 
  16682.  resource. 
  16683.  
  16684.  Once the problem is narrowed down to a single application statement, the 
  16685.  identification phase determines the cause of the problem and makes appropriate 
  16686.  corrections to the source code.  This phase requires familiarity with the OS/2 
  16687.  and Presentation Manager environments. 
  16688.  
  16689.  When the application has been corrected and submitted once more for testing, 
  16690.  the problem and its resolution should be documented and this information made 
  16691.  available for future problem determination activities. The availability of 
  16692.  such information may be used to more quickly determine likely causes of 
  16693.  similar problems in the future. 
  16694.  
  16695.  
  16696. ΓòÉΓòÉΓòÉ 25. Generic Application Modules ΓòÉΓòÉΓòÉ
  16697.  
  16698. As mentioned throughout this document, the Presentation Manager application 
  16699. model promotes the reuse of application objects, by facilitating code 
  16700. modularity through data abstraction and encapsulation. With correct design 
  16701. procedures, it is possible to create generic application objects that may be 
  16702. used by multiple applications.  Should subsequent applications require 
  16703. modification to allow different processing of particular message classes, this 
  16704. may be achieved through subclassing. The Workplace Shell application model 
  16705. introduced in OS/2 Version 2.0 provides even more potential for reuse, due to 
  16706. its enhanced support of inheritance and subsequently enhanced provision for 
  16707. object reuse. 
  16708.  
  16709. Standardization and reuse of application code promotes consistency between 
  16710. applications in terms of processing techniques and user interfaces, and helps 
  16711. to enforce organizational programming and interface design standards. It also 
  16712. reduces the amount of new code required for applications, potentially 
  16713. shortening development time, and the use of previously developed and tested 
  16714. code may also decrease application testing time. 
  16715.  
  16716. In situations where reusability at the application object level is either not 
  16717. possible or impractical, common application functions may still be developed as 
  16718. subroutines, and placed in libraries for access by multiple applications.  The 
  16719. use of such subroutines reduces application development time. 
  16720.  
  16721. This chapter examines the creation of such generic objects and subroutines 
  16722. within the Presentation Manager application model, and their placement in 
  16723. dynamic link libraries for subsequent use by applications.  Since Workplace 
  16724. Shell objects are by definition placed in DLLs and available for reuse, they 
  16725. are not explicitly discussed in this chapter. 
  16726.  
  16727.  
  16728. ΓòÉΓòÉΓòÉ 25.1. Generic Application Objects ΓòÉΓòÉΓòÉ
  16729.  
  16730. Within the Presentation Manager application model, a window procedure provides 
  16731. both the definition of a data object and the methods that operate upon that 
  16732. data object.  A window procedure may therefore be considered as a complete 
  16733. application object in its own right. 
  16734.  
  16735. Where the data object to be manipulated by a window will be accessed by a 
  16736. number of applications, it makes sense to define the data object and its 
  16737. methods once, in a single window procedure, and to make that window procedure 
  16738. available to any application that needs to manipulate the data object.  Any 
  16739. changes to the data object's characteristics or processing requirements can 
  16740. then be contained within the application object, avoiding the need to modify 
  16741. and recompile multiple applications.  The dynamic linking capabilities of OS/2 
  16742. facilitate such a technique, enabling such modifications to be automatically 
  16743. incorporated into applications at load time or run time. 
  16744.  
  16745.  
  16746. ΓòÉΓòÉΓòÉ 25.1.1. Display Windows ΓòÉΓòÉΓòÉ
  16747.  
  16748. A display window may be created as a generic application object, and its window 
  16749. procedure placed in a dynamic link library.  The following steps are typically 
  16750. followed in creating such a window procedure: 
  16751.  
  16752.    1. Both the window procedure and a calling routine to create the window are 
  16753.       written in the normal manner. 
  16754.  
  16755.    2. The routine containing the code to create the window is declared as an 
  16756.       exportable entry point, and may thus be called by applications. 
  16757.  
  16758.    3. This routine returns the handle of the newly created window to the 
  16759.       calling application, along with a success or failure code. 
  16760.  
  16761.    4. The source code is compiled and link edited as described in Creating a 
  16762.       DLL. 
  16763.  
  16764.  The calling application then simply issues a single function call, such as: 
  16765.  
  16766.   usSuccess = CreateEditWindow(hEdit);
  16767.  
  16768.  The CreateEditWindow() function within the DLL handles all necessary 
  16769.  operations including registration of the window class and creation of the 
  16770.  window, places the resulting window handle in the address indicated by the 
  16771.  hEdit parameter, and returns a success or failure code (usSuccess) to the 
  16772.  calling application. 
  16773.  
  16774.  Note, however, that the above example assumes that the window is created with 
  16775.  a predetermined title, size and position on the desktop.  Should this not be 
  16776.  the case, additional parameters to the CreateWindow() function would be 
  16777.  required. 
  16778.  
  16779.  The definition of the CreateEditWindow() function as the only entry point in 
  16780.  the DLL enforces the consistency of using this function.  The calling 
  16781.  application is still provided with the window handle, which allows it to 
  16782.  communicate with the window and to subclass the window if required. 
  16783.  
  16784.  
  16785. ΓòÉΓòÉΓòÉ 25.1.2. Object Windows ΓòÉΓòÉΓòÉ
  16786.  
  16787. Object windows may be created and placed into dynamic link libraries in a 
  16788. similar manner to that already explained for display windows.  However, object 
  16789. windows have an additional complication in that they are frequently created in 
  16790. secondary threads in order to handle long-running application tasks. 
  16791.  
  16792. The steps in creating an object window for inclusion in a DLL are therefore as 
  16793. follows: 
  16794.  
  16795.    1. The window procedure, the calling routine to create the window and a 
  16796.       routine to start the secondary thread from which the window is created, 
  16797.       are written in the normal manner, as described in Threads Containing 
  16798.       Object Windows. 
  16799.  
  16800.    2. The routine containing the code to start the secondary thread is declared 
  16801.       as an exportable entry point, and may thus be called by applications. 
  16802.  
  16803.    3. The source code is compiled and link edited as described in Creating a 
  16804.       DLL. 
  16805.  
  16806.  Note that the routine called by the application does not return the handle of 
  16807.  the newly created window.  Indeed, it cannot do so, since the creation of the 
  16808.  window takes place asynchronously, in a secondary thread. 
  16809.  
  16810.  This obstacle is overcome by having the calling application (typically a 
  16811.  window procedure) pass its own window handle as a parameter.  This is passed 
  16812.  to the object window, which then passes an acknowledgement message to the 
  16813.  calling window procedure, containing its window handle.  The calling window 
  16814.  procedure may subsequently communicate with or subclass the object window as 
  16815.  required.  This technique is described, along with an example, in Threads 
  16816.  Containing Object Windows. 
  16817.  
  16818.  
  16819. ΓòÉΓòÉΓòÉ 25.1.3. Subclassing ΓòÉΓòÉΓòÉ
  16820.  
  16821. When a generic application object (that is, window class) does not quite meet 
  16822. the requirements of an application, a developer may choose to use the generic 
  16823. object and modify its behavior, through subclassing, to meet the specific 
  16824. requirements.  This may be easily achieved in conjunction with the methods 
  16825. described above, since the handle of the newly created window is either 
  16826. returned directly by the called routine or indirectly by the window itself. 
  16827. This handle can then be used in the WinSubclassWindow() function call. 
  16828.  
  16829. The subject of subclassing is described in detail in Subclassing a Window, 
  16830. along with examples of both the WinSubclassWindow() function and a subclass 
  16831. window procedure. 
  16832.  
  16833.  
  16834. ΓòÉΓòÉΓòÉ 25.2. Dialog Boxes ΓòÉΓòÉΓòÉ
  16835.  
  16836. Standard dialog boxes to handle commonly performed user dialogs may also be 
  16837. generated and placed in dynamic link libraries.  The inclusion of a dialog box 
  16838. in a DLL however, is slightly more complicated than the inclusion of a "normal" 
  16839. display or object window, due to the definition of the dialog template as a 
  16840. Presentation Manager resource.  The DLL must therefore include not only the 
  16841. dialog procedure and the invoking routine, but also the dialog template 
  16842. definition. 
  16843.  
  16844. This necessitates the invoking routine within the DLL not only executing the 
  16845. WinDlgBox() function call, but also obtaining a module handle for the DLL and 
  16846. an entry point address for the dialog procedure.  The necessary steps are as 
  16847. follows: 
  16848.  
  16849.    1. The dialog procedure and the invoking routine are developed and placed in 
  16850.       a dynamic link library. 
  16851.  
  16852.    2. The invoking routine is declared as an exportable entry point and may 
  16853.       thus be called by applications. 
  16854.  
  16855.    3. The dialog template is created using the Dialog Box Editor, resource 
  16856.       compiled and combined with the DLL. 
  16857.  
  16858.  The invoking routine for a dialog box loaded from a DLL is described, along 
  16859.  with an example, in Loading a Dialog Resource From a DLL. 
  16860.  
  16861.  
  16862. ΓòÉΓòÉΓòÉ 25.3. Generic Subroutines ΓòÉΓòÉΓòÉ
  16863.  
  16864. In addition to code reuse at the application object level, significant 
  16865. productivity gains can be achieved by the reuse of application code at the 
  16866. subroutine level, to carry out common operating system and Presentation Manager 
  16867. functions. 
  16868.  
  16869. For example, initialization functions are required to perform tasks related to 
  16870. initializing the Presentation Manager environment and any data areas to be used 
  16871. by utility routines.  Functions required to be performed include: 
  16872.  
  16873.    o  Registration of the application to Presentation Manager 
  16874.    o  Creation of a message queue 
  16875.    o  Creation of an entry in the Workplace Shell Window List. 
  16876.  
  16877.  These functions may be combined into one or more standard initialization 
  16878.  routines, which may be invoked upon entry to an application or thread. 
  16879.  Examples of the necessary code are given in Sample Application Main Routine 
  16880.  (Part 1) - Registration, Sample Application Main Routine (Part 2) - Window 
  16881.  Creation and WinAddSwitchEntry() Function. 
  16882.  
  16883.  Termination functions required by Presentation Manager applications could also 
  16884.  be standardized;  these functions include: 
  16885.  
  16886.    o  Removing the application from the Workplace Shell Window List 
  16887.    o  Destroying the application's main window 
  16888.    o  Destroying the primary thread's message queue 
  16889.    o  Deregistration of the application from the Presentation Manager 
  16890.       environment. 
  16891.  
  16892.  These operations are performed by Presentation Manager upon termination of the 
  16893.  application if the application does not perform them explicitly.  However, it 
  16894.  is recommended that the application carries out these actions, since they may 
  16895.  then be achieved in a controlled manner.  Examples of the necessary code are 
  16896.  given in Sample Application Main Routine (Part 2) - Window Creation. 
  16897.  
  16898.  Other functions may often be required during the execution of an application, 
  16899.  such as: 
  16900.  
  16901.    o  Obtaining the window handle of the application's main client window. An 
  16902.       example of this procedure is given in Identifying the Destination Window. 
  16903.  
  16904.    o  Passing a message from a subclass window procedure to the original window 
  16905.       procedure for that window class.  An example is given in Subclass Window 
  16906.       Procedure. 
  16907.  
  16908.  These functions may also be combined into standard subroutines and placed in a 
  16909.  library, thereby avoiding the need for application developers to repetitively 
  16910.  code such functions. 
  16911.  
  16912.  A final function often used in the stepwise development of object-oriented 
  16913.  Presentation Manager applications is a small routine to display a message box 
  16914.  with the message "Action Not Yet Implemented", invoked when the user selects a 
  16915.  menu bar or pulldown entry for which a method has not yet been coded.  This 
  16916.  function is typically invoked as the default case for the WM_COMMAND message 
  16917.  class.  In this way, methods within a window procedure may be implemented in a 
  16918.  stepwise manner, and testing of existing methods may occur while new ones are 
  16919.  being added.  Selecting an action for which no method has yet been implemented 
  16920.  will always result in the same message box being displayed. 
  16921.  
  16922.  
  16923. ΓòÉΓòÉΓòÉ 25.4. Granularity ΓòÉΓòÉΓòÉ
  16924.  
  16925. When placing generic code in a dynamic link library, whether that code is at 
  16926. the application object level or at the functional level, the question arises as 
  16927. to the way in which the code should be partitioned into individual DLL modules, 
  16928. and thus the level of granularity that will be achieved within the reusable 
  16929. code. 
  16930.  
  16931. This decision must be made on the basis of interdependence; where routines are 
  16932. interdependent and are required or likely to be used together, it is advisable 
  16933. to place them in a single dynamic link library.  For example, a group of 
  16934. standard window manipulation routines would typically reside in single DLL. 
  16935.  
  16936. However, generic application objects should bear no predefined relationship to 
  16937. one another, and generic window classes may therefore be used independently. 
  16938. In such a case, the window procedure and invoking routine for each window class 
  16939. should be placed in a separate DLL, along with any subroutines specific to that 
  16940. window procedure.  Applications that desire to use more than one such 
  16941. application object may then access multiple DLLs. 
  16942.  
  16943.  
  16944. ΓòÉΓòÉΓòÉ 25.5. Packaging ΓòÉΓòÉΓòÉ
  16945.  
  16946. When a set of application objects and/or subroutines has been created and 
  16947. placed into a dynamic link library, the following items will have been 
  16948. generated: 
  16949.  
  16950.    o  The dynamic link library containing the application objects and/or 
  16951.       subroutines 
  16952.  
  16953.    o  A header file containing declarations for the routines that will be 
  16954.       called by applications in order to create the application objects or 
  16955.       invoke the subroutines 
  16956.  
  16957.    o  An import library file, containing entry point definitions for those 
  16958.       routines that will be called by applications. 
  16959.  
  16960.  These items must be stored in a location from which application developers may 
  16961.  access them.  The use of a local area network to provide and manage access to 
  16962.  such items is discussed in Managing Development. 
  16963.  
  16964.  In addition, appropriate entries must be included in an interface control 
  16965.  document, which defines all common application objects and subroutines along 
  16966.  with their external interfaces, and acts as a reference for application 
  16967.  developers who wish to use such objects or routines. 
  16968.  
  16969.  
  16970. ΓòÉΓòÉΓòÉ 25.6. Summary ΓòÉΓòÉΓòÉ
  16971.  
  16972. The Presentation Manager application model affords the opportunity for 
  16973. significant standardization and reuse of application code, at both the 
  16974. application object and function levels.  The dynamic linking facilities 
  16975. provided by OS/2 allow this capability to be carried over to executable code as 
  16976. well as source code.  Such reusability reduces the amount of new code required 
  16977. for applications, thereby reducing the development time and cost of new 
  16978. applications. 
  16979.  
  16980. Common application elements such as windows and dialogs may be defined and 
  16981. stored in dynamic link libraries for access by one or more applications, thus 
  16982. implementing reusability at the application object or dialog level. At a lower 
  16983. level, a large number of common Presentation Manager application tasks may be 
  16984. identified, which may also be placed in standard routines for purposes of 
  16985. enhancing programmer productivity. 
  16986.  
  16987. A further benefit of using standardized routines is the improvement in the 
  16988. consistency of both the application code and the user interface.  Such 
  16989. standardization provides an easy means of enforcing Systems Application 
  16990. Architecture CUA standards without the need for programmers to repetitively 
  16991. code definitions for an CUA-conforming user interface.  In addition, the 
  16992. standardized implementation of various functions and techniques eases the task 
  16993. of application maintenance, since all applications will behave in a similar 
  16994. manner through the use of common code. 
  16995.  
  16996. Although the functions mentioned in this chapter are restricted to Presentation 
  16997. Manager functions, the same principles may be applied to other functions, 
  16998. dialogs etc., which are common to multiple applications within the 
  16999. organization. The creation of standard routines for such functions, and the 
  17000. incorporation of these routines into dynamically linked modules under OS/2, may 
  17001. enhance the modularity and granularity of applications and bring additional 
  17002. benefits through reduced development time for new applications, and through 
  17003. easier application maintenance and change management. 
  17004.  
  17005.  
  17006. ΓòÉΓòÉΓòÉ 26. Managing Development ΓòÉΓòÉΓòÉ
  17007.  
  17008. In order to enable the implementation of large-scale applications in the 
  17009. programmable workstation environment, with multiple application developers 
  17010. participating in design, coding and testing, it is important not only to have 
  17011. an appropriate technological and architectural base for development, but also 
  17012. to provide appropriate and effective management of and control over the 
  17013. development process and development resources.  Established techniques exist in 
  17014. the host-based application development environment for addressing such issues, 
  17015. but historically, the considerations of large-scale management and control have 
  17016. been overlooked in the workstation environment due to the relatively minor 
  17017. nature of workstation-based development projects in the past. 
  17018.  
  17019. Two areas worthy of note in the workstation-based development environment are 
  17020. the management of developmental risk, and the management and control of 
  17021. development resources that are used and created during the application 
  17022. development process.  This chapter will briefly describe these issues and offer 
  17023. some suggestions as to how they may be effectively resolved.  Much of the 
  17024. discussion in this chapter will deal with Presentation Manager applications 
  17025. written using the C programming language, but the techniques described may be 
  17026. adapted to suit other environments and programming languages. 
  17027.  
  17028.  
  17029. ΓòÉΓòÉΓòÉ 26.1. Risk Management ΓòÉΓòÉΓòÉ
  17030.  
  17031. In any application development project, there are risks imposed by the use of 
  17032. new technologies and methods.  These risks may be divided into two basic types: 
  17033.  
  17034.    o  Technological risk; that which is imposed by new or unfamiliar 
  17035.       technologies which will be used in an application or during the creation 
  17036.       of the application. 
  17037.  
  17038.    o  Managerial risk; that which arises from the lack of established 
  17039.       management techniques to support new technologies and methods. 
  17040.  
  17041.  These two elements of risk are closely related, and affect one another in a 
  17042.  variety of ways.  The following sections discuss both elements and suggest 
  17043.  some mechanisms for their mitigation. 
  17044.  
  17045.  
  17046. ΓòÉΓòÉΓòÉ 26.1.1. Technological Risk ΓòÉΓòÉΓòÉ
  17047.  
  17048. Technological risks may take a wide variety of forms, and vary from simple 
  17049. risks to highly complex instances involving the interrelationship of many 
  17050. divergent technologies.  Some relatively simple examples of technological risk 
  17051. are: 
  17052.  
  17053.    o  Use of a new prototyping tool 
  17054.  
  17055.    o  Use of a programming language other than that which is normally used by 
  17056.       the particular development organization 
  17057.  
  17058.    o  Use of a new programming interface 
  17059.  
  17060.    o  Incorporation of new analysis techniques for the gathering of 
  17061.       requirements. 
  17062.  
  17063.  The element of risk in the incorporation of new technologies arises from the 
  17064.  simple fact that they are new, and likely to be unfamiliar to the majority of 
  17065.  development personnel.  A period of learning will be necessary, and the 
  17066.  probable length of this period must be assessed in the light of required 
  17067.  development schedules.  Technological risk is always greater where new 
  17068.  techniques and procedures must be evolved in order to support and exercise the 
  17069.  new technologies, since elements of managerial risk are then involved.  Simple 
  17070.  technological tools are relatively easy to learn and use, but techniques for 
  17071.  their effective employment are often learned over a longer period. 
  17072.  
  17073.  The decision as to whether to utilize new technologies in a development 
  17074.  project must be based upon the question of whether the development 
  17075.  organization possesses the requisite skills to effectively exercise the new 
  17076.  technologies, or can acquire such skills within the timeframe of the 
  17077.  development project, without adversely affecting the schedule and budget of 
  17078.  the project.  If the first question can be answered in the positive, there is 
  17079.  no risk involved; if not, then it is the second question that constitutes the 
  17080.  element of risk. 
  17081.  
  17082.  Technological risk may be mitigated by ensuring that development personnel 
  17083.  possess the necessary skills to effectively utilize the new technologies, 
  17084.  through the provision of relevant education.  The potential benefit to be 
  17085.  gained from the use of these technologies must be identified and quantified, 
  17086.  in terms of enhanced application functionality, reduced development time and 
  17087.  cost, etc.  This benefit must be weighed against the time and cost involved in 
  17088.  training personnel to a sufficient skill level in order to effectively 
  17089.  mitigate the risk, and against the schedule and budget imposed upon the 
  17090.  development organization. 
  17091.  
  17092.  Technological risk may also be mitigated by minimizing the managerial risk 
  17093.  involved in the use of new technologies.  If established managerial techniques 
  17094.  can be adapted and applied to the implementation of new technologies, the use 
  17095.  of these mechanisms may provide a greater degree of control over the 
  17096.  development process, and help to control and reduce the associated 
  17097.  technological risk.  Thus it can be seen that technological and managerial 
  17098.  risk are closely related and complimentary to one another. 
  17099.  
  17100.  
  17101. ΓòÉΓòÉΓòÉ 26.1.2. Managerial Risk ΓòÉΓòÉΓòÉ
  17102.  
  17103. Managerial risk is somewhat more complex than technological risk, since it 
  17104. involves the effective administration of and control over the use of new 
  17105. technologies. While it is possible to train or employ development personnel in 
  17106. order to gain the required skills in the use of new technologies, it is less 
  17107. easy to obtain the managerial skills necessary to ensure the maximum benefit is 
  17108. gained from their use. 
  17109.  
  17110. Like technological risk, managerial risk may also vary from the relatively 
  17111. simple to the highly complex.  Some examples of managerial risk are: 
  17112.  
  17113.    o  Transformation of new analysis techniques into application design 
  17114.       specifications 
  17115.  
  17116.    o  Establishment of effective control procedures for a new development 
  17117.       environment 
  17118.  
  17119.    o  Measurement of programmer productivity when using a new programming tool 
  17120.       or language. 
  17121.  
  17122.  The managerial risk arises not from the question of whether sufficient skills 
  17123.  are present to utilize new technologies, but from the question of whether 
  17124.  managerial personnel are sufficiently well-versed in the concepts underlying 
  17125.  these technologies to provide effective administration and control over the 
  17126.  use of the technologies, in order to ensure that maximum benefit is gained 
  17127.  from their use. 
  17128.  
  17129.  Managerial risk may be mitigated by ensuring that managerial personnel possess 
  17130.  a sufficient grounding in the principles underlying new technologies, in order 
  17131.  that they may successfully adapt existing managerial techniques to the 
  17132.  administration and control of the new technologies. These skills may be 
  17133.  acquired in a similar manner to the technological skills required by 
  17134.  programmers, through training and familiarity with the technologies involved. 
  17135.  The decision must be made as to whether the benefit to be gained from the use 
  17136.  of these technologies is sufficient to offset the time and effort involved in 
  17137.  acquiring the necessary skills and establishing the managerial techniques to 
  17138.  effectively control their use. 
  17139.  
  17140.  Managerial risk may also be mitigated by reducing the associated technological 
  17141.  risk.  For example, a new technology such as object-oriented programming 
  17142.  principles can be implemented using tools such as the C programming language 
  17143.  and Presentation Manager.  There is likely to be a higher degree of 
  17144.  familiarity with such tools in the development organization than with tools 
  17145.  such as C++ or Smalltalk V.  Therefore, implementation of object-oriented 
  17146.  principles may be more effectively controlled by the application of 
  17147.  established managerial techniques for C application development.  While this 
  17148.  will not eliminate the element of risk altogether, it will significantly 
  17149.  reduce the managerial risk involved, and also help to mitigate the 
  17150.  technological risk by facilitating effective control over the development 
  17151.  process. 
  17152.  
  17153.  
  17154. ΓòÉΓòÉΓòÉ 26.2. Configuration/Library Management ΓòÉΓòÉΓòÉ
  17155.  
  17156. While the same techniques of management are valid in both host and workstation 
  17157. environments, the distributed nature of the workstation environment presents 
  17158. difficulties for the centralized control and administration of development 
  17159. resources.  This section provides some suggestions as to the ways in which a 
  17160. local area network (LAN) may be used to provide centralized control and 
  17161. administration to a workstation-based application development environment. 
  17162.  
  17163. In the case of C language applications developed for the Presentation Manager 
  17164. environment, development resources include: 
  17165.  
  17166.    o  Application source modules.  An application source module is defined to 
  17167.       comprise not only the source code itself, but also the local and external 
  17168.       interface include files that accompany the source code (see Application 
  17169.       Program Construction). 
  17170.  
  17171.    o  Existing code libraries; these may need to be modified or additional 
  17172.       routines generated in order to meet the requirements of the application. 
  17173.  
  17174.    o  Presentation Manager resources such as icons, fonts, bitmaps and dialog 
  17175.       definitions. 
  17176.  
  17177.    o  Test data sets or databases. 
  17178.  
  17179.    o  Compilers, link-editors, run-time libraries and other development tools; 
  17180.       in an evolving development environment, it is crucial to ensure that all 
  17181.       development personnel use the same version and modification level of 
  17182.       compiler and linkage editor software, and that programming language 
  17183.       runtime libraries are consistent in their version. 
  17184.  
  17185.  These resources must be created, tested and placed in locations from which 
  17186.  they may be accessed easily and concurrently by a number of application 
  17187.  developers, while at the same time maintaining adequate control over their 
  17188.  access and particularly over any modifications made to individual modules. 
  17189.  
  17190.  A LAN provides a useful means of enabling access by multiple developers to a 
  17191.  common repository of application resources.  The ways in which a LAN may be 
  17192.  used to address the configuration management issues arising from the PWS 
  17193.  development environment are described in the following sections. 
  17194.  
  17195.  
  17196. ΓòÉΓòÉΓòÉ 26.2.1. Terminology ΓòÉΓòÉΓòÉ
  17197.  
  17198. In the subsequent discussion of configuration and library management, the 
  17199. following terminology will be used.  The term application resource will be used 
  17200. to indicate a particular development resource such as a source module (along 
  17201. with its supporting include file), a custom-developed dynamic link library 
  17202. (that is, a dynamic link library not taken from a group of generic library 
  17203. modules), a Presentation Manager resource such as an icon or dialog definition 
  17204. etc., which is specific to the current application.  Other development 
  17205. resources such as compilers, link-editors, programmers' toolkits, generic code 
  17206. libraries and so on, may be used in the development of an application, but are 
  17207. not considered to be application resources. 
  17208.  
  17209. The term production level will be used to indicate a version of an application 
  17210. resource that has been created, tested and approved for placement in a 
  17211. production library.  The process of testing and subsequent approval for 
  17212. placement in a production library is called baselining. 
  17213.  
  17214. The term user level will be used to indicate a version of an application 
  17215. resource that is currently undergoing modification, and has not been either 
  17216. tested or placed in a production library.  The actual transfer of an 
  17217. application resource from a developer's local work library to a production 
  17218. library is called promotion. 
  17219.  
  17220.  
  17221. ΓòÉΓòÉΓòÉ 26.2.2. Network Organization ΓòÉΓòÉΓòÉ
  17222.  
  17223. The topology of a local area network is very much determined by the structure 
  17224. of the development organization, and by the size and nature of the projects 
  17225. undertaken by that organization.  The techniques of LAN installation, 
  17226. configuration and management are beyond the scope of this document.  However, 
  17227. it is possible to formulate some simple guidelines which facilitate management 
  17228. of the development process. 
  17229.  
  17230. Local area networks are typically divided into logical partitions known as 
  17231. domains.  A domain is defined as a logical subgroup of a network, which 
  17232. contains a defined group of network nodes (machines), a defined set of network 
  17233. resources such as shared disks, directories and printers, and a defined set of 
  17234. authorized users.  Each domain thus forms a logical network in its own right, 
  17235. and multiple domains may exist on a single physical network.  A domain may 
  17236. include resources residing on multiple network server nodes, and multiple 
  17237. domains may access the resources of any particular server.  Each user on the 
  17238. network is provided with a unique user ID and password.  An application 
  17239. developer may be defined as an authorized user of multiple domains within the 
  17240. same physical network; the same or different user IDs and passwords may be 
  17241. used. 
  17242.  
  17243. Network Domains 
  17244.  
  17245. NetworkDomainsillustratesanetworkwiththreedomains 
  17246. ,eachcontaininganumberofnetworknodes . Eachdomainhasoneormoreservernodes( 
  17247. markedS )uponwhichresidesharedresourcesaccessiblebyusersonothernodes 
  17248. .Notethattheserversmaybeaccessedfromwithinasingledomainorfrommultipledomains 
  17249. ,andthatothernetworknodesmayalsobelongtomultipledomains 
  17250. . Notealsothatthereisnodirectmappingbetweenanetworknodeandanetworkuser 
  17251. ;ausermay ,inprinciple 
  17252. ,signonandaccessserverresourcesfromanynetworknodeinthedomain .
  17253.  
  17254. Assuming a project-team orientation in the development organization, it is 
  17255. expedient to logically group the members of a particular project team, in order 
  17256. that they may be treated as a distinct group and separated from other project 
  17257. teams for purposes of resource access and administration. 
  17258.  
  17259. In the simplest case, a number of project teams in the same physical location 
  17260. would use the same physical network, partitioned into separate domains for each 
  17261. project team.  Each domain would possess its own set of production libraries 
  17262. for application resources; other development resources such as compilers and 
  17263. generic code libraries, which are common across the entire development 
  17264. organization, would be stored in a production library on a single server, and 
  17265. defined within all domains.  This technique provides isolation of application 
  17266. resources while also allowing common access to other development resources, and 
  17267. eases the task of maintaining and updating these common resources since only 
  17268. one copy need exist on the network. 
  17269.  
  17270. The principle of one domain per project team is obviously a "rule of thumb" and 
  17271. must be evaluated in light of the individual development organization. In the 
  17272. case of very large projects, it may be necessary to subdivide the project team 
  17273. into manageable subgroups.  This would probably be necessary purely for 
  17274. managerial purposes, irrespective of whether a LAN were to be used. 
  17275. Conversely, very small project teams may not warrant the effort of establishing 
  17276. a separate domain, and several such small teams may be combined in a single 
  17277. management unit with a single network domain. 
  17278.  
  17279.  
  17280. ΓòÉΓòÉΓòÉ 26.2.3. Common Access to Resources ΓòÉΓòÉΓòÉ
  17281.  
  17282. On a local area network server node, directories may be created that act as 
  17283. production libraries.  Production libraries for a particular development 
  17284. project may exist on one or more network server nodes, depending upon the size 
  17285. and organization of the LAN. 
  17286.  
  17287. These libraries serve as repositories for the current production-level versions 
  17288. of all development resources.  The exact number and type of libraries created 
  17289. is highly dependent upon the structure of the development organization and the 
  17290. application under development, but the following skeleton structure is 
  17291. recommended. 
  17292.  
  17293.   Server Root Directory ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇ Compilers and link-editors
  17294.               Γöé
  17295.               Γö£ΓöÇΓöÇΓöÇ Application source code
  17296.               Γöé
  17297.               Γö£ΓöÇΓöÇΓöÇ Application include files
  17298.               Γöé
  17299.               Γö£ΓöÇΓöÇΓöÇ Presentation Manager resources
  17300.               Γöé
  17301.               Γö£ΓöÇΓöÇΓöÇ Installation code libraries
  17302.               Γöé
  17303.               ΓööΓöÇΓöÇΓöÇ Test data
  17304.  
  17305. Production Libraries on a LAN Server 
  17306.  
  17307. All application developers should be given read-only access to production 
  17308. libraries.  This will enable those developers to access compilers, link-editors 
  17309. and programming language run-time libraries, and to access the current 
  17310. production-level versions of application source modules, Presentation Manager 
  17311. resources and test data, but not to update those production versions. 
  17312.  
  17313. Application resources currently undergoing modification (that is, user level 
  17314. resources) are held in a work directory on the developer's own workstation, 
  17315. from which only that developer may access them.  This restriction of access is 
  17316. implicit since only appropriately declared and configured server nodes may 
  17317. share their disks and directories on the network. 
  17318.  
  17319. Production level application resources may be transparently accessed at compile 
  17320. or link-edit time by ensuring that each developer's compiler search path 
  17321. specifies the production libraries.  The search path should first specify an 
  17322. application developer's local work directory, in order to pick up any user 
  17323. level resources currently being worked upon by that developer, and then search 
  17324. the appropriate production libraries in order to pick up production level 
  17325. copies of other resources not currently subject to modification by that 
  17326. developer.  This technique ensures that each application build accesses the 
  17327. latest tested and baselined versions of all application resources, except for 
  17328. those resources that exist in the developer's local work directory, and that 
  17329. are therefore likely to be under test. 
  17330.  
  17331. Each application resource should have an owner appointed at the start of 
  17332. development.  This owner may be the application developer primarily responsible 
  17333. for the creation of a source module, or in the case of larger and more complex 
  17334. development projects, may be a developer responsible for the testing of a 
  17335. number of modules that together comprise a coherent code unit.  In either case, 
  17336. the owner is given update access to the files in the production libraries that 
  17337. comprise the module or modules under his/her jurisdiction, and only to those 
  17338. files.  The updating of each application resource may then be achieved in a 
  17339. controlled manner. 
  17340.  
  17341. This assumes that the name of the file or files containing each application 
  17342. resource is known at the outset of development.  This in turn requires a sound 
  17343. approach to application design and to the correct partitioning of the 
  17344. application at the design stage.  It also requires the adoption of a set of 
  17345. file or data set naming conventions across the development organization. 
  17346.  
  17347.  
  17348. ΓòÉΓòÉΓòÉ 26.2.4. Update/Modification of Resources ΓòÉΓòÉΓòÉ
  17349.  
  17350. When an application developer wishes to make a modification to an application's 
  17351. resources, those resources should be copied from the production library to the 
  17352. developer's local work directory.  This is known as drawdown, and must be 
  17353. recorded, including the date, time, the identity of the developer and the name 
  17354. of the module being copied.  This recording process is known as checkout.  Only 
  17355. one developer at any time must be allowed to check out and draw down a 
  17356. particular module, in order to avoid the problems inherent in the well-known 
  17357. simultaneous update situation. Control over checkouts may be achieved in a 
  17358. number of ways.  However, it is recommended that the drawdown process be 
  17359. achieved by way of a simple utility application that performs the following 
  17360. steps: 
  17361.  
  17362.    1. Accesses a central database that contains the name of each application 
  17363.       resource under development, and determines whether that resource is 
  17364.       currently checked out. 
  17365.  
  17366.    2. If the resource has been checked out, the utility application returns the 
  17367.       identity of the developer by whom the resource has been checked out 
  17368.  
  17369.    3. If the resource has not been checked out, the utility application 
  17370.       performs a checkout operation, recording the identity of the application 
  17371.       developer and that of the application resource in the central database, 
  17372.       and draws down the application resource into the developer's local work 
  17373.       directory, ready for modification. 
  17374.  
  17375.  When modification of a resource is complete and the resource has been 
  17376.  adequately tested, the user level version should be passed to the resource's 
  17377.  owner who, after determining that appropriate testing has been satisfactorily 
  17378.  carried out, should then promote the new version to production level, ready 
  17379.  for access by other developers. 
  17380.  
  17381.  When a user level version of an application resource is consigned to the 
  17382.  resource owner, that version must be deleted from the developer's local work 
  17383.  directory, in order to ensure that only the latest production level version is 
  17384.  accessed by the compiler or link editor during the next build. This operation 
  17385.  may be automated as part of the promotion process, or may be left as an 
  17386.  explicit task for the developer. 
  17387.  
  17388.  
  17389. ΓòÉΓòÉΓòÉ 26.2.5. Administration ΓòÉΓòÉΓòÉ
  17390.  
  17391. As in any multi-user environment, some degree of system administration is 
  17392. necessary in a LAN environment.  When a LAN is used to provide a workstation 
  17393. application development platform, the LAN administrator must perform the 
  17394. following duties: 
  17395.  
  17396.    o  At the outset of development for a particular application, create a 
  17397.       network domain for that development project.  This is optional, and it 
  17398.       may be considered expedient to combine a number of smaller projects into 
  17399.       a single network domain. 
  17400.  
  17401.    o  Create the production libraries for the project's network domain. 
  17402.  
  17403.    o  Register each developer as a user of the project's network domain, and 
  17404.       define each developer to have read-only access to production libraries. 
  17405.  
  17406.    o  Provide the appointed owner of each application resource with write 
  17407.       access to the resource or resources under his/her jurisdiction. 
  17408.  
  17409.    o  In the case where an application resource has been checked out and 
  17410.       remains checked out for an unnecessary length of time (for example, a 
  17411.       developer checks out a resource and then goes on vacation without first 
  17412.       submitting the new version for promotion), provide an override capability 
  17413.       to cancel the checkout. 
  17414.  
  17415.  It is recommended that the LAN administrator be the same person responsible 
  17416.  for administration of the production libraries that contain system software 
  17417.  such as compilers and link-editors, in order to place all such system 
  17418.  administration responsibilities with the same person. 
  17419.  
  17420.  
  17421. ΓòÉΓòÉΓòÉ 26.3. Summary ΓòÉΓòÉΓòÉ
  17422.  
  17423. The management and mitigation of risk during the application development 
  17424. process is an important aspect of managing application development, 
  17425. particularly where new or unfamiliar technologies are to be used.  There are 
  17426. two closely related elements of risk that arise from the incorporation of new 
  17427. technologies.  These are technological risk, which arises from the need for 
  17428. adequate skills to exercise the technologies, and managerial risk, which arises 
  17429. from the need for adequate administration and control mechanisms to ensure that 
  17430. maximum benefit is gained from the use of the technologies.  It is the 
  17431. responsibility of a development manager to assess, quantify and weigh the 
  17432. potential benefits of new technologies against the risk involved in their use, 
  17433. and to provide adequate mitigation of these risks. 
  17434.  
  17435. The issue of configuration management in a distributed, workstation-based 
  17436. development environment is another issue that must be addressed in order to 
  17437. support the large-scale development of workstation-based applications.  The use 
  17438. of a local area network as a development platform for such applications has a 
  17439. number of benefits, particularly from the viewpoint of configuration management 
  17440. and control over application resources such as source code, Presentation 
  17441. Manager resources, test data and the like.  The use of a LAN provides: 
  17442.  
  17443.    o  Common access by all developers to production level versions of 
  17444.       application resources 
  17445.  
  17446.    o  The ability to directly access these production level versions during the 
  17447.       build process 
  17448.  
  17449.    o  The ability to combine production level versions with user level versions 
  17450.       of application resources during the build process 
  17451.  
  17452.    o  The ability to manage and regulate the modification and update of 
  17453.       production level application resources. 
  17454.  
  17455.  The proper use of a LAN in the workstation-based development environment, and 
  17456.  the achievement of the aforementioned benefits, requires the adoption of and 
  17457.  adherence to a consistent set of standards in the areas of module naming, 
  17458.  access and testing, and a measure of discipline on the part of application 
  17459.  developers.  However, it is considered that the increased time and effort 
  17460.  expended in maintaining these standards is more than offset by the reduced 
  17461.  incidence of error and wastage of development time and effort imposed by the 
  17462.  lack of adequate coordination and control in a multi-developer project. 
  17463.  
  17464.  The issues of management and control in the workstation-based development 
  17465.  environment are of increasing importance as organizations begin to develop and 
  17466.  deploy line-of-business applications on workstation platforms.  These issues 
  17467.  may be adequately addressed by the use of appropriate tools and the adaptation 
  17468.  and application of existing management techniques.  With the proper care and 
  17469.  planning, the maximum benefit may be obtained from the use of the workstation 
  17470.  as a development and delivery platform for business applications. 
  17471.  
  17472.  
  17473. ΓòÉΓòÉΓòÉ 27. Naming Conventions ΓòÉΓòÉΓòÉ
  17474.  
  17475. It is often a desirable practice to implement common naming conventions for 
  17476. application routines and for symbolic constant and variable names.  The 
  17477. adoption of such techniques facilitates application readability and code 
  17478. maintenance, since the nature and role of various routines and data items used 
  17479. by an application may be more easily understood.  This chapter proposes some 
  17480. naming conventions; it is not suggested that application developers should use 
  17481. these conventions slavishly, but that they should use the suggestions provided 
  17482. as guidelines in developing their own consistent set of organizational 
  17483. standards. 
  17484.  
  17485. The conventions proposed herein will cover the following areas: 
  17486.  
  17487.    o  Symbolic names and constants 
  17488.    o  Subroutine names 
  17489.    o  Window and dialog procedure names 
  17490.    o  Variable names. 
  17491.  
  17492.  The conventions proposed will adhere to most "standard" C programming 
  17493.  conventions, in that lowercase characters will be used for routine and 
  17494.  variable names, with uppercase characters used for symbolic names and 
  17495.  constants.  Application developers wishing to use standardized naming 
  17496.  conventions for applications written in other languages will obviously need to 
  17497.  adapt these conventions to suit their particular language implementation. 
  17498.  
  17499.  The conventions proposed herein will also use a notational concept known as 
  17500.  Hungarian notation, named for its inventor, Charles Simyoni.  Under this 
  17501.  notational system each variable, symbolic name or procedure name is prefixed 
  17502.  by a one-, two- or three-character mnemonic that indicates its type or 
  17503.  function. 
  17504.  
  17505.  
  17506. ΓòÉΓòÉΓòÉ 27.1. Symbolic Names and Constants ΓòÉΓòÉΓòÉ
  17507.  
  17508. In a PM application, symbolic names are typically used within an application to 
  17509. represent numeric values such as message classes or control window identifiers 
  17510. by a meaningful name rather than a less meaningful numeric representation.  A 
  17511. list of suggested prefixes is given in Type Prefixes for Symbolic Constants, to 
  17512. give an indication of type when using a symbolic name or constant. 
  17513.  
  17514. ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
  17515. Γöé Type Prefixes for Symbolic Constants                  Γöé
  17516. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  17517. Γöé ITEM                 Γöé CONSTANT TYPE  Γöé PREFIX     Γöé
  17518. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  17519. Γöé Menu Item (Command)         Γöé Integer     Γöé MI_       Γöé
  17520. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  17521. Γöé Check Box              Γöé Integer     Γöé CK_       Γöé
  17522. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  17523. Γöé Entry Field             Γöé Integer     Γöé EF_       Γöé
  17524. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  17525. Γöé List Box               Γöé Integer     Γöé LB_       Γöé
  17526. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  17527. Γöé Push Button             Γöé Integer     Γöé PB_       Γöé
  17528. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  17529. Γöé Radio Button             Γöé Integer     Γöé RB_       Γöé
  17530. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  17531. Γöé Static Text String          Γöé String      Γöé STR_      Γöé
  17532. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  17533. Γöé Window Class             Γöé String      Γöé WC_       Γöé
  17534. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  17535. Γöé Dialog Class             Γöé String      Γöé DC_       Γöé
  17536. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  17537. Γöé Message Class (Application-defined) Γöé Integer     Γöé WMP_      Γöé
  17538. ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
  17539.  
  17540. These one-, two- or three-letter prefixes may be concatenated with the actual 
  17541. symbolic names of control windows, window classes etc., in order to provide a 
  17542. more meaningful representation of the symbolic name in the source code. 
  17543.  
  17544.  
  17545. ΓòÉΓòÉΓòÉ 27.2. Subroutine Names ΓòÉΓòÉΓòÉ
  17546.  
  17547. For the purpose of discussion, a distinction will be made between subroutines 
  17548. invoked using normal programming language calling mechanisms, and window or 
  17549. dialog procedures invoked by Presentation Manager in response to the 
  17550. application issuing a WinDispatchMsg(), WinPostMsg() or WinSendMsg() call. 
  17551. Window and dialog procedures are discussed in the following section. 
  17552.  
  17553. When examining application code, it is useful to know the type of event handled 
  17554. or processing carried out by a particular function or subroutine, without the 
  17555. need for detailed examination of the code for that subroutine. This capability 
  17556. can be facilitated by the use of a prefix to the function or subroutine name, 
  17557. which indicates the type of the function or subroutine to the reader. 
  17558.  
  17559. Since the types of functions carried out within applications may be extremely 
  17560. diverse, no standards will be suggested here.  However, readers should note the 
  17561. potential benefits of such a practice, and may wish to adopt a suitable 
  17562. convention for their own applications. 
  17563.  
  17564.  
  17565. ΓòÉΓòÉΓòÉ 27.3. Window and Dialog Procedure Names ΓòÉΓòÉΓòÉ
  17566.  
  17567. In order to indicate that a particular subroutine within an application is a 
  17568. window procedure, it is suggested that all window procedure names should be 
  17569. prefixed with wp in lowercase letters.  Similarly, dialog procedures for 
  17570. processing modal dialog boxes, should be prefixed with "dp" to identify the 
  17571. nature of their processing and to differentiate them from normal window 
  17572. procedures. 
  17573.  
  17574.  
  17575. ΓòÉΓòÉΓòÉ 27.4. Variable Names ΓòÉΓòÉΓòÉ
  17576.  
  17577. It is far easier to determine the nature and usage of a variable if its data 
  17578. type is known to the reader.  Variable names may be prefixed with mnemonics 
  17579. indicating their data type, in a similar way to that proposed for symbolic 
  17580. names and constants.  A list of suggested prefixes for various data types is 
  17581. given in Type Prefixes for Variables. 
  17582.  
  17583. ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
  17584. Γöé Type Prefixes for Variables                       Γöé
  17585. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  17586. Γöé DATA TYPE              Γöé DEFINITION    Γöé PREFIX     Γöé
  17587. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  17588. Γöé Boolean               Γöé BOOL (flag)   Γöé f        Γöé
  17589. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  17590. Γöé Character              Γöé CHAR       Γöé ch       Γöé
  17591. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  17592. Γöé Unsigned character          Γöé UCHAR      Γöé uch       Γöé
  17593. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  17594. Γöé String                Γöé CHAR[]      Γöé sz       Γöé
  17595. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  17596. Γöé Short integer            Γöé SHORT      Γöé s        Γöé
  17597. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  17598. Γöé Unsigned short integer        Γöé USHORT      Γöé us       Γöé
  17599. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  17600. Γöé Long integer             Γöé LONG       Γöé l        Γöé
  17601. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  17602. Γöé Unsigned long integer        Γöé ULONG      Γöé ul       Γöé
  17603. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  17604. Γöé Handle                Γöé HWND, HMODULE,  Γöé h        Γöé
  17605. Γöé                   Γöé etc       Γöé         Γöé
  17606. ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
  17607.  
  17608. For example, a character string variable (a zero- or null-terminated string) 
  17609. named WindowTitle might have an attached mnemonic prefix of sz to indicate the 
  17610. data type, making the variable name szWindowTitle.  This is a simple example; 
  17611. to take a more complex instance, a handle to a window might have a variable 
  17612. name hMainWindow, which would differentiate it in the source code from a window 
  17613. procedure wpMainWindow or other data items relating to the window, while 
  17614. maintaining an indication of the relationship between the items by the 
  17615. similarity in their names. 
  17616.  
  17617. Prefixing variable names in this way has the additional advantage that a 
  17618. compiler cross-reference listing will group together all variables of the same 
  17619. data type.  Any redundancies may thus be seen at a glance. 
  17620.  
  17621. A pointer to a variable is indicated by using an additional prefix p before the 
  17622. prefix indicating the data type of the variable.  Some examples are shown in 
  17623. Type Prefixes for Pointers. 
  17624.  
  17625. ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
  17626. Γöé Type Prefixes for Pointers                       Γöé
  17627. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  17628. Γöé DATA TYPE              Γöé DEFINITION    Γöé PREFIX     Γöé
  17629. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  17630. Γöé Pointer to CHAR           Γöé CHAR *      Γöé pch       Γöé
  17631. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  17632. Γöé Pointer to string          Γöé PSZ       Γöé psz       Γöé
  17633. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  17634. Γöé Pointer to function         Γöé PFN, PFNWP    Γöé pfn       Γöé
  17635. ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
  17636.  
  17637. As a further example, an unsigned integer UserResponse might have a prefix of 
  17638. us making the variable name usUserResponse.  A pointer to this variable would 
  17639. have the name pusUserResponse.  The name thus indicates both the data type of 
  17640. the pointer and its relationship with the variable to which it points. 
  17641.  
  17642.  
  17643. ΓòÉΓòÉΓòÉ 28. Application Program Construction ΓòÉΓòÉΓòÉ
  17644.  
  17645. This section of the document presents guidelines for the structuring of 
  17646. applications and their component modules, in order to achieve the optimum level 
  17647. of modularity and granularity within an application.  The guidelines contained 
  17648. herein are particularly applicable to the C programming language, although they 
  17649. may also apply to other languages with similar structures. 
  17650.  
  17651.  
  17652. ΓòÉΓòÉΓòÉ 28.1. Modularization ΓòÉΓòÉΓòÉ
  17653.  
  17654. Within a Presentation Manager application, it is recommended that the 
  17655. application code be separated into distinct source modules, as follows: 
  17656.  
  17657.    o  Each window procedure (that is, application object) should be placed in 
  17658.       its own separate source module, along with functions and subroutines 
  17659.       created for and exclusively called by that window procedure.  This 
  17660.       creates the situation where a single window is contained per source 
  17661.       module, which preserves isolation and facilitates independence of 
  17662.       application objects. 
  17663.  
  17664.    o  Type definitions, variable and constant declarations (including private 
  17665.       message classes) and function prototypes that are local to a particular 
  17666.       source module should be placed in a private header file or alternatively, 
  17667.       included in the source module itself. 
  17668.  
  17669.    o  Function prototypes for those window procedures or subroutines that will 
  17670.       become the entry points to the source module should be placed in a 
  17671.       separate header file, along with type definitions, variable and constant 
  17672.       declarations that will be required by other source modules calling those 
  17673.       procedures or subroutines.  This header file may then be referenced by 
  17674.       each source module that requires access to these procedures or routines. 
  17675.       This header file is known as the public header file. 
  17676.  
  17677.    o  Global type definitions, variable and constant declarations should be 
  17678.       placed in a global header file that may be referenced by each source 
  17679.       module.  In the ideal case, global variables and constants should not be 
  17680.       used by an application, and this header file would therefore not be 
  17681.       required. 
  17682.  
  17683.    o  Generic functions and subroutines accessed by more than one window 
  17684.       procedure should be placed in a separate source module with its own 
  17685.       header file (known as a generic routines header file), which may be 
  17686.       referenced by each module requiring access to the generic routines. This 
  17687.       includes "functions" such as dialog definitions and dialog procedures 
  17688.       that are accessed from multiple window procedures, and message handling 
  17689.       routines. 
  17690.  
  17691.    o  Presentation Manager resources used by modules within an application 
  17692.       should be placed in a resource script file, and their associated 
  17693.       identifiers defined in the application's public header file. 
  17694.  
  17695.  Note that a Workplace Shell object's source code is automatically partitioned 
  17696.  in a similar manner to that described above, since the various files are 
  17697.  created by the SOM Precompiler from the object's class definition file. 
  17698.  
  17699.  Separation of the application code into its constituent application objects in 
  17700.  this manner facilitates the isolation and independence of application objects, 
  17701.  and enhances the potential for their subsequent reuse.  It also eases the task 
  17702.  of application maintenance and change management, by effectively modularizing 
  17703.  an application and therefore helping to contain the scope of change within a 
  17704.  single source module and its dependent header files. 
  17705.  
  17706.  The separation of header files into private, public and global definitions in 
  17707.  the manner described above further enhances the independence of application 
  17708.  objects and facilitates change management, in the following ways: 
  17709.  
  17710.    o  The separation of an application object's public interfaces means that 
  17711.       other application objects are aware only of those interfaces, and not of 
  17712.       the internal definitions and operations of the application object. 
  17713.       Changes within an application object, to local type, variable or constant 
  17714.       definitions, do not impact other application objects with which the 
  17715.       changed object communicates 
  17716.  
  17717.    o  The separation of the private and public interfaces explicitly defines 
  17718.       each of these interfaces, so that a maintenance programmer is clearly 
  17719.       aware of changes that will or will not impact other application objects. 
  17720.       Other applications that do require modification as a result may be easily 
  17721.       identified, since their source modules will contain a reference to the 
  17722.       changed object's external interface header file. 
  17723.  
  17724.  When managing the development of large projects, an "owner" should be 
  17725.  appointed for each source module.  This owner is typically a member of the 
  17726.  development team who bears responsibility for that module.  A module's owner 
  17727.  should also have the responsibility for that module's private and public 
  17728.  header files. 
  17729.  
  17730.  
  17731. ΓòÉΓòÉΓòÉ 28.2. Header Files ΓòÉΓòÉΓòÉ
  17732.  
  17733. Header files should be used wherever possible in order to isolate data and 
  17734. function declarations from the application code, thereby enhancing modularity 
  17735. and improving readability. 
  17736.  
  17737. For management purposes and to facilitate subsequent maintenance of the 
  17738. application code, a header file should include a prolog identifying the 
  17739. application and source module with which it is associated, its author and 
  17740. owner, and whether the header file is a private, public, global or generic 
  17741. header file (see below for definitions of these terms). 
  17742.  
  17743.  
  17744. ΓòÉΓòÉΓòÉ 28.2.1. Private Header File ΓòÉΓòÉΓòÉ
  17745.  
  17746. Each source module should have its own private header file, or have the 
  17747. contents of such a file included in the source module itself.  The private 
  17748. header file should itself include: 
  17749.  
  17750.    o  Declarations for all local constants used within the source module; that 
  17751.       is, those constants that are not accessed or referenced from outside the 
  17752.       source module.  This includes those application-defined message classes 
  17753.       used by a window procedure in indicating events to itself, or by 
  17754.       dependent functions and/or subroutines to indicate messages to their 
  17755.       parent window procedure. 
  17756.  
  17757.    o  Declarations for all non-local variables used within the source module; 
  17758.       that is, those variables that are accessed from more than one routine 
  17759.       within the source module, but are not accessed from outside the source 
  17760.       module. 
  17761.  
  17762.    o  Prototypes for all functions and subroutines that are accessed only from 
  17763.       within the source module. 
  17764.  
  17765.  A private header file should be referenced, using an appropriate #include 
  17766.  statement, only by its own source module. 
  17767.  
  17768.  
  17769. ΓòÉΓòÉΓòÉ 28.2.2. External Interface Header File ΓòÉΓòÉΓòÉ
  17770.  
  17771. Each source module should possess its own public header file.  The public 
  17772. header file should contain: 
  17773.  
  17774.    o  Function prototypes for the entry-point functions or subroutines within 
  17775.       the source module, and only for those routines.  This preserves the 
  17776.       isolation of the source module's internal workings from the calling 
  17777.       application. 
  17778.  
  17779.    o  Type definitions for any application-defined data types required by the 
  17780.       entry-point functions or subroutines. 
  17781.  
  17782.    o  Message class definitions for application-defined message classes that 
  17783.       will be used to signal events to a window procedure within the source 
  17784.       module. 
  17785.  
  17786.  A public header file should be referenced by its own source module and by any 
  17787.  other source module which requires access to the entry points of the module. 
  17788.  In an ideal case, where optimum isolation is achieved by relating all 
  17789.  processing within the source module to a single window, access to these entry 
  17790.  points would be achieved by: 
  17791.  
  17792.    o  A single "conventional" subroutine call to create the window, with the 
  17793.       caller specifying appropriate parameters and the called routine returning 
  17794.       a handle to the window.  The public header file must therefore contain 
  17795.       definitions for any application-defined data types to be passed as 
  17796.       parameters to this call. 
  17797.  
  17798.    o  Passing a series of messages to the window in order to indicate events 
  17799.       and request actions.  The public header file must therefore also contain 
  17800.       definitions for any application-defined message classes used by the 
  17801.       window. 
  17802.  
  17803.  Since the public header file contains the interfaces to its parent window 
  17804.  (that is, application object) it should be carefully documented, and the entry 
  17805.  points and their means of access should be placed in the application's design 
  17806.  documentation.  Interfaces to those application objects that are identified as 
  17807.  having potential for reuse should also be placed in an Interface Control 
  17808.  Document from which they may be accessed for future reuse of the application 
  17809.  object (see Packaging). 
  17810.  
  17811.  
  17812. ΓòÉΓòÉΓòÉ 28.2.3. Global Header File ΓòÉΓòÉΓòÉ
  17813.  
  17814. An application may contain a global header file, which itself should contain: 
  17815.  
  17816.    o  Declarations for all global constants used by the application; that is, 
  17817.       those constants that are accessed from more than one source module within 
  17818.       the application. 
  17819.  
  17820.    o  Declarations for all global variables used by the application; that is, 
  17821.       those variables that are accessed from more than one source module within 
  17822.       the application.  Note that this does not include those variables that 
  17823.       are used by multiple routines within the same source module. 
  17824.  
  17825.  The global header file should be referenced, using an appropriate #include 
  17826.  statement, by all source modules within the application, other than the 
  17827.  module(s) containing generic routines. 
  17828.  
  17829.  
  17830. ΓòÉΓòÉΓòÉ 28.2.4. Generic Routines Header File ΓòÉΓòÉΓòÉ
  17831.  
  17832. One or more source modules in an application may contain generic routines that 
  17833. are accessed from multiple source modules within the application. These source 
  17834. modules may possess their own local header files to define data and functions 
  17835. accessed only from within their own module.  In addition, such source modules 
  17836. should possess a single generic routines header file per application, which 
  17837. should contain: 
  17838.  
  17839.    o  Prototypes for all generic functions and subroutines that will be 
  17840.       accessed from other source modules within the application 
  17841.  
  17842.    o  Declarations for data types and constants necessary to the invocation of 
  17843.       these generic routines. 
  17844.  
  17845.  The generic routines header file should be referenced, via an appropriate 
  17846.  #include statement, by its own source modules and by each source module within 
  17847.  the application that requires access to generic routines. 
  17848.  
  17849.  
  17850. ΓòÉΓòÉΓòÉ 28.2.5. System-Supplied Header Files ΓòÉΓòÉΓòÉ
  17851.  
  17852. Source modules in an application will typically require access to operating 
  17853. system or C language functions.  Prototypes for these functions and 
  17854. declarations for their associated data types and constants are provided in 
  17855. system-supplied header files.  Examples of system-supplied header files are the 
  17856. OS/2 system functions file os2.h and the C language run-time library files such 
  17857. as stlib.h and string.h. 
  17858.  
  17859.  
  17860. ΓòÉΓòÉΓòÉ 28.3. Data Abstraction and Encapsulation ΓòÉΓòÉΓòÉ
  17861.  
  17862. In order to enhance reusability and to facilitate the containment (and 
  17863. therefore the management) of change, data definition and initialization should, 
  17864. wherever possible, be encapsulated within source modules as follows: 
  17865.  
  17866.    o  Local variables should be used wherever possible.  Where the value of a 
  17867.       variable must be held between invocations of the same function or 
  17868.       subroutine, the static keyword may be used in declaring the variable. 
  17869.  
  17870.    o  For window procedures where the values of variables must be held beyond 
  17871.       the scope of processing a single message, a memory object may be 
  17872.       allocated for the variable(s) and a pointer to that object stored in the 
  17873.       window words of the window. 
  17874.  
  17875.    o  External data objects such as files, databases, etc., should be defined 
  17876.       and accessed only from within a single window procedure and its dependent 
  17877.       functions and subroutines.  Definition of and/or establishment of access 
  17878.       to such data objects should be performed upon window creation as part of 
  17879.       the WM_CREATE message processing, and termination of access should be 
  17880.       performed upon window closure as part of the WM_CLOSE message processing. 
  17881.  
  17882.    o  The use of global variables should be avoided wherever possible, although 
  17883.       it is recognized that global variables are necessary in certain 
  17884.       circumstances within a Presentation Manager application.  Where global 
  17885.       variables are to be used, they should be declared in the application's 
  17886.       main source module (that is, the module that contains the application's 
  17887.       main routine) and referenced from the application's global header file 
  17888.       using the extern keyword. 
  17889.  
  17890.    o  Except in the case noted above, the use of external variable declarations 
  17891.       using the extern keyword should be avoided wherever possible, since this 
  17892.       creates an interdependence between source modules (and therefore between 
  17893.       application objects) that may subsequently limit the potential for reuse 
  17894.       of those objects.  Variables should preferably be defined locally within 
  17895.       a source module or alternatively, defined globally and referenced in the 
  17896.       application's global header file. 
  17897.  
  17898.    o  Where non-local variables and/or constants (that is, variables and/or 
  17899.       constants that are accessed only from within a particular source module, 
  17900.       but are not local to any routine within that module) are declared, they 
  17901.       should be placed in that source module's private header file or, if the 
  17902.       module does not possess its own header file, placed at the beginning of 
  17903.       the source module. 
  17904.  
  17905.  The practice of maximizing the use of local and encapsulated data, and of 
  17906.  minimizing and simplifying the external interfaces of application objects, 
  17907.  will achieve the maximum level of isolation and therefore of independence 
  17908.  between application objects, thus enhancing the potential for their reuse and 
  17909.  facilitating their future maintenance by isolating their internal workings 
  17910.  from those of other application objects. 
  17911.  
  17912.  
  17913. ΓòÉΓòÉΓòÉ 28.4. Packaging ΓòÉΓòÉΓòÉ
  17914.  
  17915. As already mentioned in Modularization, application code should be separated 
  17916. into distinct source modules.  These source modules are then compiled to 
  17917. produce individual object modules, which in turn are link-edited to produce 
  17918. executable code. However, the executable application code may itself consist of 
  17919. more than one executable module, by virtue of the dynamic linking capabilities 
  17920. of the OS/2 operating system. 
  17921.  
  17922.  
  17923. ΓòÉΓòÉΓòÉ 28.4.1. Application Object Modules ΓòÉΓòÉΓòÉ
  17924.  
  17925. If the foregoing guidelines are followed, each object module produced by the C 
  17926. language compiler will contain the following: 
  17927.  
  17928.    o  Definitions for all locally defined data types, variables and constants 
  17929.       required by routines within the module, obtained from the module's 
  17930.       private header file at compile time 
  17931.  
  17932.    o  Prototypes for all local window procedures, functions and subroutines 
  17933.       accessed only by routines within the module, obtained from the 
  17934.       application's private header file at compile time 
  17935.  
  17936.    o  Definitions for all external data structures, variables and constants 
  17937.       required to communicate with other source modules, obtained from one or 
  17938.       more public header files at compile time 
  17939.  
  17940.    o  Prototypes for all external window procedures, functions and subroutines 
  17941.       accessed by routines within the module, other than those that constitute 
  17942.       generic routines, obtained from one or more public header files at 
  17943.       compile time 
  17944.  
  17945.    o  Declarations for all global variables and constants required by routines 
  17946.       within the module, obtained from the application's global header file at 
  17947.       compile time 
  17948.  
  17949.    o  Prototypes for all generic routines, obtained from the application's 
  17950.       generic routines header file at compile time 
  17951.  
  17952.    o  Code for those routines contained within the module. 
  17953.  
  17954.  Each object module therefore exists as a coherent identity in its own right, 
  17955.  and ideally has no dependence upon other object modules, other than the need 
  17956.  to communicate with and make use of window procedures, functions and 
  17957.  subroutines contained within those modules, which is achieved through public 
  17958.  interfaces that are clearly defined and documented.  The separation of source 
  17959.  modules is now carried over to the object code, in that each object module 
  17960.  represents a separate application object. 
  17961.  
  17962.  It is therefore possible to assemble a number of object modules in various 
  17963.  ways to achieve an executable application.  The following guidelines are 
  17964.  offered for the construction of the executable application. 
  17965.  
  17966.  
  17967. ΓòÉΓòÉΓòÉ 28.4.2. Application Executable File ΓòÉΓòÉΓòÉ
  17968.  
  17969. The application's main executable file (that is, the file that is invoked to 
  17970. start the application) should contain those object modules which are required 
  17971. to execute the application, and that do not contain generic routines or generic 
  17972. Presentation Manager resources. 
  17973.  
  17974. Where it is envisaged that an application object is usable only by the current 
  17975. application, and has no possible potential for future reuse, it may be bound 
  17976. with the application's main executable file.  However, if such potential for 
  17977. reuse exists, the application object should be placed in a dynamic link 
  17978. library. 
  17979.  
  17980.  
  17981. ΓòÉΓòÉΓòÉ 28.4.3. Dynamic Link Libraries ΓòÉΓòÉΓòÉ
  17982.  
  17983. The following routines and objects should, wherever possible, be placed in 
  17984. dynamic link libraries: 
  17985.  
  17986.    o  Those application objects that have been identified as having potential 
  17987.       for future reuse by other applications 
  17988.  
  17989.    o  Those routines identified as generic routines, which will be accessed 
  17990.       from more than one window procedure 
  17991.  
  17992.    o  Those Presentation Manager resources (for example, dialog definitions, 
  17993.       along with their associated dialog procedures) that are accessed from 
  17994.       multiple window procedures within the application. 
  17995.  
  17996.  The placement of such items in dynamic link libraries enhances their 
  17997.  independence from the application's code, enabling changes to be made without 
  17998.  affecting the code or requiring application maintenance.  In addition, 
  17999.  placement in dynamic link libraries facilitates reuse of such items by 
  18000.  multiple applications.  It is thus possible to achieve object code reuse at 
  18001.  both the application object and at the subroutine level. 
  18002.  
  18003.  To this end, all items placed in dynamic link libraries should have their 
  18004.  external interfaces documented, baselined and included in an Interface Control 
  18005.  Document, for subsequent use as development library routines.  It is the 
  18006.  responsibility of the development organization to establish procedures for the 
  18007.  testing and acceptance of reusable code modules into libraries from which they 
  18008.  may subsequently be accessed by application developers, and the creation of a 
  18009.  repository of documentation detailing the application objects that are 
  18010.  available, their behavior and external interfaces. 
  18011.  
  18012.  
  18013. ΓòÉΓòÉΓòÉ 29. OS/2 Kernel API Functions ΓòÉΓòÉΓòÉ
  18014.  
  18015. This section of the document describes the functions that are available to 
  18016. application programs for accessing operating system services.  Note that only 
  18017. the operating system kernel functions are described in this section, since the 
  18018. Presentation Manager programming interface has not significantly changed, 
  18019. although a number of new Presentation Manager functions have been added. 
  18020.  
  18021. The following tables list the kernel functions available under OS/2 Version 1┬╖3 
  18022. and their equivalent function under OS/2 Version 2.0, categorized by function 
  18023. area. 
  18024.  
  18025.  
  18026. ΓòÉΓòÉΓòÉ 29.1. Memory Allocation and Management ΓòÉΓòÉΓòÉ
  18027.  
  18028. Memory management under OS/2 Version 2.0 is greatly simplified through use of 
  18029. the 32-bit flat memory model, eliminating the need for applications to create 
  18030. and manipulate separate memory segments. 
  18031.  
  18032. ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
  18033. Γöé Memory Management Functions.  This table compares the OS/2 Version   Γöé
  18034. Γöé 1.3 and OS/2 Version 2.0 memory allocation and management functions   Γöé
  18035. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18036. Γöé 16-BIT FUNCTION NAME        Γöé 32-BIT FUNCTION NAME        Γöé
  18037. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18038. Γöé DosAllocSeg             Γöé N/A                Γöé
  18039. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18040. Γöé DosAllocShrSeg           Γöé N/A                Γöé
  18041. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18042. Γöé DosGetShrSeg            Γöé N/A                Γöé
  18043. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18044. Γöé DosGetSeg              Γöé N/A                Γöé
  18045. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18046. Γöé DosGiveSeg             Γöé N/A                Γöé
  18047. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18048. Γöé DosReallocSeg            Γöé N/A                Γöé
  18049. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18050. Γöé DosFreeSeg             Γöé N/A                Γöé
  18051. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18052. Γöé DosAllocHuge            Γöé N/A                Γöé
  18053. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18054. Γöé DosGetHugeShift           Γöé N/A                Γöé
  18055. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18056. Γöé DosReallocHuge           Γöé N/A                Γöé
  18057. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18058. Γöé DosCreateCSAlias          Γöé N/A                Γöé
  18059. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18060. Γöé DosLockSeg             Γöé N/A                Γöé
  18061. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18062. Γöé DosUnLockSeg            Γöé N/A                Γöé
  18063. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18064. Γöé DosMemAvail             Γöé N/A                Γöé
  18065. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18066. Γöé DosSizeSeg             Γöé N/A                Γöé
  18067. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18068. Γöé DosGetResource           Γöé DosGetResource           Γöé
  18069. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18070. Γöé DosSubAlloc             Γöé DosSubAlloc            Γöé
  18071. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18072. Γöé DosSubFree             Γöé DosSubFree             Γöé
  18073. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18074. Γöé DosSubSet              Γöé DosSubSet             Γöé
  18075. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18076. Γöé N/A                 Γöé DosSubUnSet            Γöé
  18077. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18078. Γöé N/A                 Γöé DosAllocMem            Γöé
  18079. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18080. Γöé N/A                 Γöé DosAllocSharedMem         Γöé
  18081. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18082. Γöé N/A                 Γöé DosGetNamedSharedMem        Γöé
  18083. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18084. Γöé N/A                 Γöé DosGetSharedMem          Γöé
  18085. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18086. Γöé N/A                 Γöé DosGiveSharedMem          Γöé
  18087. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18088. Γöé N/A                 Γöé DosFreeMem             Γöé
  18089. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18090. Γöé N/A                 Γöé DosSetMem             Γöé
  18091. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18092. Γöé N/A                 Γöé DosQueryMem            Γöé
  18093. ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
  18094.  
  18095.  
  18096. ΓòÉΓòÉΓòÉ 29.2. Session Management ΓòÉΓòÉΓòÉ
  18097.  
  18098. There are few changes in session management functions between OS/2 Version 1┬╖3 
  18099. and OS/2 Version 2.0.  Only the DosSMRegisterDD() function has been removed 
  18100. from OS/2 Version 2.0. 
  18101.  
  18102. ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
  18103. Γöé Session Management Functions.  This table compares the OS/2       Γöé
  18104. Γöé Version 1.3 and OS/2 Version 2.0 session management functions.     Γöé
  18105. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18106. Γöé 16-BIT FUNCTIONS NAME        Γöé 32-BIT FUNCTION NAME        Γöé
  18107. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18108. Γöé DosStartSession           Γöé DosStartSession          Γöé
  18109. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18110. Γöé DosSetSession            Γöé DosSetSession           Γöé
  18111. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18112. Γöé DosSelectSession          Γöé DosSelectSession          Γöé
  18113. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18114. Γöé DosStopSession           Γöé DosStopSession           Γöé
  18115. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18116. Γöé DosSMRegisterDD           Γöé N/A                Γöé
  18117. ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
  18118.  
  18119.  
  18120. ΓòÉΓòÉΓòÉ 29.3. Task Management ΓòÉΓòÉΓòÉ
  18121.  
  18122. A number of function names have changed in the task management area.  These 
  18123. changes are primarily due to the simplified 32-bit programming environment. 
  18124.  
  18125. ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
  18126. Γöé Task Management Functions.  This table compares the OS/2 Version    Γöé
  18127. Γöé 1.3 and OS/2 Version 2.0 task management functions.           Γöé
  18128. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18129. Γöé 16-BIT FUNCTION NAME        Γöé 32-BIT FUNCTION NAME        Γöé
  18130. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18131. Γöé DosCreateThread           Γöé DosCreateThread          Γöé
  18132. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18133. Γöé DosCWait              Γöé DosWaitChild            Γöé
  18134. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18135. Γöé N/A                 Γöé DosWaitThread           Γöé
  18136. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18137. Γöé DosResumeThread           Γöé DosResumeThread          Γöé
  18138. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18139. Γöé DosSuspendThread          Γöé DosSuspendThread          Γöé
  18140. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18141. Γöé DosEnterCritSec           Γöé DosEnterCritSec          Γöé
  18142. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18143. Γöé DosExecPgm             Γöé DosExecPgm             Γöé
  18144. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18145. Γöé DosExit               Γöé DosExit              Γöé
  18146. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18147. Γöé DosExitCritSec           Γöé DosExitCritSec           Γöé
  18148. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18149. Γöé DosExitList             Γöé DosExitList            Γöé
  18150. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18151. Γöé DosGetInfoSeg            Γöé N/A                Γöé
  18152. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18153. Γöé N/A                 Γöé DosGetInfoBlocks          Γöé
  18154. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18155. Γöé DosGetPrty             Γöé N/A                Γöé
  18156. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18157. Γöé DosKillProcess           Γöé DosKillProcess           Γöé
  18158. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18159. Γöé N/A                 Γöé DosKillThread           Γöé
  18160. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18161. Γöé DosSetPrty             Γöé DosSetPriority           Γöé
  18162. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18163. Γöé DosGetPID              Γöé N/A                Γöé
  18164. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18165. Γöé DosGetPPID             Γöé N/A                Γöé
  18166. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18167. Γöé DosR2StackRealloc          Γöé N/A                Γöé
  18168. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18169. Γöé DosCallBack             Γöé N/A                Γöé
  18170. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18171. Γöé DosRetForward            Γöé N/A                Γöé
  18172. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18173. Γöé N/A                 Γöé DosDebug              Γöé
  18174. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18175. Γöé DosPTrace              Γöé N/A                Γöé
  18176. ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
  18177.  
  18178. The following comments apply to the functions described in the table above: 
  18179.  
  18180.    o  The DosCreateThread() function is enhanced in Version 2.0 to allow 
  18181.       dynamic stack growth, operating system management of stacks for secondary 
  18182.       threads, and the ability to create a suspended thread. 
  18183.  
  18184.    o  The InfoSeg architecture of 16-bit OS/2 versions is redefined for the 
  18185.       flat memory model.  The equivalent per thread and per process data is 
  18186.       obtained under Version 2.0 using the DosGetInfoBlocks() function, whereas 
  18187.       the non-changing values can be obtained using the DosQuerySysInfo() 
  18188.       function. 
  18189.  
  18190.    o  The DosGetPrty(), DosGetPID(), and DosGetPPID() functions are not 
  18191.       implemented since this information is available through the 
  18192.       DosGetInfoBlocks() function. 
  18193.  
  18194.    o  DosPTrace() support is provided under OS/2 Version 2.0 for 16-bit 
  18195.       debugging tools such as CodeView.  For 32-bit debugging tools, the 
  18196.       DosPTrace() function is replaced by the DosDebug() function. 
  18197.  
  18198.    o  DosWaitThread() is a new function allowing a thread to suspend itself, 
  18199.       waiting for other threads within a process to terminate. 
  18200.  
  18201.    o  DosKillThread() is a new function allowing a thread to forcibly terminate 
  18202.       another thread within the current process. 
  18203.  
  18204.    o  The DosR2StackRealloc(), DosCallBack(), and DosRetForward() functions are 
  18205.       not applicable in the 32-bit flat memory model environment. 
  18206.  
  18207.  
  18208. ΓòÉΓòÉΓòÉ 29.4. Signal and Exception Handling ΓòÉΓòÉΓòÉ
  18209.  
  18210. OS/2 Version 2.0 removes the function handling signals and combines signal 
  18211. handling with hardware exception handling, providing a more unified approach 
  18212. that allows greater flexibility. 
  18213.  
  18214. ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
  18215. Γöé Exception Handling Functions.  This table compares the OS/2       Γöé
  18216. Γöé Version 1.3 and OS/2 Version 2.0 signal and exception handling     Γöé
  18217. Γöé functions.                               Γöé
  18218. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18219. Γöé 16-BIT FUNCTION NAME        Γöé 32-BIT FUNCTION NAME        Γöé
  18220. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18221. Γöé DosHoldSignal            Γöé N/A                Γöé
  18222. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18223. Γöé DosSetSignalHandler         Γöé N/A                Γöé
  18224. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18225. Γöé DosSendSignal            Γöé N/A                Γöé
  18226. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18227. Γöé N/A                 Γöé DosSetKBDSigFocus         Γöé
  18228. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18229. Γöé DosSetVec              Γöé N/A                Γöé
  18230. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18231. Γöé N/A                 Γöé DosSetExceptionHandler       Γöé
  18232. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18233. Γöé N/A                 Γöé DosUnSetExceptionHandler      Γöé
  18234. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18235. Γöé N/A                 Γöé DosRaiseException         Γöé
  18236. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18237. Γöé N/A                 Γöé DosUnwindException         Γöé
  18238. ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
  18239.  
  18240. The DosSetKBDSigFocus() function is used to allow 32-bit programs to inform the 
  18241. operating system that they are "primed for signals", although the signals are 
  18242. dispatched as exceptions. 
  18243.  
  18244. Note the following: 
  18245.  
  18246.    o  16-bit DosSetVec() exceptions are supported under OS/2 Version 2.0. 
  18247.  
  18248.    o  The 32-bit OS/2 Version 2.0 exception manager allows per-thread exception 
  18249.       handling. 
  18250.  
  18251.    o  OS/2 Version 2.0 does not allow an exception handler to be registeed for 
  18252.       the numeric processor exception (NPX). 
  18253.  
  18254.  
  18255. ΓòÉΓòÉΓòÉ 29.5. Interprocess Communication ΓòÉΓòÉΓòÉ
  18256.  
  18257. OS/2 Version 2.0 provides the same interprocess communication and 
  18258. synchronization facilities as OS/2 Version 1┬╖3.  Differences in functions used 
  18259. to invoke these facilities are shown in the following tables. 
  18260.  
  18261.  
  18262. ΓòÉΓòÉΓòÉ 29.5.1. Anonymous Pipes ΓòÉΓòÉΓòÉ
  18263.  
  18264. The name of the DosMakePipe() function has been changed to DosCreatePipe() to 
  18265. conform with the consistent naming rules introduced in OS/2 Version 2.0. 
  18266.  
  18267. ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
  18268. Γöé Anonymous Pipe Functions.  This table compares the OS/2 Version     Γöé
  18269. Γöé 1.3 and OS/2 Version 2.0 anonymous pipe functions.           Γöé
  18270. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18271. Γöé 16-BIT FUNCTION NAME        Γöé 32-BIT FUNCTION NAME        Γöé
  18272. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18273. Γöé DosMakePipe             Γöé DosCreatePipe           Γöé
  18274. ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
  18275. Other functions used to access anonymous pipes are basic file I/O functions, 
  18276. and are described in File I/O. 
  18277.  
  18278.  
  18279. ΓòÉΓòÉΓòÉ 29.5.2. Named Pipes ΓòÉΓòÉΓòÉ
  18280.  
  18281. Changes to the functions used to create and manipulate named pipes have been 
  18282. made in order to conform to the consistent naming rules introduced in OS/2 
  18283. Version 2.0. 
  18284.  
  18285. ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
  18286. Γöé Named Pipe Functions.  This table compares the OS/2 Version 1.3     Γöé
  18287. Γöé and OS/2 Version 2.0 named pipe functions.               Γöé
  18288. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18289. Γöé 16-BIT FUNCTION NAME        Γöé 32-BIT FUNCTION NAME        Γöé
  18290. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18291. Γöé DosCallNmPipe            Γöé DosCallNPipe            Γöé
  18292. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18293. Γöé DosConnectNmPipe          Γöé DosConnectNPipe          Γöé
  18294. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18295. Γöé DosDisConnectNmPipe         Γöé DosDisConnectNPipe         Γöé
  18296. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18297. Γöé DosMakeNmPipe            Γöé DosCreateNpipe           Γöé
  18298. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18299. Γöé DosPeekNmPipe            Γöé DosPeekNPipe            Γöé
  18300. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18301. Γöé DosQNmPHandState          Γöé DosQueryNPHState          Γöé
  18302. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18303. Γöé DosQNmPipeInfo           Γöé DosQueryNPipeInfo         Γöé
  18304. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18305. Γöé DosQNmPipeSemState         Γöé DosQueryNPipeSemState       Γöé
  18306. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18307. Γöé DosRawReadNmPipe          Γöé DosRawReadNPipe          Γöé
  18308. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18309. Γöé DosRawWriteNmPipe          Γöé DosRawWriteNPipe          Γöé
  18310. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18311. Γöé DosSetNmPHandInfo          Γöé DosSetNPHState           Γöé
  18312. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18313. Γöé DosSetNmPipeSem           Γöé DosSetNPipeSem           Γöé
  18314. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18315. Γöé DosTransactNmPipe          Γöé DosTransactNPipe          Γöé
  18316. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18317. Γöé DosWaitNmPipe            Γöé DosWaitNPipe            Γöé
  18318. ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
  18319.  
  18320.  
  18321. ΓòÉΓòÉΓòÉ 29.5.3. Queues ΓòÉΓòÉΓòÉ
  18322.  
  18323. No changes have been made to function names for queue manipulation between the 
  18324. OS/2 Version 1┬╖3 and OS/2 Version 2.0 implementations. 
  18325.  
  18326. ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
  18327. Γöé Queue Functions.  This table compares the OS/2 Version 1.3 and     Γöé
  18328. Γöé OS/2 Version 2.0 queue management functions.              Γöé
  18329. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18330. Γöé 16-BIT FUNCTION NAME        Γöé 32-BIT FUNCTION NAME        Γöé
  18331. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18332. Γöé DosCreateQueue           Γöé DosCreateQueue           Γöé
  18333. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18334. Γöé DosOpenQueue            Γöé DosOpenQueue            Γöé
  18335. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18336. Γöé DosCloseQueue            Γöé DosCloseQueue           Γöé
  18337. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18338. Γöé DosPeekQueue            Γöé DosPeekQueue            Γöé
  18339. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18340. Γöé DosPurgeQueue            Γöé DosPurgeQueue           Γöé
  18341. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18342. Γöé DosQueryQueue            Γöé DosQueryQueue           Γöé
  18343. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18344. Γöé DosReadQueue            Γöé DosReadQueue            Γöé
  18345. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18346. Γöé DosWriteQueue            Γöé DosWriteQueue           Γöé
  18347. ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
  18348.  
  18349. The queueing functions for the 16-bit and 32-bit environments are virtually 
  18350. identical; the only difference is that the 32-bit API uses 0:32 addressing and 
  18351. may use element sizes greater than 64KB.  Note that a a 32-bit application may 
  18352. not open a queue created by a 16-bit application using the 16-bit 
  18353. DosCreateQueue() function. 
  18354.  
  18355.  
  18356. ΓòÉΓòÉΓòÉ 29.5.4. Semaphores ΓòÉΓòÉΓòÉ
  18357.  
  18358. Significant changes have been made to semaphore functions under OS/2 Version 
  18359. 2.0, in order to provide additional flexibility and enhance the architectural 
  18360. independence of applications using semaphores. 
  18361.  
  18362. ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
  18363. Γöé Semaphore Functions.  This table compares the OS/2 Version 1.3 and   Γöé
  18364. Γöé OS/2 Version 2.0 semaphore functions.                  Γöé
  18365. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18366. Γöé 16-BIT FUNCTION NAME        Γöé 32-BIT FUNCTION NAME        Γöé
  18367. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18368. Γöé DosSemClear             Γöé N/A                Γöé
  18369. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18370. Γöé DosSemRequest            Γöé N/A                Γöé
  18371. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18372. Γöé DosSemSet              Γöé N/A                Γöé
  18373. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18374. Γöé DosSemSetWait            Γöé N/A                Γöé
  18375. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18376. Γöé DosSemWait             Γöé N/A                Γöé
  18377. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18378. Γöé DosMuxSemWait            Γöé N/A                Γöé
  18379. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18380. Γöé DosCloseSem             Γöé N/A                Γöé
  18381. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18382. Γöé DosCreateSem            Γöé N/A                Γöé
  18383. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18384. Γöé DosOpenSem             Γöé N/A                Γöé
  18385. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18386. Γöé DosFSRamSemRequest         Γöé N/A                Γöé
  18387. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18388. Γöé DosFSRamSemClear          Γöé N/A                Γöé
  18389. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18390. Γöé N/A                 Γöé DosCreateMutexSem         Γöé
  18391. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18392. Γöé N/A                 Γöé DosOpenMutexSem          Γöé
  18393. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18394. Γöé N/A                 Γöé DosCloseMutexSem          Γöé
  18395. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18396. Γöé N/A                 Γöé DosRequestMutexSem         Γöé
  18397. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18398. Γöé N/A                 Γöé DosReleaseMutexSem         Γöé
  18399. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18400. Γöé N/A                 Γöé DosQueryMutexSem          Γöé
  18401. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18402. Γöé N/A                 Γöé DosCreateEventSem         Γöé
  18403. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18404. Γöé N/A                 Γöé DosOpenEventSem          Γöé
  18405. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18406. Γöé N/A                 Γöé DosCloseEventSem          Γöé
  18407. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18408. Γöé N/A                 Γöé DosResetEventSem          Γöé
  18409. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18410. Γöé N/A                 Γöé DosPostEventSem          Γöé
  18411. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18412. Γöé N/A                 Γöé DosWaitEventSem          Γöé
  18413. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18414. Γöé N/A                 Γöé DosQueryEventSem          Γöé
  18415. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18416. Γöé N/A                 Γöé DosCreateMuxWaitSem        Γöé
  18417. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18418. Γöé N/A                 Γöé DosOpenMuxWaitSem         Γöé
  18419. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18420. Γöé N/A                 Γöé DosCloseMuxWaitSem         Γöé
  18421. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18422. Γöé N/A                 Γöé DosWaitMuxWaitSem         Γöé
  18423. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18424. Γöé N/A                 Γöé DosAddMuxWaitSem          Γöé
  18425. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18426. Γöé N/A                 Γöé DosDeleteMuxWaitSem        Γöé
  18427. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18428. Γöé N/A                 Γöé DosQueryMuxWaitSem         Γöé
  18429. ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
  18430.  
  18431. OS/2 Version 2.0 provides 16-bit entry points allowing compatibility with 
  18432. 16-bit applications that use the old system semaphores, RAM semaphores and Fast 
  18433. Safe RAM (FSR) semaphores. 
  18434.  
  18435.  
  18436. ΓòÉΓòÉΓòÉ 29.6. Message Retrieval ΓòÉΓòÉΓòÉ
  18437.  
  18438. Few changes have been made to the kernel message retrieval functions.  Only the 
  18439. name of the DosInsMessage() function has been changed to DosInsertMessage() in 
  18440. order to conform with the consistent naming rules introduced in OS/2 Version 
  18441. 2.0. 
  18442.  
  18443. ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
  18444. Γöé Message Retrieval Functions.  This table compares the OS/2 Version   Γöé
  18445. Γöé 1.3 and OS/2 Version 2.0 message retrieval functions.          Γöé
  18446. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18447. Γöé 16-BIT FUNCTION NAME        Γöé 32-BIT FUNCTION NAME        Γöé
  18448. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18449. Γöé DosGetMessage            Γöé DosGetMessage           Γöé
  18450. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18451. Γöé DosInsMessage            Γöé DosInsertMessage          Γöé
  18452. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18453. Γöé DosPutMessage            Γöé DosPutMessage           Γöé
  18454. ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
  18455.  
  18456.  
  18457. ΓòÉΓòÉΓòÉ 29.7. Timer Services ΓòÉΓòÉΓòÉ
  18458.  
  18459. A number of timer function names have changed under OS/2 Version 2.0, in order 
  18460. to conform to the consistent naming rules introduced in OS/2 Version 2.0. 
  18461.  
  18462. ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
  18463. Γöé Timer Services Functions.  This table compares the OS/2 Version     Γöé
  18464. Γöé 1.3 and OS/2 Version 2.0 timer services functions.           Γöé
  18465. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18466. Γöé 16-BIT FUNCTION NAME        Γöé 32-BIT FUNCTION NAME        Γöé
  18467. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18468. Γöé DosGetDateTime           Γöé DosGetDateTime           Γöé
  18469. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18470. Γöé DosSetDateTime           Γöé DosSetDateTime           Γöé
  18471. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18472. Γöé DosSleep              Γöé DosSleep              Γöé
  18473. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18474. Γöé DosTimerAsync            Γöé DosAsyncTimer           Γöé
  18475. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18476. Γöé DosTimerStart            Γöé DosStartTimer           Γöé
  18477. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18478. Γöé DosTimerStop            Γöé DosStopTimer            Γöé
  18479. ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
  18480.  
  18481.  
  18482. ΓòÉΓòÉΓòÉ 29.8. Dynamic Linking ΓòÉΓòÉΓòÉ
  18483.  
  18484. A number of dynamic linking function names have been changed in order to 
  18485. conform to the consistent naming rules introduced in OS/2 Version 2.0. 
  18486.  
  18487. ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
  18488. Γöé Dynamic Linking Functions.  This table compares the OS/2 Version    Γöé
  18489. Γöé 1.3 and OS/2 Version 2.0 dynamic linking functions.           Γöé
  18490. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18491. Γöé 16-BIT FUNCTION NAME        Γöé 32-BIT FUNCTION NAME        Γöé
  18492. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18493. Γöé DosLoadModule            Γöé DosLoadModule           Γöé
  18494. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18495. Γöé DosFreeModule            Γöé DosFreeModule           Γöé
  18496. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18497. Γöé DosGetProcAddr           Γöé DosQueryProcAddr          Γöé
  18498. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18499. Γöé DosGetModHandle           Γöé DosQueryModuleHandle        Γöé
  18500. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18501. Γöé DosGetModName            Γöé DosQueryModuleName         Γöé
  18502. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18503. Γöé DosQAppType             Γöé DosQueryAppType          Γöé
  18504. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18505. Γöé DosGetMachineMode          Γöé N/A                Γöé
  18506. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18507. Γöé BadDynLink             Γöé N/A                Γöé
  18508. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18509. Γöé DosGetVersion            Γöé N/A                Γöé
  18510. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18511. Γöé DosGetEnv              Γöé N/A                Γöé
  18512. ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
  18513.  
  18514.  
  18515. ΓòÉΓòÉΓòÉ 29.9. Device I/O ΓòÉΓòÉΓòÉ
  18516.  
  18517. No changes have been made to device I/O functions under OS/2 Version 2.0. 
  18518.  
  18519. ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
  18520. Γöé Device I/O Functions.  This table compares the OS/2 Version 1.3     Γöé
  18521. Γöé and OS/2 Version 2.0 device I/O functions.               Γöé
  18522. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18523. Γöé 16-BIT FUNCTION NAME        Γöé 32-BIT FUNCTION NAME        Γöé
  18524. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18525. Γöé DosBeep               Γöé DosBeep              Γöé
  18526. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18527. Γöé DosCLIAccess            Γöé N/A                Γöé
  18528. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18529. Γöé DosPortAccess            Γöé N/A                Γöé
  18530. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18531. Γöé DosDevConfig            Γöé DosDevConfig            Γöé
  18532. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18533. Γöé DosPhysicalDisk           Γöé DosPhysicalDisk          Γöé
  18534. ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
  18535.  
  18536.  
  18537. ΓòÉΓòÉΓòÉ 29.10. File I/O ΓòÉΓòÉΓòÉ
  18538.  
  18539. A number of changes have been made to file I/O functions, in order to conform 
  18540. to the consistent naming rules introduced in OS/2 Version 2.0. 
  18541.  
  18542. ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
  18543. Γöé File I/O Functions.  This table compares OS/2 Version 1.3 and OS/2   Γöé
  18544. Γöé Version 2.0 file I/O functions.                     Γöé
  18545. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18546. Γöé 16-BIT FUNCTION NAME        Γöé 32-BIT FUNCTION NAME        Γöé
  18547. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18548. Γöé DosBufReset             Γöé DosResetBuffer           Γöé
  18549. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18550. Γöé DosChDir              Γöé DosSetCurrentDir          Γöé
  18551. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18552. Γöé DosChgFilePtr            Γöé DosSetFilePtr           Γöé
  18553. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18554. Γöé DosClose              Γöé DosClose              Γöé
  18555. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18556. Γöé DosDelete              Γöé DosDelete             Γöé
  18557. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18558. Γöé DosDevIOCTL             Γöé DosDevIOCTL            Γöé
  18559. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18560. Γöé DosDupHandle            Γöé DosDupHandle            Γöé
  18561. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18562. Γöé DosEditName             Γöé DosEditName            Γöé
  18563. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18564. Γöé DosFileIO              Γöé DosFileIO             Γöé
  18565. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18566. Γöé DosFileLocks            Γöé DosSetFileLocks          Γöé
  18567. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18568. Γöé DosFindClose            Γöé DosFindClose            Γöé
  18569. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18570. Γöé DosFindFirst            Γöé DosFindFirst            Γöé
  18571. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18572. Γöé DosFindNext             Γöé DosFindNext            Γöé
  18573. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18574. Γöé DosFindNotifyClose         Γöé DosFindNotifyClose         Γöé
  18575. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18576. Γöé DosFindNotifyFirst         Γöé DosFindNotifyFirst         Γöé
  18577. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18578. Γöé DosFindNotifyNext          Γöé DosFindNotifyNext         Γöé
  18579. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18580. Γöé DosFSAttach             Γöé DosFSAttach            Γöé
  18581. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18582. Γöé DosFSCtl              Γöé DosFSCtl              Γöé
  18583. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18584. Γöé DosMkDir              Γöé DosCreateDir            Γöé
  18585. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18586. Γöé DosMove               Γöé DosMove              Γöé
  18587. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18588. Γöé DosNewSize             Γöé DosSetFileSize           Γöé
  18589. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18590. Γöé DosOpen               Γöé DosOpen              Γöé
  18591. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18592. Γöé DosQCurDir             Γöé DosQueryCurrentDir         Γöé
  18593. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18594. Γöé DosQCurDisk             Γöé DosQueryCurrentDisk        Γöé
  18595. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18596. Γöé DosQFHandState           Γöé DosQueryFHState          Γöé
  18597. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18598. Γöé DosQFileInfo            Γöé DosQueryFileInfo          Γöé
  18599. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18600. Γöé DosQFileMode            Γöé DosQueryFileMode          Γöé
  18601. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18602. Γöé DosQFSAttach            Γöé DosQueryFSAttach          Γöé
  18603. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18604. Γöé DosQFSinfo             Γöé DosQueryFSInfo           Γöé
  18605. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18606. Γöé DosQHandType            Γöé DosQueryHType           Γöé
  18607. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18608. Γöé DosQPathInfo            Γöé DosQueryPathInfo          Γöé
  18609. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18610. Γöé DosQSysInfo             Γöé DosQuerySysInfo          Γöé
  18611. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18612. Γöé DosQVerify             Γöé DosQueryVerify           Γöé
  18613. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18614. Γöé DosRead               Γöé DosRead              Γöé
  18615. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18616. Γöé DosReadAsync            Γöé N/A                Γöé
  18617. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18618. Γöé DosRmDir              Γöé DosDeleteDir            Γöé
  18619. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18620. Γöé DosScanEnv             Γöé DosScanEnv             Γöé
  18621. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18622. Γöé DosSearchPath            Γöé DosSearchPath           Γöé
  18623. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18624. Γöé DosSelectDisk            Γöé DosSetDefaultDisk         Γöé
  18625. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18626. Γöé DosSetFHandState          Γöé DosSetFHState           Γöé
  18627. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18628. Γöé DosSetFileInfo           Γöé DosSetFileInfo           Γöé
  18629. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18630. Γöé DosSetFileMode           Γöé DosSetFileMode           Γöé
  18631. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18632. Γöé DosSetFsInfo            Γöé DosSetFsInfo            Γöé
  18633. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18634. Γöé DosSetMaxFH             Γöé DosSetMaxFH            Γöé
  18635. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18636. Γöé DosSetPathInfo           Γöé DosSetPathInfo           Γöé
  18637. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18638. Γöé DosSetVerify            Γöé DosSetVerify            Γöé
  18639. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18640. Γöé DosWrite              Γöé DosWrite              Γöé
  18641. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18642. Γöé DosWriteAsync            Γöé N/A                Γöé
  18643. ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
  18644.  
  18645.  
  18646. ΓòÉΓòÉΓòÉ 29.11. Code Page Support ΓòÉΓòÉΓòÉ
  18647.  
  18648. Code page support has been simplified under OS/2 Version 2.0, and a number of 
  18649. function names have been changed to conform to the consistent naming rules 
  18650. introduced in Version 2.0. 
  18651.  
  18652. ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
  18653. Γöé Code Page Functions.  This table compares the OS/2 Version 1.3 and   Γöé
  18654. Γöé OS/2 Version 2.0 file code page support functions.           Γöé
  18655. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18656. Γöé 16-BIT FUNCTION NAME        Γöé 32-BIT FUNCTION NAME        Γöé
  18657. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18658. Γöé DosSetCp              Γöé N/A                Γöé
  18659. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18660. Γöé DosSetProcCp            Γöé DosSetProcessCp          Γöé
  18661. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18662. Γöé DosGetCp              Γöé DosQueryCp             Γöé
  18663. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18664. Γöé DosGetCtryInfo           Γöé DosQueryCtryInfo          Γöé
  18665. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18666. Γöé DosCaseMap             Γöé N/A                Γöé
  18667. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18668. Γöé DosGetDBCSEv            Γöé DosQueryDBCSEnv          Γöé
  18669. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18670. Γöé DosGetCollate            Γöé DosQueryCollate          Γöé
  18671. ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
  18672. The DosSetCp() function is no longer implemented, since under OS/2 Version 2.0 
  18673. an application may only set the code page for its own process, using the 
  18674. DosSetProcessCp() function. 
  18675.  
  18676. The DosCaseMap() function is no longer implemented since the same task is 
  18677. performed by the WinUpper() function. 
  18678.  
  18679.  
  18680. ΓòÉΓòÉΓòÉ 29.12. Error Management ΓòÉΓòÉΓòÉ
  18681.  
  18682. No changes have been made to error management functions under OS/2 Version 2.0. 
  18683.  
  18684. ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
  18685. Γöé Error Management Functions.  This table compares the OS/2 Version    Γöé
  18686. Γöé 1.3 and OS/2 Version 2.0 error management functions.          Γöé
  18687. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18688. Γöé 16-BIT FUNCTION NAME        Γöé 32-BIT FUNCTION NAME        Γöé
  18689. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18690. Γöé DosErrClass             Γöé DosErrClass            Γöé
  18691. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18692. Γöé DosError              Γöé DosError              Γöé
  18693. ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
  18694.  
  18695.  
  18696. ΓòÉΓòÉΓòÉ 30. Problem Reporting Worksheet ΓòÉΓòÉΓòÉ
  18697.  
  18698. The following page contains a worksheet that may be used for reporting problems 
  18699. encountered during application testing.  This worksheet follows the guidelines 
  18700. given in Problem Determination, and requires the application user to complete 
  18701. the following information: 
  18702.  
  18703.    o  The name of the application.  This is necessary in order that developers 
  18704.       may search for the error in the correct program. 
  18705.  
  18706.    o  The title of the active window when the error occurred.  This is 
  18707.       necessary in order to identify the window procedure in which the problem 
  18708.       most likely resides. 
  18709.  
  18710.    o  The title of the last user action prior to the error occurring.  This is 
  18711.       required in order to identify the Presentation Manager message that is 
  18712.       likely to have caused the error; it is probable that the problem lies in 
  18713.       the processing for this message. 
  18714.  
  18715.    o  Whether the action was attempted for the first time, or whether the 
  18716.       action had already been successfully completed one or more times during 
  18717.       the current execution of the application.  This indicates whether the 
  18718.       problem is probably a resource allocation error, or whether another cause 
  18719.       is more likely. 
  18720.  
  18721.    o  A description of the error, including an error message if one was 
  18722.       provided by the application, Presentation Manager or the operating 
  18723.       system. 
  18724.  
  18725.    o  The name of the user who discovered the error, along with a telephone 
  18726.       number for future contact if any clarification is required. 
  18727.  
  18728.    o  The date and time at which the error occurred.  While not necessary from 
  18729.       a problem determination viewpoint, this information allows a problem 
  18730.       management coordinator to monitor the amount of time necessary to respond 
  18731.       to and rectify application problems, and therefore allows management to 
  18732.       determine the effectiveness of the testing and debugging process. 
  18733.  
  18734.  The worksheet also contains a space at the foot of the page, into which 
  18735.  readers may insert the name of the person responsible for coordinating problem 
  18736.  determination and resolution activities, and to whom completed worksheets 
  18737.  should be sent.  This person would then typically allocate the isolation, 
  18738.  diagnosis and resolution of problems to specific developers. 
  18739.  
  18740.  For a more complete description of Presentation Manager problem determination 
  18741.  procedures, readers should refer to Problem Determination. 
  18742.  
  18743.  Readers may photocopy the worksheet on the following page, insert the name of 
  18744.  the appropriate coordinator, and distribute the worksheet within their 
  18745.  organizations for problem-reporting purposes. 
  18746.  
  18747.  
  18748. ΓòÉΓòÉΓòÉ 31. Problem Reporting Worksheet ΓòÉΓòÉΓòÉ
  18749.  
  18750. ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
  18751. Γöé            PROBLEM REPORTING WORKSHEET            Γöé
  18752. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18753. Γöé This worksheet is to be completed by application testers, for all    Γöé
  18754. Γöé problems encountered during testing of Presentation Manager       Γöé
  18755. Γöé applications.                              Γöé
  18756. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18757. Γöé APPLICATION:  What was the name of the application you were       Γöé
  18758. Γöé running when the error occurred?                    Γöé        Γöé
  18759. Γöé                                     Γöé
  18760. Γöé                                     Γöé
  18761. Γöé                                     Γöé
  18762. Γöé                                     Γöé
  18763. Γöé                                     Γöé
  18764. Γöé                                     Γöé
  18765. Γöé                                     Γöé
  18766. Γöé                                     Γöé
  18767. Γöé                                     Γöé
  18768. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18769. Γöé WINDOW:  What was the title of the window you were accessing      Γöé
  18770. Γöé when the error occurred?                        Γöé
  18771. Γöé                                     Γöé
  18772. Γöé                                     Γöé
  18773. Γöé                                     Γöé
  18774. Γöé                                     Γöé
  18775. Γöé                                     Γöé
  18776. Γöé                                     Γöé
  18777. Γöé                                     Γöé
  18778. Γöé                                     Γöé
  18779. Γöé                                     Γöé
  18780. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18781. Γöé ACTION:  What was the last action bar entry or accelerator key     Γöé
  18782. Γöé combination you selected?                        Γöé
  18783. Γöé                                     Γöé
  18784. Γöé                                     Γöé
  18785. Γöé                                     Γöé
  18786. Γöé                                     Γöé
  18787. Γöé                                     Γöé
  18788. Γöé                                     Γöé
  18789. Γöé                                     Γöé
  18790. Γöé                                     Γöé
  18791. Γöé                                     Γöé
  18792. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18793. Γöé [_] First time action was      Γöé [_] Action was repeated multiple  Γöé
  18794. Γöé   attempted            Γöé   times             Γöé
  18795. ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18796. ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18797. Γöé            PROBLEM REPORTING WORKSHEET            Γöé
  18798. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18799. Γöé ERROR DESCRIPTION:  Provide a description of the error, including the  Γöé
  18800. Γöé error message if one was displayed.                   Γöé
  18801. Γöé                                     Γöé
  18802. Γöé                                     Γöé
  18803. Γöé                                     Γöé
  18804. Γöé                                     Γöé
  18805. Γöé                                     Γöé
  18806. Γöé                                     Γöé
  18807. Γöé                                     Γöé
  18808. Γöé                                     Γöé
  18809. Γöé                                     Γöé
  18810. Γöé                                     Γöé
  18811. Γöé                                     Γöé
  18812. Γöé                                     Γöé
  18813. Γöé                                     Γöé
  18814. Γöé                                     Γöé
  18815. Γöé                                     Γöé
  18816. Γöé                                     Γöé
  18817. Γöé                                     Γöé
  18818. Γöé                                     Γöé
  18819. Γöé                                     Γöé
  18820. Γöé                                     Γöé
  18821. Γöé                                     Γöé
  18822. Γöé                                     Γöé
  18823. Γöé                                     Γöé
  18824. Γöé                                     Γöé
  18825. Γöé                                     Γöé
  18826. Γöé                                     Γöé
  18827. Γöé                                     Γöé
  18828. Γöé                                     Γöé
  18829. Γöé                                     Γöé
  18830. Γöé                                     Γöé
  18831. Γöé                                     Γöé
  18832. Γöé                                     Γöé
  18833. Γöé                                     Γöé
  18834. Γöé                                     Γöé
  18835. Γöé                                     Γöé
  18836. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18837. Γöé REPORTED BY Γöé Name:                    Γöé Ext:     Γöé
  18838. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18839. Γöé Include the date/time at which the error  Γöé Date:     Γöé Time:    Γöé
  18840. Γöé occurred                  Γöé        Γöé       Γöé
  18841. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  18842. Γöé When completed, please forward this worksheet to:            Γöé
  18843. Γöé                                     Γöé
  18844. Γöé                                     Γöé
  18845. Γöé                                     Γöé
  18846. Γöé                                     Γöé
  18847. Γöé                                     Γöé
  18848. Γöé                                     Γöé
  18849. Γöé                                     Γöé
  18850. Γöé                                     Γöé
  18851. ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
  18852.  
  18853.  
  18854. ΓòÉΓòÉΓòÉ 32. Source Code for the PWFolder and PWFinanceFile objects ΓòÉΓòÉΓòÉ
  18855.  
  18856. This appendix details the source code for the PWFolder and PWFinanceFile 
  18857. objects. 
  18858.  
  18859.  
  18860. ΓòÉΓòÉΓòÉ 32.1. Source Code for the PWFolder Object ΓòÉΓòÉΓòÉ
  18861.  
  18862. This section list the source code necessary to generate the dynamic link 
  18863. library (DLL) file PWFOLDER.DLL. 
  18864.  
  18865.  
  18866. ΓòÉΓòÉΓòÉ 32.1.1. Source Code for the PWFolder.CSC file ΓòÉΓòÉΓòÉ
  18867.  
  18868. ##########################################################
  18869. #                                                        #
  18870. #  PWFOLDER.CSC          (c) IBM Corporation 1992        #
  18871. #                                                        #
  18872. #  This class derives from WPFolder, and is used to      #
  18873. #  represent a folder which is protected by a password.  #
  18874. #                                                        #
  18875. ##########################################################
  18876.  
  18877. #
  18878. # Include the class definition file for the parent class
  18879. #
  18880. include <wpfolder.sc>
  18881.  
  18882. #
  18883. #   Define the new class
  18884. #
  18885. class: PWFolder,
  18886.        file stem = pwfolder,
  18887.        external prefix = pwfolder_,
  18888.        class prefix = pwfoldercls_,
  18889.        major version = 1,
  18890.        minor version = 1,
  18891.        local;
  18892.  
  18893. -- PWFolder is a Password protected folder.
  18894. -- It is derived as follows:
  18895. --        SOMOject
  18896. --          - WPObject
  18897. --             - WPFileSystem
  18898. --                - WPFolder
  18899. --                   - PWFolder
  18900.  
  18901. #
  18902. # Specify the parent class
  18903. #
  18904. parent: WPFolder;
  18905.  
  18906. #
  18907. # Specify the release order of new methods
  18908. #
  18909. release order: LockFolder;
  18910.  
  18911. #
  18912. # Passthru a debug message box to the .ih file
  18913. # (for inclusion in the .c file)
  18914. #
  18915. passthru: C.h, after;
  18916.  
  18917. #define DebugBox(title, text)  WinMessageBox(HWND_DESKTOP,HWND_DESKTOP, \
  18918.                                (PSZ) text , (PSZ) title, 0, \
  18919.                                MB_OK | MB_INFORMATION )
  18920.  
  18921. endpassthru;
  18922.  
  18923. #
  18924. # Passthru private definitions to the .ph file
  18925. # (for inclusion in the .c file)
  18926. #
  18927. passthru: C.ph;
  18928.  
  18929. typedef struct _PWF_INFO {                       /* Define password structure */
  18930.   CHAR   szPassword[20];                         /* Folder current password   */
  18931.   CHAR   szCurrentPassword[20];                  /* User-entered password     */
  18932.   CHAR   szUserid[20];                           /* Userid                    */
  18933. } PWF_INFO;
  18934. typedef PWF_INFO *PPWF_INFO;                     /* Define pointer type       */
  18935.  
  18936. endpassthru;
  18937.  
  18938. #
  18939. # Define instance data for the class
  18940. #
  18941. data:
  18942. CHAR szPassword[20];
  18943. --  This is the password which locks the folder
  18944.  
  18945. CHAR szCurrentPassword[20];
  18946. --  This is the password the user has typed in to be
  18947. --  checked against the lock password
  18948.  
  18949. CHAR szUserid[20];
  18950. --  Userid
  18951.  
  18952. #
  18953. # Define new methods
  18954. #
  18955. methods:
  18956.  
  18957. BOOL QueryInfo(PPWF_INFO pPWFolderInfo), private;
  18958. --
  18959. --  METHOD:   QueryInfo                                   PRIVATE
  18960. --
  18961. --  PURPOSE:  Copies instance data into the PWF_INFO structure.
  18962. --
  18963. --  INVOKED:  From PasswordDlgProc
  18964. --
  18965.  
  18966. BOOL SetInfo(PPWF_INFO pPWFolderInfo), private;
  18967. --
  18968. --  METHOD:   SetInfo                                     PRIVATE
  18969. --
  18970. --  PURPOSE:  Sets instance data from the PWF_INFO structure.
  18971. --
  18972. --  INVOKED:  From PasswordDlgProc
  18973. --
  18974.  
  18975. BOOL LockFolder();
  18976. --
  18977. --  METHOD:   LockFolder                                  PUBLIC
  18978. --
  18979. --  PURPOSE:  Invalidates the current password, thereby locking the folder.
  18980. --
  18981. --  INVOKED:  From _wpMenuItemSelected
  18982. --
  18983.  
  18984. #
  18985. # Specify methods being overridden
  18986. #
  18987. override wpInitData;
  18988. --
  18989. --  METHOD:   wpInitData                                  PUBLIC
  18990. --
  18991. --  PURPOSE:  Initializes instance data
  18992. --
  18993. --  INVOKED:  By Workplace Shell, upon instantiation of the object instance.
  18994. --
  18995.  
  18996. override wpModifyPopupMenu;
  18997. --
  18998. --  METHOD:   wpModifyPopupMenu                           PUBLIC
  18999. --
  19000. --  PURPOSE:  Adds an additional "Lock" item to the object's context menu.
  19001. --
  19002. --  INVOKED:  By Workplace Shell, upon instantiation of the object instance.
  19003. --
  19004.  
  19005. override wpMenuItemSelected;
  19006. --
  19007. --  METHOD:   wpMenuItemSelected                          PUBLIC
  19008. --
  19009. --  PURPOSE:  Processes the user's selections from the context menu.  The
  19010. --            overridden method processes only the added "Lock" item, before
  19011. --            invoking the parent's default processing to handle other items.
  19012. --
  19013. --  INVOKED:  By Workplace Shell, upon selection of a menu item by the user.
  19014. --
  19015.  
  19016. override wpOpen;
  19017. --
  19018. --  METHOD:   wpOpen                                      PUBLIC
  19019. --
  19020. --  PURPOSE:  Only allows a folder to be opened if the folder is unlocked, or
  19021. --            if the user supplies the correct password in response to the
  19022. --            dialog.
  19023. --
  19024. --  INVOKED:  By Workplace Shell, upon selection of the "Open" menu item by
  19025. --            the user.
  19026. --
  19027.  
  19028. override wpSetTitle;
  19029. --
  19030. --  METHOD:   wpSetTitle                                  PUBLIC
  19031. --
  19032. --  PURPOSE:  Sets the folder's title (icon text) to have the phrase <Locked>
  19033. --            as a suffix if the folder is locked, or removes this suffix if
  19034. --            the folder is unlocked.
  19035. --
  19036. --  INVOKED:  By wpOpen to set the unlocked state, and by LockFolder to set
  19037. --            the locked state.
  19038. --
  19039.  
  19040. override wpSetup;
  19041. --
  19042. --  METHOD:   wpSetup                                     PUBLIC
  19043. --
  19044. --  PURPOSE:  Sets folder properties based upon a setup string passed by the
  19045. --            object's creator as part of the WinCreateObject() call.  The
  19046. --            overridden method simply processes the PASSWORD keyword to set
  19047. --            the folder's password immediately upon instantiation, before
  19048. --            invoking the parent's default processing to handle all other
  19049. --            keywords.
  19050. --
  19051. --  INVOKED:  By the Workplace Shell, upon instantiation of the object
  19052. --            instance.
  19053. --
  19054.  
  19055. override wpSaveState;
  19056. --
  19057. --  METHOD:   wpSaveState                                 PUBLIC
  19058. --
  19059. --  PURPOSE:  Saves the object instance's persistent state data.  The
  19060. --            overridden method simply saves the password data, then invokes
  19061. --            the parent's default processing to handle any other instance
  19062. --            data defined by ancestor classes.
  19063. --
  19064. --  INVOKED:  By the Workplace Shell, when the object becomes dormant.
  19065. --
  19066.  
  19067. override wpRestoreState;
  19068. --
  19069. --  METHOD:   wpRestoreState                              PUBLIC
  19070. --
  19071. --  PURPOSE:  Restores the object instance's persistent state data.  The
  19072. --            overridden method simply restores the password data, then
  19073. --            invokes the parent's default processing to handle any other
  19074. --            instance data defined by ancestor classes.
  19075. --
  19076. --  INVOKED:  By the Workplace Shell, when the object becomes awake.
  19077. --
  19078.  
  19079. override wpSetIcon;
  19080. --
  19081. --  METHOD:   wpSetIcon                                   PUBLIC
  19082. --
  19083. --  PURPOSE:  This class method returns the handle to the correct icon for
  19084. --            the object.
  19085. --
  19086. --  INVOKED:  -
  19087. --
  19088.  
  19089. override wpclsQueryTitle, classmethod;
  19090. --
  19091. --  METHOD:   wpclsQueryTitle                             PUBLIC
  19092. --
  19093. --  PURPOSE:  This class method returns the default folder title for any
  19094. --            instance of the password protected folder class.  This title
  19095. --            is used if a title is not supplied in the WinCreateObject()
  19096. --            call.
  19097. --
  19098. --  INVOKED:  By the Workplace Shell, upon instantiation of the object
  19099. --            instance.
  19100. --
  19101.  
  19102. override wpclsInitData, classmethod;
  19103. --
  19104. --  METHOD:   wpclsInitData                               PUBLIC
  19105. --
  19106. --  PURPOSE:  This class method allows the initialization of any class data
  19107. --            items.  The overridden method simply obtains a module handle
  19108. --            to be used when accessing Presentation Manager resources, then
  19109. --            invokes the parent's default processing.
  19110. --
  19111. --  INVOKED:  By the Workplace Shell, upon loading the class DLL.
  19112. --
  19113.  
  19114. override wpclsQueryIcon, classmethod;
  19115. --
  19116. --  METHOD:   wpclsQueryIcon                                 PUBLIC
  19117. --
  19118. --  PURPOSE:  This class method returns the handle to the default icon for
  19119. --            the class.  This method is not used in the current version,
  19120. --            but could be used if different icons are to be used for the
  19121. --            locked and unlocked states.
  19122. --
  19123. --  INVOKED:  -
  19124. --
  19125.  
  19126. override wpclsUnInitData, classmethod;
  19127. --
  19128. --  METHOD:   wpclsUnInitData                             PUBLIC
  19129. --
  19130. --  PURPOSE:  This class method allows the release of any class data items
  19131. --            or resources.  The overridden method releases the module handle
  19132. --            obtained by wpclsInitData, then invokes the parent's default
  19133. --            processing.
  19134. --
  19135. --  INVOKED:  By the Workplace Shell, upon unloading the class DLL.
  19136. --
  19137.  
  19138.  
  19139. ΓòÉΓòÉΓòÉ 32.1.2. Source Code for the PWFolder.C file ΓòÉΓòÉΓòÉ
  19140.  
  19141. /*************************************************************************/
  19142. /*                                                                       */
  19143. /* ITSC Redbook OS/2 v2.0 Sample Program                                 */
  19144. /*                                                                       */
  19145. /*                                                                       */
  19146. /* PWFOLDER.C                                                            */
  19147. /*                                                                       */
  19148. /*                                                                       */
  19149. /*************************************************************************/
  19150.  
  19151. /*
  19152.  * This file was generated by the SOM Compiler.
  19153.  * FileName: pwfolder.c.
  19154.  * Generated using:
  19155.  *     SOM Precompiler spc: 1.22
  19156.  *     SOM Emitter emitc: 1.24
  19157.  */
  19158. #define INCL_WIN
  19159. #define INCL_DOS
  19160. #define INCL_GPIBITMAPS
  19161. #define INCL_WPCLASS
  19162. #define INCL_WPFOLDER
  19163.  
  19164. /******************************************************************************/
  19165. /* System-defined header files                                                */
  19166. /******************************************************************************/
  19167. #include <os2.h>
  19168.  
  19169. #include <pmwp.h>  /* eventually will be #define INCL_WINWORKPLACE */
  19170.  
  19171. #include <string.h>
  19172. #include <stdio.h>
  19173. #include <memory.h>
  19174. #include <stdlib.h>
  19175.  
  19176. /******************************************************************************/
  19177. /* Function prototype for dialog proc                                         */
  19178. /******************************************************************************/
  19179. M