home *** CD-ROM | disk | FTP | other *** search
/ Arawak OS/2 Shareware / PAKLED.ISO / docs / edm / edmi2-2.inf (.txt) < prev    next >
Encoding:
OS/2 Help File  |  1994-02-01  |  133.1 KB  |  1,606 lines

  1.  
  2. ΓòÉΓòÉΓòÉ 1. Title Page ΓòÉΓòÉΓòÉ
  3.  
  4.            Welcome to EDM/2 - The Electronic OS/2 Developers Magazine!
  5.                    Portions copyright (c) by Larry Salomon Jr.
  6.                                 Volume 2, issue 2
  7.  
  8. Copyright Notice and Other Stuff 
  9.  
  10. The editor of this electronic magazine is Larry Salomon, Jr. 
  11.  
  12. Portions of EDM/2 are copyrighted by the editors.  This publication may be 
  13. freely distributed in electronic form provided that all parts are present in 
  14. their original unmodified form.  A reasonable fee may be charged for the 
  15. physical act of distribution; no fee may be charged for the publication itself. 
  16.  
  17. All articles are copyrighted by their authors. No part of any article may be 
  18. reproduced without permission from the original author. 
  19.  
  20. Neither this publication nor the editors are affiliated with International 
  21. Business Machines Corporation. 
  22.  
  23. OS/2 is a registered trademark of International Business Machines Corporation. 
  24. Other trademarks are property of their respective owners.  Any mention of a 
  25. product in this publication does not constitute an endorsement or affiliation 
  26. unless specifically stated in the text. 
  27.  
  28. Administrivia 
  29.  
  30. More Format Changes 
  31.  
  32. First, I would like to say that I (finally) understood what the comments of 
  33. "duplicate introductions" mean.  Let me defend myself by claiming that I always 
  34. thought that the readers would use the hyperlinks that were defined at the end 
  35. of each section.  People who noticed this behavior were instead using the 
  36. Forward button to cycle through all of the panels. Since the issue was built 
  37. with two copies of the introduction - one which is displayed if you select the 
  38. article or column title, and one if you select the Introduction section - they 
  39. were seeing both.  In lieu of this annoying behavior, only one introduction 
  40. will be present. 
  41.  
  42. As a last minute change, I decided to remove the hyperlinks at the end of each 
  43. section for the following two reasons: 
  44.  
  45. o They duplicate the functionality of the Forward button. 
  46. o If there are other hyperlinks in the section, it is not "just a press of the 
  47.   Enter key" to get to the next section. 
  48.  
  49. Thus, I have removed these links and suggest to those that used them to use the 
  50. Alt+F key or the Forward button via the mouse. 
  51.  
  52. Another format change is that the CONTENTS.NDX file has been moved out of the 
  53. EDMIv-i.ZIP file.  To avoid conflicts with index files from later issues, it 
  54. has also been renamed to EDMIv-i.NDX. Doing this will allow those who are 
  55. interested in specific topics to just download this file to see what the issue 
  56. contains. 
  57.  
  58. Awards News Flash 
  59.  
  60. If anyone knows how to contact Gavin Baker, please do so and tell him what he 
  61. won (, Bob :) .  Email sent to his address bounces, so I cannot get his address 
  62. to mail his prize.  If we do not hear from him by the release of next month's 
  63. issue, the prize will be awarded to someone else. 
  64.  
  65. Speaking of prizes, we still have not received them.  While we are not blaming 
  66. anyone, this is being pointed out to explain for the delay.  As soon we receive 
  67. them, they will be shipped out. 
  68.  
  69. And In This Corner 
  70.  
  71. This month seems to be the month of reviews; we have two reviews that I think 
  72. the readers will be interested in:  Gordon Zeglinski has (finally) received his 
  73. copy of IBM's C-Set++/2 version 2.1 product and presents an update to his 
  74. compiler comparison that appeared in volume 1, issue 5.  Also, Jonathan Story 
  75. wrote a very interesting review of Quercus Systems's Personal Rexx product on 
  76. the Internet, and we were granted permission to reproduce it here.  Many thanks 
  77. to Jonathan for allowing us to do so. 
  78.  
  79. Congratulations to Patrick Mueller for finally getting approval from IBM to 
  80. submit his article.  He had expressed a desire to do so around volume 1, issue 
  81. 5, but didn't have time to deal with the beaurocratic issues involved.  Maybe 
  82. Lou's influence is starting to extend itself to North Carolina :) .  I would 
  83. also like to state that - to date - Patrick's article was the easiest to 
  84. reformat, since 99% of his submitted text followed the Article Submission 
  85. Guidelines. 
  86.  
  87. (I wonder how many people will pick up the puns in the graphic for that 
  88. article.  I'll take your guesses and will publish the name of the first correct 
  89. answer for each of the three.) 
  90.  
  91. WPS Developer Wanna-Be's 
  92.  
  93. For the people beginning (or attempting to begin, as the case may be) to do 
  94. Workplace Shell development, watch this space; I'm learning quickly how this 
  95. stuff works, and while I am only a beginner, many people have a hard time 
  96. getting anything to work at all.  I'm hoping to have an introductory article on 
  97. this topic for the next issue. 
  98.  
  99. In the meantime, there is a SOM/WPS mailing list run by Gess Shankar, who does 
  100. the EDM/2 distribution on the Internet.  If you are interested in joining, send 
  101. a blank mail message to somwps-info@knex.via.mind.org. 
  102.  
  103. Continuations 
  104.  
  105. Andre Asselin apologizes for not having the next part of his award-winning 
  106. series OS/2 Installable File Systems ready for this issue, but promised to have 
  107. it for the next issue. 
  108.  
  109. Marc van Woerkom was to continue his series Making Noise with MMPM/2.  Because 
  110. he was running behind, I agreed to wait until Friday for his article. 
  111. Unfortunately, something has come up and I will not be here on Friday, so I 
  112. asked him if he could get it to me sooner.  Since I never received a response, 
  113. I decided to push his article until next issue. 
  114.  
  115. I hate doing things like this, but such is the life of the editor. :( 
  116.  
  117. A Final Thanks 
  118.  
  119. ...to all of the subscribers who answered my four question survey sent out in 
  120. the last week of January.  The results were very interesting; I hope to compile 
  121. them and send out a summary of what I received.  It's still not too late to 
  122. send me your responses, however! 
  123.  
  124.  
  125. ΓòÉΓòÉΓòÉ 2. This Issue's Features ΓòÉΓòÉΓòÉ
  126.  
  127. The following articles constitute this issue's features: 
  128.  
  129. o A Review of Personal REXX for OS/2 
  130. o TCP/IP Socket Programming in REXX 
  131.  
  132.  
  133. ΓòÉΓòÉΓòÉ 2.1. A Review of Personal REXX for OS/2 ΓòÉΓòÉΓòÉ
  134.  
  135. Written by Jonathan Story 
  136.  
  137. OS/2 is like a chest full of treasures.  It runs OS/2, DOS and Windows 
  138. programs, and you don't need to buy DOS or Windows because both are already 
  139. included.  And when you dig a little deeper you discover REXX, a jewel brought 
  140. over from the mainframe world. 
  141.  
  142. OS/2 includes REXX for no extra charge.  Quercus Systems, makers of Personal 
  143. REXX, would be very happy to sell you a copy of their version.  Why should 
  144. anyone pay good money for something they already have?  Well, consider OS/2's 
  145. REXX compared to Personal REXX as the difference between a good pair of 
  146. sensible street shoes and top-of-the-line rollerblades. 
  147.  
  148.  
  149. ΓòÉΓòÉΓòÉ 2.1.1. Documentation ΓòÉΓòÉΓòÉ
  150.  
  151. The documentation that comes with Personal REXX can help almost anyone to get 
  152. started learning and using REXX.  It includes:  a User's Guide, an OS/2 
  153. Addendum, a REXXLIB User's Guide, a Reference Summary booklet, and the book The 
  154. REXX Language:  A Practical Approach to Programming, Second Edition by M.F. 
  155. Cowlishaw (the 'bible' for the REXX language.) 
  156.  
  157. For the novice, the User's Guide introduces the elements of the language in an 
  158. easy step-by-step fashion illustrated by brief example programs.  The Guide 
  159. takes care to distinguish between what is a part of the language itself and the 
  160. extensions from Quercus.  For someone who wants to make his programs work on as 
  161. many environments as possible, this is very important to know. 
  162.  
  163.  
  164. ΓòÉΓòÉΓòÉ 2.1.2. Installation ΓòÉΓòÉΓòÉ
  165.  
  166. This is one of the few areas I would like to see improved.  Personal REXX for 
  167. OS/2 has an install program, but it does not modify your CONFIG.SYS.  It could 
  168. be that the installation process avoids changing anything that might cause 
  169. problems, although for me installing manually caused problems anyway:  I 
  170. completed what was left of the install by hand according to the instructions, 
  171. but it took me two tries (rebooting each time) before successfully making the 
  172. changeover from the REXX included with OS/2 to Quercus's Personal REXX.  Why 
  173. should the ordinary REXX user have to know about PATH and LIBPATH?  Adding a 
  174. few more smarts so that everything will install automatically (an uninstall 
  175. would be another pleasant bonus) can remove this unwelcome technical encounter. 
  176.  
  177. A minor nit:  a program called INSTEST checks that all components of the 
  178. package have been installed.  This is useful (and, for me, was necessary), but 
  179. when nothing is correctly installed the report can be misinterpreted to suggest 
  180. that all is okay.  A more informative message ("Personal REXX is NOT 
  181. installed") and some corrective suggestions would make INSTEST more useful. 
  182.  
  183.  
  184. ΓòÉΓòÉΓòÉ 2.1.3. Compatibility ΓòÉΓòÉΓòÉ
  185.  
  186. Almost every program that runs under OS/2's REXX will also run under Personal 
  187. REXX.  The exceptions are few and are documented.  (One very rare condition is 
  188. not documented:  If a REXX program is reading characters from the standard 
  189. input and then invokes another program that also is reading from the standard 
  190. input, the second program might not receive the first part of the remaining 
  191. data.  This has to do with how Personal REXX reads buffers and here 
  192. compatibility is sacrificed for speed.) 
  193.  
  194. In addition, Personal REXX has loosened some of the constraints in OS/2's REXX. 
  195. It has increased the maximum number of arguments for a procedure from 20 to 
  196. 250, and the number of I/O streams from 15 to 50.  But mere compatibility is 
  197. not sufficient reason to use Personal REXX. 
  198.  
  199.  
  200. ΓòÉΓòÉΓòÉ 2.1.4. Enhancements ΓòÉΓòÉΓòÉ
  201.  
  202. It is, of course, important that programs running OS/2's REXX continue to work 
  203. with Personal REXX.  But the real seasoning for this product comes from greater 
  204. speed and abilities. 
  205.  
  206. The first thing you notice when using Personal REXX is that programs run 
  207. faster.  In most cases the difference is not only noticeable, it is striking. 
  208. Like moving from a 386 to a 486, or from a 486 to a Pentium, performance 
  209. typically doubles or better.  Some people use REXX for easy prototyping and 
  210. then recode in C for speed.  Personal REXX surprisingly often can be an 
  211. acceptable alternative to a compiled program.  In addition to programs running 
  212. faster, Personal REXX includes functions for things that either cannot be done 
  213. in standard REXX or that would otherwise need clever workarounds. 
  214.  
  215. The utilities enhancements to standard REXX can be grouped into three areas: 
  216. PC hardware; the Operating System; and miscellaneous functions. With the 
  217. hardware functions you can discover the PC type, the type of drives on the 
  218. system, the type of keyboard, the number of serial and parallel ports, and so 
  219. on.  You can change the cursor position, make sounds from the PC's speaker, 
  220. change the shift state of the NumLock and CapsLock keys, and more. (There is 
  221. some difference in the kinds of things that can be done by the OS/2 version and 
  222. the DOS version of Personal REXX.  This is related to the degree the operating 
  223. system isolates a program from the physical environment and the meaningfulness 
  224. of the information.  For example, in OS/2 you don't have PEEK() and POKE(), and 
  225. there is no such thing as EMS memory.) 
  226.  
  227. Operating system functions can sometimes be handled in REXX simply by passing 
  228. the command on to the OS environment.  Personal REXX provides functions that do 
  229. these too, and more.  In addition to DOSCD() to change the current directory, 
  230. there is also DOSISDEV() and DOSISDIR() to detect whether something is a file 
  231. or a device. 
  232.  
  233. Miscellaneous functions provided with Personal REXX include some that it would 
  234. be easy to imagine had been left out of standard REXX by mistake.  In 
  235. particular, UPPER() to convert characters to upper case and LOWER(), plus 
  236. DATECONV() to convert a date from one type to another. 
  237.  
  238. CMS-like facilities 
  239.  
  240. For the old guard REXX programmer who learned the language when it first 
  241. appeared on IBM's mainframes, Personal REXX gives some consideration.  The 
  242. three commands LISTFILE, EXECIO, and GLOBALV were a staple of such old REXX 
  243. programs.  In this package these three commands are included as utilities, 
  244. making it easier to convert code to run on PCs. 
  245.  
  246.  
  247. ΓòÉΓòÉΓòÉ 2.1.5. REXXLIB ΓòÉΓòÉΓòÉ
  248.  
  249. REXXLIB is a package included with Personal REXX for OS/2, but one can purchase 
  250. it separately to use with OS/2's REXX.  It contains a wide range of functions 
  251. to make programming easier. 
  252.  
  253. One group of functions repairs a major deficiency in the language itself. 
  254. Compound variables serve the same purpose as arrays do in other languages. 
  255. These variables can have arbitrary indexes - a valuable tool.  But REXX cannot 
  256. simply find all indexes that have been defined, which reduces the power of 
  257. arbitrary indexes.  REXXLIB addresses this flaw with CVTAILS() and related 
  258. functions:  CVTAILS() makes an array of all the tails of a compound variable. 
  259. CVWRITE() writes all values of a variable to a file and CVREAD() reads values 
  260. from this file.  CVCOPY() copies the values of a compound variable. 
  261.  
  262. Another type of compound variable is known as an array.  Here, the stem indexes 
  263. begin at 1 and increase sequentially.  The total number of array elements is 
  264. kept in the element 0. Functions developed for this are:  ARRAYCOPY(), 
  265. ARRAYDELETE(), ARRAYINSERT(), and ARRAYSORT(). 
  266.  
  267. VARDUMP(), VARREAD(), and VARWRITE() read and write the values of variables 
  268. from and to a file.  This makes it easy for a program to recall what it was 
  269. doing the last time it ran. 
  270.  
  271. There are also functions that deal with OS/2 sessions, processes, and other 
  272. services.  These let you, for example, change the priority of a process or kill 
  273. it.  In addition, to make working with concurrently running processes easier, 
  274. REXXLIB includes the ability to use semaphores and named pipes. 
  275.  
  276. Finally, the package includes some very useful mathematical functions: 
  277. logarithms (LOG(), LOG10()); exponentiation (EXP(), POW(), SQRT()); 
  278. trigonometric (SIN(), COS(), TAN(), etc.); hyperbolic (COSH(), SINH(), TANH()); 
  279. plus ERF(), ERFC(), and GAMMA(). 
  280.  
  281.  
  282. ΓòÉΓòÉΓòÉ 2.1.6. Conclusion ΓòÉΓòÉΓòÉ
  283.  
  284. Personal REXX for OS/2 with REXXLIB adds speed and power to REXX in the OS/2 
  285. environment.  True, it doesn't match the glitter of the GUI REXXes, but in raw 
  286. performance it shines. 
  287.  
  288. Contact information: 
  289.  
  290. Quercus Systems
  291. P.O. Box 2157
  292. Saratoga, CA 95070
  293.    (408) 867-7399
  294. Fax: (408) 867-7489
  295. BBS: (408) 867-7488
  296.  
  297.  
  298. ΓòÉΓòÉΓòÉ 2.2. TCP/IP Socket Programming in REXX ΓòÉΓòÉΓòÉ
  299.  
  300. Written by Patrick Mueller 
  301.  
  302. Legal Glorp 
  303.  
  304. Copyright IBM Corp., 1994.  All Rights Reserved. 
  305.  
  306. While the information provided herein is believed to be accurate, IBM does not 
  307. warrant the information, and the information is provided "as is". 
  308.  
  309. OS/2 is a trademark of International Business Machines Corp.
  310. Unix is a trademark of X/Open Company Ltd.
  311.  
  312.  
  313. Introduction 
  314.  
  315. Remember when your mother used to tell you "Don't stick things into the wall 
  316. outlets - sockets are dangerous!"  Well, you've grown up, and guess what: 
  317. sockets are fun to play with!  At least TCP/IP sockets are. TCP/IP sockets are 
  318. the programming interface used by all your favorite TCP/IP programs, including 
  319. FTP, TELNET, news readers, IRC, and so forth. 
  320.  
  321. Most implementations of TCP/IP provide a programming toolkit that includes a C 
  322. language library for socket functions.  I've created a REXX interface to the 
  323. TCP/IP socket functions as provided by the IBM TCP/IP product, allowing 
  324. programs that use sockets to be written in the REXX language as well as the C 
  325. language. 
  326.  
  327. In this article, I will discuss how to write programs in REXX that access 
  328. TCP/IP sockets.  First, I give an overview of sockets, followed by a 
  329. description of the socket programming interface available for REXX.  Then, I 
  330. explain the sample programs shipped with the article (TMSG.CMD and TMSGD.CMD). 
  331. Finally, I list a set of references that provide more information on 
  332. programming with sockets, and what you can use sockets for. 
  333.  
  334. After reading the article, you should have enough information to start 
  335. implementing clients and servers for your favorite TCP/IP protocols, or 
  336. implementing new protocols and applications in REXX that run over TCP/IP. 
  337.  
  338.  
  339. ΓòÉΓòÉΓòÉ 2.2.1. What are sockets? ΓòÉΓòÉΓòÉ
  340.  
  341. The TCP/IP programming interface provides a way to allow multiple computers to 
  342. work together, assuming that they are connected somehow.  Computers that are 
  343. connected form a network, and there are a number of different ways computers 
  344. can be connected to one another:  Token Ring LANs, Ethernet, telephone 
  345. connections, and so on.  Although it is possible to write programs with a 
  346. specific type of connection in mind, it is often not practical to do so. 
  347. Instead, there are abstraction layers for network programming that provide 
  348. common programming interfaces and handle the underlying physical network 
  349. connections for you. 
  350.  
  351. TCP/IP is one such abstraction layer.  There are TCP/IP implementations 
  352. available for nearly all popular networks.  It is also widely available on 
  353. various harware platforms - from lowly 8088 PCs, to supercomputers - and 
  354. everything in between.  So, programming to the TCP/IP layer not only gives you 
  355. network independence, but also some level of platform independence. 
  356.  
  357. The lowest level of programming to the TCP/IP layer is done with sockets. 
  358. Sockets are in many ways similar to file handles in traditional programming 
  359. languages.  Within a program, you open a socket, read from the socket, write to 
  360. the socket, and close the socket.  The main difference is that instead of a 
  361. file handle being associated with a file on a disk drive, a socket is 
  362. associated with another program that is also reading and writing data on the 
  363. socket.  In this manner, sockets are similar in behavior to pipes on OS/2 and 
  364. Unix. 
  365.  
  366. Programs that use sockets often use a client/server model.  In this model, a 
  367. server program and a client program both open sockets and connect them 
  368. together.  The client sends some data to the server; the server reads the data, 
  369. does some processing, and sends data back to the client.  The client then reads 
  370. that data back from the server.  This data exchange can continue back and forth 
  371. for some time.  Eventually, both the client and server program close their 
  372. sockets and end the communication. 
  373.  
  374. As an example, consider news readers and news servers.  When you read Usenet 
  375. news, you start up your news reader (client).  The client connects to an 
  376. already-running news server (server).  The client requests information from the 
  377. server, for instance, "list all the subject lines for articles in the 
  378. comp.os.os2.programmer.misc news group".  The client requests the information 
  379. by sending this command (in a more standardized form than the English example 
  380. given above) to the server. The server consults its database of Usenet news and 
  381. sends back the list of subject lines.  This sort of command/response flow is 
  382. typical of the client/server model. 
  383.  
  384.  
  385. ΓòÉΓòÉΓòÉ 2.2.2. Socket functions for sending and receiving data ΓòÉΓòÉΓòÉ
  386.  
  387. Below is a description of the basic socket functions that TCP/IP socket 
  388. programs can use.  There are functions to open and close a socket and functions 
  389. to read from and write to a socket.  The functions described are the REXX 
  390. functions available in the rxSock function package. 
  391.  
  392. o SockSocket(family,type,protocol) 
  393.  
  394.   This function creates a new socket and returns it to the caller.  The socket 
  395.   is an integer value.  The socket is used by all the other socket functions, 
  396.   passed as the first parameter. 
  397.  
  398.   The parameters passed to the socket determine different flavors of socket the 
  399.   programmer can use.  Most of the time, the values AF_INET, SOCK_STREAM, and 
  400.   IPPROTO_TCP are used as the parameters, respectively.  Other values are used 
  401.   only for special purposes. 
  402.  
  403. o SockRecv(socket,buffer,length,flags) 
  404.  
  405.   This function reads data from the socket.  The buffer parameter is the name 
  406.   of a variable that will be used to place the data received from the socket. 
  407.   The length parameter is the maximum amount of data to be received by the 
  408.   socket.  The flags parameter is generally unused and is optional. 
  409.  
  410.   The number of bytes actually read into the buffer variable is returned from 
  411.   the function. 
  412.  
  413. o SockSend(socket,string,flags) 
  414.  
  415.   This function writes data into the socket.  The string parameter is the data 
  416.   sent into the socket.  The flags parameter is generally unused and is 
  417.   optional. 
  418.  
  419.   The number of bytes actually written is returned from the function. 
  420.  
  421. o SockClose(socket) 
  422.  
  423.   This function closes a socket and makes it unusable on both sides of the 
  424.   connection. 
  425.  
  426. Sockets have the following properties: 
  427.  
  428. o The data sent and received on a socket is not translated in any way.  If your 
  429.   programs must deal with EBCDIC and ASCII character encoding, or byte ordering 
  430.   of integers, you need to provide this in your program. 
  431.  
  432. o Sockets are full duplex, meaning that a program can both read and write to 
  433.   the same socket. 
  434.  
  435. o Data transmitted via SockSend() can be broken up by the underlying software 
  436.   into smaller units.  For example, if a SockSend() of 8 bytes occurs, the data 
  437.   may be received by one call to SockRecv() returning 3 bytes, and the next 
  438.   call to SockRecv() returning 5 bytes. 
  439.  
  440. o If a program calls SockRecv() and the other program has not sent any data via 
  441.   SockSend(), the SockRecv() call blocks until some data has been sent, or the 
  442.   socket is closed on the SockSend() side. 
  443.  
  444. The properties described above imply that the client and server programs have 
  445. to know something about the data being sent over the network.  For instance, if 
  446. you plan on sending binary data as 2-or 4-byte integers between a client and 
  447. server, you'll have to decide before writing the programs what the order of the 
  448. bytes in the integer will be.  On most PC workstations, integers are stored 
  449. internally with their bytes reversed.  For instance, the number 0x12AB is 
  450. stored internally as AB 12.  Many of the higher-powered, non-PC workstations 
  451. store integers without the bytes reversed. Choose either the reversed or 
  452. non-reversed format, and then make sure the hardware your program is running on 
  453. uses that format.  If it doesn't, reverse the bytes before sending them (or 
  454. after receiving them, as the case may be). 
  455.  
  456. Also, because text sent with SockSend() can be broken into multiple packets, 
  457. you will have to determine how the program doing the SockRecv() will decide 
  458. when it has received enough data.  It can't read until it gets everything, 
  459. since it will eventually block. Instead, you will have to rely on one of the 
  460. following techniques: 
  461.  
  462. o Have the sender and receiver pass messages of a predetermined, fixed length. 
  463.  
  464. o Have the sender sender prefix the data being sent with its length, which the 
  465.   receiver can read first to determine the length of the data to be received. 
  466.  
  467. o Have the sender add a special character or characters to the end of the data 
  468.   to signify the end of the data.  Many client/server programs use this method, 
  469.   particularly if they are sending textual data across the network.  The 
  470.   terminating characters are often a carriage return, followed by a line feed. 
  471.  
  472.  
  473. ΓòÉΓòÉΓòÉ 2.2.3. Socket functions for connecting clients and servers ΓòÉΓòÉΓòÉ
  474.  
  475. The functions SockRecv() and SockSend() described above only can be used once a 
  476. socket is connected to another machine.  But how does the connection between 
  477. two programs take place?  In order for a client program to talk to a server 
  478. program, the client has to know on what machine the server is running.  Every 
  479. machine on the TCP/IP network is uniquely identified by a 32-bit number, called 
  480. its Internet address, or IP address.  Because 32-bit numbers can get rather 
  481. unwieldy to use for humans, they are often displayed as four 8-bit numbers, 
  482. converted to decimal numbers with dots between them, called dot decimal 
  483. addresses.  For example, the address 9.67.225.165 corresponds to the 32-bit 
  484. number 9 * 256^3 + 67 * 256^2 + 225 * 256 + 165 = 155,443,621.  Even dot 
  485. decimal addresses are unwieldy, so there's usually a human readable name also 
  486. associated with each IP address, called its hostname. 
  487.  
  488. The socket functions generally deal with IP addresses.  There is a function - 
  489. SockGetHostByName() - that can be used to convert a hostname to an IP address, 
  490. so many programs accept either an IP address or hostname as a machine address. 
  491. When a hostname is passed in, it is converted to an IP address, and that 
  492. address is used in the remainder of the program. 
  493.  
  494. Because there is often more than one server program running on a machine, there 
  495. must be a way to distinguish between them.  This is done with a port.  A port 
  496. is just an integral number that is associated with a particular server.  Most 
  497. of the programs provided with TCP/IP, such as FTP, TELNET, SMTP (mail), have 
  498. "well-known" ports associated with them.  The well-known port for FTP is 21, 
  499. and the well-known port for TELNET is 23.  In other words, any program that 
  500. wants to interact with an FTP server uses 21 as the port.  Two servers on the 
  501. same machine cannot use the same port. 
  502.  
  503. If you are writing your own client and server program with sockets, you'll need 
  504. to have the client and server agree on a port.  This can be done by hard-coding 
  505. it in your program or by allowing it to be passed in as a parameter to the 
  506. program. 
  507.  
  508. The combination of an address and port are enough to distinguish any particular 
  509. server running on any machine in the network.  These two numbers are set in the 
  510. address stem variable, which is used in functions to connect clients and 
  511. servers.  These functions are described below.  See the rxsock.doc file shipped 
  512. with the rxSock function package for more information on the address stem 
  513. variable. 
  514.  
  515. o SockBind(socket,address) 
  516.  
  517.   This function is used by servers to reserve a port.  The port field of the 
  518.   address stem variable is filled in with the port the server will be using. 
  519.  
  520. o SockAccept(socket,address) 
  521.  
  522.   This function is used by a server to wait for a client to try to make a 
  523.   connection.  The socket must have been bound with the SockBind() function 
  524.   above before calling SockAccept().  Once the connection is made, the function 
  525.   returns a new socket and fills in the address stem variable with the IP 
  526.   address of the client.  The new socket returned is used for all other 
  527.   communication with the client.  The original socket remains open, waiting for 
  528.   new connections. 
  529.  
  530. o SockConnect(socket,address) 
  531.  
  532.   This function is used by a client when it tries to connect to a server. The 
  533.   address stem variable is filled in with the IP address and port of the 
  534.   server. 
  535.  
  536. The basic flow of the reading, writing, and connecting functions is shown 
  537. below. 
  538.  
  539. Note that the loop for SockSend() and SockRecv() is dependant on the 
  540. application - some clients will just send, receive, or send and receive data 
  541. once.  The loop enclosing SockAccept() on the server is to handle each client ; 
  542. each time through the loop corresponds with one client session.  The 
  543. SockClose() call in the loop on the server is to close the socket obtained by 
  544. SockAccept(), not the socket obtained by SockSocket(). 
  545.  
  546.       client                     server
  547.       ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇ           ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇ
  548.                                  SockSocket()
  549.                                  SockBind()
  550.       SockSocket()
  551.                                  loop ...
  552.       SockConnect()                 SockAccept()
  553.  
  554.       loop ...                      loop ...
  555.          SockSend()                    SockRecv()
  556.          SockRecv()                    SockSend()
  557.  
  558.       SockClose()                   SockClose()
  559.                                  SockClose()
  560.  
  561.  
  562. ΓòÉΓòÉΓòÉ 2.2.4. rxSock - the REXX Socket Programming Function Package ΓòÉΓòÉΓòÉ
  563.  
  564. Up until now I've only discussed the socket functions themselves.  The socket 
  565. functions are not included in OS/2 REXX itself, but implemented in a function 
  566. package.  The function package is implemented in an OS/2 Dynamic Link Library 
  567. (DLL), available from the IBM Employee Written Software (EWS) program.  EWS 
  568. files are available from a number of places, including CompuServe, and the 
  569. ftp.cdrom.com and software.watson.ibm.com anonymous FTP sites.  Look for a 
  570. subdirectory called EWS.  On ftp.cdrom.com, rxsock is located in the 
  571. /pub/os2/ibm/ews subdirectory.  The rxSock function package is in a file called 
  572. rxsock.zip. Unpack the .ZIP file, and read the rxsock.doc file for installation 
  573. instructions and reference material on the functions in rxSock. 
  574.  
  575. The REXX functions implemented in rxSock closely match the socket functions 
  576. available to C programs.  If you already know C, once you learn the REXX socket 
  577. functions, you won't have any problem learning the C socket functions.  In this 
  578. respect, rxSock provides a way to prototype socket programs in REXX, and then 
  579. implement them in C for speed. 
  580.  
  581. The rxSock function package is supported with the OS/2 TCP/IP product, versions 
  582. 1.2.1 and 2.0.  At this time, I know of no other non-IBM TCP/IP implementations 
  583. that support rxSock. 
  584.  
  585.  
  586. ΓòÉΓòÉΓòÉ 2.2.5. Example programs - TMSG and TMSGD ΓòÉΓòÉΓòÉ
  587.  
  588. Now it's time to put all the pieces together and write an application. This 
  589. example is an application to send a textual message from one OS/2 machine to 
  590. another. 
  591.  
  592. Two programs are used to implement the application:  TMSG is the client, and 
  593. TMSGD is the server.  The client program is used to send a message to the 
  594. server.  The server receives the message and displays it on the console. 
  595.  
  596. To start the server, just run the TMSGD program.  It will display a startup 
  597. message and then wait for clients to send messages.  The program will not 
  598. terminate unless you press Ctrl-C or Ctrl-Break. 
  599.  
  600. To use the client, run the TMSG program, passing it the hostname of the machine 
  601. to display the message on, followed by the text of the message. 
  602.  
  603. To test the programs on your own system, 
  604.  
  605.  1. start the server 
  606.  2. run the client, passing your hostname as the first parameter 
  607.  
  608. Both programs assign a port number (the same number) at the top of the program, 
  609. and make sure the rxSock package is loaded. 
  610.  
  611. The TMSG program does the following: 
  612.  
  613. o Converts the hostname to an IP address 
  614. o Creates a socket 
  615. o Connects the socket to the server 
  616. o Sends the message to the server - the message is followed by a carriage 
  617.   return and then a linefeed character 
  618. o Closes the socket 
  619.  
  620. The TMSGD program does the following: 
  621.  
  622. o Creates a socket 
  623. o Minds the socket to a port 
  624. o Loops through the following processing (once per client connection) 
  625.  
  626.    - Accepts a connection from the client 
  627.  
  628.    - Converts the client's IP address to a hostname 
  629.  
  630.    - Reads the message from the client - it reads from the socket until it 
  631.      receives a carriage return and then a linefeed character. 
  632.  
  633.    - Closes the socket returned from the SockAccept() call 
  634.  
  635.    - Displays the message 
  636.  
  637. A few notes on some of the other processing the programs do: 
  638.  
  639. o The client program does a SockRecv() before closing the socket. The server 
  640.   never sends any data back, but the SockRecv() call will return having read 0 
  641.   bytes when the server closes the socket.  The call to SockRecv() does nothing 
  642.   more than wait for the server to close its side of the socket before the 
  643.   client closes its side.  If the client were to close its socket before the 
  644.   server read all the data, the server might not receive all the data. 
  645.  
  646. o In this example, the client program never received anything back from the 
  647.   server.  Quite often, the client receives data back from the server after 
  648.   sending it some data, but not always. 
  649.  
  650. o The SockListen() call by the server is used to set the backlog of connections 
  651.   that TCP/IP will handle.  If the server gets a connection request while it's 
  652.   processing another client, this connection will be queued up until the server 
  653.   can handle it.  The number passed to SockListen() determines the maximum 
  654.   number of connection requests the will be queued up by the server. 
  655.  
  656.  
  657. ΓòÉΓòÉΓòÉ 2.2.6. References ΓòÉΓòÉΓòÉ
  658.  
  659. Two good books on socket programming are: 
  660.  
  661. o "Internetworking with TCP/IP" by Douglas Comer, ISBN 0134685059 
  662.  
  663. o "Unix Network Programming" by Richard Stevens, ISBN 0139498761 
  664.  
  665. The Comer book focuses more on TCP/IP, especially on the internals of TCP/IP, 
  666. and the Stevens book focuses more on different types of interprocess 
  667. communication on Unix systems.  Unless you are really interested in the 
  668. internals of TCP/IP, the Stevens book is probably the better source of 
  669. information. 
  670.  
  671. Many of the TCP/IP protocols used by programs are documented in RFC files 
  672. (Request For Comments).  These include NNTP (news), TELNET, FTP, and hundreds 
  673. more.  These files may be obtained via the Internet from venera.isi.edu in the 
  674. in-notes directory.  The rfc-index.txt file contains an index of all the RFCs 
  675. currently available. 
  676.  
  677. There are a few programs publically available that make use of the rxSock 
  678. function package.  These programs are available via anonymous ftp to 
  679. ftp.cdrom.com, in the /pub/os2/2_x/network subdirectory. The programs are: 
  680.  
  681. fingerd.zip    a finger server 
  682.  
  683. ntp.zip        a Network Time Protocol (NTP) client 
  684.  
  685. rxnew11a.zip   an NNTP news reader 
  686.  
  687. Besides being useful programs in their own right, the programs can also be used 
  688. as further examples of socket programming with the rxSock function package. 
  689.  
  690.  
  691. ΓòÉΓòÉΓòÉ 3. Columns ΓòÉΓòÉΓòÉ
  692.  
  693. The following columns can be found in this issue: 
  694.  
  695. o C++ Corner 
  696. o Introduction to PM Programming 
  697. o Scratch Patch 
  698.  
  699.  
  700. ΓòÉΓòÉΓòÉ 3.1. C++ Corner ΓòÉΓòÉΓòÉ
  701.  
  702. Written by Gordon Zeglinski 
  703.  
  704. At long last the infamous C-Set++ 2.1 CD-ROM has arrived!  Was it worth the 
  705. wait? 
  706.  
  707. This column will look at the new features in C-Set++ 2.1, and then benchmark 
  708. the compiler against the Watcom C/C++ v9.5a compiler using POV version 2.1 and 
  709. a mini-application from numerical analysis. POV has been chosen as a test 
  710. program because its source is freely available and it is fairly popular. 
  711.  
  712.  
  713. ΓòÉΓòÉΓòÉ 3.1.1. What's New? ΓòÉΓòÉΓòÉ
  714.  
  715. The new features in C-Set++ 2.1 are: 
  716.  
  717. o WorkFrame version 2.1 
  718. o Drag-and-drop support to the User Interface Class Libs 
  719. o KASE:Set 
  720.  
  721. Bundled features in C-Set++ 2.1 are: 
  722.  
  723. o CSD Level 002 applied to the compiler, tools, and the user interface class 
  724.   libraries. 
  725. o Toolkit 2.1 
  726.  
  727. Note:  by now, the compiler is at CSD level 005, and the user interface class 
  728. libs are at CSD level 003. 
  729.  
  730. WorkFrame Version 2.1 
  731.  
  732. The new WorkFrame (WF for short) is nothing short of pure WPS magic.  As with 
  733. most magic, it doesn't always work though.  Before getting to the disappointing 
  734. stuff, let's look at the new whiz-bang features. 
  735.  
  736. The new WF is totally different that the older versions of the WF.  It 
  737. introduces several new WPS objects, two of which are, the WorkFrame/2 Project 
  738. and the WorkFrame/2 Composite Project.  The WorkFrame/2 Project is roughly 
  739. analogous to the projects in WF version 1.x. 
  740.  
  741. The new projects are enhanced to allow source files being located in multiple 
  742. directories, and it has a more intelligent make file creator.  At last, the 
  743. make file creator "remembers" which files have been previously selected, and 
  744. what actions to perform on them!  The WorkFrame/2 Composite Project objects 
  745. allows multiple targets to be maked at once or in sequence.  Typically, these 
  746. multiple targets (or projects in WF terminology) are the various components of 
  747. the application like DLL's, help files, etc. 
  748.  
  749. The best feature in the new WF is its make file creator.  It not only remembers 
  750. previous selections, but also masks out files whose extensions don't match the 
  751. actions you are doing.  For instance, suppose, you are compiling and linking 
  752. your code; only files matching the masks of *.C, *.CPP, etc. would be shown in 
  753. the file list of the makefile creator. 
  754.  
  755. Like the previous versions, version 2.1 is still compiler independent.  It uses 
  756. objects called Actions Profiles to provide a WPS front end to the actions a 
  757. tool can perform. 
  758.  
  759. On to the bad part, the WPS is not 100% bug free.  Thus, any of its bugs will 
  760. affect the WF.  On top of that, the WF isn't 100% bug free either. Numerous 
  761. warning message boxes have popped up telling me that some unknown detached 
  762. processed has generated some sort of exception and that it should be 
  763. terminated. 
  764.  
  765. These, however, are not too bad as OS/2 is quite capable of surviving them. The 
  766. more serious bugs will actually hang OS/2.  Most PM developers are aware of how 
  767. fragile the message dispatch thread is to exceptions.  The easiest way to hang 
  768. PM is to have an exception occur in this thread.  The WF unfortunately has a 
  769. few of these bugs too.  Also, the migrate option in the new WF doesn't migrate 
  770. all of my old WF 1.1 projects. 
  771.  
  772. Overall, the new WF is a big improvement over WF 1.1, but is also a bit less 
  773. stable.  I'm sure it will improve over time. 
  774.  
  775. Drag and Drop Support to the User Interface Class Libraries 
  776.  
  777. Basically, this is an extension to the user interface class libs that shipped 
  778. with C-Set++ 2.0.  It is comprised of several new classes which encapsulate 
  779. OS/2's drag and drop mechanism.  This topic in itself could cover several 
  780. issues, so I'll not get into any details here but rather save it for a future 
  781. column or two.  For those who can't wait, the C-Set distribution includes 
  782. several sample programs that illustrate their use and some documentation on 
  783. them. 
  784.  
  785. KASE:Set 
  786.  
  787. This is the most disappointing part of the package simply because my 
  788. expectations were high.  This package makes use of existing IBM supplied tools 
  789. for editing dialog resources, bitmaps, and icons.  It does provide a built-in 
  790. menu editor, but I found it a bit awkward to use.  This product can't be used 
  791. to generate many of today's applications due to it's limitations.  However, 
  792. some people may find it fun to play with.  The Guidelines product, which has a 
  793. one free copy per organization license, is better for those interested in code 
  794. generating tools. 
  795.  
  796. Note:  Guidelines also requires C-Set++ at present. 
  797.  
  798. IPMD 
  799.  
  800. IPMD is the debugger included with the C-Set++ 2.1 (and the C-Set++ FirstStep) 
  801. package.  Although it is the same debugger that is mentioned in my previous 
  802. compiler showdown, many debugger features were not discussed in that issue 
  803. because of the number of compiler packages looked at.  We will look at some of 
  804. these features here. 
  805.  
  806. The debugger is PM based and is equipped with many features designed to help 
  807. debug PM based applications.  It has message queue monitor that can be used to 
  808. display the PM messages being sent to an application.  These messages can be 
  809. filtered on the bases of the window they are going to, the message queue they 
  810. are sent to, and by the actual message.  A nice feature here is that you can 
  811. specify how your custom messages are displayed. 
  812.  
  813. For instance, if your application has defined the message WM_USER+1 as 
  814. MSG_MY_MESSAGE, you can configure IPMD to display MSG_MY_MESSAGE as the message 
  815. instead of the number given by WM_USER+1.  In addition, the message parameters 
  816. are displayed in a form that represents their interpretation for the given 
  817. message.  If a message specifies that paramater 1 holds two SHORTs, IPMD will 
  818. display the message as two short integers.  Another nice feature for PM 
  819. programmers is the window analysis views.  In these views, all the details 
  820. about the windows an application has created are shown. 
  821.  
  822. For C++ programmers, the debugger includes a hierarchy browser.  The real value 
  823. in this browser is realized when you are using class libraries written by other 
  824. people.  The hierarchy can be viewed in a graphical form, and explored in a 
  825. textual form. 
  826.  
  827. As expected, the debugger includes all the features common to debuggers in 
  828. general,, ncluding, variable viewers/modifiers, break points, etc.  But one 
  829. feature I haven't seem on a PC-based debugger is it's ability to save the debug 
  830. state when you exit the debugger.  Saving the debug state saves the 
  831. breakpoints, open source code views, and various monitor windows (the PM 
  832. message monitor, variable monitor, etc.).  This feature is of use to both PM 
  833. and non-PM programmers alike. 
  834.  
  835.  
  836. ΓòÉΓòÉΓòÉ 3.1.2. On with the Benchmarks. ΓòÉΓòÉΓòÉ
  837.  
  838. As I mentioned before, POV 2.1 will be used as the test program for these 
  839. benchmarks.  Both compile times and execution times will be measured.  In 
  840. addition to POV 2.1, a specialized heat transfer application based on the 
  841. finite difference method will also be tested.  For the curious, makefiles for 
  842. the C-Set++ and Watcom compilers are included. 
  843.  
  844. POV 2.1 test 
  845.  
  846. First, let's look at the code generation. The following table presents the 
  847. results from this first test: 
  848.  
  849. ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
  850. ΓöéCompiler                 ΓöéCompile Time        ΓöéExecutable Size     Γöé
  851. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  852. ΓöéWatcom C/C++ 9.5a        Γöé6 min 20 sec        Γöé239006              Γöé
  853. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  854. ΓöéC-Set++ CSD005           Γöé4 min 42 sec        Γöé343040              Γöé
  855. ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
  856.  
  857. Now let's look at the time it takes to trace the following scene: 
  858.  
  859. The above scene is the result of test 1.  Test 1 traces the scene into a 
  860. 200x200 image using antialiasing.  Test 2 traces the same scene into a 100x100 
  861. image without antialiasing. 
  862.  
  863. ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
  864. ΓöéTest Number    ΓöéWatcom Time    ΓöéC-Set++ Time   Γöératio:         Γöé
  865. Γöé               Γöé               Γöé               ΓöéWatcom/C-Set++ Γöé
  866. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  867. Γöé1              Γöé59 min 8 sec   Γöé46 min 2 sec   Γöé1.28           Γöé
  868. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  869. Γöé2              Γöé2 min 17 sec   Γöé1 min 45 sec   Γöé1.30           Γöé
  870. ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
  871.  
  872. Heat Transfer App. Test 
  873.  
  874. The heat transfer application is based around the Gauss-Seidel iterative method 
  875. for solving matrix systems.  The code is not object-oriented, but it makes use 
  876. of a few C++ specific features.  The Gauss-Seidel method is quite common in 
  877. certain areas of numerical analysis; thus, it was included in this comparison 
  878. to reflect a real world application. 
  879.  
  880. ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
  881. ΓöéCompiler                 ΓöéCompile Time        ΓöéExecutable Size     Γöé
  882. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  883. ΓöéWatcom C/C++ 9.5a        Γöé48/46 sec           Γöé44290               Γöé
  884. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  885. ΓöéC-Set++ CSD005           Γöé41/37 sec           Γöé73716               Γöé
  886. ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
  887.  
  888. The compile times given are in the form of first compile/second compile. The 
  889. first compile refers the first time the compiler is executed within the VIO 
  890. window.  The second refers the second time the compiler is executed within the 
  891. same VIO window.  This was done, because this application comprises of only one 
  892. fairly small source file.  A better feel for the compile time can be achieved 
  893. by averaging the two times. 
  894.  
  895. The execution time shown below, is for a 216x216 matrix. 
  896.  
  897. ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
  898. ΓöéCompiler            ΓöéExecution Time      Γöé
  899. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  900. ΓöéWatcom C/C++ 9.5a   Γöé27 sec              Γöé
  901. Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
  902. ΓöéC-Set++ CSD005      Γöé31 sec              Γöé
  903. ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
  904.  
  905. Notes For The Curious 
  906.  
  907. The heat transfer program will prompt you to enter the number of nodes in the X 
  908. and Y directions.  The number of nodes must follow the following equations: 
  909.  
  910. NODES =(3/N)+1
  911.      x
  912.  
  913. NODES =(1/N)+1
  914.      y
  915.  
  916. N must be less than or equal to 0.5 and 1/N must be an integer.
  917.  
  918. The program will also prompt you for the value of k and H.  Any non zero value 
  919. can be used for these two variables. 
  920.  
  921. Bits and Pieces 
  922.  
  923. The tests were performed on a 486 DX2-66 based system with 128K external cache 
  924. and 16M of main RAM.  The execution times and compile times were measured after 
  925. rebooting OS/2 except where noted otherwise. 
  926.  
  927. Two zip files are included with this column.  POV.ZIP includes the makefile for 
  928. the watcom version of POV for OS/2.  The file HEAT.ZIP includes the 
  929. executables, source code, and makefiles for the program used in the heat 
  930. transfer application test. 
  931.  
  932.  
  933. ΓòÉΓòÉΓòÉ 3.1.3. Summary ΓòÉΓòÉΓòÉ
  934.  
  935. For a C-Set++ 2.0 owner, the real value of the C-Set++ 2.1 package lies in it's 
  936. inclusion of the new WorkFrame, the drag and drop support objects in the user 
  937. interface library, and the 2.1 toolkit.  Although C-Set++ generates code that 
  938. is somewhat larger than that generated by the Watcom compiler, it may or may 
  939. not be faster than the Watcom compiler.  Your mileage will vary depending on 
  940. the application. 
  941.  
  942. More importantly, there are cases where the speed of the executable is not 
  943. important.  This is especially true, in applications which depend heavily on 
  944. user interaction or those which are I/O-bound.  When developing PM 
  945. applications, the quality of the support tools is just as important as the 
  946. quality of the compiler.  Without a good PM aware debugger, discovering why a 
  947. PM application is not behaving as expected would more be difficult. 
  948.  
  949.  
  950. ΓòÉΓòÉΓòÉ 3.2. Introduction to PM Programming ΓòÉΓòÉΓòÉ
  951.  
  952. Written by Larry Salomon, Jr. 
  953.  
  954. The purpose of this column is to provide to the readers out there who are not 
  955. familiar with PM application development the information necessary to satisfy 
  956. their curiousity, educate themselves, and give them an advantage over the 
  957. documentation supplied by IBM.  Of course, much of this stuff could probably be 
  958. found in one of the many books out there, but the problem with books in general 
  959. is that they don't answer the questions you have after you read the book the 
  960. first time through. 
  961.  
  962. I will gladly entertain feedback from the readers about what was "glossed over" 
  963. or what was detailed well, what tangential topics need to be covered and what 
  964. superfluous crap should have been removed.  This feedback is essential in 
  965. guaranteeing that you get what you pay for.  :) 
  966.  
  967. It should be said that you must not depend solely on this column to teach you 
  968. how to develop PM applications; instead, this should be viewed as a supplement 
  969. to your other information storehouses (books, the network conferences, etc.). 
  970. Because this column must take a general approach, there will be some topics 
  971. that would like to see discussed that really do not belong here.  Specific 
  972. questions can be directed to the Scratch Patch, where an attempt to answer them 
  973. will be made. 
  974.  
  975.  
  976. ΓòÉΓòÉΓòÉ 3.2.1. Last Month ΓòÉΓòÉΓòÉ
  977.  
  978. Last month, we took a good hard look at a very typical main() function for a PM 
  979. application.  We discussed in detail the WinCreateStdWindow() function, as well 
  980. as the many parameters and flags it can take.  Finally, we started looking at 
  981. window procedures and some of the more important messages that you - as a PM 
  982. developer - will be interested in. 
  983.  
  984. Since a large portion of PM application development is done in coding the 
  985. window procedure, this month, we will begin to look more closely at this beast 
  986. and see how, through the use of various messages, we can tame it in order to 
  987. accomplish our own goals. 
  988.  
  989.  
  990. ΓòÉΓòÉΓòÉ 3.2.2. Presentation Spaces, the WM_PAINT Message, and Painting ΓòÉΓòÉΓòÉ
  991.  
  992. Since the most important task you will probably have to perform will be 
  993. painting your window, let us first look at the mechanism used to accomplish 
  994. this.  Reproduced below from last month's column is the simple window procedure 
  995. that we saw. 
  996.  
  997. MRESULT EXPENTRY windowProc(HWND hwndWnd,
  998.                             ULONG ulMsg,
  999.                             MPARAM mpParm1,
  1000.                             MPARAM mpParm2)
  1001. {
  1002.    switch (ulMsg) {
  1003.    case WM_PAINT:
  1004.       {
  1005.          HPS hpsPaint;
  1006.          RECTL rclPaint;
  1007.  
  1008.          hpsPaint=WinBeginPaint(hwndWnd,NULLHANDLE,&rclPaint);
  1009.  
  1010.          WinFillRect(hpsPaint,&rclPaint,SYSCLR_WINDOW);
  1011.  
  1012.          WinQueryWindowRect(hwndWnd,&rclPaint);
  1013.  
  1014.          WinDrawText(hpsPaint,
  1015.                      -1,
  1016.                      "Hello world.",
  1017.                      &rclPaint,
  1018.                      CLR_BLACK,
  1019.                      0,
  1020.                      DT_CENTER|DT_VCENTER);
  1021.  
  1022.          WinEndPaint(hpsPaint);
  1023.       }
  1024.       break;
  1025.    default:
  1026.       return WinDefWindowProc(hwndWnd,ulMsg,mpParm1,mpParm2);
  1027.    } /* endswitch */
  1028.  
  1029.    return MRFROMSHORT(FALSE);
  1030. }
  1031.  
  1032. Figure 1)  Simple window procedure 
  1033.  
  1034. Hmmm...The variable hpsPaint - of the type HPS - seems to be used quite a bit. 
  1035. What is an HPS?  Looking into os2defs.h, we don't see much to help answer this. 
  1036.  
  1037. typedef LHANDLE HPS;
  1038. typedef HPS *PHPS;
  1039.  
  1040. In case you haven't associated the title of this section with our question, an 
  1041. HPS is a handle to a presentation space.  Okay, that helps a lot...not!  What 
  1042. is a presentation space? 
  1043.  
  1044. Presentation Spaces and Device Contexts 
  1045.  
  1046. The easiest way to explain a presentation space is to use the familiar (and 
  1047. usually very vague, as you should remember from your college days :) "logical 
  1048. and physical" explanation.  Consider an output device, which has numerous 
  1049. physical characteristics:  the size of the output medium, the current colors, 
  1050. the current font, etc.  All of these characteristics are physical 
  1051. characteristics, and they are collectively known as a device context. 
  1052.  
  1053. Figure 2)  Physical output device 
  1054.  
  1055. However, as a programmer, you don't want to have to be cognizant of the types 
  1056. and brands of each output device; thus, OS/2 provides the concept of a logical 
  1057. device which has an analagous set of characteristics. This logical device is 
  1058. called a presentation space (HPS).  When you draw on the HPS, PM automatically 
  1059. converts all of the logical characteristics to their physical equivalents. 
  1060.  
  1061. Figure 3)  Logical output which results in the figure 2 
  1062.  
  1063. The point is, and this is the only part you need to remember, any drawing is 
  1064. done on an HPS. 
  1065.  
  1066. Invalidation 
  1067.  
  1068. One of the many characteristics that an HPS has is called a clipping region. 
  1069. If you'll recall, last issue in the New Concepts section of this column, figure 
  1070. 5 illustrated many children clipped to their parent.  While it was implied that 
  1071. clipping areas - or regions as they are called - are rectangular, this is not 
  1072. always the case. 
  1073.  
  1074. Figure 4)  No clipping 
  1075.  
  1076. Figure 4 illustrates a drawing of a box with no clipping applied.  Applying a 
  1077. clipping region of a triangular shape yields the following (the clipping 
  1078. boundary is shown as a dotted line for illustrative purposes only): 
  1079.  
  1080. Figure 5)  Triangular clipping 
  1081.  
  1082. Whenever any portion of your window needs repainting, the section that needs to 
  1083. be painted is said to be invalid.  While PM could in fact provide a precise 
  1084. clipping region that outlines the invalid portion, for performance reasons, it 
  1085. instead provides the coordinates of the smallest rectangle to completely bound 
  1086. the invalid area.  Why are we bothering with all of this?  Keep reading... 
  1087.  
  1088. The WM_PAINT Message 
  1089.  
  1090. Whenever your window has an invalid region, PM sends your window procedure a 
  1091. WM_PAINT message. 
  1092.  
  1093. WM_PAINT 
  1094.  
  1095. This message occurs when an application needs to repaint itself. 
  1096.  
  1097. Parameters 
  1098.  
  1099.    param1 
  1100.  
  1101.       Reserved. 
  1102.  
  1103.       NULL      Reserved value. 
  1104.  
  1105.    param2 
  1106.  
  1107.       Reserved. 
  1108.  
  1109.       NULL      Reserved value. 
  1110.  
  1111. Returns 
  1112.  
  1113.    reply 
  1114.  
  1115.       Reserved. 
  1116.  
  1117.       NULL      Reserved value. 
  1118.  
  1119. Since we have already said that, in order to do any drawing, you need an HPS, 
  1120. all that is left to reveal is the method by which you obtain one.  As you have 
  1121. probably guessed, the function to use is WinBeginPaint(). 
  1122.  
  1123. HPS WinBeginPaint(HWND hwndWindow,
  1124.                   HPS hpsCreated,
  1125.                   PRECTL prclInvalid);
  1126.  
  1127. hwndWindow - the window for which the HPS is to be obtained. 
  1128.  
  1129. hpsCreated - used whenever you have already created an HPS and would like to 
  1130. use it instead of having the system allocate one for you.  We will always 
  1131. specify NULLHANDLE for this parameter. 
  1132.  
  1133. prclInvalid - points to a RECTL structure to receive the bounding rectangle. 
  1134. This can be NULL. 
  1135.  
  1136. For reasons beyond the scope of this column, the HPS must be returned to the 
  1137. system once you are finished.  The function to do this is WinEndPaint(), and 
  1138. its only parameter is the HPS to release. 
  1139.  
  1140. BOOL WinEndPaint(HPS hpsRelease);
  1141.  
  1142. Some important things to note: 
  1143.  
  1144. o The HPS returned by WinBeginPaint() automatically has a clipping region set 
  1145.   to the bounding rectangle returned in prclInvalid.  This rectangle is 
  1146.   returned to the caller to take advantage of any painting optimizations 
  1147.   possible by restricting the area that is repainted to only the rectangle. 
  1148. o The WinEndPaint() call sets the invalid region to empty (empty is also 
  1149.   referred to as NULLHANDLE with respect to regions, since they are also a 
  1150.   datatype in PM). 
  1151. o You cannot use WinBeginPaint() and WinEndPaint() except in the context of a 
  1152.   WM_PAINT message.  Should you need to do any drawing in any other message, 
  1153.   the functions WinGetPS() and WinReleasePS() should be used.  This is because 
  1154.   there will be no invalid region, so everything will be clipped. 
  1155. o An HPS is used to allow you to draw only.  It does not remember what was 
  1156.   drawn, so you must redraw each time you receive a WM_PAINT message.  There 
  1157.   are ways around this, however, which we will look at in future issues. 
  1158.  
  1159.  
  1160. ΓòÉΓòÉΓòÉ 3.2.3. Now That I Have an HPS, What do I do Next? ΓòÉΓòÉΓòÉ
  1161.  
  1162. There is an entire system devoted to drawing, known as the Graphical 
  1163. Programming Interface but usually referred to as the Gpi. Since it is so 
  1164. extensive, we will not cover it directly; instead, some of the more common 
  1165. functions will be explained as they are encountered. 
  1166.  
  1167. In the Win subsystem, however, there are a number of functions which provide 
  1168. access to the more commonly needed functions. 
  1169.  
  1170. o WinDrawBitmap() - draws a bitmap at a specified position, with some control 
  1171.   over appearance 
  1172. o WinDrawBorder() - draws a border inside a specified rectangle 
  1173. o WinDrawPointer() - draws a mouse pointer or an icon at a specified position 
  1174. o WinDrawText() - draws a string at a specified position, with many different 
  1175.   options for appearance 
  1176. o WinFillRect() - fills the specified rectangle with the specified color 
  1177. o WinInvertRect() - inverts (a la xor) the specified rectangle 
  1178.  
  1179. I will leave it as a reader exercise to refer to the Programming Reference for 
  1180. more information about these functions. 
  1181.  
  1182.  
  1183. ΓòÉΓòÉΓòÉ 3.2.4. And On The First Day... ΓòÉΓòÉΓòÉ
  1184.  
  1185. ...&deity. sent a WM_CREATE message.  :) 
  1186.  
  1187. The final topic for this month's column is two new messages:  these are the 
  1188. WM_CREATE and WM_DESTROY messages. 
  1189.  
  1190. WM_CREATE 
  1191.  
  1192. This message occurs when an application requests the creation of a window. 
  1193.  
  1194. Parameters 
  1195.  
  1196.    param1 
  1197.  
  1198.       pvData (PVOID) 
  1199.  
  1200.          Window-specific data that is specified on the call to 
  1201.          WinCreateWindow(). 
  1202.  
  1203.    param2 
  1204.  
  1205.       pcsCreate (PCREATESTRUCT) 
  1206.  
  1207.          Points to a CREATESTRUCT structure that specifies the various initial 
  1208.          characteristics of the window, e.g. size, position, etc. 
  1209.  
  1210. Returns 
  1211.  
  1212.    reply 
  1213.  
  1214.       bReply (BOOL) 
  1215.  
  1216.          Success indicator: 
  1217.  
  1218.          FALSE     Initialization succeeded.  Continue with window creation. 
  1219.          TRUE      Initialization failed.  Do not create the window. 
  1220.  
  1221. WM_DESTROY 
  1222.  
  1223. This message occurs when an application destroys a window. 
  1224.  
  1225. Parameters 
  1226.  
  1227.    param1 
  1228.  
  1229.       Reserved. 
  1230.  
  1231.       NULL      Reserved value. 
  1232.  
  1233.    param2 
  1234.  
  1235.       Reserved. 
  1236.  
  1237.       NULL      Reserved value. 
  1238.  
  1239. Returns 
  1240.  
  1241.    reply 
  1242.  
  1243.       Reserved. 
  1244.  
  1245.       NULL      Reserved value. 
  1246.  
  1247. These two messages are sent to allow a window to perform any initialization and 
  1248. termination processing.  As shown, if initialization fails, the window 
  1249. procedure should return TRUE to prohibit the creation of the window. 
  1250.  
  1251. A couple of things should be noted: 
  1252.  
  1253. o The window procedure is directly invoked to send the WM_CREATE message.  This 
  1254.   is different than it being sent or posted to the window procedure in that the 
  1255.   window doesn't actually exist until the processing completes and returns 
  1256.   FALSE.  This significance is noted because, since the window doesn't really 
  1257.   exist, certain functions will not work properly (i.e. WinQueryWindowRect(), 
  1258.   WinQueryWindowPos(), etc.).  Instead, you should use the values of the fields 
  1259.   of the pcsCreate parameter. 
  1260. o Last issue, we saw the following code: 
  1261.  
  1262.     hwndFrame=WinCreateStdWindow(HWND_DESKTOP,
  1263.                                  WS_VISIBLE,
  1264.                                  &ulCreate,
  1265.                                  CLS_CLIENT,
  1266.                                  "Hello World Sample",
  1267.                                  0,
  1268.                                  NULLHANDLE,
  1269.                                  RES_CLIENT,
  1270.                                  &hwndClient);
  1271.  
  1272.   Since the WM_CREATE message is a direct function call, WinCreateStdWindow() 
  1273.   hasn't returned yet, and so hwndFrame is still uninitialized.  If the 
  1274.   unlikely event that you declare hwndFrame to be a global variable, you cannot 
  1275.   use its value in the WM_CREATE message processing.  Instead, you should use 
  1276.   the function WinQueryWindow() in the following manner: 
  1277.  
  1278.     case WM_CREATE:
  1279.        {
  1280.           HWND hwndFrame;
  1281.  
  1282.             :
  1283.           hwndFrame=WinQueryWindow(hwndWnd,QW_PARENT);
  1284.             :
  1285.        }
  1286.        break;
  1287.  
  1288. Before you shrug your shoulders and say "Yeah, that's nice, but what is the 
  1289. real benefit of these messages?", keep reading... 
  1290.  
  1291. Think back to the first installment of this column, where it was said that a 
  1292. window procedure is the common way of referring to the entity called a window 
  1293. class procedure.  The point here is that, should you write an application that 
  1294. has to create multiple windows of the same class (which you developed), you can 
  1295. no longer use global or static variables to store information that must be 
  1296. shared among message processing blocks.  This is because all windows of the 
  1297. class share these variables; if one window needs to update the value of one 
  1298. variable, the update will affect all windows of that class. 
  1299.  
  1300. To alleviate this, PM has the idea of window words, which are additional bytes 
  1301. of memory allocated for each instance of a window class.  You could, for 
  1302. example, then specify that an additional 4 bytes of memory is to be allocated, 
  1303. and then use those 4 bytes to point to a structure containing instance-specific 
  1304. data.  See the section Design in the article Development of a New Window Class 
  1305. - Part 1 in issue 4 of EDM/2 for more information about window words. 
  1306.  
  1307. Another common reason for using these messages is for creating other window 
  1308. that are the children of your window class.  For example, say you want to 
  1309. display a list of choices, and underneath you want to display the text 
  1310. currently selected.  There are two defined window classes - listboxes and 
  1311. static controls - which individually do part of what is desired.  You could 
  1312. then create them as part of the initialization process and if either should 
  1313. fail, return TRUE to stop the application from continuing. 
  1314.  
  1315.  
  1316. ΓòÉΓòÉΓòÉ 3.2.5. Summary ΓòÉΓòÉΓòÉ
  1317.  
  1318. This month, we took a much more detailed look at the concept of painting and 
  1319. how presentation spaces are used by the system to hide the specifics of 
  1320. whatever physical output medium is connected to the CPU.  We explained update 
  1321. regions and their corresponding bounding rectangles, and their relationship to 
  1322. invalid regions.  Finally, we looked at two new messages - WM_CREATE and 
  1323. WM_DESTROY - and briefly touched on their purpose. 
  1324.  
  1325. If you understood everything in this column and the last one, you should be 
  1326. able to look at intro.zip (provided last month) and understand most - if not 
  1327. all - of the program source code.  This should be verified in order to 
  1328. determine your retention percentage, and, should any further clarification be 
  1329. necessary, send me email with your questions. 
  1330.  
  1331. Next month, we will introduce some of the other controls in order to discuss 
  1332. dialog boxes and how they are used to communicate with the user.  We will also 
  1333. take a more detailed look at resources and how they are used in the development 
  1334. of dialog boxes.  Finally, we will continue our perusal of the messages that 
  1335. are commonly used in PM application development. 
  1336.  
  1337.  
  1338. ΓòÉΓòÉΓòÉ 3.3. Scratch Patch ΓòÉΓòÉΓòÉ
  1339.  
  1340. Written by Larry Salomon, Jr. 
  1341.  
  1342. Welcome to this month's "Scratch Patch"!  Each month, I collect various items 
  1343. that fit into this column sent to me via email. The ones that I feel contribute 
  1344. the most to developers, whether in terms of information or as a nifty trick to 
  1345. tuck into your cap, get published in this column. 
  1346.  
  1347. To submit an item, send it via email to my address - os2man@panix.com - and be 
  1348. sure to grant permission to publish it (those that forget will not be 
  1349. considered for publication).  This month, we have the following: 
  1350.  
  1351. o Questions and Answers 
  1352. o Snippet(s) of the Month 
  1353. o Want Ads 
  1354.  
  1355.  
  1356. ΓòÉΓòÉΓòÉ 3.3.1. Questions and Answers ΓòÉΓòÉΓòÉ
  1357.  
  1358. Unfortunately, I saved the following questions while replying to the sender's 
  1359. mail.  Since the Elm mail utility doesn't put the header information into the 
  1360. temporary file used to compose the mail, I do not have the address of this 
  1361. person, nor the name. 
  1362.  
  1363. Nonetheless, he (I remember the gender at least!) writes: 
  1364.  
  1365. I have three questions that are really starting to drive me crazy, so hopefully 
  1366. they are driving other people crazy and would make good inclusions into the 
  1367. next EDM/2. 
  1368.  
  1369. 1)  I've seen programs that have their icon bound into the .EXE somehow rather 
  1370. than in [extended attributes].  The WPS has no problem finding the icon in this 
  1371. programs and displaying it from a program object or from the drives object. 
  1372. How is this done?  I even have source for programs that do this, and I still 
  1373. can't figure out what they are doing that I'm not! 
  1374.  
  1375. 2)  I've designed a nice dialog box with IBM's Dialog Editor.  In it I have 
  1376. some static text fields with their font's and colors changed to make them look 
  1377. nice (e.g.  I have the title of the program in 18.Tms Rmn). Unfortunately, I've 
  1378. found that dragging a scheme from the scheme palette onto my dialog causes all 
  1379. of the fonts to revert to System Proportional!  :-( From what I can tell, PM 
  1380. does not send any message before it kills everything, only after 
  1381. (WM_PRESPARAMSCHANGED).  How can I keep things from being changed?  The 
  1382. behavior that I would like to see would be for the drag-n-drop operation to be 
  1383. denied (I don't know the actually terminology, but you get that "circle with a 
  1384. bar in it" icon). 
  1385.  
  1386. 3)  This is the most frustrating one.  I've been through the PM Reference so 
  1387. many times I can hardly see, and I still haven't figured out how to load a font 
  1388. resource.  I have all of my resources bound into my .EXE, but GpiLoadFonts() 
  1389. requires the name of a .FON file.  The font is one that I have created in IBM's 
  1390. Font Editor, and I've included in in my resource file like so: 
  1391.  
  1392. FONT ID_MAIN "c:\\project\\myproject\\myfont.fnt"
  1393.  
  1394. Thanks for any help you can give me.  You have full permission to do absolutely 
  1395. anything with these questions you want, including print them in EDM/2 :-) 
  1396.  
  1397. 1)  The first icon resource found is used, I believe. 
  1398.  
  1399. 2)  All three palettes work in this way:  when they receive the WM_BEGINDRAG 
  1400. message, they capture the mouse ; when the WM_ENDDRAG message is received, they 
  1401. call WinWindowFromPoint() to get the handle of the window under the mouse; 
  1402. finally, they call WinSetPresParam() to change the appropriate attributes. 
  1403. Thus, they aren't using direct manipulation, so you can't stop it from 
  1404. happening. 
  1405.  
  1406. 3)  Fonts can only be loaded from .FON files, which are nothing more than DLL's 
  1407. with a different extension.  The easiest way to create this is to write a short 
  1408. C program which contains a static function dummy().  This function is defined 
  1409. as such: 
  1410.  
  1411. VOID dummy(VOID)
  1412. {
  1413. }
  1414.  
  1415. This will compile and link, creating a .DLL that you can bind your font to. 
  1416. Rename the file to .FON and you're finished. 
  1417.  
  1418.  
  1419. ΓòÉΓòÉΓòÉ 3.3.2. Snippet(s) of the Month ΓòÉΓòÉΓòÉ
  1420.  
  1421. This following function was submitted (along with a host of other functions) by 
  1422. our own Gordon Zeglinski.  It can be found in the file scratch.zip. 
  1423.  
  1424. VOID AddSysMenuItem ( HWND hwndFrame, MENUITEM *Item, PSZ Text )
  1425. {
  1426.  /***************************************************************************
  1427.   * Local Declarations                                                      *
  1428.   ***************************************************************************/
  1429.  
  1430.   HWND hwndSysMenu ;
  1431.   HWND hwndSysSubMenu ;
  1432.   USHORT idSysMenu ;
  1433.   MENUITEM miSysMenu ;
  1434.  
  1435.  /***************************************************************************
  1436.   * Obtain the system menu window handle.                                   *
  1437.   ***************************************************************************/
  1438.  
  1439.   hwndSysMenu = WinWindowFromID ( hwndFrame, FID_SYSMENU ) ;
  1440.  
  1441.  /***************************************************************************
  1442.   * Get the system menu's base item and its window handle.                  *
  1443.   ***************************************************************************/
  1444.  
  1445.   idSysMenu = SHORT1FROMMR ( WinSendMsg ( hwndSysMenu,
  1446.                                           MM_ITEMIDFROMPOSITION,
  1447.                                           NULL,
  1448.                                           NULL ) ) ;
  1449.  
  1450.   WinSendMsg ( hwndSysMenu,
  1451.                MM_QUERYITEM,
  1452.                MPFROM2SHORT(idSysMenu,FALSE),
  1453.                MPFROMP(&miSysMenu) ) ;
  1454.  
  1455.   hwndSysSubMenu = miSysMenu.hwndSubMenu ;
  1456.  
  1457.  /***************************************************************************
  1458.   * Add the new item to the system menu's submenu, which is what we see.    *
  1459.   ***************************************************************************/
  1460.  
  1461.   WinSendMsg ( hwndSysSubMenu, MM_INSERTITEM, MPFROMP(Item), MPFROMP(Text) ) ;
  1462. }
  1463.  
  1464.  
  1465. ΓòÉΓòÉΓòÉ 3.3.3. Want Ads ΓòÉΓòÉΓòÉ
  1466.  
  1467. Below are the hot topics as of this issue's writing.  Feel free to write on any 
  1468. of these. 
  1469.  
  1470. Workplace Shell Programming (hot) - lately, I have noticed two things: 1) lots 
  1471. of people want to learn how to write new Workplace Shell classes and 2) no one 
  1472. who knows anything about it is telling the rest of us how to do it.  I'll even 
  1473. stoop down to accepting an article in ASCII format on this topic! :) 
  1474.  
  1475. Client/Server (hot) - using either named pipes (with or without a network) or 
  1476. sockets, client/server programming is all-the-rage these days.  On a related 
  1477. note, some people have also expressed an interest in learning about interfacing 
  1478. with the various protocol drivers (e.g.  NDIS, IPX/SPX, etc.).  Any articles in 
  1479. this area are most welcome. 
  1480.  
  1481. Multimedia (warm) - last month we had two articles on this topic.  However, 
  1482. they both dealt with sound, which we all know is not the only alternative media 
  1483. type.  Articles on anything else - MIDI, video, etc. - are needed. 
  1484.  
  1485. Animation (warm) - a few readers expressed an interest in the various animation 
  1486. techniques that can be applied to PM applications.  The ultimate article, in my 
  1487. opinion, would be one that develops a sprite library a la the Commodore 64's 
  1488. (and Amiga's?) built-in routines, since this is probably the hardest component 
  1489. of any good animation sequence.  Call this a "personal request"... 
  1490.  
  1491.  
  1492. ΓòÉΓòÉΓòÉ 4. How do I get EDM/2? ΓòÉΓòÉΓòÉ
  1493.  
  1494. EDM/2 can be obtained in any of the following ways: 
  1495.  
  1496. On the Internet 
  1497.  
  1498. o All back issues are available via anonymous FTP from ftp.cdrom.com in the 
  1499.   /pub/os2/2_x/program/newsltr directory. 
  1500. o The EDM/2 mailing list.  Send an empty message to edm2-info@knex.via.mind.org 
  1501.   to receive a file containing (among other things) instructions for 
  1502.   subscribing to EDM/2. 
  1503. o IBM's external gopher server, which I have not the address of, in Almaden. 
  1504.  
  1505. On Compuserve 
  1506.  
  1507. All back issues are available in the OS/2 Developers Forum 2. 
  1508.  
  1509. IBM Internal 
  1510.  
  1511. o IBM's internal gopher server, which I have not the address of, in Almaden. 
  1512. o IBM's REQUEST command on all internal VM systems.  Enter the VM command 
  1513.   REQUEST LIST FROM ASSELIN AT RALVM12 and a list of the requestable packages 
  1514.   will be sent to you; in this list are the names of the packages containing 
  1515.   the EDM/2 issues. 
  1516.  
  1517.  
  1518. ΓòÉΓòÉΓòÉ 5. Contributors to this Issue ΓòÉΓòÉΓòÉ
  1519.  
  1520. Are You a Potential Author? 
  1521.  
  1522. As always, we are always looking for (new) authors.  If you have a topic about 
  1523. which you would like to write, send a brief description of the topic 
  1524. electronically to any of the editors, whose addresses are listed below, by the 
  1525. 15th of the month in which your article will appear.  This alerts us that you 
  1526. will be sending an article so that we can plan the issue layout accordingly. 
  1527. After you have done this, get the latest copy of the Article Submission 
  1528. Guidelines from ftp.cdrom.com in the /pub/os2/2_x/program/newsltr directory. 
  1529. (the file is artsub.zip)  The completed text of your article should be sent to 
  1530. us no later than the last day of the month; any articles received after that 
  1531. time may be pushed to the next issue. 
  1532.  
  1533. The editors can be reached at the following email addresses: 
  1534.  
  1535. o Larry Salomon - os2man@panix.com (Internet). 
  1536.  
  1537. The following people contributed to this issue in one form or another (in 
  1538. alphabetical order): 
  1539.  
  1540. o Larry Salomon, Jr. 
  1541. o Jonathan Story 
  1542. o Gordon Zeglinski 
  1543. o Network distributors 
  1544.  
  1545.  
  1546. ΓòÉΓòÉΓòÉ 5.1. Patrick Mueller ΓòÉΓòÉΓòÉ
  1547.  
  1548. Patrick Mueller is currently working in the Software Solutions division of IBM 
  1549. in Cary, North Carolina.  He has been working for IBM for eight years, on 
  1550. various things including spell- and grammar-checking systems, editors, 
  1551. distributed systems, and object oriented programming.  He has written a number 
  1552. of programs for the OS/2 Employee Written Software Program (EWS), including 
  1553. rxMath, rxSock, rxFTP, RxD, cPost, and cBook. 
  1554.  
  1555. Patrick can be reached electronically via the Internet at pmuellr@vnet.ibm.com. 
  1556.  
  1557.  
  1558. ΓòÉΓòÉΓòÉ 5.2. Larry Salomon, Jr. ΓòÉΓòÉΓòÉ
  1559.  
  1560. Larry Salomon wrote his first Presentation Manager application for OS/2 version 
  1561. 1.1 in 1989.  Since that time, he has written numerous VIO and PM applications, 
  1562. including the Scramble applet included with OS/2 and the I-Brow/Magnify/Screen 
  1563. Capture trio included with the IBM Professional Developers Kit CD-ROM currently 
  1564. being distributed by IBM.  Currently, he works for International Masters 
  1565. Publishers in Stamford, Connecticut and resides in Bellerose, New York with his 
  1566. wife Lisa. 
  1567.  
  1568. Larry can be reached electronically via the Internet at os2man@panix.com. 
  1569.  
  1570.  
  1571. ΓòÉΓòÉΓòÉ 5.3. Jonathan Story ΓòÉΓòÉΓòÉ
  1572.  
  1573. Jonathan Story is associated with the Vancouver PC Users Society - OS/2 Special 
  1574. Interest Group.  He can be reach via email on the Internet at 
  1575. jonathan@jspc.wimsey.bc.ca. 
  1576.  
  1577.  
  1578. ΓòÉΓòÉΓòÉ 5.4. Gordon Zeglinski ΓòÉΓòÉΓòÉ
  1579.  
  1580. Gordon Zeglinski is a freelance programmer/consultant who received his Master's 
  1581. degree in Mechanical Engineering with a thesis on C++ sparse matrix objects. 
  1582. He has been programming in C++ for 6 years and also has a strong background in 
  1583. FORTRAN.  He started developing OS/2 applications with version 2.0 . 
  1584.  
  1585. His current projects include a client/server communications program that 
  1586. utilitizes OS/2's features which has entered beta testing.  Additionally, he is 
  1587. involved in the development of a "real-time" automated vehicle based on OS/2 
  1588. and using C++ in which he does device driver development and designs the 
  1589. applications that comprise the control logic and user interface. 
  1590.  
  1591. He can be reached via the Internet at zeglins@cc.umanitoba.ca. 
  1592.  
  1593.  
  1594. ΓòÉΓòÉΓòÉ 5.5. Network distributors ΓòÉΓòÉΓòÉ
  1595.  
  1596. These people are part of our distribution system to provide EDM/2 on networks 
  1597. other than the Internet.  Their help to provide access to this magazine for 
  1598. others is voluntary and we appreciate them a lot! 
  1599.  
  1600. o Paul Hethman (hethman@cs.utk.edu) - Compuserve 
  1601. o Gess Shankar (gess@knex.via.mind.org) - Internet 
  1602. o David Singer (singer@almaden.ibm.com) - IBM Internal 
  1603. o Andre Asselin (ASSELIN AT RALVM12) - IBM Internal 
  1604.  
  1605. If you would like to become a "network distributor", be sure to contact the 
  1606. editors so that we can give you the credit you deserve!