Tutorial step 3
===============


The file step3.cc adds to step3 a new window class derived from class Window
that can be opened by a menu selection.

Use the following command line to compile this step:
   
   gcc -o step3.exe step3.cc -ltws -lgr

To exit the program you can now use the File|Exit menu selection that you
just added.
The File|New selection will bring up the new window. This cannot be closed
yet though.



-----------------



The next step is to get the window to close. We will have to add in the event
handling macros in the same manner as with step1. However instead of the
function CmFileExit() add the function CmSysBox(). This finction should then
be linked to the button up event from the sysbox. ie:

   E_BUTTONUP(ID_SYSBOX,CmSysBox)

This should be put in the response table for the class. Take a look at
step4.cc if you need to see how it should be done.

In the new function DrawWindow::CmSysBox we need to make the window close
itself. This is done by sending a special event to the window's parent:

   ws.QueueEvent(parent,event(W_REMOVE_CHILD,(int)this));

This tells the parent window to remove it's child pointed to by this.


Now we want the window to do something, so let's draw on it. Every window
(bar the top window) has a buffer (ViewBuffer structure) that is the surface
of the window. Drawing on this buffer draws directly on the window itself.
This buffer can be accessed inside the class with as 'wnd'. 

You should add in a response for the left mouse button down event and the 
mouse move event. You will also need to add two integers to the class to 
hold the last x and y coords (eg lastx,lasty). Have a look at step4.cc if 
you are having trouble.

Firstly the left mouse button down event. If the mouse button is pressed and
the mouse is within the client area then we want to start drawing. The
function for this event should be:
   LButtonDown(int x,int y,int kb_stat)
Where (x,y) is the absolute position of the mouse cursor and kb_stat is the
status of the keyboard.
In this function we need to first adjust the coords relative to the window.
The absolute position of the window's top-left corner is given by the two
protected members of the Window class absx and absy. These should be 
subtracted from x and y. Then you should check to see if the resultant (x,y)
is within the client rectangle. This is given by the protected members of 
the Window class cx1,cy1,cx2,cy2. The client area is the rectangle described
by (cx1,cy1),(cx2,cy2) and including these points.
If the above conditions hold then set lastx,lasty to x,y.

Now to actually draw the line with the mouse move event. The function 
prototype is:
   MouseMove(int x,int y,int kb_stat,int mb_stat)
Where (x,y) is the new absolute position, mb_stat is the mouse button status
and kb_stat is the keyboard status.
We need to check mb_stat to see if the left button is down. This can be done
by checking mb_stat&MBS_LEFT_BUTTON which will be TRUE.
When we draw on the window we don't want to overwrite the border or title 
bar, so we'll need to create a temporary ViewBuffer to clip our drawing to 
the client area of the window only. This will do it:
   ViewBuffer *temp=GetClientBuffer();
This function is a member of class Window and creates a new buffer to point
to the client area of the window. It should be deleted before the function
finishes.
Now we need to draw a line from lastx,lasty to x-abs-cx1,y-asby-cy1:
   Line(temp,lastx,lasty,x-absx-cx1,y-absy-cy1,0);
This function like most graphics functions takes a pointer to a buffer as 
the first argument. This is where the function will draw the line (and also
clip the line to the edges of the buffer). The last argument is the colour
black which will be the colour of the line.

Now that the line has been drawn on the window we have to refresh the window
onto screen. This can be done with the function RefreshWindow() eg
   RefreshWindow();
Although this will cause the whole window to be refreshed (very inefficient
esp when the line is probably short.). This is better:
   RefreshWindow(absx+lastx+cx1,absy+lasty+cy1,x,y);
Although it only works if x>=lastx+absx+cx1 and y>=lasty+absy+cy1. In 
step4.cc it is handled properly. Note that RefreshWindow takes absolute 
coordinates.

Now that should be all. You should have something that resembles step4.cc
and step4.h.

