Scrolling Menubar
Volume Number: 5
Issue Number: 4
Column Tag: Programmer's Workshop
April Fool's INIT: Scrolling the Menu Bar!?
By Mike Scanlin, San Diego, CA
Note: Source code files accompanying article are located on MacTech CD-ROM or
source code disks.
Probably everyone who reads this magazine knows at least one person who owns a
Mac that they’d like to play a joke on. This INIT resource might be just the thing
you’re looking for. It is a patch to _GetNextEvent that will scroll the menu bar off the
right side of the screen (leaving the menu bar blank) when the mouse is clicked in the
very top pixel of the menu bar with an odd horizontal position. It does nothing if the
mouse is clicked anywhere else on the screen, so it is possible to use the menus when
this patch is installed, just so long as you don’t click in the very top pixel at an odd
position. The menus will come back eventually (after a few sarcastic messages are
displayed in the empty menu bar), so this is a pretty harmless patch (although
extremely annoying according to my guinea pig roommate). Command key equivalents
for current menus (like COMMAND-Q) will work even though no menus are shown. It
is possible to remove the patch once it is installed by typing
COMMAND-SHIFT-OPTION-TAB. The patch will beep to let you know it has been
removed.
HOW IT WORKS
This patch to _GetNextEvent is an application of the technique I used in the Shift
Mod patch (September 1987 issue of MacTutor). It is a tail patch on _GetNextEvent
that looks at the event being returned and intercepts it if it is a mouseDown event with
a vertical position of zero and an odd horizontal position. When it finds such an event
the menu bar is scrolled off the screen and then _DrawMenuBar and _HiliteMenu are
patched to do nothing. The reason those two traps are patched is because we don’t want
anything drawn in the menu bar while we’re displaying our messages. The menu bar is
restored by restoring those two traps and then calling _DrawMenuBar. Note that
because we are patching _DrawMenuBar the user will not be able to get the menus back
by quitting the current application and/or launching another application (because
every application uses _DrawMenuBar to put their menus up).
Once we have scrolled the menus off, the patch to _GetNextEvent will intercept
any mouseDown event anywhere in the menu bar area and display a message in the
menu bar for 1 second or until the mouse button is let go, which ever is longer. After
four such messages, the patches to _DrawMenuBar and _HiliteMenuBar are removed
and _DrawMenuBar is called to draw the current menu bar (which may not
necessarily be the one that was scrolled off since the user could have changed
applications in the mean time).
To do the actual scrolling you would expect me to use _ScrollRect. That’s what I
tried at first, but it was too slow (took about 10 seconds for the menu bar to get all the
way off the screen). Then I tried scrolling by 3 or 4 pixels at a time, but it wasn’t
smooth enough. The version you see here is scrolling by rotating bits in screen
memory (via the 68000’s roxr instruction). Although somewhat unorthodox (Apple
wouldn’t approve) it now only takes about 2 seconds to smoothly scroll the menu bar
all the way off the screen.
PROBLEM
There is a potential problem with this patch. There is a danger in patching and
unpatching traps that may be patched by other applications. For applications that patch
traps this isn’t normally a problem because they get a chance to restore the traps