Before we discuss the way in which we save using a traditional save window, we must first complete the response to clicks on buttons in the main window. The '|<' and '>|' symbols are meant to represent 'go to the first record' and 'go to the last record', which provides a little extra help in moving through the records. Suggested as an exercise in module 9, we simply list the appropriate coding for you here.
Firstly, in PROCclick and the main% loop we need to add two more options:
WHEN 7: PROCbegin
and
WHEN 10: PROClast
The two procedures should now be inserted, the first before DEFPROCback, and the second after the ENDPROC of DEFPROCnext.
DEFPROCbegin
IFn%=1 ENDPROC
n%=1
PROCreset
ENDPROC
DEFPROClast
IFn%>=50 ENDPROC
n%=50
PROCreset
ENDPROC

Completing the button functions
This process is very much a Wimp-related one, and has little to add to our knowledge of how to use Basic. It is made complicated by the need to use the Wimp message system to communicate with the filer itself. We also have to define a new type of icon that can actually be dragged around the screen. In order to 'hear' the messages from the Wimp, we must include additional reason codes in the wimp poll loop. To do this, add the line
WHEN 17,18:PROCreceive
to the polling loop. Notice here that we can include more than one option in the WHEN statement. Both reason codes will be responded to in this case and handled by the same procedure, PROCreceive.
To keep matters tidy as we go along, now add DEFPROCreceive as a new procedure definition immediately following the ENDPROC of DEFPROCmenuselect.
DEFPROCreceive
CASE block%!16 OF
WHEN 0:quit%=TRUE
ENDCASE
ENDPROC
Strictly speaking, every program should contain this code, since otherwise it will always ignore messages sent to it by the Wimp. The code 0 picked up by this routine tells the program that it is being shut down, and it may be that you would want to take some action before it happens. quit% = TRUE makes the program leave the poll loop and end.
The order of events will be as follows.
1. A standard save-type window will be opened, and the user will type in a suitable name for the file, and then drag the icon to a filer directory.
2. When the icon in the save box is clicked on, PROCclick responds by sending the program to a procedure that drags the icon in response to movement of the mouse.
3. When the mouse button is released, a message is sent back from the Wimp to the program. This is picked up in the wimp poll loop as reason code 7 which directs the program to PROCstartsave. This procedure works out where the pointer is, and sends a message to the Wimp to ask for the details of the directory.
4. The poll routine picks up the reply through reason code 17 and goes to PROCreceive so that the information can be interpreted and acted upon. It carries with it an action code 2 enabling the procedure to pick out the necessary response by directing to PROCdatasave. This procedure acknowledges the information by sending back action code 3, and finally the wimp sends back a message to say all is complete.
5. The actual saving process now begins with PROCmanualsave.
We make no further attempt to explain the finer details of the required code, but some of it is complex and must be copied with care.
Insert the following at the end of PROCinit.
REM Save box window
DIM savespr% 8,savetext% 255,saveval% 5
$saveval%="R2A~ ":$savespr%="file_ffd":$savetext%="SecretData"
save%=FNcreate_window(604,336,280,180,0,0,&86000012,2,2,&19,"Save as:",3,0)
a%=FNcreate_icon(save%,100,-92,68,68,&6102,"",savespr%,1,9)
a%=FNcreate_icon(save%,8,-156,192,48,&700F12D,"",savetext%,saveval%,256)
a%=FNcreate_icon(save%,208,-156,64,48,&C701913D,"",ok%,R5%,3)
The code in saveval% will control what characters can be entered in the pathname of the file, thus preventing disallowed characters. Note the use of 'file_ffd' to define the icon type to appear in the window. This is the standard data icon. Note also the button type for this icon that makes it dragable.

The save window is easily recognisable
In PROCclick, we need to add yet another option in order to open this window, but remember that this window opens in response to 'Enter filename' in the check code window. The following lines must therefore be added in the savecheck section within PROCclick, between the lines 'PROCautosave' and 'ENDCASE'.
WHEN 4:
!block%=savecheck%
SYS"Wimp_CloseWindow",,block%
!block%=save%
SYS"Wimp_GetWindowState",,block%
block%!28=-1
SYS"Wimp_OpenWindow",,block%
PROCcaret(save%,1)
When we click on the icon to drag it, PROCclick needs to respond. Add the following code to the end of PROCclick.
WHEN save%
CASE block%!16 OF
WHEN 0:REM Click on dragable icon
IF block%!8 AND 64 PROCdragbox
WHEN 2:REM Click on OK
IF block%!8 AND 5 PROCquicksave
ENDCASE

