GetNextEvent
GetNextEvent Obtain next available event of specified type(s)
#include <Events.h> Event Manager
Boolean GetNextEvent( eventMask, theEvent );
short eventMask ; bit flags for events; 0xFFFF is all events
EventRecord *theEvent ; receives the 16-byte event record
returns Should application respond to this event?
GetNextEvent obtains a copy of the oldest event in the event queue of the
requested type or types. If a requested event is found, it is removed from the
queue; otherwise, GetNextEvent returns FALSE and indicates a null event.
eventMask specifies which event(s) should be checked. It is a 16-bit binary
mask where a 1 elects to include an event and a 0 excludes the event.
The most common usage is to use eventMask=everyEvent, defined in
Events.h as 0xFFFF. See Event Mask for the layout and named
constants.
If you specify a value other than everyEvent, only the specified
events are returned. Request two or more event types by ORing their
flags. For example:
if (GetNextEvent( (diskMask | keyUpMask), &myEvent ) ) {
... process diskEvt or keyUp here ...
}
Some events (e.g., keyUp events) may never make it to the event
queue. See SetEventMask.
theEvent is the address of a 16-byte EventRecord. Upon return, it is filled
with information about the event. The field values are described in
Notes, below.
Returns: a Boolean value; it identifies whether or not the caller should
respond to the event. It is the return code from an internal call to
SystemEvent and will be one of:
FALSE This is a DA or System or Null event. Ignore it.
TRUE This event is intended for you. Examine and respond.

