Handling Events Outside the Main Event Loop
You'll notice that some types of events--for example,keyUpandmouseUp--are simply ignored by the main event loop defined in Listing 4-4. Key-up events are ignored because most applications don't need to know that a key was released, only that it was pressed. Similarly, you usually don't need to know when the mouse button was released, because you're more interested in knowing whether (and where) the mouse button was pressed. In certain cases, however, you will be interested in a mouse-up event. For example, if the user presses the mouse button while the cursor is in a window's close box but then moves the cursor outside the close box before releasing the mouse button, you don't want to handle the mouse-down event. (This is another good example of user-centered design: allowing users to change their minds.)It might appear that a problem is lurking, because the main event loop defined in
Listing 4-4 ignores mouse-up events. How, then, can your application determine that the user released the mouse button when the cursor was outside of the close box? The answer is simple: the system software provides a routine,TrackGoAway, that you call in response to a user click in the close box. TheTrackGoAwayfunction tracks user actions involving the close box; it returns the Boolean valueTRUEif the cursor is still inside the close box when the button is released andFALSEotherwise. Listing 4-5 illustrates how to callTrackGoAway.Listing 4-5 Tracking mouse events in the close box
PROCEDURE DoGoAwayBox (myWindow: WindowPtr; mouseloc: Point); BEGIN IF TrackGoAway(myWindow, mouseloc) THEN DoCloseWindow(myWindow); END;TheTrackGoAwayfunction exits only when the mouse button is released. Because it determines internally when that happens, your application doesn't need to.The system software provides routines to handle the three main cases in which you need to track the mouse and determine if the cursor is in a particular location when the button is released. Here are the main routines you'll use:
Mouse-tracking routine Action TrackBoxTrack the cursor in a window's zoom box TrackControlTrack the cursor within a control TrackGoAwayTrack the cursor in a window's close box For various purposes, you might need to perform similar tracking on an arbitrary rectangle in a window. The function
DoTrackRectdefined in Listing 4-6 shows one way to define such a function.
Listing 4-6 Tracking the cursor in an arbitrary rectangle
- Note
- Venn Diagrammer calls
DoTrackRectto handle mouse-down events in the tool icons. See Listing 6-9 beginning on page 121.![]()
FUNCTION DoTrackRect (myWindow: WindowPtr; myRect: Rect): Boolean; VAR myIgnore: LongInt; myPoint: Point; BEGIN InvertRect(myRect); {invert the rectangle} REPEAT Delay(kVisualDelay, myIgnore) UNTIL NOT StillDown; {until mouse is released} InvertRect(myRect); GetMouse(myPoint); {get mouse location} DoTrackRect := PtInRect(myPoint, myRect); END;TheDoTrackRectfunction inverts the specified rectangle and keeps it inverted until the user releases the mouse button. The Event Manager functionStillDownlooks in your application's event queue for a mouse-up event; if none is found,StillDownreturnsTRUE; otherwise,StillDownreturnsFALSE. Note thatDoTrackRectloops untilStillDownreturnsFALSE, indicating that the corresponding mouse-up event has been found. The call to theDelayprocedure within the loop is to ensure that the rectangle is inverted for some minimum, user-perceptible amount of time.
CONST kVisualDelay = 6; {wait 6 ticks (one-tenth second)}TheDoTrackRectfunction loops untilStillDowndetects the appropriate mouse-up event and then returns the specified rectangle to its original state by inverting it again. Next,DoTrackRectcalls the Event Manager functionGetMouseto determine the current position of the cursor. If, when the mouse button is released, the cursor is still inside the specified rectangle (as determined by the QuickDraw routinePtInRect), thenDoTrackRectreturnsTRUE.As you can see, you sometimes want to call Event Manager routines from outside your main event loop, most often to monitor mouse movements and button states once the user has clicked in some particular part of a window.