What is happening as we drag a file?
We are ignoring the click on the OK button at the moment, but we must now write PROCdragbox. Copy it with care! Place it before DEFPROCautosave.
DEFPROCdragbox
!block%=save%
SYS "Wimp_GetWindowState",,block%
vx%=block%!4-block%!20
vy%=block%!16-block%!24
block%!4=0
SYS "Wimp_GetIconState",,block%
sprite$="file_ffd"
IF spritedrag% THEN
!block%=block%!8+vx%
block%!4=vy%+block%!12
block%!8=block%!16+vx%
block%!12=vy%+block%!20
SYS "DragASprite_Start",%11000101,1,sprite$,block%
ELSE
block%!4=5:block%!8=vx%+block%!8
block%!12=vy%+block%!12
block%!16=vx%+block%!16
block%!20=vy%+block%!20
block%!24=0:block%!28=0
block%!32=&7FFFFFFF
block%!36=&7FFFFFFF
SYS "Wimp_DragBox",,block%
ENDIF
ENDPROC
This procedure might have been better placed in the Library but it does contain two specific items to this program. Firstly it again specifies the data sprite in the eight line. Secondly it uses a variable called spritedrag% which we must now define at the start of PROCinit. The purpose of this is to enable solid drags if the OS in use is capable of doing so. The code to check this and set spritedrag% accordingly is as follows, and should be inserted immediately after the ON ERROR statement at the beginning of PROCinit.
SYS "OS_Byte",161,28 TO ,,val%
spritedrag%=((val% AND 2)=2)
spritedrag% is TRUE if solid drags are supported.
When the mouse button is released, the Wimp passes a reason code of 7, as so begins the exchange of messages. In the Poll loop, add the response
WHEN 7:PROCstartsave
Now add DEFPROCstartsave immediately following DEFPROCdragbox.
DEFPROCstartsave
IFspritedrag% SYS"DragASprite_Stop"
fsize%=2000:type%=&FFD
SYS "Wimp_GetPointerInfo",,block%
block%!20=block%!12:block%!24=block%!16
block%!28=!block%:block%!32=block%!4
block%!36=fsize%
!block%=64:block%!12=0
block%!16=1:block%!40=type%
$(block%+44)=FNgetleaf($savetext%)
SYS "Wimp_SendMessage",18,block%,block%!20,block%!24
saveref%=block%!8
ENDPROC
This process receives a reply through the line 'WHEN 17,18:PROCreceive', but to handle this we must now add a second option to the choices within PROCreceive:
WHEN 2:PROCdatasave
Add DEFPROCdatasave after the startsave procedure:
DEFPROCdatasave
$savetext%=FNstring(block%+44)
!block%=save%
block%!12=block%!8
block%!16=3:!block%=256
SYS "Wimp_SendMessage",18,block%,block%!20,block%!24
PROCmanualsave
altered%=FALSE
ENDPROC
and follow on with PROCmanualsave:
DEFPROCmanualsave
!block%=save%
SYS"Wimp_CloseWindow",,block%
code2$=FNstring(code%)
$code%=STRING$(8,CHR$0)
IF code$<>code2$ PROCreport("Codes do not match",1):ENDPROC
PROCencode
path$=FNstring(savetext%)
$path%=path$
PROCsave
FORX%=1TO50
secret$(0,X%)=""
desc$(0,X%)=""
NEXT
ENDPROC
Note that this is very similar to autosave. We are back on more familiar ground. Finally, for completeness, go on and add PROCquicksave which enables you to save by clicking on the OK icon.
DEFPROCquicksave
IF INSTR($savetext%,".") THEN
PROCmanualsave
altered%=FALSE
ELSE
PROCreport("To save, drag the icon to a directory viewer",1)
ENDIF
ENDPROC
Notice how we change the value of altered% in these routines to register that the current data has been saved. This is not exploited in the program yet, but could be with little further code.
You were warned that this would be complex. To know more about this you are referred to Lee Calcraft and Alan Wrigley's book 'Wimp Programming for All' or other similar texts. Meanwhile, you could of course have copied most of this code from the Freeware version, but would you have learnt as much?