home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 2 / DATAFILE_PDCD2.iso / utilities / nplib111 / NPLib111 / Documents next >
Encoding:
Text File  |  1994-08-16  |  121.6 KB  |  2,863 lines

  1. NPLibrary version 1.11 written by Chris Coe  (c) Norsoft Productions 1994
  2. =========================================================================
  3.  
  4. The Norsoft Productions library is the wimp procedure library that has been
  5. employed by ALL multi-tasking programs from Norsoft Productions. Having
  6. looked at many wimp libraries in the Public Domain, I decided to write my
  7. own. The problem with these libraries is that often they don't suit the style
  8. of programming of anybody but the author. Obviously I can't say that
  9. NPLibrary is any different, but I hope that it will be found useful to WIMP
  10. programmers everywhere.
  11.  
  12. NPLibrary is written in BASIC, so it will be of most use to BASIC
  13. programmers. You can find the version number in the fourth line of the
  14. program (a REM statement). As the library is only in the 'expanding' stage at
  15. the moment, it is inevitable that people will want to add their own routines
  16. to the library. I would like programmers to write to me with any improvements
  17. they think might be useful rather than doing this, as it will lead to many
  18. strange, incompatible and inconsistent versions springing up everywhere.
  19.  
  20. Note that NPLibrary is NOT for people with "little or no knowledge" of Wimp
  21. programming, because it's quite complicated, and expects you to know what you
  22. are doing. I have given help where I think it's necessary, and at the end
  23. there is an example program showing where all these procedures are meant to
  24. go in the program, but once again I must stress that it's not for newcomers
  25. to Wimp programming, and a copy of the new PRMs is strongly recommended.
  26.  
  27. Usage of NPLibrary: technical & official
  28. ----------------------------------------
  29.  
  30. ***** TECHNICAL *****
  31.  
  32. GENERAL
  33. 1) All procedures and variables used in NPLibrary begin with 'lib_', and all
  34. variables are localised except for a special few (see later), so it is almost
  35. impossible to have procedures and variables in your program and NPLibrary
  36. clashing with each other.
  37. 2) In an ordinary Wimp task, the task would have to keep track of things like
  38. the last menu that was open, the template buffer and so on. When you use
  39. NPLibrary, the library takes care of all this. In fact, the task doesn't even
  40. need to know anything about it.
  41.  
  42. INSTALLING
  43. As with any other files used by your applications, NPLibrary should be placed
  44. inside the application it is to be used in. One of the first lines of your
  45. program should be:
  46.  
  47. LIBRARY "<Obey$Dir>.NPLibrary"
  48.  
  49. You can of course replace "<Obey$Dir>" with the program's system variable if
  50. it has one, like "<App$Dir>".
  51.  
  52. MEMORY CONSUMPTION
  53. Because of the overheads incurred by tacking large amounts of code to your
  54. program, you should add about 64k onto the expected wimpslot value of the
  55. program, so a program with a 32k wimpslot becomes a program with a 96k one.
  56.  
  57. WimpSlot -min 96k -max 96k
  58. Run <Obey$Dir>.!RunImage
  59.  
  60. INITIALISING
  61. Before any NPLibrary procedures are called or variables are used, the
  62. procedure PROClib_initialise must be called. For details of this, see the
  63. definitions of each function/procedure below.
  64.  
  65. POLLING LOOP
  66. The main Wimp polling loop is also dealt with by NPLibrary. In version 1.00
  67. (which has been released inside earlier programs of mine but this is its
  68. first release as a stand-alone program) was handled by the task. The new
  69. method takes even more programming strain away from the task to let the
  70. programmer concentrate on what it was designed for. It also means that little
  71. things like reopening the menu if adjust was used and sending superfluous
  72. keypresses to the next task are dealt with automatically, whereas before they
  73. had to be in the task.
  74.  
  75. The task's main program loop should look something like this:
  76.  
  77. DEF PROCpoll
  78. finish%=FALSE
  79. REPEAT
  80. PROClib_poll(work%)
  81. UNTIL finish%
  82. ENDPROC
  83.  
  84. Where finish% is a flag that should be set when the user quits the task, or
  85. the task is forced by the Wimp to close down. PROClib_poll will call the task
  86. when it needs help, but many things can be carried out entirely in the
  87. background without the programmer even realizing that they have to be done.
  88.  
  89. COMPULSORY PROCEDURES
  90. The task you are writing is expected to have certain special procedures that
  91. can be called. To avoid confusion, these all start with 'task_' and should be
  92. located within the main code somewhere, and NOT in NPLibrary.
  93. There are also several procedures to do with polling, and these all start
  94. with 'poll_'. These too should be placed in the main code.
  95.  
  96. ERROR TRAPPING
  97. To trap internal errors with the ON ERROR statement, you should have a line
  98. near the start of the program looking similar to:
  99.  
  100. ON ERROR PROClib_fatalerror:PROCtask_quit:END
  101.  
  102. Obviously, you should only put this AFTER you have installed NPLibrary with
  103. the LIBRARY command.
  104.  
  105. TEMPLATES
  106. Two template files are included with NPLibrary, Template2D and Template3D. In
  107. this version, they contain just two window definitions - "info" and "savebox"
  108. - with exactly the same icon numbers etc. The only difference is that one is
  109. for RISC OS 2, the other is for RISC OS 3 with the 3D bit in the CMOS RAM
  110. set. You should use these as the basis of your template files, as they are
  111. standard windows that I have already set up for you.
  112.  
  113. PINBOARD ICONS
  114. The two files IcSprite and IcSprite22 contain two blank sprites on which you
  115. should base your designs for iconized window sprites. IcSprite is the lo-res
  116. version and IcSprite22 is for those with hi-res monitors. See the section on
  117. iconizing windows for more information.
  118.  
  119. ***** OFFICIAL *****
  120.  
  121. If you wish to use NPLibrary in programs for general release, be it Public
  122. Domain, shareware, commercial or whatever, you should contact me with a copy
  123. of the program to obtain my permission to use it. I won't refuse you unless
  124. the program is obscene or utter crap, so there aren't really any strings
  125. attached. The only other condition is that I am credited somewhere in the
  126. program that is visible to the user during use (that means not in a REM line
  127. somewhere that nobody will ever look at!).
  128. If you have any suggestions for improvement to the library, please let me
  129. know so I can implement them and send you a copy of the new version. I am
  130. aware that NPLibrary is not a full library of Wimp routines at present,
  131. mainly because I have been adding bits to it as I need them rather than
  132. programming it as a project in its own right. To contact me, please write to:
  133.  
  134.                            Norsoft Productions,
  135.                            19, Seton Road,
  136.                            Taverham,
  137.                            Norwich,
  138.                            Norfolk,
  139.                            NR8 6QE.
  140.                            
  141. Enclose a SAE for the return of your disk(s).
  142.  
  143.  
  144. Accessible NPLibrary variables
  145. ------------------------------
  146.  
  147. VARIABLE NAME        CONTENTS
  148. *lib_templatesize%   The size in bytes of NPLibrary's template area.
  149. *lib_indirectsize%   The size in bytes of NPLibrary's indirected icon data
  150.                      block.
  151. *lib_menusize%       The size in bytes of NPLibrary's menu data block.
  152. *lib_blocksize%      The size in bytes of NPLibrary's miscellaneous data
  153.                      block.
  154. *lib_block%          The start address of NPLibrary's miscellaneous data
  155.                      block.
  156. *lib_templatebuffer% The start address of NPLibrary's template area.
  157. *lib_indirect%       The start address of NPLibrary's indirected icon data
  158.                      block.
  159. *lib_menu%           The start address of NPLibrary's menu data block.
  160. lib_left%            Used to refer to the left-hand side of the icon bar.
  161.                      It is a constant holding the value -2.
  162. lib_right%           Used to refer to the right-hand side of the icon bar.
  163.                      It is a constant holding the value -1.
  164. *lib_menuptr%        NPLibrary's current position down the menu data block.
  165. lib_lastopen%        The handle of the last menu that was open. When
  166.                      undefined, it holds the value -1.
  167. *lib_lastopenitems%  The number of items in the last menu that was open. When
  168.                      undefined or unrequired, it holds the value -1.
  169. lib_front%           Used to refer to the setting of the positions of windows
  170.                      to the front. It is a constant holding the value -1.
  171. *lib_lastopenx%      Used to refer to the x position of the last menu open.
  172.                      When undefined, it holds the value -1.
  173. *lib_lastopeny%      Used to refer to the y position of the last menu open.
  174.                      When undefined, it holds the value -1.
  175. lib_saved%           A flag showing whether the current document has been
  176.                      saved (-1/TRUE if so, 0/FALSE if not). When undefined,
  177.                      it holds the value -2.
  178. lib_taskname$        The name of the task to be used in the task manager
  179.                      display. When undefined, it holds the string
  180.                      "<Untitled>".
  181. *lib_sprites%        Contains the pointer to NPLibrary's private sprite area.
  182.                      When undefined, it contains the value 1 (this will cause
  183.                      the Wimp to look in its own sprite pool when the task is
  184.                      looking for a sprite).
  185.  
  186. * should not need to be referred to by the task.
  187.  
  188.  
  189. Compulsory task procedures
  190. --------------------------
  191.  
  192. These must be found in !RunImage somewhere. They can be called by the task if
  193. it so desires, but NPLibrary expects all of them to be there, even if it just
  194. passes control straight back to the library and does nothing.
  195. The complete list of procedures and functions is:
  196.           
  197. WINDOWS   PROCtask_redrawwindow        Initiate redraw of window
  198.           FNtask_closewindow           Check if it is ok for NPLibrary to
  199.                                        close a window
  200.           
  201. FILE      FNtask_oktosave              Check if it is ok for NPLibrary to
  202. HANDLING                               initiate a save
  203.           PROCtask_save                Saves a file/document
  204.           FNtask_oktoload              Check if it is ok for NPLibrary to
  205.                                        initiate a load
  206.           PROCtask_load                Loads a file/document
  207.           PROCtask_updatefilestatus    Perform any tidying up necessary
  208.                                        concerning file status
  209.           
  210. TASK      PROCtask_quit                Close down the task
  211. HANDLING
  212.  
  213. ..................................................................WINDOWS....
  214.  
  215. PROCEDURE/FUNCTION NAME: PROCtask_redrawwindow
  216.  
  217. PURPOSE: Initiate redraw of window
  218.  
  219. PARAMETERS: On entry:
  220.             1. window handle
  221.             2. visible top-left x origin of window
  222.             3. visible top-left y origin of window
  223.             4. redraw minimum x coordinate
  224.             5. redraw minimum y coordinate
  225.             6. redraw maximum x coordinate
  226.             7. redraw maximum y coordinate
  227.  
  228. USAGE: When NPLibrary needs the task's help to redraw a window, it will call
  229.        PROCtask_redrawwindow with the graphics window set to the redraw
  230.        rectangle. Because of this, it doesn't matter if you just redraw the
  231.        whole window at P2,P3 because the only part that will actually be
  232.        redrawn is the graphics window.
  233.  
  234. EXAMPLE: DEF PROCtask_redrawwindow(window%,xorigin%,yorigin%,x1%,y1%,x2%,y2%)
  235.          CASE window% OF
  236.          WHEN window handle 1:PROCredraw_preferenceswindow
  237.          WHEN window handle 2:PROCredraw_palettewindow
  238.          WHEN window handle 3:PROCredraw_picturewindow
  239.          ENDCASE
  240.          ENDPROC
  241.        
  242. .............................................................................
  243.  
  244. PROCEDURE/FUNCTION NAME: FNtask_closewindow
  245.  
  246. PURPOSE: Check if it is ok for NPLibrary to close a window
  247.  
  248. PARAMETERS: On entry:
  249.             1. window handle
  250.  
  251.             On exit:
  252.             1. TRUE = ok to close window
  253.                FALSE = not ok to close window
  254.             
  255. USAGE: This should return TRUE or FALSE depending on whether or not it is ok
  256.        to close the window of that particular handle. You can also use it to
  257.        perform actions like opening filer windows if the user is holding down
  258.        SHIFT etc.
  259.  
  260. EXAMPLE: DEF FNtask_closewindow(window%)
  261.          LOCAL ok%:ok%=TRUE
  262.          CASE window% OF
  263.          WHEN mainwindow%:
  264.          IF lib_saved%=0 PROClib_openwindowincentre(warning%,FALSE):ok%=FALSE
  265.          ENDCASE
  266.          =ok%
  267.          
  268.          The third from last line means: if the document has not been saved,
  269.          then bring up a warning window and set the ok% flag to NOT ok to
  270.          close the window.
  271.  
  272. ...........................................................FILE HANDLING.....
  273.  
  274. PROCEDURE/FUNCTION NAME: FNtask_oktosave
  275.  
  276. PURPOSE: Check if it is ok for NPLibrary to initiate a save
  277.  
  278. PARAMETERS: On entry:
  279.             1. filename
  280.             
  281.             On exit:
  282.             1. TRUE = ok to save
  283.                FALSE = not ok to save
  284.  
  285. USAGE: This procedure gives the task a chance to object if for some reason
  286.        there is a problem with saving the file. For example, it could be used
  287.        to make sure that a file of the same name doesn't exist, and this is
  288.        the subject of the example below.
  289.  
  290. EXAMPLE: DEF FNtask_oktosave(file$)
  291.          LOCAL h%,ok%:ok%=TRUE
  292.          h%=OPENIN(file$):CLOSE#h%
  293.          IF h%>0 THEN PROClib_openwholewindowincentre(overwritewarning%,FALSE
  294.          ):ok%=FALSE
  295.          =ok%
  296.          
  297.          If the handle (h%) of the file opened is 0, then it doesn't exist
  298.          and returns OK, but if it has a handle >0, then it does exist and
  299.          a warning window is opened, and the ok% flag is set to FALSE.
  300.  
  301. .............................................................................
  302.  
  303. PROCEDURE/FUNCTION NAME: PROCtask_save
  304.  
  305. PURPOSE: Saves a file/document
  306.  
  307. PARAMETERS: On entry:
  308.             1. filename
  309.  
  310. USAGE: Although NPLibrary handles the majority of the data transfer protocol,
  311.        there comes a point when the actual data must be written, and at this
  312.        point PROCtask_save is called. The task must save the file, update any
  313.        filename icons to reflect the new filename, set the saved flag if
  314.        necessary, carry out any other actions like closing windows etc., and
  315.        pass control back to the library.
  316.  
  317. EXAMPLE: DEF PROCtask_save(file$)
  318.          LOCAL handle%
  319.          handle%=OPENOUT(file$)
  320.          BPUT#handle%,"Hello World"
  321.          CLOSE#handle%
  322.          PROClib_saved(TRUE)        <- This sets the lib_saved% flag
  323.          $file%=file$               <- Assuming file% holds the indirected
  324.                                        icon address of the save box file
  325.                                        icon, this updates its contents.
  326.          PROClib_closewindow(documentwindow%)
  327.          ENDPROC
  328.  
  329. .............................................................................
  330.  
  331. PROCEDURE/FUNCTION NAME: FNtask_oktoload
  332.  
  333. PURPOSE: Check if it is ok for NPLibrary to initiate a load
  334.  
  335. PARAMETERS: On entry:
  336.             1. filename
  337.             
  338.             On exit:
  339.             1. TRUE = ok to load
  340.                FALSE = not ok to load
  341.  
  342. USAGE: This procedure gives the task a chance to object if for some reason
  343.        there is a problem with loading the file. For example, an unsaved
  344.        file could already be in memory, and the loading action would
  345.        overwrite it, and this is the subject of the example below.
  346.  
  347. EXAMPLE: DEF FNtask_oktoload(file$)
  348.          LOCAL ok%:ok%=TRUE
  349.          IF lib_saved%=0 THEN PROClib_openwholewindowincentre(savewarning%,FA
  350.          LSE):ok%=FALSE
  351.          =ok%
  352.  
  353. .............................................................................
  354.  
  355. PROCEDURE/FUNCTION NAME: PROCtask_load
  356.  
  357. PURPOSE: Load a file/document
  358.  
  359. PARAMETERS: On entry:
  360.             1. filename
  361.  
  362. USAGE: This may be called by the task or by NPLibrary to load something into
  363.        the task. The procedure must reset everything necessary, load the
  364.        file, and open a window displaying its contents. As in PROCtask_save,
  365.        you must also update any filename icons necessary and set the
  366.        lib_saved% flag (as the file won't have been altered yet if it has
  367.        just been loaded). Finally, control must be passed back to NPLibrary.
  368.  
  369. EXAMPLE: DEF PROCtask_load(file$)
  370.          PROCclearmemory
  371.          OSCLI"Load "+file$+" "+STR$~memory%  <- memory% has been previously
  372.                                                  allocated with a DIM
  373.          PROCputfileinwindow
  374.          PROClib_openwholewindowincentre(mainwindow%,FALSE) <- opens the
  375.                                                                main window
  376.          PROClib_saved(TRUE)
  377.          $file%=file$     <- assuming file% points to the indirected icon
  378.                              for the save box
  379.          ENDPROC
  380.  
  381. .............................................................................
  382.  
  383. PROCEDURE/FUNCTION NAME: PROCtask_updatefilestatus
  384.  
  385. PURPOSE: Perform any tidying up necessary concerning file status
  386.  
  387. PARAMETERS: None
  388.  
  389. USAGE: This procedure is used in various places by NPLibrary to keep the
  390.        user of the task informed about file information. The procedure
  391.        should add or remove "*"s from window titles showing whether or not
  392.        a file has been changed since it was last saved, update info windows,
  393.        title bars and so on to reflect any change in document filenames etc.
  394.  
  395. EXAMPLE: DEF PROCtask_updatefilestatus
  396.          IF lib_saved% PROClib_changeindtexticon(windinfo%,1,"NO") ELSE PROCl
  397.          ib_changeindtexticon(windinfo%,1,"YES")
  398.          ENDPROC
  399.          
  400.          The middle line examines the lib_saved% flag and changes the text
  401.          in an indirected icon to NO if it has been saved, and YES if it
  402.          hasn't. Suppose there were two icons in a window:
  403.          
  404.          Modified?       ----
  405.          
  406.            ^^^            ^^
  407.           Icon 0         Icon 1
  408.           
  409.          Icon 1 is changed to YES if the file hasn't been saved, so it
  410.          appears as: Modified? YES.
  411.  
  412. ............................................................TASK HANDLING....
  413.  
  414. PROCEDURE/FUNCTION NAME: PROCtask_quit
  415.  
  416. PURPOSE: Close down the task
  417.  
  418. PARAMETERS: None
  419.  
  420. USAGE: The task must close any files open, tidy up and finally close itself
  421.        down as a Wimp task. By this stage any warning windows will have
  422.        already 'been and gone' - all this procedure must do is quit. Note
  423.        though that control is still passed back to the library/program at
  424.        the end for it to issue a final END statement.
  425.  
  426. EXAMPLE: DEF PROCtask_quit
  427.          CLOSE#handle%
  428.          OSCLI"Wipe <Wimp$ScrapDir>.MyApp ~C~V FR"  <- deletes its part of
  429.                                                        the !Scrap directory
  430.          PROClib_closedown(taskhandle%)
  431.          ENDPROC
  432.  
  433. .............................................................................
  434.  
  435.  
  436. Polling procedures and functions
  437. --------------------------------
  438.  
  439. These must all be located in the main !RunImage file, and are called by
  440. PROClib_poll when the need arises. Events marked "---" are handled by
  441. NPLibrary itself. You will not need to use many of these, but they should
  442. still be present in your program in case they are ever called, so
  443.  
  444. DEF PROCpoll_pointerenteringwindow:ENDPROC
  445.  
  446. is fine.
  447.        
  448.  Procedure/function called           Event code                Event number
  449.  -------------------------           ----------                ------------
  450.  
  451.  PROCpoll_null                       Null_Reason_Code          0
  452.    ---                               Redraw_Window_Request     1
  453.  PROCpoll_openwindow                 Open_Window_Request       2
  454.    ---                               Close_Window_Request      3
  455.  PROCpoll_pointerleavingwindow       Pointer_Leaving_Window    4
  456.  PROCpoll_pointerenteringwindow      Pointer_Entering_Window   5
  457.  PROCpoll_checkmouse                 Mouse_Click               6
  458.  PROCpoll_drag                       User_Drag_Box             7
  459.  FNpoll_keypressed                   Key_Pressed               8
  460.  PROCpoll_menuselection              Menu_Selection            9
  461.  PROCpoll_scrollrequest              Scroll_Request           10
  462.  PROCpoll_losecaret                  Lose_Caret               11
  463.  PROCpoll_gaincaret                  Gain_Caret               12
  464.  PROCpoll_receivemessage             User_Message(_Recorded)  17(18)
  465.  
  466. .............................................................................
  467.  
  468. PROCEDURE/FUNCTION NAME: PROCpoll_null
  469.  
  470. CALL EVENT: Null_Reason_Code
  471.  
  472. PARAMETERS: None
  473.  
  474. USAGE: This is the time to be doing any calculations or other work that the
  475.        task may want to do, for Null_Reason_Code means that the computer has
  476.        some time on its hands and is offering it to your task.
  477.  
  478. .............................................................................
  479.  
  480. PROCEDURE/FUNCTION NAME: PROCpoll_openwindow
  481.  
  482. CALL EVENT: Open_Window_Request
  483.  
  484. PARAMETERS: Received:
  485.             1. window handle
  486.             2. visible area minimum x coordinate
  487.             3. visible area minimum y coordinate
  488.  
  489. USAGE: By the time the task is called, NPLibrary will have already opened
  490.        the window specified by the Wimp. It is now up to the task to
  491.        correctly open/reposition any toolboxes necessary. The handle of the
  492.        window opened is supplied so that the task can work out if any other
  493.        windows attached to that one need to be moved, and if so, you can
  494.        simply offset them from the coordinates supplied.
  495.  
  496. .............................................................................
  497.  
  498. PROCEDURE/FUNCTION NAME: PROCpoll_pointerleavingwindow
  499.  
  500. CALL EVENT: Pointer_Leaving_Window
  501.  
  502. PARAMETERS: Received:
  503.             1. window handle
  504.  
  505. USAGE: This is the task's opportunity to change the shape of the pointer,
  506.        remove the input focus from the window etc. The window the pointer
  507.        has left is specified in P1.
  508.  
  509. .............................................................................
  510.  
  511. PROCEDURE/FUNCTION NAME: PROCpoll_pointerenteringwindow
  512.  
  513. CALL EVENT: Pointer_Entering_Window
  514.  
  515. PARAMETERS: Received:
  516.             1. window handle
  517.             
  518. USAGE: The pointer has just entered window P1, so if you are writing an art
  519.        package for instance you can use this procedure to change the pointer
  520.        shape to that of the currently used tool. The window the pointer has
  521.        entered is specified in P1.
  522.  
  523. .............................................................................
  524.  
  525. PROCEDURE/FUNCTION NAME: PROCpoll_checkmouse
  526.  
  527. CALL EVENT: Mouse_Click
  528.  
  529. PARAMETERS: Received:
  530.             1. mouse absolute x coordinate
  531.             2. mouse absolute y coordinate
  532.             3. button state:
  533.                     bit 0 set = select depressed
  534.                     bit 1 set = menu depressed
  535.                     bit 2 set = adjust depressed
  536.             4. window handle
  537.             5. icon handle
  538.  
  539. USAGE: The user has just depressed a button on the mouse. Note if more than
  540.        one button is depressed, then two or more bits can be set, so the way
  541.        to check that select is pressed is not:
  542.        
  543.        IF buttons%=1<<2               but
  544.        IF (buttons% AND 1<<2)
  545.        
  546.        The first will only work if select is the only button depressed, but
  547.        the second will work whatever combination is depressed (as long as
  548.        select is one of them). P4 and P5 specify the icon clicked on and
  549.        what window it is in. The task is more likely to want to use these
  550.        values than P1 and P2.
  551.  
  552. .............................................................................
  553.  
  554. PROCEDURE/FUNCTION NAME: PROCpoll_drag
  555.  
  556. CALL EVENT: User_Drag_Box
  557.  
  558. PARAMETERS: Received:
  559.             1. drag box absolute x minimum coordinate
  560.             2. drag box absolute y minimum coordinate
  561.             3. drag box absolute x maximum coordinate
  562.             4. drag box absolute y maximum coordinate
  563.             
  564. USAGE: The user has just released all the mouse buttons, terminating a user
  565.        drag event. The size of the box made is returned, but remember that
  566.        a drag also occurs when the user drags files to filer windows, so
  567.        the most common use of this procedure will be to initiate a save (in
  568.        which case the coordinates supplied are not used).
  569.        
  570. .............................................................................
  571.  
  572. PROCEDURE/FUNCTION NAME: FNpoll_keypressed
  573.  
  574. CALL EVENT: Key_Pressed
  575.  
  576. PARAMETERS: Received:
  577.             1. window handle
  578.             2. icon handle
  579.             3. ASCII code of key pressed
  580.             
  581.             Sent:
  582.             1. key process status:
  583.                    TRUE = keypress was for us, do not send to other tasks
  584.                   FALSE = keypress was not for us, send to other tasks
  585.  
  586. USAGE: The Wimp can deal with most keypresses itself, but keypresses
  587.        invoking action such as RETURN must be dealt with by the task. P1 and
  588.        P2 are the window and icon handles that the caret is in. P3 can be
  589.        converted to a character with BASIC's CHR$(a) function, where 'a' is
  590.        an ASCII code. RETURN has the ASCII code 13. The task must decide
  591.        and return whether the keypress was intended for it, TRUE if it was
  592.        (and this will terminate it), FALSE if it wasn't (NPLibrary will pass
  593.        it on to the next task). It is crucial that you program this correctly
  594.        as programs that employ hot-key functions won't work if you terminate
  595.        every keypress that reaches your task.
  596.  
  597. .............................................................................
  598.  
  599. PROCEDURE/FUNCTION NAME: PROCpoll_menuselection
  600.  
  601. CALL EVENT: Menu_Selection
  602.  
  603. PARAMETERS: Received:
  604.             1. textual selection (submenus separated by periods)
  605.             2. last menu open
  606.             
  607. USAGE: This returns the actual text that was clicked on in the menu
  608.        structure, so clicking on "Quit" will return "Quit". P2 is supplied
  609.        just in case you have the same option in more than one menu, and of
  610.        course you need to check that it was actually one of your task's
  611.        menus that an option was chosen from.
  612.  
  613. .............................................................................
  614.  
  615. PROCEDURE/FUNCTION NAME: PROCpoll_scrollrequest
  616.  
  617. CALL EVENT: Scroll_Request
  618.  
  619. PARAMETERS: None
  620.  
  621. USAGE: This procedure is not yet supported. While no parameters are
  622.        supplied, you can still find out anything you want from the block
  623.        returned by Wimp_Poll.
  624.  
  625. .............................................................................
  626.  
  627. PROCEDURE/FUNCTION NAME: PROCpoll_losecaret
  628.  
  629. CALL EVENT: Lose_Caret
  630.  
  631. PARAMETERS: Received:
  632.             1. window handle
  633.             2. icon handle
  634.  
  635. USAGE: The Lose_Caret event occurs when the window with the input focus
  636.        window changes. It does not occur if a different icon in the same
  637.        window gets the input focus. Bear in mind that if your task has more
  638.        than one window capable of holding the input focus, then the caret
  639.        may still be with it. A Gain_Caret message is broadcast immediately
  640.        after the Lose_Caret to notify the task in question, so you will find
  641.        out if your task still has the input focus. P1 and P2 specify from
  642.        where the task has lost the caret.
  643.  
  644. .............................................................................
  645.  
  646. PROCEDURE/FUNCTION NAME: PROCpoll_gaincaret
  647.  
  648. CALL EVENT: Gain_Caret
  649.  
  650. PARAMETERS: Received:
  651.             1. window handle
  652.             2. icon handle
  653.             
  654. USAGE: The task has just gained the caret. P1 and P2 specifies the window and
  655.        icon the caret has been placed in. Window P1 will also gain the input
  656.        focus.
  657.        
  658. .............................................................................
  659.  
  660. PROCEDURE/FUNCTION NAME: PROCpoll_receivemessage
  661.  
  662. CALL EVENT: User_Message / User_Message_Recorded
  663.  
  664. PARAMETERS: Received:
  665.             1. message action code
  666.             
  667. USAGE: All wimp, filer, pinboard messages and so on will be routed here. The
  668.        use of these messages varies enormously, so it is left to the task
  669.        programmer to examine the parts of the message block that he or she
  670.        wants to use. You really need the PRMs to take advantage of such
  671.        messages, which include saving files, iconizing windows, setting
  672.        task alarms and so on. Owners of the RISC OS 3 PRMs can find detailed
  673.        information about every message available in RISC OS 3 starting on
  674.        page 3-230. This information is extremely useful.
  675.        PROCpoll_receivemessage should take the form:
  676.        
  677.        DEF PROCpoll_receivemessage(message%)
  678.        CASE message% OF
  679.        WHEN 0:PROCtask_quit:END           <-- always include this line
  680.        WHEN 2:PROClib_dosave(savewind_handle,saveicon_handle,wimp_poll_block)
  681.        WHEN 3,5:PROClib_doload(wimp_poll_block,file_type)
  682.        ...
  683.        ENDCASE
  684.        ENDPROC
  685.        
  686.        where wimp_poll_block is the block returned by PROClib_poll - you
  687.        specify it as the first parameter to PROClib_poll. A couple of
  688.        messages have been included here: 0 = Message_Quit - instant shutdown,
  689.        no choices; 2 = Message_DataSaveAck - filer acknowledges save start;
  690.        3 = Message_DataLoad - filer wants task to load file; 5 = Message_ -
  691.        DataOpen - the user has double-clicked on a file/directory. The list
  692.        should continue in this manner for every message you want to
  693.        intercept.
  694.        
  695. .............................................................................
  696.  
  697.  
  698. NPLibrary procedures and functions
  699. ----------------------------------
  700.  
  701. These form the skeleton of Wimp programs, which you can use in your own
  702. programs. You do need some knowledge of Wimp programming, but the task in
  703. hand should be greatly simplified by NPLibrary, especially operations where
  704. messages are being broadcast all over the place, like saving operations,
  705. which are reduced to three or four PROCs in the right place.
  706. In the descriptions below, as well as full details on all the procedures
  707. implemented so far, their context in the whole overall program are discussed
  708. so you know exactly where they go.
  709. There are also some routines which have nothing to do with the Wimp itself,
  710. but will be useful to Wimp programmers, such as a routine to check if a
  711. filename is valid.
  712. The complete list of procedures and functions is:
  713.           
  714. TASK      PROClib_initialise           Initialise NPLibrary
  715. HANDLING  FNlib_startuptask            Register a task on the active list
  716.           PROClib_closedown            Remove a task from the active list
  717.           
  718. ERROR     PROClib_reporterror          Report an error
  719. HANDLING  PROClib_fatalerror           Deal with and report a fatal error
  720.           FNlib_reportwarning          Report a warning error
  721.           
  722. ICONS     FNlib_iconbar                Put an icon on the icon bar
  723.           FNlib_indirecticon           Return the address of an indirect icon
  724.           PROClib_changeindtexticon    Change the contents of an indirected
  725.                                        text only icon
  726.           PROClib_changeiconbartext    Changes the text in an icon bar icon
  727.                                        (does not work properly yet)
  728.           PROClib_redrawicon           Redraw an icon
  729.           PROClib_deleteicon           Delete an icon
  730.           PROClib_iconselectable       Select whether an icon is selectable
  731.                                        or greyed out
  732.           PROClib_iconselectstatus     Select whether an icon is selected or
  733.                                        unselected
  734.           FNlib_selected               Return whether an icon is selected or
  735.                                        unselected
  736.           FNlib_putspriteinicon        Puts a sprite into an indirected,
  737.                                        sprite-only icon.
  738.           
  739. WINDOWS   PROClib_opentemplate         Open a window template
  740.           FNlib_loadtemplate           Load a window template
  741.           PROClib_closetemplate        Close a window template
  742.           PROClib_openwindow           Open a window
  743.           PROClib_openwholewindow      Open a whole window
  744.           PROClib_openwindowincentre   Open a whole window in the centre of
  745.                                        the screen, regardless of mode
  746.           FNlib_windowopen             Check if a window is open
  747.           PROClib_closewindow          Close a window
  748.           PROClib_redrawwindow         Initiate a window redraw
  749.           PROClib_forceredraw          Redraw a whole window
  750.           PROClib_changewindowtitle    Change the title of a window
  751.           FNlib_windowtitle            Return the contents of an indirect
  752.                                        window title
  753.           PROClib_bringtofront         Bring a window to the front
  754.           PROClib_openfilerwindowifadjust  Check the mouse button status, and
  755.                                        open a filer window if adjust is being
  756.                                        held down
  757.           FNlib_centrex                Get the x position a window would need
  758.                                        to be plotted at to make it central to
  759.                                        the screen edges on the x axis
  760.           FNlib_centrey                Get the y position a window would need
  761.                                        to be plotted at to make it central to
  762.                                        the screen edges on the y axis
  763.           PROClib_setwindowheight      Sets the height of a window
  764.           PROClib_setwindowwidth       Sets the width of a window
  765.           FNlib_getwindowheight        Gets the height of a window
  766.           FNlib_getwindowwidth         Gets the width of a window
  767.           PROClib_iconizewindow        Iconizes a window (RISC OS 3 only)
  768.           
  769. MENUS     FNlib_createmenu             Set up a menu structure
  770.           PROClib_openmenu             Display a menu on the screen
  771.           FNlib_getmenuselection       Return the user's menu choice in a
  772.                                        textual representation
  773.           PROClib_reopenmenuifadjust   Check the mouse button status, and
  774.                                        reopen the last open menu if adjust
  775.                                        is being held down.
  776.           PROClib_menuselectable       Set whether a menu option is greyed
  777.                                        out or selectable
  778.           PROClib_menutick             Select whether a menu option is ticked
  779.                                        or not
  780.           
  781. FILE      PROClib_savedragstart        Initiate a save drag from the save
  782. HANDLING                               box to a filer window
  783.           PROClib_quicksave            Initiate a save from an OK click in
  784.                                        the save box
  785.           PROClib_tellfileraboutsave   Send save message to the filer
  786.           PROClib_dosave               Perform final checking before a save,
  787.                                        then save
  788.           PROClib_saved                Set the lib_saved% flag status
  789.           PROClib_doload               Perform final checking before a load,
  790.                                        then load
  791.           
  792. MISC      PROClib_setcaretposition     Position the caret
  793. WIMP      PROClib_pointerinfo          Returns the window and icon the mouse
  794.                                        pointer is currently in
  795.           PROClib_loadsprites          Initializes and loads sprites into
  796.                                        NPLibrary's private sprite area
  797.           
  798. MISC      FNlib_getstring              Extract string from memory
  799. NON-WIMP  FNlib_validfilename          Check if the passed filename is valid
  800.           FNlib_getleafname            Gets the leafname of a whole pathname
  801.           FNlib_getfiletype            Gets the filetype of a file
  802.           FNlib_gettimestamp           Get the datestamp from a file
  803.           FNlib_putbit                 Change the value of a bit in a number
  804.           FNlib_bit                    Get the value of a bit in a number
  805.           FNlib_roundup                Rounds up a whole number to the
  806.                                        nearest multiple of another whole
  807.                                        number
  808.  
  809. ............................................................TASK HANDLING....
  810.  
  811. PROCEDURE/FUNCTION NAME: PROClib_initialise
  812.  
  813. PURPOSE: Initialise NPLibrary
  814.  
  815. PARAMETERS: On entry:
  816.             1. template size (kilobytes)
  817.             2. indirected icon data size (kilobytes)
  818.             3. menu block size (kilobytes)
  819.  
  820. USAGE: This call should be issued before any other NPLibrary procedures or
  821.        functions are used. The procedure sets up various data blocks and
  822.        variables, and also initialises the library.
  823.        To work out the template size, use the Count option in the filer menu
  824.        on the template file, divide the number you get by 1024 (to find its
  825.        value in kilobytes) then round up to the nearest multiple of 4. So if
  826.        the number you got was 5346, that's 5346/1024=5.22k, rounded up gives
  827.        8k. That solves the problem of the template buffer size.
  828.        Try a low value like 2k for the indirected icon data size first, and
  829.        if you find that windows have the wrong contents, or their flags have
  830.        been corrupted, or the window is the wrong size, increase it in steps
  831.        of 2k until it works ok.
  832.        Menu blocks are also small, 28 bytes for the header and 24 bytes for
  833.        each menu option, so 2 or 4k should suffice for most programs. If it
  834.        doesn't, try increasing it in 1k steps. Not counting headers, you
  835.        can work out the number of menu options you can get per kilobyte with
  836.        the formula:
  837.                          (m*1024)/o
  838.        where m is the number of kilobytes allocated and o is the number of
  839.        bytes used per menu option (always 24).
  840.  
  841. EXAMPLE: PROClib_initialise(16,4,2)
  842.          Initialises NPLibrary, and allocates 16k for template data, 4k for
  843.          indirected icon data and 2k for menu structures.
  844.  
  845. .............................................................................
  846.  
  847. PROCEDURE/FUNCTION NAME: FNlib_startuptask
  848.  
  849. PURPOSE: Register a task on the active list
  850.  
  851. PARAMETERS: On entry:
  852.             1. proposed task name
  853.             2. highest version of RISC OS that task recognizes
  854.             
  855.             On exit:
  856.             1. task handle
  857.             
  858. USAGE: This will register a task with the Wimp its list of active tasks. The
  859.        task name that is specified in P1 is what will appear in the task
  860.        display.
  861.        If P2 is 2 (ie. RISC OS 2), then messages and events new to RISC OS
  862.        3.1 will never be returned by Wimp_Poll. This allows backwards-
  863.        compatibility between programs that may object to unfamiliar events.
  864.        When writing Wimp programs, you should NEVER do this. Unrecognized
  865.        events should be ignored. If P2 is 3.1, a table of messages to be
  866.        masked in should be passed to Wimp_Initialise, but the current version
  867.        of NPLibrary specifies 0 - which means that all messages are important
  868.        to this task. This is the easiest way of doing it.
  869.        This procedure also sets up the variable lib_taskname$ (see above).
  870.  
  871. EXAMPLE: taskhandle%=FNlib_startuptask("MyApp",2)
  872.          This registers a task called MyApp with the Wimp, requesting it to
  873.          return all messages and events that were present in the old RISC OS
  874.          2, and none since then. The task handle is returned in a variable
  875.          called taskhandle%.
  876.  
  877. .............................................................................
  878.  
  879. PROCEDURE/FUNCTION NAME: PROClib_closedown
  880.  
  881. PURPOSE: Remove a task from the active list
  882.  
  883. PARAMETERS: On entry:
  884.             1. task handle of quitting task
  885.             
  886. USAGE: This removes any task from the Wimp's list of active tasks, not just
  887.        the one it is running from. This means that as well as quitting your
  888.        own task, which would be the normal use for it, you can also force
  889.        other tasks to close down if you know their task handles. This is
  890.        rather unorthodox and I can't think of any non-malicious uses for it.
  891.        Nevertheless, the feature is there.
  892.        Even though you may have closed down your own task, the procedure will
  893.        still return control back to the main program for it to issue a final
  894.        END statement etc.
  895.  
  896. EXAMPLE: PROClib_closedown(taskhandle%)
  897.          Assuming that earlier on you called:
  898.          taskhandle%=FNlib_startuptask...
  899.          then this command will deregister your task from the active list.
  900.          
  901.          PROClib_closedown(&12345678)
  902.          This deregisters task &12345678 from the active list.
  903.  
  904. ...........................................................ERROR HANDLING....
  905.  
  906. PROCEDURE/FUNCTION NAME: PROClib_reporterror
  907.  
  908. PURPOSE: Report an error
  909.  
  910. PARAMETERS: On entry:
  911.             1. error message
  912.             2. flags
  913.             
  914. USAGE: This will pop up a standard error box with P1 written in it, and the
  915.        taskname as used in FNlib_startuptask in the title bar. The flags
  916.        have the following functions:
  917.        
  918.                    Bit       Meaning when set
  919.                     
  920.                     0        Provide an OK box
  921.                     1        Provide a Cancel box
  922.                     2        Highlight Cancel (or OK if bit is cleared)
  923.                     3        If the error is generated while a text-style
  924.                              window is open (eg. within a call to
  925.                              Wimp_CommandWindow), then don't produce the
  926.                              prompt "Press SPACE or click mouse to continue",
  927.                              but return immediately
  928.                     4        Don't prefix the application name with "Error
  929.                              from" in the error window's title bar
  930.                     5        If neither box is clicked, return immediately
  931.                              (with R1=0) and leave the error window open
  932.                     6        Select one of the boxes according to bits 0 and
  933.                              1, close the window and return
  934.                     7        Don't produce a beep even if WimpFlags bit 4 is
  935.                              clear (this bit is reserved in RISC OS 2)
  936.                     8-31     Reserved; must be 0
  937.        
  938.        Currently, you are unable to tell which button has been pressed in the
  939.        error window; to do this, use FNlib_reportwarning.
  940.  
  941. EXAMPLE: PROClib_reporterror("You've put the disk in upside-down",%10010110)
  942.          Report the error in a box, don't beep and don't prefix the task name
  943.          with "Error from", highlight Cancel and provide a Cancel box but no
  944.          OK box.
  945.          
  946.          PROClib_reporterror("I wouldn't press that if I were you",%011)
  947.          Report the error in a box, highlight OK and provide an OK box and a
  948.          Cancel box.
  949.  
  950. .............................................................................
  951.  
  952. PROCEDURE/FUNCTION NAME: PROClib_fatalerror
  953.  
  954. PURPOSE: Deal with and report a fatal error
  955.  
  956. PARAMETERS: None
  957.  
  958. USAGE: This procedure turns off the hourglass, closes all open files and
  959.        calls PROClib_reporterror with BASIC's REPORT$ variable plus the text:
  960.        
  961.        (internal error code [line number]) - must exit immediately
  962.        
  963.        The flags are set to 1, ie provide a cancel box only.
  964.        This call can also be used with an ON ERROR statement, see below.
  965.        
  966. EXAMPLE: ON ERROR PROClib_fatalerror:PROCtask_quit:END
  967.          If something untoward should happen in the program code, this device
  968.          will make sure that the program exits neatly and reports the nature
  969.          and location of the error. The additional call to PROCtask_quit is
  970.          essential in case the task wants to tidy up anything not dealt with
  971.          by PROClib_fatalerror, and if you have written your program properly
  972.          this will also call PROClib_closedown (see the definition of
  973.          PROCtask_quit above for more information).
  974.  
  975. .............................................................................
  976.  
  977. PROCEDURE/FUNCTION NAME: FNlib_reportwarning
  978.  
  979. PURPOSE: Report a warning error
  980.  
  981. PARAMETERS: On entry:
  982.             1. error message
  983.             
  984.             On exit:
  985.             1. icon selection:
  986.                    1 = OK selected
  987.                    2 = Cancel selected
  988.             
  989. USAGE: This calls Wimp_ReportError (as in PROClib_reporterror) with bits 4, 1
  990.        and 0 set, ie. don't prefix the task name with "Error from", and
  991.        provide an ok and a cancel box (highlight the ok box, as bit 2 is
  992.        clear).
  993.        The main difference between this call and PROClib_reporterror is that
  994.        this call will return whether the user selects OK or Cancel.
  995.        
  996. EXAMPLE: ok%=FNlib_reportwarning("Clicking on OK will initiate a nuclear
  997.          meltdown. Are you sure you wish to proceed?")
  998.          IF ok%=2 THEN he's no fool
  999.          This will print the warning in the standard error box and wait for
  1000.          the user to select ok or cancel. The result is put into the variable
  1001.          ok% and action is then taken according to the user's choice.
  1002.  
  1003. ....................................................................ICONS....
  1004.  
  1005. PROCEDURE/FUNCTION NAME: FNlib_iconbar
  1006.  
  1007. PURPOSE: Put an icon on the icon bar
  1008.  
  1009. PARAMETERS: On entry:
  1010.             1. name of sprite to use as icon
  1011.             2. side of icon bar to put sprite on:
  1012.                    -1 = right-hand side
  1013.                    -2 = left-hand side
  1014.             3. buffer to text to put underneath icon,
  1015.                 or -1 for no text
  1016.             
  1017.             On exit:
  1018.             1. icon handle
  1019.             
  1020. USAGE: Most programs will want an icon to go on the icon bar, and this call
  1021.        makes the process very simple. For the second parameter, to save you
  1022.        remembering the two numbers, you may use the NPLibrary variables
  1023.        lib_left% and lib_right% (documented above) which hold the
  1024.        corresponding values.
  1025.        
  1026. EXAMPLE: icon%=FNlib_iconbar("!myapp",lib_right%,-1)
  1027.          This is what most calls to this function will look like. This will
  1028.          place the icon !myapp on the right-hand side of the icon bar with
  1029.          no text.
  1030.          
  1031.          DIM icontext% 12
  1032.          $icontext%="An Icon"
  1033.          icon%=FNlib_iconbar("!myapp",-1,icontext%)
  1034.          This will place the icon !myapp on the right-hand side of the icon
  1035.          bar with the text "An Icon" written underneath.
  1036.  
  1037. .............................................................................
  1038.  
  1039. PROCEDURE/FUNCTION NAME: FNlib_indirecticon
  1040.  
  1041. PURPOSE: Return the address of an indirect icon
  1042.  
  1043. PARAMETERS: On entry:
  1044.             1. window handle
  1045.             2. icon handle
  1046.             
  1047.             On exit:
  1048.             1. address of indirect data buffer
  1049.             
  1050. USAGE: In pre-release versions of NPLibrary, this was an essential function,
  1051.        and while it is not so important now that more friendly procedures
  1052.        are available to you, it is still useful and still used internally.
  1053.        Some icons have text in them, and any icon that needs to have over
  1054.        twelve characters has to be indirected. This will apply particularly
  1055.        to writable icons. So that the task can read the contents of the icon,
  1056.        or so that it can change its contents, it needs to know its address in
  1057.        memory, and that is what this function does. Simply supply the window
  1058.        handle of the window that the icon is in, and the icon handle itself,
  1059.        and the indirect text address will be returned. Note that this will
  1060.        ONLY work on indirected, text, no sprite icons.
  1061.        This procedure has now been superseded in many ways by
  1062.        PROClib_changeindtexticon (see below).
  1063.  
  1064. EXAMPLE: savefilename%=FNlib_indirecticon(savewindow%,2)
  1065.          Supposing that savewindow% is the window handle of a standard save
  1066.          box, and 2 is the icon handle of the writable filename icon in it,
  1067.          then this will return the address in memory at which that filename
  1068.          is stored. In future, the task can now find out the default filename
  1069.          in the save box with the reference: $savefilename%.
  1070.  
  1071. .............................................................................
  1072.  
  1073. PROCEDURE/FUNCTION NAME: PROClib_changeindtexticon
  1074.  
  1075. PURPOSE: Change the contents of an indirected text only icon
  1076.  
  1077. PARAMETERS: On entry:
  1078.             1. window handle
  1079.             2. icon handle
  1080.             3. new textual content of icon
  1081.             
  1082. USAGE: Icons that need to hold text in excess of twelve characters long must
  1083.        be indirected, and this procedure provides a way of changing that
  1084.        data. You supply the window handle of the window contain the icon,
  1085.        and the icon handle itself, and the procedure will issue a call to
  1086.        FNlib_indirecticon(P1,P2) to find the indirected icon's address.
  1087.        The address will then be poked with P3, terminated by a carriage
  1088.        return (ASC 13).
  1089.  
  1090. EXAMPLE: PROClib_changeindtexticon(progress%,status%,"Ready")
  1091.          Assuming that progress% is the window handle of a window containing
  1092.          some kind of progress report, and status% is the icon handle of an
  1093.          indirected text only icon containing information on what the task is
  1094.          doing, then this will change that icon to read "Ready".
  1095.  
  1096. .............................................................................
  1097.  
  1098. PROCEDURE/FUNCTION NAME: PROClib_changeiconbartext
  1099.  
  1100. PURPOSE: Changes the text in an icon bar icon (does not work properly yet)
  1101.  
  1102. PARAMETERS: On entry:
  1103.             1. icon handle of icon bar icon
  1104.             2. pointer to icon bar text buffer
  1105.             3. new textual content of icon
  1106.             
  1107. USAGE: THIS PROCEDURE HAS NOT BEEN FULLY WRITTEN YET. YOU SHOULD NOT USE IT
  1108.        IN YOUR OWN PROGRAMS.
  1109.        
  1110. EXAMPLE: PROClib_changeiconbartext(taskicon%,textbuf%,"Waiting")
  1111.          Assuming that taskicon% is the icon handle of the task's icon bar
  1112.          icon and textbuf% is the text buffer of that icon, then this will
  1113.          change the text underneath the icon to read "Waiting".
  1114.  
  1115. .............................................................................
  1116.  
  1117. PROCEDURE/FUNCTION NAME: PROClib_redrawicon
  1118.  
  1119. PURPOSE: Redraw an icon
  1120.  
  1121. PARAMETERS: On entry:
  1122.             1. window handle
  1123.             2. icon handle
  1124.             
  1125. USAGE: This procedure calls SWI Wimp_SetIconState with both the AND and EOR
  1126.        words set to zero, which has the effect of redrawing the icon with no
  1127.        changes. The window handle is that which the icon is contained in.
  1128.        
  1129. EXAMPLE: PROClib_redrawicon(window%,icon%)
  1130.          This redraws the icon with the handle icon% in window window%.
  1131.  
  1132. .............................................................................
  1133.  
  1134. PROCEDURE/FUNCTION NAME: PROClib_deleteicon
  1135.  
  1136. PURPOSE: Delete an icon
  1137.  
  1138. PARAMETERS: On entry:
  1139.             1. window handle
  1140.             2. icon handle
  1141.             
  1142. USAGE: This procedure deletes the icon with the specified icon handle from
  1143.        the specified window. It will then call PROClib_forceredraw(P1),
  1144.        causing the whole window to be updated.
  1145.  
  1146. EXAMPLE: PROClib_deleteicon(window%,icon%)
  1147.          This deletes icon icon% from window window% and redraws the window.
  1148.          
  1149. .............................................................................
  1150.  
  1151. PROCEDURE/FUNCTION NAME: PROClib_iconselectable
  1152.  
  1153. PURPOSE: Select whether an icon is selectable or greyed out
  1154.  
  1155. PARAMETERS: On entry:
  1156.             1. window handle
  1157.             2. icon handle
  1158.             3. icon status:
  1159.                     TRUE = icon is selectable
  1160.                    FALSE = icon is unselectable and greyed out
  1161.  
  1162. USAGE: In some situations you may only want the user to be able to access a
  1163.        particular icon if certain other conditions have been met. For
  1164.        example, you would only allow the user to type in the screen blanking
  1165.        delay if he had previously chosen to have the screen blanker on. If
  1166.        he or she has chosen to switch it off, then there is no point in
  1167.        entering a delay, and so it is the RISC OS standard to grey out such
  1168.        icons.
  1169.        
  1170. EXAMPLE: PROClib_iconselectable(window%,2,FNlib_selected(window%,4))
  1171.          (FNlib_selected is described below, and is used to determine whether
  1172.          an icon is selected or unselected)
  1173.          This will make icon 2 in window window% selectable or unselectable
  1174.          depending on whether or not icon 4 in window window% is selected.
  1175.          If icon 4 is selected, icon 2 will be selectable.
  1176.          If icon 4 is unselected, icon 2 will be greyed out.
  1177.  
  1178. .............................................................................
  1179.  
  1180. PROCEDURE/FUNCTION NAME: PROClib_iconselectstatus
  1181.  
  1182. PURPOSE: Select whether an icon is selected or unselected
  1183.  
  1184. PARAMATERS: On entry:
  1185.             1. window handle
  1186.             2. icon handle
  1187.             3. icon status:
  1188.                     TRUE = icon is selected
  1189.                    FALSE = icon is unselected
  1190.  
  1191. USAGE: Usually the user can determine the state of icons (particularly radio
  1192.        icons) by clicking on them with the appropriate mouse button. However,
  1193.        there may be some cases where the task needs to set the state of the
  1194.        icons itself. For instance, if the task has just loaded up a
  1195.        preferences file, then all the options on the preference screen will
  1196.        need to be set accordingly. This procedure performs that function.
  1197.  
  1198. EXAMPLE: PROClib_iconselectstatus(pref%,6,confirm%)
  1199.          Supposing confirm% was a boolean variable (a variable holding either
  1200.          TRUE or FALSE) and pref% was the window handle of a preferences
  1201.          window, then icon 6 in the preferences window would reflect the
  1202.          value of confirm%.
  1203.          If confirm% is TRUE, then icon 6 will be selected.
  1204.          If confirm% is FALSE, then icon 6 will be deselected.
  1205.  
  1206. .............................................................................
  1207.  
  1208. PROCEDURE/FUNCTION NAME: FNlib_selected
  1209.  
  1210. PURPOSE: Return whether an icon is selected or unselected
  1211.  
  1212. PARAMETERS: On entry:
  1213.             1. window handle
  1214.             2. icon handle
  1215.             
  1216.             On exit:
  1217.             1. icon status:
  1218.                     TRUE = the icon is selected
  1219.                    FALSE = the icon is unselected
  1220.             
  1221. USAGE: This performs the opposite of PROClib_iconselectstatus. Rather than
  1222.        setting the selected status of an icon, FNlib_selected will return it.
  1223.        This is essential for setting variables according to the status of
  1224.        icons.
  1225.  
  1226. EXAMPLE: confirm%=FNicon_selected(pref%,6)
  1227.          Assuming pref% is the window handle of a preferences window, then
  1228.          confirm% will be set according to the status of icon 6 in that
  1229.          window.
  1230.          If icon 6 is selected, confirm% will be TRUE.
  1231.          If icon 6 is unselected, confirm% will be FALSE.
  1232.          
  1233. .............................................................................
  1234.  
  1235. PROCEDURE/FUNCTION NAME: FNlib_putspriteinicon
  1236.  
  1237. PURPOSE: Puts a sprite into an indirected, sprite-only icon
  1238.  
  1239. PARAMETERS: On entry:
  1240.             1. sprite name
  1241.             2. window handle
  1242.             3. icon handle
  1243.             
  1244.             On exit:
  1245.             1. icon handle
  1246.  
  1247. USAGE: This function is used to make a non-indirected sprite-only icon point
  1248.        to a sprite. All calls to this command ought to be made towards the
  1249.        end of the task's initialization procedure. Since FNlib_putsprite-
  1250.        inicon causes the handle of the icon being changed to be renumbered,
  1251.        its new icon handle is returned at the end.
  1252.        Note this call will ONLY work on indirected, sprite-only icons.
  1253.        The area where the sprite is looked for is determined by the variable
  1254.        lib_sprites%. If lib_sprites% holds the value 1 (which it does after
  1255.        PROClib_initialize is called), then the sprite will be found in the
  1256.        Wimp sprite pool. If lib_sprites% holds any other value (calling
  1257.        PROClib_loadsprites will cause this to happen), then the sprite will
  1258.        be found in NPLibrary's private sprite area.
  1259.        
  1260. ..................................................................WINDOWS....
  1261.  
  1262. Window coordinate information
  1263. -----------------------------
  1264.  
  1265. There are several terms and definitions that you need to understand concerned
  1266. with the plotting of windows. These represent what part of the window is
  1267. displayed, how much of it is displayed, and where it is displayed.
  1268.  
  1269. WORK AREA: A window is only a partial view. Imagine a document twice the size
  1270. of the screen - you can only see part of it at any one time. The area of the
  1271. whole document is called the work area. The bottom-left corner represents the
  1272. minimum x and y, and x and y increase as the work area extends right and up
  1273. respectively. However, the top-left corner of the work area is always (0,0),
  1274. so this means that the bottom-left corner of a work area 200 pixels high is
  1275. (0,-200).
  1276.  
  1277. VISIBLE AREA: The visible area is the area of the screen that is taken up by
  1278. the window. The bottom-left corner represents the minimum x and y, and x and
  1279. y increase as the visible area extends right and up respectively. The visible
  1280. area x and y coordinates are relative to the screen, whose bottom-left corner
  1281. is always (0,0), so the minimum x and y of a window 300 pixels across and 100
  1282. up is (300,100).
  1283.  
  1284. SCROLL OFFSET: The scroll offset determines which part of the window is
  1285. displayed. The scroll offset x and y coordinates specify the top-left corner
  1286. of the work area to be displayed, so a scroll offset of (200,-250) is 200
  1287. pixels from the left and 250 from the top.
  1288.  
  1289. VISIBLE WORK AREA: The visible work area takes the concept of the scroll
  1290. offset one step further. Suppose we want to display part of a work area in a
  1291. window with a visible area of (400,300)-(800,500). If the scroll offset is
  1292. (100,-100) then the visible work area can be worked out thus:
  1293.  
  1294. width = 800 - 400 = 400
  1295. height = 800 - 500 = 300
  1296. visible work area minimum x = scroll offset x = 100
  1297. visible work area maximum y = scroll offset y = -100
  1298. visible work area maximum x = scroll offset + width = 100 + 400 = 500
  1299. visible work area minimum y = scroll offset - height = -100 - 300 = -400
  1300.  
  1301. So the visible work area is (100,-100)-(500,-400) and it is to be plotted at
  1302. (400,300)-(800,500).
  1303.  
  1304.               SCROLL OFFSET
  1305.           0,0     :
  1306.             ------:-----------------------------------------
  1307.             | 100,-100                                     |
  1308.             |    -----------------------                   |
  1309.             |    |                     |                   |
  1310.             |    |      VISIBLE        |       WORK        |
  1311.             |    |       WORK          |       AREA        |
  1312.             |    |        AREA         |                   |
  1313.             |    |                     |                   |
  1314.             |    |                     |                   |
  1315.             |    -----------------------                   |
  1316.             |                        500,-400              |
  1317.             |                                              |
  1318.             |                                              |
  1319.             ------------------------------------------------
  1320.                                                          800,-600
  1321.                                                          
  1322. .............................................................................
  1323.  
  1324. PROCEDURE/FUNCTION NAME: PROClib_opentemplate
  1325.  
  1326. PURPOSE: Open a window template
  1327.  
  1328. PARAMETERS: On entry:
  1329.             1. template filename (full pathname)
  1330.             2. 3D option:
  1331.                      TRUE = use two template files
  1332.                     FALSE = use one template file
  1333.  
  1334. USAGE: Template files are used to describe window shapes and contents. Before
  1335.        a program can display any windows in template files, area has to be
  1336.        set aside in memory for them, they must be loaded and their indirect
  1337.        data fields must be set up. This procedure will open a template file
  1338.        ready for use. The actual file opened depends upon two factors:
  1339.        
  1340.        If P2=FALSE then the file specified will be opened as normal and
  1341.        control will return to the task.
  1342.        
  1343.        If P2=TRUE then the current version of RISC OS will be checked.
  1344.               If the version is less than 3.1 then the filename + "2D" will
  1345.               be opened.
  1346.               If the version is 3.1 or over, then the 3D bit in CMOS RAM will
  1347.               be checked.
  1348.                    If the 3D bit is clear, then the filename + "2D" will be
  1349.                    opened.
  1350.                    If the 3D bit is set, then the filename + "3D" will be
  1351.                    opened.
  1352.        
  1353.        In RISC OS 3.1, there is a previously unused bit in the CMOS RAM which
  1354.        determines whether old RISC OS 2-style 2D window icons will be used,
  1355.        or whether new RISC OS 3 upwards 3D window icons will be used. What
  1356.        this amounts to is that you need to define two sets of windows, one
  1357.        with the suffix 2D and one with the suffix 3D (make sure all the icon
  1358.        numbers match otherwise the program will not work as expected). If
  1359.        the user is using a RISC OS 3.1+ machine and the 3D bit is set, then
  1360.        the 3D template will be loaded, otherwise the 2D templates will be
  1361.        loaded. Of course, you can just specify FALSE for P2 and the same
  1362.        templates will be used whatever the operating system.
  1363.        
  1364.        All template data handling is done by NPLibrary - the task needn't get
  1365.        involved.
  1366.        
  1367. EXAMPLE: PROClib_opentemplate("<Obey$Dir>.Templates",FALSE)
  1368.          Template file "<Obey$Dir>.Templates" will be opened.
  1369.          
  1370.          PROClib_opentemplate("<Obey$Dir>.Temp",TRUE)
  1371.          Template file "<Obey$Dir>.Temp2D" will be opened, unless the user
  1372.          is using a RISC OS 3.1+ machine with the 3D bit set, in which case
  1373.          "<Obey$Dir>.Temp3D" will be opened instead.
  1374.  
  1375. .............................................................................
  1376.  
  1377. PROCEDURE/FUNCTION NAME: FNlib_loadtemplate
  1378.  
  1379. PURPOSE: Load a window template
  1380.  
  1381. PARAMETERS: On entry:
  1382.             1. window name
  1383.             
  1384.             On exit:
  1385.             1. window handle
  1386.             
  1387. USAGE: This function will search the currently open template file from the
  1388.        beginning for any window whose name matches that given in P1. If it
  1389.        does, then it will be loaded, a window created and any indirected data
  1390.        fields set up. The function will then exit with the new handle of the
  1391.        window loaded, with which it will always be referred to by from now
  1392.        on. Every window will have the current sprite block pointer inserted
  1393.        into it so that it knows where to find sprites, so if you have any
  1394.        sprite files to load, do so BEFORE loading any templates.
  1395.  
  1396. EXAMPLE: main%=FNlib_loadtemplate("editwindow")
  1397.          This will scan through the template file looking for a window called
  1398.          "editwindow". The window handle allocated to it will be stored in
  1399.          main%.
  1400.  
  1401. .............................................................................
  1402.  
  1403. PROCEDURE/FUNCTION NAME: PROClib_closetemplate
  1404.  
  1405. PURPOSE: Close a window template
  1406.  
  1407. PARAMETERS: None
  1408.  
  1409. USAGE: This quite simply closes a window template with SWI Wimp_CloseTemplate
  1410.        and returns control to the task.
  1411.        
  1412. EXAMPLE: PROClib_opentemplate("<Obey$Dir>.Template",TRUE)
  1413.          infowind%=FNlib_loadtemplate("info")
  1414.          savewind%=FNlib_loadtemplate("xfer_send")
  1415.          mainwind%=FNlib_loadtemplate("main")
  1416.          PROClib_closetemplate
  1417.          Open the template file, load in three windows and close it again.
  1418.  
  1419. .............................................................................
  1420.  
  1421. PROCEDURE/FUNCTION NAME: PROClib_openwindow
  1422.  
  1423. PURPOSE: Open a window
  1424.  
  1425. PARAMETERS: On entry:
  1426.             1. window handle
  1427.             2. visible area minimum x coordinate
  1428.             3. visible area minimum y coordinate
  1429.             4. visible area maximum x coordinate
  1430.             5. visible area maximum y coordinate
  1431.             6. scroll x offset relative to work area origin
  1432.             7. scroll y offset relative to work area origin
  1433.             8. layer position of window:
  1434.                      -1 = at front
  1435.                      -2 = at back
  1436.                      -3 = behind Wimp's backwindow, hiding it from sight
  1437.             9. transiency of window:
  1438.                    TRUE = window is transient
  1439.                   FALSE = window is persistent
  1440.  
  1441. USAGE: This procedure will open any part of a window on any part of the
  1442.        screen. P8 determines where in the window stack the window shall be
  1443.        opened. The variable lib_front% (which is a constant holding the value
  1444.        -1) can be substituted to make your program easier to read. The value
  1445.        -3 causes the input focus to be taken away before the window is
  1446.        opened, and is not available on RISC OS 2. P9 specifies the transiency
  1447.        of the window. A transient window is one that disappears when you
  1448.        click outside of it, like save boxes and menus. A persistent window is
  1449.        one that stays on the screen until the user closes it in some way,
  1450.        like filer windows. The coordinates for this procedure are rather
  1451.        complex, and two other window opening procedures (PROClib_openwhole-
  1452.        window and PROClib_openwindowincentre) are provided to simplify
  1453.        things a little. There are also functions for working out centre
  1454.        positions on screen (FNlib_centrex and FNlib_centrey).
  1455.        See the section on window coordinates for information on work areas,
  1456.        visible work areas and scroll offsets.
  1457.  
  1458. EXAMPLE: PROClib_openwindow(main%,300,200,900,400,200,200,lib_front%,FALSE)
  1459.          This opens a persistent window at the front of the stack.
  1460.          The bottom-left coordinate on screen is 300,200 and the top-right
  1461.          is 900,400. The top-left of the window is 200,200 across and down
  1462.          from the start of the work area, so the bottom-right pixel is
  1463.          800,700 across and down.
  1464.  
  1465. .............................................................................
  1466.  
  1467. PROCEDURE/FUNCTION NAME: PROClib_openwholewindow
  1468.  
  1469. PURPOSE: Open a whole window
  1470.  
  1471. PARAMETERS: On entry:
  1472.             1. window handle
  1473.             2. visible area minimum x coordinate
  1474.             3. visible area minimum y coordinate
  1475.             4. transiency of window:
  1476.                      TRUE = window is transient
  1477.                     FALSE = window is persistent
  1478.  
  1479. USAGE: This procedure will work out the width and height of a window and then
  1480.        display it wholly on the screen using P2 and P3 as the bottom-left
  1481.        hand corner of the window. PROClib_openwindow is called thus:
  1482.        
  1483.        PROClib_openwholewindow(P1,P2,P3,P2+width,P3+height,0,0,-1,P4)
  1484.        
  1485.        Note that the window will always be opened at the front of the stack.
  1486.        See PROClib_openwholewindow for a more detailed description, and
  1487.        information on window transiency.
  1488.  
  1489. EXAMPLE: PROClib_openwholewindow(savebox%,500,500,TRUE)
  1490.          This will open the whole window savebox% at 500,500 on the screen.
  1491.  
  1492. .............................................................................
  1493.  
  1494. PROCEDURE/FUNCTION NAME: PROClib_openwindowincentre
  1495.  
  1496. PURPOSE: Open a whole window in the centre of the screen, regardless of mode
  1497.  
  1498. PARAMETERS: On entry:
  1499.             1. window handle
  1500.             2. transiency of window:
  1501.                      TRUE = window is transient
  1502.                     FALSE = window is persistent
  1503.  
  1504. USAGE: This command will open a whole window in the centre of the screen.
  1505.        To be more precise, the bottom-left position to plot the window at
  1506.        for it to appear in the centre of the screen is calculated with a
  1507.        call to each of FNlib_centrex and FNlib_centrey (see below), and
  1508.        PROClib_openwholewindow is called thus:
  1509.        
  1510.        PROClib_openwholewindow(P1,FNlib_centrex(P1),FNlib_centrey(P1),P2)
  1511.        
  1512.        PROClib_openwholewindow will in turn calculate any other coordinates
  1513.        necessary and call PROClib_openwindow. See PROClib_openwindow above
  1514.        for more details and information on window transiency. Note that as
  1515.        the call is routed through PROClib_openwholewindow, the window will
  1516.        always be opened at the front of the stack.
  1517.  
  1518. EXAMPLE: PROClib_openwindowincentre(warning%,FALSE)
  1519.          This will open the entire window warning% in the centre of the
  1520.          screen (the window will be persistent).
  1521.  
  1522. .............................................................................
  1523.  
  1524. PROCEDURE/FUNCTION NAME: FNlib_windowopen
  1525.  
  1526. PURPOSE: Check if a window is open
  1527.  
  1528. PARAMETERS: On entry:
  1529.             1. window handle
  1530.             
  1531.             On exit:
  1532.             1. window status:
  1533.                      TRUE = window is open
  1534.                     FALSE = window is not open
  1535.  
  1536. USAGE: This function can be used in all sorts of situations to check if a
  1537.        given window is open or not. For instance, suppose you are writing a
  1538.        music package, and every time a new track is loaded the control panel
  1539.        is opened. If you just call PROClib_openwindow then the window's
  1540.        position on the stack is corrupted. However, you can use:
  1541.        
  1542.        IF NOT FNlib_windowopen(panel%) THEN PROClib_openwindow(panel%,...)
  1543.        
  1544.        and the panel will only be opened if it isn't already on the screen.
  1545.        
  1546. EXAMPLE: IF NOT FNlib_windowopen(main%) PROClib_closewindow(pane%)
  1547.          Supposing pane% is a pane on top of window main%, then if window
  1548.          main% mysteriously disappears from the screen, this makes sure
  1549.          that the pane is not left behind.
  1550.  
  1551. .............................................................................
  1552.  
  1553. PROCEDURE/FUNCTION NAME: PROClib_closewindow
  1554.  
  1555. PURPOSE: Close a window
  1556.  
  1557. PARAMETERS: On entry:
  1558.             1. window handle
  1559.  
  1560. USAGE: This function closes the window given in P1, providing that the task
  1561.        approves - before closing a call is made to FNtask_closewindow, and
  1562.        the window will be closed only if this function returns TRUE. This
  1563.        is so that if the user clicks the close icon of a window containing
  1564.        edited data, the task has a chance to object by opening a warning
  1565.        window and returning FALSE.
  1566.  
  1567. EXAMPLE: PROClib_closewindow(warning%)
  1568.          Closes the window whose handle is warning%.
  1569.  
  1570. .............................................................................
  1571.  
  1572. PROCEDURE/FUNCTION NAME: PROClib_redrawwindow
  1573.  
  1574. PURPOSE: Initiate a window redraw
  1575.  
  1576. PARAMETERS: On entry:
  1577.             1. pointer to block
  1578.  
  1579. USAGE: PROClib_redrawwindow takes care of the Wimp's side of things when a
  1580.        window needs to be redrawn. The Wimp will split the window down into
  1581.        rectangular sections that need to be updated, and PROClib_redrawwindow
  1582.        will call PROCtask_redrawwindow with these coordinates after setting
  1583.        the graphics window appropriately. This is so that it doesn't matter
  1584.        if the task overlaps the redraw area, as it will never be displayed.
  1585.        PROCtask_redrawwindow will be called repeatedly until the window has
  1586.        been updated completely.
  1587.        A task can either just redraw the whole window, which removes all the
  1588.        calculations necessary but is rather sloppy and inefficient, or just
  1589.        the section that needs to be redrawn, which is faster but more
  1590.        complex. Normally, redrawing the whole window is acceptable, except
  1591.        for speed critical applications and programs such as art packages,
  1592.        which would become painfully slow to work with should they be
  1593.        programmed in this manner.
  1594.        On entry, the first word of the block should contain the window
  1595.        handle. All the coordinate information is filled in when NPLibrary
  1596.        calls SWI Wimp_RedrawWindow.
  1597.        PROClib_redrawwindow used to have to be called by the task when the
  1598.        Wimp returned a Redraw_Window_Request, but now polling is handled by
  1599.        NPLibrary, the task should not need to call this procedure. Use
  1600.        PROClib_forceredraw to update a window's contents.
  1601.  
  1602.  
  1603. EXAMPLE: DIM temp% 44
  1604.          !temp%=mainwindow%
  1605.          PROClib_redrawwindow(temp%)
  1606.          This allocates a block for NPLibrary to store all the window's
  1607.          coordinate information in (this uses 44 bytes of space). The first
  1608.          word is filled in with the window handle and the block pointer is
  1609.          then sent to PROClib_redrawwindow which then initiates the redraw.
  1610.  
  1611. .............................................................................
  1612.  
  1613. PROCEDURE/FUNCTION NAME: PROClib_forceredraw
  1614.  
  1615. PURPOSE: Redraw a whole window
  1616.  
  1617. PARAMETERS: On entry:
  1618.             1. window handle
  1619.             
  1620. USAGE: This procedure is used to force an entire window to be redrawn. This
  1621.        is done by generating Window_Redraw_Request events to be sent to
  1622.        itself. When this happens, PROClib_poll will intercept the events
  1623.        and call PROClib_redrawwindow (described above) which in turn will
  1624.        call PROCtask_redrawwindow, where the window will actually be redrawn.
  1625.        As far as the task is concerned, this sort of window redraw is no
  1626.        different from any other - it is completely unaware that the event was
  1627.        generated by itself. PROClib_forceredraw will calculate the visible
  1628.        work area of the window whose handle is given in P1 and mark that
  1629.        area as invalid, thus forcing the whole window to be updated. This
  1630.        is the preferred way of redrawing a window.
  1631.        NPLibrary itself calls PROClib_forceredraw after deleting an icon
  1632.        from a window, so there is no need for the task to call it a second
  1633.        time.
  1634.  
  1635. EXAMPLE: a$="Hello"
  1636.          PROClib_forceredraw(wind%)
  1637.          ...
  1638.          DEF PROCtask_redrawwindow(window%,xo%,yo%,x1%,y1%,x2%,y2%)
  1639.          CASE window% OF
  1640.          WHEN wind%:VDU 5:MOVE xo%+100,yo%+300:PRINT a$:VDU 4
  1641.          ...
  1642.          ENDCASE
  1643.          ENDPROC
  1644.          This set up means that when window wind% is updated, the contents
  1645.          of variable a$ are printed at a scroll offset of (100,300). So when
  1646.          the task changes the contents of a$, the window needs to be updated
  1647.          to reflect this, which is what PROClib_forceredraw does here.
  1648.          
  1649. .............................................................................
  1650.  
  1651. PROCEDURE/FUNCTION NAME: PROClib_changewindowtitle
  1652.  
  1653. PURPOSE: Change the title of a window
  1654.  
  1655. PARAMETERS: On entry:
  1656.             1. window handle
  1657.             2. new title
  1658.             
  1659. USAGE: The title bar on a window is an indirected icon, but needs some extra
  1660.        help to be redrawn when its contents are changed, so this procedure
  1661.        will let you do so with ease. Simply supply the window handle in P1
  1662.        and a string showing the new title bar contents in P2 and the icon
  1663.        will be changed and a Redraw_Window_Request will be generated for the
  1664.        title bar only (that is the top 36 pixels of the window).
  1665.  
  1666. EXAMPLE: PROClib_changewindowtitle(main%,filename$)
  1667.          Assuming filename$ stores the filename of the currently edited
  1668.          document, then this will change and redraw the title bar of window
  1669.          main% to display that filename.
  1670.          
  1671. .............................................................................
  1672.  
  1673. PROCEDURE/FUNCTION NAME: FNlib_windowtitle
  1674.  
  1675. PURPOSE: Return the contents of an indirect window title
  1676.  
  1677. PARAMETERS: On entry:
  1678.             1. window handle
  1679.             
  1680.             On exit:
  1681.             1. contents of title bar
  1682.             
  1683. USAGE: This procedure is provided to let you check the contents of a window's
  1684.        indirected text only title bar icon. The actual textual content of
  1685.        the title bar icon of window P1 is what is returned.
  1686.  
  1687. EXAMPLE: PROClib_changewindowtitle(main%,FNlib_windowtitle(main%)+" *")
  1688.          In RISC OS programs it is custom to add a '*' to the end of the
  1689.          contents of the title bar if the document being editing has been
  1690.          modified in anyway, and this command does just that - looks up the
  1691.          title of window main%, adds a space and an asterisk, and writes it
  1692.          back to window main%.
  1693.  
  1694. .............................................................................
  1695.  
  1696. PROCEDURE/FUNCTION NAME: PROClib_bringtofront
  1697.  
  1698. PURPOSE: Bring a window to the front
  1699.  
  1700. PARAMETERS: On entry:
  1701.             1. window handle
  1702.             
  1703. USAGE: This procedure is slightly more subtle than you may think. It does
  1704.        two things:
  1705.          It sets a flag in the window data specifying that the window is now
  1706.          at the front of the stack
  1707.          If the window is closed, no further action is taken
  1708.          If the window is open, it is opened again at the front
  1709.        This effectively means that even if the window is closed, you can
  1710.        still move it to the front ready for the next time it is opened.
  1711.        FNlib_windowopen is called to check if a window is open or not.
  1712.        
  1713. EXAMPLE: PROClib_bringtofront(warning%)
  1714.          Brings the window warning% to the front of the window stack.
  1715.  
  1716. .............................................................................
  1717.  
  1718. PROCEDURE/FUNCTION NAME: PROClib_openfilerwindowifadjust
  1719.  
  1720. PURPOSE: Check the mouse button status, and open a filer window if adjust is
  1721.          being held down
  1722.  
  1723. PARAMETERS: On entry:
  1724.             1. full pathname
  1725.             
  1726. USAGE: In RISC OS 3 there is a new 'standard' feature of opening the parent
  1727.        window of a document when the document window is closed with adjust
  1728.        rather than select. To make your application support this, you need
  1729.        to add an extra command when NPLibrary notifies your task that it
  1730.        wants to close the document window. You should use the filename stored
  1731.        in the save box, check to see if it is valid, and if so call
  1732.        PROClib_openfilerwindowifadjust. If adjust is not depressed then
  1733.        control will return to the task and no action will be taken. If adjust
  1734.        is being depressed however, then NPLibrary will remove the leafname
  1735.        leafname from the end (the name of the actual file), leaving the
  1736.        pathname (the directory that the file is in) and attempt to open a
  1737.        filer window of that pathname.
  1738.        
  1739. EXAMPLE: DEF FNtask_closewindow(window%)
  1740.          LOCAL ok%:ok%=TRUE
  1741.          CASE window% OF
  1742.          WHEN editwindow%:
  1743.          IF NOT lib_saved% THEN
  1744.          REM object if file not saved
  1745.          ok%=FALSE
  1746.          ELSE
  1747.          lib_saved%=-2
  1748.          IF FNlib_validfilename($savename%) PROClib_openfilerwindowifadjust(s
  1749.          avename%)
  1750.          ENDIF
  1751.          ENDCASE
  1752.          =ok%
  1753.          Before PROClib_closewindow closes any windows, it calls FNtask_-
  1754.          closewindow first to make sure it is ok. This setup means that if
  1755.          NPLibrary wants to close window editwindow% (supposing that this is
  1756.          the main document window) then one of two things may occur:
  1757.          If the document has not been saved then FNtask_closewindow will
  1758.          return FALSE, terminating any action (and probably popping a warning
  1759.          window up),
  1760.          If the document has been saved, then FNtask_closewindow will return
  1761.          TRUE, allowing the window to be closed, but will first call
  1762.          PROClib_openfilerwindowifadjust to open the document's parent filer
  1763.          window if the user clicked adjust on the close icon.
  1764.          
  1765. .............................................................................
  1766.  
  1767. PROCEDURE/FUNCTION NAME: FNlib_centrex
  1768.  
  1769. PURPOSE: Get the x position a window would need to be plotted at to make it
  1770.          central to the screen edges on the x axis
  1771.  
  1772. PARAMETERS: On entry:
  1773.             1. window handle
  1774.             
  1775.             On exit:
  1776.             1. x position
  1777.             
  1778. USAGE: This function will find the width of the window and calculate what
  1779.        x position you would need to plot it at to make it central on the
  1780.        left and right screen edges. This function is mode independent since
  1781.        it reads the width of the mode and its x pixel ratio, so in large
  1782.        modes the window will not appear off to the left. If the window has
  1783.        a vertical scroll bar then this too is taken into account.
  1784.        The formula to work out the x position required is:
  1785.        width = ( visible area maximum x - visible area minimum x )
  1786.        pixels = ( ( x pixels on screen - 1 ) * 2 ^ x eig shift factor )
  1787.        window x position = ( pixels - width ) / 2
  1788.        window x position = window x position + 40 if vertical scroll bar
  1789.  
  1790. EXAMPLE: PROClib_openwholewindow(progress%,FNlib_centrex(progress%),0,FALSE)
  1791.          This will open the whole window progress% at the bottom of the
  1792.          screen centralized on the x axis.
  1793.  
  1794. .............................................................................
  1795.  
  1796. PROCEDURE/FUNCTION NAME: FNlib_centrey
  1797.  
  1798. PURPOSE: Get the y position a window would need to be plotted at to make it
  1799.          central to the screen edges on the y axis
  1800.          
  1801. PARAMETERS: On entry:
  1802.             1. window handle
  1803.             
  1804.             On exit:
  1805.             1. y position
  1806.             
  1807. USAGE: This function will find the height of the window and calculate what
  1808.        y position you would need to plot it at to make it central on the
  1809.        top and bottom screen edges. This function is mode independent since
  1810.        it reads the height of the mode and its y pixel ratio, so in large
  1811.        modes the window will not appear off to the bottom. The fact that a
  1812.        window may have a horizontal scroll bar is NOT taken into account.
  1813.        The formula to work out the y position required is:
  1814.        height = ( visible area maximum y - visible area minimum y )
  1815.        pixels = ( ( y pixels on screen - 1 ) * 2 ^ y eig shift factor )
  1816.        window y position = ( pixels - width ) / 2
  1817.  
  1818. EXAMPLE: PROClib_openwholewindow(progress%,0,FNlib_centrey(progress%),FALSE)
  1819.          This will open the whole window progress% on the left of the screen
  1820.          centralized on the y axis.
  1821.  
  1822. .............................................................................
  1823.  
  1824. PROCEDURE/FUNCTION NAME: PROClib_setwindowheight
  1825.  
  1826. PURPOSE: Sets the height of a window
  1827.  
  1828. PARAMETERS: On entry:
  1829.             1. window handle
  1830.             2. new work area height
  1831.  
  1832. USAGE: This procedure changes the height of the total work area. It does not
  1833.        change the size of the actual window on screen (visible work area),
  1834.        but will cause the scroll bars to be redrawn if the window is open.
  1835.        This sort of thing is normally done in applications like word
  1836.        processors when the text fills the available space.
  1837.        
  1838. EXAMPLE: PROClib_setwindowheight(document%,FNlib_getwindowheight(document%)+5
  1839.          00)
  1840.          This adds another 500 pixels onto the the bottom of the work area
  1841.          height of window document%. Note the call to FNlib_getwindowheight
  1842.          to find out how high the work area is already.
  1843.  
  1844. .............................................................................
  1845.  
  1846. PROCEDURE/FUNCTION NAME: PROClib_setwindowwidth
  1847.  
  1848. PURPOSE: Sets the width of a window
  1849.  
  1850. PARAMETERS: On entry:
  1851.             1. window handle
  1852.             2. new work area width
  1853.             
  1854. USAGE: This procedure changes the width of the total work area. It does not
  1855.        change the size of the actual window on screen (visible work area),
  1856.        but will cause the scroll bars to be redrawn if the window is open.
  1857.        This sort of thing is normally done in applications like word
  1858.        processors when the text fills the available space.
  1859.        
  1860. EXAMPLE: PROClib_setwindowwidth(document%,950)
  1861.          Sets the width of the work area of window document% to be 950
  1862.          pixels.
  1863.          
  1864. .............................................................................
  1865.  
  1866. PROCEDURE/FUNCTION NAME: FNlib_getwindowheight
  1867.  
  1868. PURPOSE: Gets the height of a window
  1869.  
  1870. PARAMETERS: On entry:
  1871.             1. window handle
  1872.             
  1873.             On exit:
  1874.             1. height of window work area
  1875.             
  1876. USAGE: This procedure can be used to find out the total height of a window's
  1877.        work area. It is used internally by PROClib_setwindowwidth (as the
  1878.        SWI Wimp_SetExtent which is used to alter work area size requires
  1879.        both the new width and new height).
  1880.        
  1881. EXAMPLE: IF FNlib_getwindowheight(main%)>2000 THEN REM maximum size of
  1882.          document reached
  1883.          You can set a maximum height for a document and then object if the
  1884.          user tries to exceed it.
  1885.  
  1886. .............................................................................
  1887.  
  1888. PROCEDURE/FUNCTION NAME: FNlib_getwindowwidth
  1889.  
  1890. PURPOSE: Gets the width of a window
  1891.  
  1892. PARAMETERS: On entry:
  1893.             1. window handle
  1894.             
  1895.             On exit:
  1896.             1. width of window work area
  1897.  
  1898. USAGE: This procedure can be used to find out the total width of a window's
  1899.        work area. It is used internally by PROClib_setwindowheight (as the
  1900.        SWI Wimp_SetExtent which is used to alter work area size requires
  1901.        both the new width and the new height).
  1902.        
  1903. EXAMPLE: IF FNlib_getwindowwidth(main%)>500 THEN REM maximum size of document
  1904.          reached
  1905.          You can set a maximum width for a document and then object if the
  1906.          user tries to exceed it.
  1907.          
  1908. .............................................................................
  1909.  
  1910. PROCEDURE/FUNCTION NAME: PROClib_iconizewindow
  1911.  
  1912. PURPOSE: Iconizes a window (RISC OS 3 only)
  1913.  
  1914. PARAMETERS: On entry:
  1915.             1. window handle
  1916.             2. sprite name
  1917.             3. icon text
  1918.             4. block returned by PROClib_poll
  1919.             
  1920. USAGE: This is one of the more luxurious offerings from NPLibrary. If you
  1921.        fail to include this in your program, then the window will be
  1922.        iconized anyway but a blank sprite will be used. However, putting
  1923.        this in at the appropriate place will allow you to use your own sprite
  1924.        plus a small description of the program underneath.
  1925.        In PROCpoll_receivemessage, you need to trap message number &400CC (it
  1926.        doesn't matter if the program is running on a RISC OS 2 machine, for
  1927.        this message will never be broadcast). Check the word at block+20, for
  1928.        this will contain the window handle of the window that the user wants
  1929.        to iconize on the pinboard. If it is a suitable window (NOT the
  1930.        preferences window etc.!), then call PROClib_iconizewindow with the
  1931.        same window handle, the name of the sprite you want to use (which
  1932.        should be present in your !Sprites/!Sprites22/!Sprites23 files),
  1933.        upto twelve characters to be written underneath the icon, and the
  1934.        pointer to the block you passed to PROClib_poll. The window will then
  1935.        be iconized.
  1936.        In the NPLibrary directory there are lo-res and hi-res versions of
  1937.        the blank iconized window icon. You should always use these as the
  1938.        basis of your own - they are the standard icons.
  1939.  
  1940. EXAMPLE: DEF PROCpoll_receivemessage(message%)
  1941.          CASE message% OF
  1942.          WHEN 0:PROCtask_quit:END
  1943.          WHEN &400CC:IF work%!20=windmain% PROClib_iconizewindow(windmain%,"i
  1944.          c_main","My Program",work%)
  1945.          ENDCASE
  1946.          ENDPROC
  1947.          Assuming that PROClib_poll(work%) was called earlier, then this is
  1948.          how to iconize windows in your own programs. Don't call the
  1949.          procedure from anywhere else.
  1950.  
  1951. ....................................................................MENUS....
  1952.  
  1953. PROCEDURE/FUNCTION NAME: FNlib_createmenu
  1954.  
  1955. PURPOSE: Set up a menu structure
  1956.  
  1957. PARAMETERS: On entry:
  1958.             1. menu structure string
  1959.             2. RETURNed variable (see P2 on exit)
  1960.             
  1961.             On exit:
  1962.             1. menu handle
  1963.             2. number of items in menu
  1964.  
  1965. USAGE: This complex procedure will set up and link together a menu structure.
  1966.        The format of the menu structure string P1 is as follows:
  1967.        
  1968.        <title of menu>{|[vars]#<menu item>/<link>}|
  1969.        
  1970.        The section in curly brackets { } is repeated for every menu option.
  1971.        The first part is simple enough, and is just what is displayed in the
  1972.        title bar of the menu. If it is longer than twelve characters long,
  1973.        it will be truncated.
  1974.        Then, for each menu option:
  1975.          start with a '|'
  1976.          if you would like any options, specify them here. They are:
  1977.            D = Dotted line  - draw a dotted line after this menu option
  1978.            U = Unselectable - this menu option is greyed out
  1979.          now add a '#'
  1980.          type in the name of the next menu item
  1981.          add a '/'
  1982.          the link parameter is next. This can be one of three things:
  1983.            for no link, type in an 'N'
  1984.            to link to another window, type in its handle variable
  1985.                (this means that all windows must be created before the menus)
  1986.            to link to another menu, type in its handle variable
  1987.                (this means that the deepest menu must be created first)
  1988.        Add a final '|' at the end to signify the end of the menu.
  1989.        
  1990.        Note that in order to uphold the RISC OS standards, I have not allowed
  1991.        you to change the colour or size of menus.
  1992.        
  1993.        Some examples will help to simplify matters a little.
  1994.  
  1995. EXAMPLE: iconbarmenu%=FNlib_createmenu(task$+"|#Info/windinfo%|#Quit/N|",it%)
  1996.          Assuming task$ is the name of the task and windinfo% is the window
  1997.          handle of a standard info box, then this creates a standard icon
  1998.          bar menu of two options, "Info" leading off to an info box, and
  1999.          "Quit", linked to no other windows or menus. Somewhere further on
  2000.          in the program, there will be a check to see if the user clicked
  2001.          on "Quit" and if so, set a finish flag.
  2002.          The menu handle (which is actually its address in memory, but unique
  2003.          nevertheless) is returned in iconbarmenu% and the number of items in
  2004.          it%.
  2005.          
  2006.          submenu1%=FNlib_createmenu("Sub1|D#Option1/N|U#No way!/N|",subit%)
  2007.          mainmenu%=FNlib_createmenu("Main|#Hello/N|#Sub menu/submenu1%|",i2%)
  2008.          This first of all creates a menu with the title "Sub1" containing
  2009.          two options, "Option1" which has a dotted line after it, and then
  2010.          the option "No way!" which is greyed out.
  2011.          Then in the definition for mainmenu%, titled "Main", one option is
  2012.          "Hello" and the second is called "Sub menu", which is linked to
  2013.          the menu submenu1% (so it will have an arrow leading across into
  2014.          it).
  2015.  
  2016. .............................................................................
  2017.  
  2018. PROCEDURE/FUNCTION NAME: PROClib_openmenu
  2019.  
  2020. PURPOSE: Display a menu on the screen
  2021.  
  2022. PARAMETERS: On entry:
  2023.             1. menu handle
  2024.             2. display flag:
  2025.                       -1 = display menu at pointer position
  2026.                    items = this is icon bar menu - display at icon bar level
  2027.  
  2028. USAGE: This will simply open up the menu whose handle is specified in P1 and
  2029.        set some flags in NPLibrary regarding which menu was last open.
  2030.        Normally menus are opened slightly left of the pointer, but on the
  2031.        icon bar, the bottom of all menus should be at the same level, and
  2032.        to work it out you need to specify the number of items in it. So,
  2033.        if -1 is specified in P2 it is assumed to be an ordinary menu, but if
  2034.        the number of items is specified, it is assumed to be the icon bar
  2035.        menu.
  2036.  
  2037. EXAMPLE: IF (buttons% AND 2) AND window%=windmain% PROClib_openmenu(mainmenu%
  2038.          ,-1)
  2039.          If the user has pressed menu over the main window (assumed to be
  2040.          windmain%), then open up menu mainmenu%.
  2041.          
  2042.          IF (buttons% AND 2) AND window%=-2 PROClib_openmenu(iconbarmenu%,ico
  2043.          nbarmenuitems%)
  2044.          If the user has pressed menu over the icon bar (window handle -2),
  2045.          then open up menu iconbarmenu% at offset 96+(iconbarmenuitems%*44)
  2046.          from the bottom of the screen.
  2047.  
  2048. .............................................................................
  2049.  
  2050. PROCEDURE/FUNCTION NAME: FNlib_getmenuselection
  2051.  
  2052. PURPOSE: Return the user's menu choice in a textual representation
  2053.  
  2054. PARAMETERS: On entry:
  2055.             1. pointer to block returned by PROClib_poll
  2056.             
  2057.             On exit:
  2058.             1. textual menu choice
  2059.             
  2060. USAGE: This turns a list of menu structure choices returned by Wimp_Poll into
  2061.        text with periods in between submenus. PROClib_poll will call this
  2062.        for you automatically if there is a Menu_Selection event, so the task
  2063.        should not need to use this procedure.
  2064.        
  2065. EXAMPLE: SYS "Wimp_Poll",0,work% TO reason%
  2066.          CASE reason% OF
  2067.          ...
  2068.          WHEN 9:PROCpoll_menuselection(FNlib_getmenuselection(work%),lib_last
  2069.          open%):PROClib_reopenmenuifadjust
  2070.          ...
  2071.          ENDCASE
  2072.          This is how PROClib_poll handles menu selection. As you can see, by
  2073.          the time it reaches the task, NPLibrary has already converted it
  2074.          into textual format. The returned text could be something of the
  2075.          form:
  2076.          Style.Font.Size.14pt
  2077.          (if using a DTP package)
  2078.  
  2079. .............................................................................
  2080.  
  2081. PROCEDURE/FUNCTION NAME: PROClib_reopenmenuifadjust
  2082.  
  2083. PURPOSE: Check the mouse button status, and reopen the last menu if adjust
  2084.          is being held down
  2085.          
  2086. PARAMETERS: None
  2087.  
  2088. USAGE: There are two ways of choosing menu options. The user can press select
  2089.        in which case the menu will disappear, or he or she can press adjust,
  2090.        where the menu should stay on the screen. It is however up to the task
  2091.        to make sure that this happens. A call to this at the end of any menu
  2092.        selection procedure will ensure that if the user has pressed adjust
  2093.        then the menu will stay on the screen.
  2094.        This is now taken care of by PROClib_poll, so you should not need to
  2095.        use this procedure.
  2096.        
  2097. EXAMPLE: PROCpoll_menuselection(FNlib_getmenuselection(work%),lib_lastopen%):
  2098.          PROClib_reopenmenuifadjust
  2099.          After the user has chosen something from a menu, this checks to see
  2100.          if he has used adjust rather than select, and if so the menu will
  2101.          remain on screen.
  2102.  
  2103. .............................................................................
  2104.  
  2105. PROCEDURE/FUNCTION NAME: PROClib_menuselectable
  2106.  
  2107. PURPOSE: Set whether a menu option is greyed out or selectable
  2108.  
  2109. PARAMETERS: On entry:
  2110.             1. menu handle
  2111.             2. item number
  2112.             3. selectability:
  2113.                     TRUE = item is selectable
  2114.                    FALSE = item is unselectable and greyed out
  2115.  
  2116. USAGE: Sometimes you only want the user to perform certain actions when
  2117.        certain conditions have been met. You can prevent the user from
  2118.        choosing these options by greying out that part of the menu, or
  2119.        conversely, you can allow him to choose the options by making them
  2120.        selectable again, and that is the purpose of this procedure.
  2121.        The item number, P2, starts at zero for the first item on the menu,
  2122.        and increases by one for each item, so for a menu with six options
  2123.        on the last option would be number five.
  2124.  
  2125. EXAMPLE: PROClib_menuselectable(edit%,3,undo%)
  2126.          Suppose that the fourth item on menu edit% is "Undo". This command
  2127.          will grey out or make selectable the "Undo" option depending on
  2128.          the contents of variable undo%.
  2129.          If undo% is TRUE, the item will be made selectable
  2130.          If undo% is FALSE, the item will be greyed out and unselectable
  2131.  
  2132. .............................................................................
  2133.  
  2134. PROCEDURE/FUNCTION NAME: PROClib_menutick
  2135.  
  2136. PURPOSE: Select whether a menu option is ticked or not
  2137.  
  2138. PARAMETERS: On entry:
  2139.             1. menu handle
  2140.             2. item number
  2141.             3. tick status:
  2142.                     TRUE = item is ticked
  2143.                    FALSE = item is not ticked
  2144.  
  2145. USAGE: You can tick or untick menu items to show whether certain options are
  2146.        selected or not. The user is able to toggle the state of the option
  2147.        by clicking on it, but sometimes the task may want to set it itself,
  2148.        and that is the purpose of this procedure.
  2149.        The item number, P2, starts at zero for the first item on the menu,
  2150.        and increases by one for each item, so for a menu with six options
  2151.        on the last option would be number five.
  2152.        
  2153. EXAMPLE: PROClib_menutick(status%,2,autosave%)
  2154.          This ticks or unticks the third option on menu status% depending on
  2155.          the contents of variable autosave%.
  2156.          If autosave% is TRUE, the item will be ticked.
  2157.          If autosave% is FALSE, the item will be unticked.
  2158.  
  2159. ............................................................FILE HANDLING....
  2160.  
  2161. File handling messages
  2162. ----------------------
  2163.  
  2164. File handling is a very important and rather complex subject when it comes to
  2165. writing desktop applications. NPLibrary simplifies matters enormously,
  2166. reducing many many lines of code to just a few calls to procedures here and
  2167. there. This section is not about NPLibrary as such, but about exactly how to
  2168. get files into and out of your programs.
  2169.  
  2170. MESSAGES
  2171. The Wimp uses messages to communicate between itself and other tasks, and
  2172. tasks between each other. Any task can create a message; some acknowledge
  2173. things, others notify tasks of things the user has done, and others ask the
  2174. task to do certain functions.
  2175. The set of messages we are concerned with here are messages from the filer,
  2176. which handles file transfer.
  2177.  
  2178. THE DATA TRANSFER PROTOCOL
  2179. The data transfer protocol is a set of messages that allow tasks to
  2180. communicate with the filer and to get files to and from media. These messages
  2181. all have names and numbers, and they are:
  2182.  
  2183.  1  Message_DataSave
  2184.  2  Message_DataSaveAck
  2185.  3  Message_DataLoad
  2186.  4  Message_DataLoadAck
  2187. 13  Message_DataSaved
  2188.  6  Message_RAMFetch
  2189.  7  Message_RAMTransmit
  2190.  
  2191. There is also a special message:
  2192.  
  2193.  5  Message_DataOpen
  2194.  
  2195. We are only concerned with messages 1-5.
  2196.  
  2197. SAVING
  2198. Between the user bringing up the save box and the file reaching the disk,
  2199. many things occur:
  2200.  
  2201. 1) After the user drags the file icon and releases the mouse button, the task
  2202.    will receive a User_Drag_Box event.
  2203. 2) The task works out which window the pointer was over when the mouse button
  2204.    was released and sends a DataSave message to the filer containing
  2205.    information about the file.
  2206. 3) The filer returns a DataSaveAck message, telling the task the full
  2207.    pathname of the file.
  2208. 4) The task saves the file.
  2209.  
  2210. LOADING
  2211. Loading should be more straightforward, but is complicated by certain factors
  2212. a little. Keeping it simple first, this is what happens when the user drags
  2213. a file to the task's icon on the icon bar:
  2214.  
  2215. 1) The filer sends a DataLoad message to the task.
  2216. 2) The task loads the file.
  2217. 3) The task sends back a DataLoadAck message, confirming a successful load.
  2218.  
  2219. Things turn a little 'nasty' when the user double-clicks on a file:
  2220.  
  2221. 1) The filer sends a DataOpen message to every task.
  2222. 2) Any task that recognizes this type of file should proceed with steps 2
  2223.    and 3 of the ordinary load.
  2224. 3) If nobody claims the file (by replying with a DataLoadAck), then the filer
  2225.    *Runs the file.
  2226. 4) If there is a system variable Alias$@RunType_xxx (where xxx is the hex
  2227.    filetype number), then the command in that variable will be executed.
  2228. 5) If there is no such variable, the error "No run action specified for this
  2229.    filetype" will pop up on the screen.
  2230.  
  2231. IMPLEMENTATION
  2232. What this all boils down to is that to successfully load and save files in
  2233. every way described, you need to put the following lines in your program:
  2234.  
  2235. DEF PROCpoll_receivemessage(message%)
  2236. CASE message% OF
  2237. WHEN 0:PROCtask_quit:END                  Always include this line
  2238. WHEN 2:PROClib_dosave(windsave%,2,work%)  If DataSaveAck received call
  2239.                                           PROClib_dosave: windsave%=save box
  2240.                                           window handle; 2=writable icon
  2241.                                           handle; work%=PROClib_poll block
  2242.                                           pointer
  2243. WHEN 3,5:PROClib_doload(work%,&123)       If DataLoad/DataOpen received call
  2244.                                           PROClib_doload; work%=PROClib_poll
  2245.                                           block pointer; &123=filetype wanted
  2246. ENDCASE
  2247. ENDPROC
  2248.  
  2249. DEF PROCpoll_checkmouse(mx%,my%,b%,window%,icon%)
  2250. CASE window% OF
  2251. WHEN save%:CASE icon% OF
  2252. WHEN 0:                                   0=OK button icon handle
  2253. IF (b% AND 4) PROClib_quicksave(save%,2)  If select pressed, call
  2254.                                           PROClib_quicksave; save%=save box
  2255.                                           window handle; 2=writable icon
  2256. WHEN 3:                                   3=file icon handle
  2257. IF (b% AND 4) PROClib_savedragstart(save%,3) If select pressed, call
  2258.                                           PROClib_savedragstart; save%=save
  2259.                                           box window handle; 3=file icon
  2260.                                           handle
  2261. ENDPROC
  2262.  
  2263. DEF PROCpoll_drag(x1%,y1%,x2%,y2%)
  2264. PROClib_tellfileraboutsave(size,&123,leaf$)  When drag ends, call
  2265.                                           PROClib_tellfileraboutsave; size=
  2266.                                           estimated file size; &123=filetype;
  2267.                                           leaf$=leaf name of file
  2268. ENDPROC
  2269.  
  2270. DEF PROCtask_save(file$)
  2271. ...
  2272. PROClib_saved(TRUE)
  2273. ENDPROC
  2274.  
  2275. DEF PROCtask_load(file$)
  2276. ...
  2277. PROClib_saved(TRUE)
  2278. ENDPROC
  2279.  
  2280. That sorts out the message side of things. Now to make your program launch when the user double-clicks on a file of a type you want to recognize, add the following to your !Boot file:
  2281.  
  2282. Set Alias$@RunType_xxx /<Obey$Dir>.!Run %%*0   (xxx=filetype number)
  2283.  
  2284. If you didn't have a !Boot file, add:
  2285.  
  2286. IconSprites <Obey$Dir>.!Sprites
  2287.  
  2288. at the start to make the Wimp load the sprite file into the sprite pool.
  2289. If you want to give the filetype a name, add:
  2290.  
  2291. Set File$Type_xxx name      (xxx=filetype number, name=name)
  2292.  
  2293. The name will be truncated to eight characters.
  2294.  
  2295. Now, the line in your !Run file that reads:
  2296.  
  2297. Run <Obey$Dir>.!RunImage         (or similar)
  2298.  
  2299. change to read
  2300.  
  2301. Run <Obey$Dir>.!RunImage %*0     (add the %*0 to the end)
  2302.  
  2303. That lot will make your program launch, but to load the file the user has
  2304. clicked on, add after your initialization routine:
  2305.  
  2306. f$=FNgetparams
  2307. IF FNlib_validfilename(f$) PROClib_saved(TRUE):IF FNtask_oktoload(f$) THEN PROCtask_load(f$)
  2308.  
  2309. Now at the end of your program, add the routine:
  2310.  
  2311. DEF FNgetparams
  2312. LOCAL i%,space%,com%
  2313. SYS "OS_GetEnv" TO com%
  2314. i%=0
  2315. WHILE com%?i%<>0
  2316. i%+=1
  2317. ENDWHILE
  2318. com%?i%=13
  2319. =MID$($com%,INSTR($com%,"!RunImage")+11)
  2320.  
  2321. If your main file is not called !RunImage, change the leafname shown and make
  2322. the number after it "LEN(leafname$)+2", so if your program is called Blob,
  2323. the number becomes 6.
  2324. This will get the program to load the file that the user clicked on.
  2325.  
  2326. .............................................................................
  2327.  
  2328. PROCEDURE/FUNCTION NAME: PROClib_savedragstart
  2329.  
  2330. PURPOSE: Initiate a save drag from the save box to a filer window
  2331.  
  2332. PARAMETERS: On entry:
  2333.             1. window handle
  2334.             2. icon handle
  2335.             
  2336. USAGE: This procedure is used when the user drags a file icon from a save box
  2337.        to a filer window, and is called when the user first depresses a
  2338.        button over the icon. P1 specifies the save window handle, and P2 the
  2339.        file icon handle (that is the one to be dragged).
  2340.        When dragging boxes, the Wimp must be told what the limits of movement
  2341.        are. Known as the parent box, no drag will be allowed to move outside
  2342.        of this box. PROClib_savedragstart assumes that you want to allow
  2343.        movement around the whole screen, so reads information for the current
  2344.        mode and uses that. This makes the procedure mode independent.
  2345.  
  2346. EXAMPLE: DEF PROCpoll_mouse(mx%,my%,but%,wind%,icon%)
  2347.          CASE wind% OF
  2348.          WHEN savewind%:CASE icon% OF
  2349.          WHEN 3:
  2350.          IF (but% AND 4) PROClib_savedragstart(savewind%,3)
  2351.          ENDCASE
  2352.          ENDCASE
  2353.          ENDPROC
  2354.          This is the context that the procedure should be used in. Assuming
  2355.          that the file icon is icon number 3 in window savewind% (in my
  2356.          supplied Template2D and Template3D files, it is), then when the
  2357.          user depresses select over the file icon, a drag will commence.
  2358.  
  2359. .............................................................................
  2360.  
  2361. PROCEDURE/FUNCTION NAME: PROClib_quicksave
  2362.  
  2363. PURPOSE: Initiate a save from an OK click in the save box
  2364.  
  2365. PARAMETERS: On entry:
  2366.             1. window handle
  2367.             2. icon handle
  2368.  
  2369. USAGE: Usually to save a file, the user must drag the file icon in the save
  2370.        box to a destination filer window. However, if there is already a
  2371.        filename in the writable icon then a click on the OK button is all
  2372.        that is required. It is the job of this procedure to handle the saving
  2373.        of files when the user clicks on the OK button. The handles passed are
  2374.        the save box window handle in P1 and the writable icon handle in P2
  2375.        (the one that contains the save filename). PROClib_quicksave will
  2376.        carry out the following actions:
  2377.        Check to see if the filename is a valid full pathname, and if not,
  2378.        issue the error "To save, drag the save icon to a directory display"
  2379.        and pass control back to the program.
  2380.        If the filename is valid, a call will be made to FNtask_oktosave to
  2381.        give the task a chance to object if it wants to. If it does, control
  2382.        is returned to the task.
  2383.        If the task does not object, a call will be made to PROCtask_save,
  2384.        where the file will be written.
  2385.        The save window will be closed.
  2386.        The menu structure (if open) will be closed.
  2387.        Control will pass back to the task.
  2388.        
  2389. EXAMPLE: DEF PROCmouse(mx%,my%,but%,wind%,icon%)
  2390.          CASE wind% OF
  2391.          WHEN savewind%:CASE icon% OF
  2392.          WHEN 0:
  2393.          IF (but% AND 4) PROClib_quicksave(savewind%,2)
  2394.          ENDCASE
  2395.          ENDCASE
  2396.          ENDPROC
  2397.          This is the context that PROClib_quicksave should be used in.
  2398.          Supposing that icon 0 in the save box is the OK button and icon 2
  2399.          is the writable icon containing the filename (both are in my
  2400.          supplied template files), then if the user depresses select over the
  2401.          OK button, PROClib_quicksave will be called with the window and
  2402.          icon handles of the filename icon and an attempt will be made to
  2403.          save the file there and then.
  2404.          
  2405. .............................................................................
  2406.  
  2407. PROCEDURE/FUNCTION NAME: PROClib_tellfileraboutsave
  2408.  
  2409. PURPOSE: Send save message to the filer
  2410.  
  2411. PARAMETERS: On entry:
  2412.             1. estimated size of file in bytes
  2413.             2. filetype of file
  2414.             3. filename of file
  2415.             
  2416. USAGE: This procedure should be called when the user releases the mouse
  2417.        button after dragging the file icon to his or her chosen destination.
  2418.        When the user releases the mouse button, PROClib_poll will receive
  2419.        a User_Drag_Box event which it will route through PROCpoll_drag, so
  2420.        it is here where you should make the call. P1 is the estimated file
  2421.        size in bytes - do not worry if you don't have a clue how big the
  2422.        file is going to be, just use a number greater than zero and the filer
  2423.        will allocate more space if need be. Note that however small a file
  2424.        is, it will use up at least 2k of disk space, because programs always
  2425.        start at the beginning of a sector, and since there are 1024 bytes in
  2426.        a kilobyte, a minimum value of 2*1024=2048 bytes is recommended.
  2427.        P3 ought to be just the leafname of the file, but if you specify a
  2428.        full pathname, NPLibrary will chop any unnecessary bits off.
  2429.  
  2430. EXAMPLE: DEF PROCpoll_drag(x1%,y1%,x2%,y2%)
  2431.          PROClib_tellfileraboutsave(2048,&FFF,$savefile%)
  2432.          ENDPROC
  2433.          Assuming that savefile% is the pointer to the save box's writable
  2434.          icon indirected text data, then when the user releases the mouse
  2435.          and terminates a drag, this will tell the filer that the task
  2436.          wants to save a 2k text file (filetype &FFF) called $savefile%.
  2437.          If $savefile% is a full pathname, then the leafname only will be
  2438.          extracted and used.
  2439.  
  2440. .............................................................................
  2441.  
  2442. PROCEDURE/FUNCTION NAME: PROClib_dosave
  2443.  
  2444. PURPOSE: Perform final checking before a save, then save
  2445.  
  2446. PARAMETERS: On entry:
  2447.             1. window handle
  2448.             2. icon handle
  2449.             3. pointer to block returned by PROClib_poll
  2450.             
  2451. USAGE: After the filer has been notified about the task's need to save a file
  2452.        by PROClib_tellfileraboutsave, the filer will eventually get back to
  2453.        the task and acknowledge receipt of the message. Now is the time to
  2454.        actually call PROClib_dosave and save the file. The actual actions
  2455.        performed are as follows:
  2456.        Get the filename from the save box (the writable icon handle is P2 and
  2457.        the save box window handle is P1) and check that is valid.
  2458.        If it is not valid, report the error "Invalid filename" and abort the
  2459.        save.
  2460.        If it is valid, a call to FNtask_oktosave is made to give the task a
  2461.        chance to object to the save.
  2462.        If the task objects, control returns to the task.
  2463.        If the task does not object, the writable icon in the savebox is
  2464.        changed to reflect the new pathname of the file.
  2465.        The file is saved.
  2466.        The save window is closed.
  2467.        The menu structure (if open) is closed.
  2468.        Control returns to the task.
  2469.  
  2470. EXAMPLE: DEF PROCpoll_receivemessage(message%)
  2471.          CASE message% OF
  2472.          WHEN 0:PROCtask_quit:END
  2473.          WHEN 2:PROClib_dosave(savewind%,2,work%)
  2474.          ENDCASE
  2475.          ENDPROC
  2476.          Assuming that work% is the pointer to the block returned by
  2477.          PROClib_poll, and that icon 2 in the save box is the writable icon
  2478.          containing the filename (which it is with my supplied template
  2479.          files), then when PROClib_poll receives the message
  2480.          Message_DataSaveAck, this will attempt to save the file.
  2481.  
  2482. .............................................................................
  2483.  
  2484. PROCEDURE/FUNCTION NAME: PROClib_saved
  2485.  
  2486. PURPOSE: Set the lib_saved% flag status
  2487.  
  2488. PARAMETERS: On entry:
  2489.             1. new status of save flag:
  2490.                        TRUE = file has been saved
  2491.                       FALSE = file has not been saved
  2492.                          -2 = undefined
  2493.             
  2494. USAGE: This flag is used by NPLibrary and can and should be used by the task
  2495.        to determine whether or not a file in memory has been saved. The
  2496.        saved flag should be set to undefined when there is no file in
  2497.        memory or when the user has tried to close a window containing edited
  2498.        and unsaved data, the task has objected and popped up an error window
  2499.        but the user has clicked on "Discard".
  2500.        You can quite easily just use the command:
  2501.        lib_saved%=<new status>
  2502.        but PROClib_saved performs the extra action of making a call to
  2503.        PROCtask_updatefilestatus, which should reflect the status of this
  2504.        flag in any "Modified?" icons or window titles (by adding an asterisk
  2505.        if the file has been edited) that need adjusting.
  2506.        If you call PROClib_saved but P1 is the same as lib_saved% was in the
  2507.        first place, PROCtask_updatefilestatus is not called.
  2508.        PROClib_saved should be found somewhere in PROCtask_save and
  2509.        PROCtask_load (you set the save flag to TRUE since the file has not
  2510.        been altered).
  2511.        
  2512. EXAMPLE: DEF PROCtask_load(file$)
  2513.          SYS "OS_File",255,file$,filestore%
  2514.          PROClib_saved(TRUE)
  2515.          ...
  2516.          When you load a file, it has not been modified, so the saved flag
  2517.          needs to be set to TRUE.
  2518.  
  2519. .............................................................................
  2520.  
  2521. PROCEDURE/FUNCTION NAME: PROClib_doload
  2522.  
  2523. PURPOSE: Perform final checking before a load, then load
  2524.  
  2525. PARAMETERS: On entry:
  2526.             1. pointer to block returned by PROClib_poll
  2527.             2. filetype:
  2528.                      filetype = file loaded must be of this filetype
  2529.                            -1 = file loaded can be of any filetype
  2530.  
  2531. USAGE: This procedure should be called when loading a new file. The exact
  2532.        actions performed are as followed:
  2533.        If the filetype of the file requested is not the same as that in P2,
  2534.        control returns to the task and the load is aborted, unless P2 is -1.
  2535.        A call is made to FNtask_oktoload to give the task a chance to object
  2536.        to the load.
  2537.        If the task objects, no further action is taken.
  2538.        If the task does not object, a call is made to PROCtask_load, where
  2539.        the file is actually loaded.
  2540.        A message is sent to the filer informing it that the file has been
  2541.        loaded successfully.
  2542.        
  2543.        This last action is very important. While it is not important when the
  2544.        user drags the file onto your task's icon, if the user simply double-
  2545.        clicks on a file, the filer passes it round every task to see if
  2546.        anyone will claim it. If you load the file but then don't tell the
  2547.        filer, it will eventually *Run the file, which could cause another
  2548.        application to be launched if any Alias$@RunType_xxx variables are
  2549.        set.
  2550.        
  2551. EXAMPLE: DEF PROCpoll_receivemessage(message%)
  2552.          CASE message% OF
  2553.          WHEN 0:PROCtask_quit:END
  2554.          WHEN 3,5:PROClib_doload(work%,&123)
  2555.          ENDCASE
  2556.          ENDPROC
  2557.          This is the context that PROClib_doload should be used in. Assuming
  2558.          that work% is the pointer to the block returned by PROClib_poll,
  2559.          then any double-click on or drag to the task's icon of files of
  2560.          type &123 will cause PROClib_doload to be called. Note there are
  2561.          two messages being trapped here, Message_DataLoad and
  2562.          Message_DataOpen. See the section on file handling messages for more
  2563.          information.
  2564.          
  2565. ................................................................MISC WIMP....
  2566.  
  2567. PROCEDURE/FUNCTION NAME: PROClib_setcaretposition
  2568.  
  2569. PURPOSE: Position the caret
  2570.  
  2571. PARAMETERS: On entry:
  2572.             1. window handle
  2573.             2. icon handle
  2574.             3. index into string
  2575.  
  2576. USAGE: This will place the caret in writable icon P2 in window P1. No checks
  2577.        are actually made to ensure that the icon is writable, so the task
  2578.        must make sure that it is correct before calling the procedure. P3
  2579.        specifies how many characters into the string written in the icon the
  2580.        caret should be placed, with 0 the beginning.
  2581.  
  2582. EXAMPLE: PROClib_setcaretposition(pref%,9,4)
  2583.          This places the caret in icon 9 of window pref%, 4 characters into
  2584.          the string, so if the string read "HELLO", the caret would be
  2585.          between the "L" and the "O".
  2586.  
  2587. .............................................................................
  2588.  
  2589. PROCEDURE/FUNCTION NAME: PROClib_pointerinfo
  2590.  
  2591. PURPOSE: Returns the window and icon the mouse pointer is currently in
  2592.  
  2593. PARAMETERS: On entry:
  2594.             1. RETURNed variable (see P1 on exit)
  2595.             2. RETURNed variable (see P2 on exit)
  2596.             
  2597.             On exit:
  2598.             1. window handle
  2599.             2. icon handle
  2600.             
  2601. USAGE: This procedure allows the task to find out exactly at the moment in
  2602.        time the procedure is called which window and icon the mouse pointer
  2603.        is over. This can be used if you want the pointer to change shape
  2604.        over writable icons etc.
  2605.        
  2606. EXAMPLE: PROClib_pointerinfo(window%,icon%)
  2607.          This will make window% contain the window handle and icon% contain
  2608.          the icon handle that the mouse pointer is currently over.
  2609.  
  2610. .............................................................................
  2611.  
  2612. PROCEDURE/FUNCTION NAME: PROClib_loadsprites
  2613.  
  2614. PURPOSE: Initializes and loads sprites into NPLibrary's private sprite area
  2615.  
  2616. PARAMETERS: On entry:
  2617.             1. filename
  2618.             
  2619. USAGE: When NPLibrary is first initialized with PROClib_initialize, the
  2620.        sprite pointer variable lib_sprites% is set to 1. This means that any
  2621.        sprites wanted will be looked for in the Wimp sprite pool. You may
  2622.        want to load up your own sprites that don't reside in this pool. If
  2623.        this is the case, one of the first procedures you should call after
  2624.        PROClib_initialize is PROClib_loadsprites. This will allocate a block
  2625.        of memory and load the sprite file specified into it. The variable
  2626.        lib_sprites% will be changed to contain the pointer to this new
  2627.        sprite block, which is where sprites will be looked for from now on.
  2628.        Note that you must call this only once, and before you attempt to load
  2629.        in any templates containing non-indirected sprite-only icons,
  2630.        otherwise it won't work.
  2631.        
  2632. ............................................................MISC NON-WIMP....
  2633.  
  2634. PROCEDURE/FUNCTION NAME: FNlib_getstring
  2635.  
  2636. PURPOSE: Extract string from memory
  2637.  
  2638. PARAMETERS: On entry:
  2639.             1. pointer to string
  2640.             
  2641.             On exit:
  2642.             1. string found
  2643.             
  2644. USAGE: This function will extract any string from memory, terminating at the
  2645.        point where the next byte is outside the range 33-126 inclusive, with
  2646.        the exception of byte 160 (hard space), which is sometimes used in
  2647.        filenames. This means that zero/CR-terminated strings will be
  2648.        correctly found, and no ordinary spaces are allowed (since a space has
  2649.        a code of 32). This function is often used to get filenames that are
  2650.        zero-terminated from their fields.
  2651.        
  2652. EXAMPLE: str$=FNlib_getstring(pointer%)
  2653.          Puts the string at pointer% into variable str$.
  2654.  
  2655. .............................................................................
  2656.  
  2657. PROCEDURE/FUNCTION NAME: FNlib_validfilename
  2658.  
  2659. PURPOSE: Check if the passed filename is valid
  2660.  
  2661. PARAMETERS: On entry:
  2662.             1. filename
  2663.             
  2664.             On exit:
  2665.             1. validity of filename
  2666.                      TRUE = filename is valid
  2667.                     FALSE = filename is invalid
  2668.                     
  2669. USAGE: This can be used on whole pathnames to check their validity.
  2670.        If there are no colons in the filename, FALSE is returned.
  2671.        If there are no periods in the filename, FALSE is returned.
  2672.        If the last character is a filename is a colon or a period, FALSE is
  2673.        returned.
  2674.        Otherwise, TRUE is returned.
  2675.        
  2676. EXAMPLE: valid%=FNvalidfilename(file$)
  2677.          If filename file$ is valid according to the rules above, then valid%
  2678.          will hold the value TRUE. If not, it will hold FALSE.
  2679.          
  2680. .............................................................................
  2681.  
  2682. PROCEDURE/FUNCTION NAME: FNlib_getleafname
  2683.  
  2684. PURPOSE: Gets the leafname of a whole pathname
  2685.  
  2686. PARAMETERS: On entry:
  2687.             1. pathname
  2688.             
  2689.             On exit:
  2690.             1. leafname
  2691.             
  2692. USAGE: This will remove all filing system, drive and directory prefixes from
  2693.        a whole pathname, leaving just the actual filename of a file.
  2694.  
  2695. EXAMPLE: leaf$=FNlib_getleafname("adfs::4.$.Music.Tracks.GoodSong")
  2696.          leaf$ will contain "GoodSong" on exit.
  2697.  
  2698. .............................................................................
  2699.  
  2700. PROCEDURE/FUNCTION NAME: FNlib_getfiletype
  2701.  
  2702. PURPOSE: Gets the filetype of a file
  2703.  
  2704. PARAMETERS: On entry:
  2705.             1. pathname
  2706.             
  2707.             On exit:
  2708.             1. filetype
  2709.             
  2710. USAGE: This function will return the filetype of any given file (the full
  2711.        pathname is required). Note that the filetype returned is a
  2712.        hexadecimal number and not a textual representation.
  2713.        
  2714. EXAMPLE: type%=FNlib_getfiletype("scsifs::4.$.!System.Modules.Colours")
  2715.          (Colours is a module, an update to ColourTrans)
  2716.          type% would contain &FFA on exit (the filetype for "Module").
  2717.          
  2718. .............................................................................
  2719.  
  2720. PROCEDURE/FUNCTION NAME: FNlib_gettimestamp
  2721.  
  2722. PURPOSE: Get the datestamp from a file
  2723.  
  2724. PARAMETERS: On entry:
  2725.             1. pathname
  2726.             
  2727.             On exit:
  2728.             1. date
  2729.  
  2730. USAGE: This function will return the datestamp of any given file (the full
  2731.        pathname is required). The datestamp returned is in the format:
  2732.        DD-MM-YYYY
  2733.        
  2734. EXAMPLE: date$=FNlib_gettimestamp("idefs::5.$.program")
  2735.          If idefs::5.$.program was created on 21 of May 1994, then date$
  2736.          would contain: "21-May-1994" on exit.
  2737.  
  2738. .............................................................................
  2739.  
  2740. PROCEDURE/FUNCTION NAME: FNlib_putbit
  2741.  
  2742. PURPOSE: Change the value of a bit in a number
  2743.  
  2744. PARAMETERS: On entry:
  2745.             1. number
  2746.             2. bit number
  2747.             3. new value of bit
  2748.             
  2749.             On exit:
  2750.             1. new number
  2751.             
  2752. USAGE: This function is used mainly by NPLibrary when it is changing
  2753.        window, icon and menu flags, but can be used by the task if it
  2754.        wishes. It allows you to poke individual bits of a number with their
  2755.        new contents, so is most useful for changing flag contents.
  2756.        P2 is the number of the bit to change (the right-most or Least
  2757.        Significant Bit is bit 0, the next from the right is bit 1 and so
  2758.        on), and 3 is its new value, 0 or 1.
  2759.        
  2760. EXAMPLE: newnum%=FNlib_putbit(57,3,0)
  2761.          This takes the number 57:
  2762.          %111001         (% is used to prefix binary numbers)
  2763.          clears bit 3:
  2764.           543210
  2765.          %111001
  2766.          %110001  = 49
  2767.          and puts the result into newnum%, so newnum% is equal to 49
  2768.          on exit.
  2769.  
  2770. .............................................................................
  2771.  
  2772. PROCEDURE/FUNCTION NAME: FNlib_bit
  2773.  
  2774. PURPOSE: Get the value of a bit in a number
  2775.  
  2776. PARAMETERS: On entry:
  2777.             1. number
  2778.             2. bit number
  2779.             
  2780.             On exit:
  2781.             1. bit value
  2782.  
  2783. USAGE: This function can be used to find out the value of individual bits in
  2784.        numbers. You supply the number in P1 and the number of the bit you
  2785.        want to peek in P2, and 0 or 1 is returned depending on the bit's
  2786.        value.
  2787.  
  2788. EXAMPLE: bitvalue%=FNlib_bit(185,6)
  2789.          This takes the number 185:
  2790.          %10111001
  2791.          examines bit 6:
  2792.           76543210
  2793.          %10111001
  2794.          and puts the result into bitvalue%, so bitvalue% is equal to 0
  2795.          on exit.
  2796.  
  2797. .............................................................................
  2798.  
  2799. PROCEDURE/FUNCTION NAME: FNlib_roundup
  2800.  
  2801. PURPOSE: Rounds up a whole number to the nearest multiple of another whole
  2802.          number
  2803.  
  2804. PARAMETERS: On entry:
  2805.             1. number
  2806.             2. multiple to round up to
  2807.             
  2808.             On exit:
  2809.             1. new number
  2810.             
  2811. USAGE: Most command used to round up to the nearest word-aligned address when
  2812.        filling data blocks, this will round up any number to the nearest
  2813.        multiple of another. Note this function will always round up.
  2814.  
  2815. EXAMPLE: round%=FNlib_roundup(8,3)
  2816.          round% will equal 9
  2817.          
  2818.          round%=FNlib_roundup(85,4)
  2819.          round% will equal 88
  2820.  
  2821. .............................................................................
  2822.  
  2823. Skeleton program
  2824. ----------------
  2825.  
  2826. Supplied with NPLibrary is a skeleton program which already contains many of
  2827. the set ups mentioned in the above descriptions. Although the program doesn't
  2828. actually do anything useful apart from provide an icon with the standard icon
  2829. bar menu, all the hooks have been left in for file handling, window
  2830. iconization etc. etc. All you need to do is copy it, change the sprite, add
  2831. some window templates and you're off!
  2832.  
  2833.  
  2834. Example program
  2835. ---------------
  2836.  
  2837. A quick example program is supplied demonstrating windows, icons,
  2838. iconization, save boxes and sprites. Again it doesn't do anything useful, but
  2839. could give a few clues if you come unstuck while trying to work something
  2840. out.
  2841.  
  2842.  
  2843. Credits
  2844. -------
  2845.  
  2846. NPLibrary was written by Chris Coe of Norsoft Productions. You are allowed to
  2847. use NPLibrary in your own programs, subject to the conditions outlined in the
  2848. "Official Use" section at the start. I have just noticed that this file is
  2849. 120k long - that's six times the length of the code! However, the code took
  2850. longer to write so I'll personally castrate anyone who doesn't credit me or
  2851. decides to change the author's name. Spleen vented, thank you.
  2852.  
  2853. History
  2854. -------
  2855.  
  2856. 1.00 - Pre-release version used in certain Norsoft Productions programs
  2857.        before official release
  2858. 1.10 - Wimp_Poll loop taken over by NPLibrary - originally left to task
  2859.        to handle
  2860. 1.11 - Sprite routines FNlib_putspriteinicon and PROClib_loadsprites added,
  2861.        and FNlib_loadtemplate and PROClib_initialize altered slightly to
  2862.        cater for the private sprite area.
  2863.