home *** CD-ROM | disk | FTP | other *** search
- ArmBob v.1.02 Tutorial 4 GCW 06/06/94
-
- Wimp programming
- ----------------
- The example !Exec is provided, as a minimal framework to start
- with. It uses no classes. When double-clicked !Exec should put
- its icon on the iconbar. Its iconbar menu has two items - Info and
- Quit. If an object is dragged onto its iconbar icon, the file
- !Exec.exec will be obeyed, with the object's pathname as argument.
- Clicking Select or Adjust on the iconbar icon will open an Edit
- window on !Exec.exec. A directory !Exec.Lib is provided for tools
- to be used by !Exec. An example provided in !Exec.Lib is Templread,
- a template disassembler. It expects a template file as argument,
- and when run opens an editable window on Bob source code defining
- the template's windows. A window called, say xyz, is defined by the
- data in a buffer called xyz_buf.
-
- !Exec is an application whose !RunImage file has filetype BobProj.
- Shift-double-click it to see its contents.
-
- Bob:h.wimp.templates Library file: load templates, get window handles
- Bob:h.wimp.ev_process Library file: main loop for wimp programs
- <Exec$dir>.main Main program
-
- Two library files are specified, and the textfile main. Main contains
- the function main - the entry point into the program. The first line
- (apart from comments) is
-
- @b = @(newstring(500));
-
- which creates a fixed buffer, 500 bytes long, at the address @b. Note
- the convention of using @ as the first letter to remind ourselves that
- @b is an address.
-
- Then
-
- handler = newvector(20);
- handler[Mouse_Click] = do_Mouse_Click;
- handler[Menu_Selection] = do_Menu_Selection;
- handler[User_Message] = handler[User_Message_Recorded] = do_Message;
-
- creates a vector of handlers to respond to the window manager. We only
- need to respond to four reason codes:
-
- Mouse_Click
- Menu_Selection
- User_Message
- User_Message_Recorded
-
- The handler's components for these reason codes are set to functions
- appearing later in the file Main. The rest are nil by default.
- A generic handler function takes two arguments - the first, the address
- of a message buffer - the second is a user-parameter, that can be used
- for passing in data. In this example, the user-parameter has the value
- nil. The handler function must return FALSE if it is to cause the
- program to terminate, and TRUE otherwise.
-
- The statement
-
- in (mesg_list= newstring(8)) put
- { Message_DataLoad; 0; }
-
- creates a two-word buffer called mesg-list, containing the messages
- we want !Exec to receive. The 'in .. put { .. ; ... ;}' structure
- is convenient for filling buffers with words and strings.
-
- We start !Exec as a wimp task with
-
- wimp_init(310,"Exec",mesg_list);
-
- The Info box item of the menu is defined in a template file. The lines
-
- (wind = newvector(1))[0] = "info";
- info = templates("<Exec$Dir>.Templates",wind)[0];
-
- load the template and get the window-handle 'info' of this box. The
- templates function, defined in Bob:h.wimp.templates takes two arguments,
- the first, a string, the pathname of the template file, the second
- a vector of window names. It returns a vector of corresponding window
- handles. The vector 'wind' is defined as a 1-component vector.
-
- The lines
-
- icon = make_icon();
- menu = make_menu();
-
- should be self-explanatory. The function main finishes with the
- statement that does all the work
-
- event_process(&1933,@b,handler,nil);
-
- The function event_process is defined in Bob:h.ev_process.
-
- event_process(mask,buffer,action,user)
- {
- local r, respond, go_on;
- r = newvector(8);
- go_on = TRUE;
- while(go_on)
- {
- r[0] = mask;
- r[1] = buffer;
- swi("Wimp_Poll",r);
- go_on =
- (typeof(respond = action[r[0]])
- == BYTECODE)?respond(buffer,user):TRUE;
- }
- wimp_closedown();
- }
-
- This function polls the wimp, and, if the component of the vector
- 'action' (which MUST have at least 20 components) given by the
- returned reason-code is a function, that function is called. If the
- function returns FALSE, execution falls through to wimp_closedown
- and the function main terminates.
-
- The event_process function provides a way of modularizing wimp
- programs. It is the possibility of having vectors of functions which
- enables ArmBob to gain in expressiveness over Basic.
-
- Now let us look at the handler functions. The most interesting is
-
- do_Message(a,user)
- {
- switch(£(a+16))
- {
- case Message_Quit:
- return FALSE; // i.e. do not continue
- break;
- case Message_DataLoad:
- if (£(a+20)==-2 && £(a+24)==icon)
- act(a,user_process);
- return TRUE;
- break;
- default:
- return TRUE;
- break;
- }
- }
-
- The first argument a is the address of the message buffer. The £ operator
- fetches the integer stored at its argument. If a DataLoad message is
- received because something has been dragged to the iconbar icon,
- then act(a,user_process) is called. The function act gets the pathname
- and filetype of the object dragged, acknowledges the DataLoad message,
- and passes the pathname and filetype to its second argument.
-
- act(a,f)
- {
- local filename, filetype;
- filename = $(a+44);
- filetype = £(a+40);
- ££(a+16,Message_DataLoadAck);
- ££(a+12,£(a+8));
- r[0] = User_Message_Acknowledge;
- r[1] = a;
- r[2] = 0;
- swi("Wimp_SendMessage",r);
- f(filename,filetype);
- }
-
- The $ function returns the string (terminated by an ASCII code less
- than 32) stored at an address. The ££ function may be used for poking
- 4-byte words into positions in buffers.
-
- Note how the function f, the action to be taken, is passed as a parameter.
-