home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 8 Other / 08-Other.zip / EXTANI.ZIP / EXTNSION.DOC < prev    next >
Text File  |  1990-04-24  |  11KB  |  219 lines

  1. Instructions for writing an Animated Desktop Extension for ANIMATE.EXE
  2.  
  3.  
  4. Good for you! You've decided to write an Animated Desktop Extension. What do
  5. you need to know to write an extension? Well, a pretty good working knowledge
  6. of Presentation Manager wouldn't hurt. These instructions will attempt to
  7. tell you how to write an extension, but they won't tell you how to program
  8. in PM. To help, two example extensions are provided and are a good place to
  9. start. When I write a new extension, I usually use 'BOXES' as a framework
  10. and go from there.
  11.  
  12. An Animated Desktop Extension is a Dynamic Link Library that contains seven
  13. functions and has the file extension of '.ANI' instead of '.DLL'. The seven
  14. functions must be exported with the following ordinals:
  15.  
  16.    animatename    @1
  17.    animateinit    @2
  18.    animatechar    @3
  19.    animatedblclk  @4
  20.    animatepaint   @5
  21.    animateclose   @6
  22.    animatethread  @7
  23.  
  24.  
  25. The seven functions are specified by the following function prototypes:
  26.  
  27.    char far pascal _loadds animatename(void);
  28.    BOOL far pascal _loadds animateinit(INITBLOCK far *);
  29.    void far pascal _loadds animatechar(char);
  30.    void far pascal _loadds animatedblclk(MPARAM);
  31.    void far pascal _loadds animatepaint(HPS, RECTL far *);
  32.    void far pascal _loadds animateclose(void);
  33.    void far pascal _loadds animatethread(void);
  34.  
  35.  
  36. And the structure INITBLOCK is defined as follows:
  37.  
  38.    typedef struct {
  39.       HAB animatehab;
  40.       HPS shadowhps;
  41.       HWND screenhwnd;
  42.       RECTL screenrectl;
  43.       ULONG hpssemaphore;
  44.       ULONG volatile closesemaphore;
  45.       HMODULE thismodule;
  46.       BOOL (far pascal *screenvisible)(void);
  47.    } INITBLOCK;
  48.  
  49.  
  50. Generally, extensions can be divided into two categories: those that update
  51. the desktop window themselves, and those that let ANIMATE do it. If you're
  52. going to let ANIMATE do it, then everything you draw into the desktop
  53. window must also be drawn into the 'shadow Presentation Space'. That way,
  54. when ANIMATE has to perform an update, it just bitblts from the shadow PS.
  55. The disadvantages of using the shadow PS are that it uses up a fair chunk
  56. of memory (150K for a VGA) and since you have to draw everything twice, your
  57. extension runs half as fast as it could otherwise. The advantage is that you
  58. don't have to write any update code. The examples are one of each kind -
  59. HAPPY does its own updates, BOXES uses the shadow PS.
  60.  
  61.  
  62. The basic execution flow of an extension is straightforward. 'animatename' is
  63. called by ANIMATE first to determine the one character ID of the extension.
  64. If the extension is chosen by ANIMATE, it calls 'animateinit' to provide the
  65. extension with a pointer to the INITBLOCK structure, and to allow the
  66. extension to do any initialization. Then, 'animatethread' is started as a
  67. separate low priority thread, and there the extension draws its graphics
  68. until ANIMATE notifies it to stop. While 'animatethread' is running, ANIMATE
  69. may call 'animatechar' to give it characters the user has typed,
  70. 'animatedblclk' if the user double clicks on the desktop, and optionally
  71. 'animatepaint' to update a section of the desktop window. When ANIMATE is
  72. closing, it notifies 'animatethread' that it should stop, waits for it to do
  73. so, and then calls 'animateclose' so that the extension can clean up and
  74. release any resources that it was using.
  75.  
  76.  
  77. The INITBLOCK structure is how ANIMATE provides the extension with
  78. information about its environment. The fields have the following meaning:
  79.  
  80. 'animatehab' is the handle of the ANIMATE program's anchor block. This may
  81.    be needed by some OS/2 functions.
  82. 'shadowhps' is a handle to a memory presentation space the size of the
  83.    screen. This is optionally used when the desktop window is updated. 
  84. 'screenhwnd' is the handle of the desktop window.
  85. 'screenrectl' is the coordinates of the desktop window.
  86. 'hpssemaphore' is a memory semaphore that is used to serialize access to
  87.    the desktop window.
  88. 'closesemaphore' is a memory semaphore that is used by 'animatethread' to
  89.    determine when to stop.
  90. 'thismodule' is the module handle of the Animated Desktop Extension. This
  91.    will be needed to access any local resources.
  92. 'screenvisible' is a pointer to a function that will return TRUE if the
  93.    Presentation Manager screen is visible.
  94.  
  95.  
  96. animatename
  97.  
  98. This function is called by ANIMATE to get the one character ID of the
  99. extension. It should return an upper case character that the user will use
  100. to specify the extension. This is usually the first character of the
  101. extension's name. This function should not allocate any resources because
  102. ANIMATE may call it and then choose not to execute the extension.
  103.  
  104. animateinit
  105.  
  106. This function is called by ANIMATE to provide the extension with a pointer
  107. to the INITBLOCK structure, and to find out if the shadow PS will be used.
  108. The function should save the pointer to the INITBLOCK structure in global
  109. memory so that it can be accessed by the other functions, and it should
  110. allocate resources and perform any other initialization that the extension
  111. needs. The function must return TRUE if the extension will use the shadow PS,
  112. and FALSE if the extension will perform its own updates. Note that the
  113. 'shadowhps' field in the INITBLOCK structure is not valid at this point
  114. (since ANIMATE doesn't know if it's needed or not), so the shadow PS cannot
  115. be initialized at this time.
  116.  
  117. animatethread
  118.  
  119. This procedure will be started as a separate thread by ANIMATE. It performs
  120. all the drawing to the desktop window and, if used, the shadow PS. Note that
  121. stack space is limited, so any sizeable memory needed should be allocated
  122. at run time using 'DosAllocSeg'. The order of operations in the procedure
  123. should be as follows:
  124.    1) Get an Anchor Block. Threads shouldn't make calls to the PM API
  125.       without one.
  126.    2) Initialize the shadow PS, if used.
  127.    3) Post a 'WM_USER' message to desktop window ('screenhwnd' in the
  128.       INITBLOCK structure). The ANIMATE program won't paint on the desktop
  129.       window until it gets this message. This gives the extension time to
  130.       initialize the shadow PS if it's being used, or to set up anything
  131.       that's needed by the 'animatepaint' procedure.
  132.    4) Draw the graphics to the desktop window until ANIMATE signals the
  133.       extension to stop by setting 'closesemaphore' in the INITBLOCK
  134.       structure to a non-zero value. If using the shadow PS, remember to draw
  135.       exactly the same graphics to it that get drawn to the desktop window.
  136.       This is where the extension will be spending most of its time, drawing
  137.       while 'closesemaphore' is zero, until ANIMATE is closed by the user. 
  138.    5) Release any resources that were allocated in 'animatethread', including
  139.       terminating the Anchor Block.
  140.    6) Enter a critical section by calling 'DosEnterCritSec'. This is needed
  141.       so ANIMATE won't de-allocate the thread's stack too soon.
  142.    7) Clear 'closesemaphore' using 'DosSemClear' and exit the procedure.
  143.       When 'closesemaphore' is cleared, ANIMATE will know that the thread
  144.       has terminated.
  145. There are two important rules that must be followed when drawing into the
  146. desktop window. First, before drawing, call the function pointed to by
  147. 'screenvisible' in the INITBLOCK structure. If the function returns FALSE,
  148. don't draw, because the PM screen is not visible (the user has probably
  149. switched to another screen group). When the user is not in the PM screen
  150. group, 'screenvisible' blocks to keep 'animatethread' from wasting CPU time.
  151. Second, when the extension gets a Presentation Space for the desktop window,
  152. or when it draws into the shadow PS, 'hpssemaphore' in the INITBLOCK
  153. structure must be requested with 'DosSemRequest' beforehand, and must be
  154. cleared with 'DosSemClear' after the Presentation Space has been released.
  155. THIS IS VERY IMPORTANT! ANIMATE often needs to draw into the desktop window,
  156. and must block any drawing 'animatethread' may do. If 'animatethread' draws
  157. at the same time as ANIMATE, sooner or later your computer will crash. Also,
  158. don't request 'hpssemaphore' and then keep it for any lengthy period of time,
  159. since ANIMATE (and thus the whole PM screen group) will be blocked until you
  160. clear it. The extension should request 'hpssemaphore', get a Presentation
  161. Space for the desktop window using 'screenhwnd' and 'WinGetPS', draw into the
  162. Presentation Space, draw into the shadow PS if used, release the desktop
  163. window Presentation Space, and then clear 'hpssemaphore'.
  164.  
  165. animatepaint
  166.  
  167. This procedure is only called when the shadow PS is not used. It should
  168. update the portion of the desktop window specified by the RECTL pointer,
  169. using the Presentation Space specified by the HPS. This is similar to
  170. 'WinBeginPaint' except that the procedure must not release the Presentation
  171. Space since ANIMATE will take care of that. Also, don't request (or clear)
  172. 'hpssemaphore' because ANIMATE already does that before calling
  173. 'animatepaint', a feature that can be used to serialize access to global
  174. variables or other resources that 'animatethread' and 'animatepaint' must
  175. share.
  176.  
  177. animatechar
  178.  
  179. When ANIMATE gets a character from the user, and doesn't process it itself,
  180. it passes the character to this procedure so that the extension can process
  181. it (or ignore it). Like 'animatepaint', ANIMATE requests 'hpssemaphore'
  182. before calling 'animatechar' (and clears it after returning) so that access
  183. to global variables or other resources 'animatethread' and 'animatechar' must
  184. share can be serialized.
  185.  
  186. animatedblclk
  187.  
  188. Animate calls this procedure when the user has double-clicked on the desktop
  189. window. Usually the procedure brings up a message box with credits and
  190. instructions, but a full fledged dialog box can be invoked if desired. The
  191. MPARAM is 'mp1' from the 'WM_BUTTON1DBLCLK' message that ANIMATE received,
  192. which contains the position of the pointer. When invoking a message box or
  193. dialog box, 'screenhwnd' should NOT be used as the parent or owner, use
  194. 'HWND_DESKTOP' instead. Since the animated desktop window is behind all other
  195. windows, any child of the animated desktop window would also be behind all
  196. other windows, something almost certainly undesirable for a message box. Note
  197. also that unlike 'animatepaint' and 'animatechar', ANIMATE does not request
  198. 'hpssemaphore' before calling 'animatedblclk'. This is so the animated
  199. desktop will continue to run while the message box is up.
  200.  
  201. animateclose
  202.  
  203. This is the last procedure called by ANIMATE, just before ANIMATE
  204. terminates. The procedure should release any resources that were allocated
  205. during 'animateinit'. Like 'animateinit', the 'shadowhps' field in the
  206. INITBLOCK structure is not valid at this point.
  207.  
  208.  
  209.  
  210. That completes the explanation. Where the instructions are a little sketchy,
  211. use the example source code to see at least one way of doing it. Good luck,
  212. and may the bits be with you.
  213.  
  214.  
  215. John Ridges
  216.  
  217. Gilmore /108 or Compuserve 72000,2057 (checked weekly)
  218. April 23, 1990
  219.