Notes: A call to GetNextEvent (or WaitNextEvent) is at the heart of all
Macintosh applications. With very few exceptions, all programs contain a
sequence similar to the following, which is executed repeatedly until the
application terminates.
if ( GetNextEvent( everyEvent, &theEvent ) ) {
switch ( theEvent.what ) {
case mouseDown: [TOKEN:12079]... process button presses ...
case keyDown: [TOKEN:12079]... process key presses ...
case activateEvt: [TOKEN:12079]... activate a window ...
//... and so forth ...
}
}
The following Event Types (found in theEvent ->what after the call) are
defined in Events.h:
nullEvent 0 no event matched eventMask
mouseDown 1 mouse button got pressed
mouseUp 2 mouse button got released
keyDown 3 character key was pressed
keyUp 4 character key was released
autoKey 5 key repeated because the user held it down
updateEvt 6 window must be redrawn
diskEvt 7 diskette was inserted
activateEvt 8 window was activated or deactivated
9 (not used)
networkEvt 10 network event (system use)
driverEvt 11 I/O device driver event (system use)
app1Evt 12 available for application use. See PostEvent
app2Evt 13 available for application use
app3Evt 14 available for application use
app4Evt 15 used by MultiFinder / Switcher
The meaning and layout of the message field of theEvent varies, depending
upon the type of event (found in theEvent ->what ).
Mouse Events
For mouseDown and mouseUp events, theEvent -> message is un defined. As
in all cases, theEvent ->where is the position in GLOBAL coordinates where
the event took place. Use FindWindow to see the part of the screen where
it occurred and then process the request (i.e., call MenuSelect,
The modifiers field of the EventRecord is significant if you are checking for
shift-, command-, control-, or option-clicks. See below.
In most cases, you can ignore mouse up events. But if you need to check for
a double click, keep track of theEvent ->when. If a mouseDown, a mouseUp,
and another mouseDown occur within the number of ticks in the global
variable DoubleTime, and within, for example, five pixels of each other,
then it's a double click. See GetDblTime for an example.
Keyboard Events
For keyDown, autoKey, and keyUp events, the layout of theEvent-> message
is:
Events.h defines the following constants that apply to the message field for
these events:
keyCodeMask (0x0000FF00) mask to extract keyboard scan code
charCodeMask (0x000000FF) mask to extract ASCII character code
The keyboard address field shows which keyboard in a multiple keyboard
configuration is presenting the event.
See Keyboard Layout for information about key codes. Typical handling of
keyDown hese events:
keyCodeMask (0x0000FF00) mask to extract keyboard scan code
charCodeMask (0x000000FF) mask to extract ASCII character code
See Keyboard Layout for information about key codes. Typical handling of
keyDown events includes code such as this:
theChar = theEvent->message & charCodeMask;
theKey = ( theEvent->message & keyCodeMask) >> 8;
if ( theEvent->modifiers & cmdKey) { ... was pressed ... }
In handling both keystrokes and mousedowns, you may wish to test the
state of the modifier keys (, option, control, or shift). Modifier keys are
not reported as keystrokes, but the modifiers field of every EventRecord
( including null events) contains the current status:
Note: keyUp events are normally masked by the Event Manager and never
make it into the event queue. See SetEventMask.
The standard Sytem automatically captures and processes two
Command-Shift-number key combinations. The combinations are:
Command-Shift-1 Eject internal disk
Command-Shift-2 Eject external disk
Combinations for 3 to 9 are also captured by GetNextEvent, but are
processed by calling 'FKEY' resources. You can implement you own actions
for Command-Shift-number combinations for numbers 5 to 9 by defining
your own 'FKEY' resource. The routine should have no parameters and the
ID of the resource has to correspond to the selected 'FKEY'. For example, to
define an action for Command-Shift-8, you would create an 'FKEY' resource
with ID 8.
The following 2 Command-Shift-number key combinations are
implemented with 'FKEY' resources in the standard System file:
Command-Shift-3 Save current screen as a MacPaint file, @e
with name Screen #
Command-Shift-4 Print the active window to an @a
ImageWriter
(with Caps Lock enabled) Print the entire screen to an
ImageWriter
Window Events
For activateEvt and updateEvt events, theEvent-> message is a WindowPtr.
For activateEvts, you should check theEvent ->modifiers and activate or
deactivate the window (e.g., show or hide the scroll bars, etc.), depending
upon the value of the activeFlag bit.
For updateEvts, you are requested to redraw your screen. A typical
sequence is to call BeginUpdate, redraw the content region of the window,
and call EndUpdate. The Window Manager clips your output to only those
parts of the screen that have been uncovered or were flagged via InvalRect.
Note: Upon receiving an update event for a window, you must call
BeginUpdate and EndUpdate, even if you don't take any other action.
Otherwise, your other windows will not be redrawn.
Note: Window events are not actually posted to the queue like other
events; they are generated by the the Event Manager at the time of the
call to GetNextEvent.
Disk Events
You can probably ignore diskEvt events. If you need to handle these,
theEvent-> message is a 2-word value as follows:
See PBMountVol for the meaning of the high word. If it is non-zero, you
may wish to call DIBadMount to format the disk.
Application-Generated Events
Event types app1Evt, app2Evt, and app3Evt are entirely available to any
application. They won't be read by GetNextEvent unless you place one in
the event queue via PostEvent. You may also post app4Evt events if you
take care to avoid conflict with the way MultiFinder uses it.
This capability lets you generalize some processing by handling it from
your main event loop. For instance, you might post an "error event" from a
low-level routine in order to let the main loop clean it up. Or in a modem
program, you could post a "ring event" or a "hang up" event. You could post
and process a "menu change" event when a menu item is added or disabled,
and so forth.
MultiFinder Events
Event type app4Evt is reserved by Apple as a way to communicate with
programs that are "MultiFinder aware" and have set one or more of the
MultiFinder control bits in their 'SIZE' resource. On an app4Evt event, the
message field is formatted as:
When the high byte is 0x01, you are getting notification that you are being
suspended or resumed. One reason for this call is to let you move your local
scrap (if any) into the global desk scrap (via PutScrap). If message bit 1
is set, you don't need to worry about it.
Note: if the "MultiFinderAware" bit of your 'SIZE' resource is set, you
must manually deactivate/activate your front window upon a
suspend/resume event (an activate event is NOT generated for you).
When you call WaitNextEvent, specifying a non-NIL " mouseRgn", then
the Event Manager will issue "mouse moved event" whenever the mouse
moves outside of the specified region (the mouse position will be in the
where field). See About MultiFinder for related information.