Section 5 Home page Section 7

6. Simple Window Events: Top and Move

The first two events we will handle are straightforward, as we can rely on the AES to do the necessary work. These two events are triggered when our window is brought to the top of the screen, or when our window is moved to a different location.

6.1. TOP

When several windows are open, only one is "on top". You can bring a window to the top by clicking on it, or if it is "behind" another window which is closed.

When our window is brought to the top, our application is sent the message WM_TOPPED. The handle of our window is provided in msg_buf. All we need to do is use wind_set to bring our window to the top.

In our event loop, we add the following code:

case WM_TOPPED:
        wind_set (msg_buf[3], WF_TOP, 0, 0);
        break;

You may wonder how a window that has been partially obscured by another window will be redrawn when you bring it to the top. The answer is that I lied a little when I said all we need to do is the above: AES will trigger a REDRAW event for a window, when you set it to the top, so our program will have to redraw the window contents. However, as we already handle REDRAW events, we have nothing else to do - our previous code and AES do everything for us already.

6.2. MOVE

Windows can be moved, usually, by holding the top bar and dragging them. For this to be available, you need to include the MOVER option in the parts list for your window when you create it (see the section on creating windows).

When our window is moved, all we need to do is set the window’s coordinates to the new location. The new location is provided in msg_buf, positions 4-7.

In our event loop, we add the following code:

case WM_MOVED:
        wind_set (msg_buf[3], WF_CURRXYWH, msg_buf[4],
                msg_buf[5], msg_buf[6], msg_buf[7]);
        break;

The AES copies our window’s contents directly to its new location. (The AES also sends redraw messages to any windows which our window was obscuring - but we can ignore those.)

We do, however, have to look more closely at our drawing code, now that the window can move anywhere on the screen. Remember that the code that draws on the screen does so through the VDI, and we do not provide any reference to our window when we do so. When we move our window, we need to draw the contents of our window in a different location. To do this, we pass the coordinates of where we want the contents drawn to our draw function. The provided x,y coordinates then represent the origin we need to use for our drawing code. We pass these coordinates to our drawing code from draw_interior.

void draw_example (int app_handle, struct win_data * wd, int x, int y, int w, int h) {

        v_gtext (app_handle, x+10, y+60, wd->text); // <1>

}
  1. We offset the drawing location by the x, y position of the window.

6.3. Sample Program: Version 3

Version 3 now includes these two events. Notice also the inclusion of MOVER when the window is created, and the updated draw_example and draw_interior functions.

Our window is now a respectable GEM program. It redraws itself when requested, does not disturb any other windows in the system, can be moved around the screen and brought back to the top. If you are content with a fixed size window, you now have enough to implement a GEM application.