home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Archive Magazine 1996
/
ARCHIVE_96.iso
/
discs
/
mag_discs
/
volume_8
/
issue_06
/
risc_os
/
cpane
< prev
next >
Wrap
Text File
|
1988-12-14
|
6KB
|
196 lines
/*
* Example program fragment in C to demonstrate handling of pane windows
* It should not be used as it stands, but instead should be used as a model
* of what to do.
*/
typedef struct {
int errnum;
char errmess[252];
} os_error;
typedef struct {
int handle, x0,y0,x1,y1,scx,scy, bhandle;
} wimp_openstr;
typedef struct {
int handle, x0,y0,x1,y1,scx,scy, bhandle, flags;
} wimp_wstate;
typedef int wimp_w; /* window handle */
typedef enum {
wimp_ENULL = 0,
wimp_EREDRAW = 1,
wimp_EOPEN = 2,
wimp_ECLOSE = 3,
wimp_EPTRLEAVING = 4,
wimp_EPTRENTERING = 5,
/* etc. */
} wimp_eventcode;
typedef union {
wimp_redrawstr redraw;
wimp_openstr open;
wimp_w close;
wimp_w ptrleaving;
wimp_w ptrentering;
/* etc. */
} wimp_eventstr;
/*
* These functions communicate with the Wimp
* Their specifications should be fairly obvious
*/
extern os_error * wimp_openwindow(wimp_openstr * openblk);
extern os_error * wimp_closewindow(wimp_w handle);
extern os_error * wimp_getwindowstate(wimp_w handle, wimp_wstate * result);
extern os_error * wimp_poll(wimp_eventstr * e, wimp_eventcode * result);
extern void wimp_reporterror(os_error * err, int flags, char * taskname);
/*
* Example Wimp task.
* This is by no means complete - it just deals with the pane window problem
*/
int main(void)
{
os _error * err;
wimp_eventstr event;
wimp_eventcode reason;
/*
* call Wimp_Initialise etc. and create windows
*/
/* simplified polling loop */
do {
if (err != NULL) wimp_reporterror(err,1,"The task name");
err = wimp_poll(&event, &reason);
if (err == NULL) {
switch(reason) {
/* etc. */
case wimp_EOPEN: err = event_openwindow(&event.open);
break;
case wimp_ECLOSE: err = event_closewindow(event.close);
/* etc. */
}
}
} while (1); /* program exits when message 0 is sent to it */
return(0);
}
/*
* The 'tool' window contains the main scrolling work area
* The 'pane' window sits on top of it, moving wherever the tool window goes
*
* For simplicity, 'tool' = handle of only tool window
* 'pane' = handle of only pane window
*
* The code below should should the basic algorithm.
* Here is a 'plain English' description of why it does what it does:
*
* We want to open the pane window on top of the tool window, using the
* coordinates of where the tool ends up (not necessarily the same as
* where it is asked to open, because of bounding constraints).
*
* Thus we would like to open the tool window first, then read off its
* coordinates and bhandle (using wimp_getwindowstate) and open the pane
* with suitable coordinate modifications.
*
* Unfortunately this results in the pane window typically being redrawn
* continuously as the window is dragged round the screen, since the tool
* is first opened above the pane, and then the pane is opened above the
* tool.
*
* The first check, then, is to open the tool window behind the pane, if
* it turns out that it is to be opened just above it.
*
* The next problem is that since the two windows are 'sliding' over one
* another as they move, it is likely that a small strip of the tool
* window next to the pane window will have to be redrawn quite often, as
* it is slightly obscured by the pane window before reappearing as the
* pane window's position is updated.
*
* The cure for this is to open the pane window first if the tool window
* is moving in the direction of the pane. This eliminates unnecessary
* redraws of the tool window, which can be extremely important if the
* contents of the tool window are complicated. Note that since the
* final coordinates of the tool window are not known for sure until
* after it has been opened itself, it is still necessary to open the
* pane window after the tool window has been opened (but this does not
* usually cause any overhead at all).
*
* Finally, an extra check has to be made for the case where the tool
* window is 'sent to the back', since the bhandle setting here is equal
* to -2, rather than to the handle of the rearmost window on the
* screen. Thus, when the pane window is opened after the tool window,
* it must not use the bhandle of -2, since this would cause it to be
* opened behind the tool window! The solution is to read back the
* actual bhandle of the tool window by calling wimp_getwindowstate.
*/
/* Note: the following routine does not check all error cases, in the
* interests of clarity - but any 'proper' program should check for errors
* correctly.
*/
os_error * event_openwindow(wimp_openstr * open)
{
wimp_wstate panestate;
wimp_wstate toolstate;
if (open->handle == tool) {
wimp_getwindowstate(pane, &panestate);
if (panestate.bhandle == open->bhandle) open->bhandle = pane;
wimp_getwindowstate(tool, &toolstate);
if (open->y1 > toolstate.y1) openpane(open, pane); /* open pane first */
wimp_openwindow(open); /* coords written back into block */
if (open->bhandle == -2) {
wimp_getwindowstate(tool, &toolstate); /* sent to the back */
open->bhandle = toolstate.bhandle;
}
return(openpane(open)); /* open pane again */
} else {
return(wimp_openwindow(open)); /* normal window */
}
}
/*
* This code opens a pane window at the top of a tool window
* It is sometimes called twice when opening a pane, to make sure that the
* coords are correct.
*/
os_error * openpane(wimp_openstr *open, wimp_w panehandle)
{
wimp_openstr o;
o.handle = panehandle;
o.x0 = open->x0;
o.y0 = open->y1 - 100; /* assume pane window height = 100 OS units */
o.x1 = open->x1;
o.y1 = open->y1;
o.scx = open->scx; /* scroll sideways in step with tool window */
o.scy = 0; /* don't scroll vertically! */
o.bhandle = open->bhandle;
return(wimp_openwindow(&o));
}
os_error * event_closewindow(wimp_w handle)
{
if (handle == tool) wimp_closewindow(pane); /* close pane as well */
return(wimp_closewindow(handle));
}