mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-12-28 01:29:20 +00:00
5b0f0cc134
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included. The Tools directory, containing mostly junk, is also excluded.
677 lines
19 KiB
C
677 lines
19 KiB
C
/*
|
|
File: ModalDialogMenuExtensions.c
|
|
|
|
Contains: C language portions of Modal Dialog Menu Access Facillity
|
|
|
|
Written by: Darin Adler
|
|
|
|
Copyright: © 1990-1992 by Apple Computer, Inc., all rights reserved.
|
|
|
|
Change History (most recent first):
|
|
|
|
<23> 11/3/92 DTY Strip out unnecessary includes.
|
|
<22> 6/10/92 JSM Moved this file to ModalDialogMenuExtensions.c from
|
|
ModalDialogMenuPatches.c since itÕs used by both the ROM and
|
|
System, keeping all the old revisions.
|
|
<21> 5/29/92 DCL Included TextUtils.p. EqualString was moved for the New Inside
|
|
Mac.
|
|
<20> 3/23/92 JSM OSEvents.h is obsolete, use Events.h.
|
|
<19> 2/20/91 KSM gbm,#KSM-3: Don't check spareflag of a NIL window.
|
|
<18> 2/10/91 KSM DBA,#80950: Fix to handle graying of Applications Menu properly.
|
|
<17> 1/5/91 fjs (KSM) do not allow non-printing function keys
|
|
<16> 12/18/90 KSM <rlc> Fix bug where DialogMgr incorrectly sets up the EditField
|
|
of the dialog record causing the Edit Menu to be incorrectly
|
|
enabled.
|
|
<15> 12/3/90 RLC <ksm> Change calls to IsWindowModal() to call the newer
|
|
GetWindowModalClass instead.
|
|
<14> 11/26/90 KSM (dba+dh)Remove extraneous ifdefs around includes. Also only
|
|
analyze in foregnd.
|
|
<13> 11/14/90 JL Changing InvalidMenuBar back to InvalMenuBar because Invalid is
|
|
misleading. All InvalÉ calls should be expanded to Invalidate if
|
|
they are expanded at all.
|
|
<12> 11/13/90 KSM <dba>Fix bug where we checked spareFlag directly instead of
|
|
calling IsWindowModal. IsWindowModal handles nil correctly, and
|
|
is smarter about variation 1 of WDEF 0. Change
|
|
SetSaveMenuEnableState to save the menu state, even if we are
|
|
only setting up the system menus and not disabling the
|
|
application menus. This fixes a bug where the system menus get
|
|
permanently disabled.
|
|
<11> 11/6/90 KSM <rlc>Revisit role of SetSaveMenuEnableState and ActiveWindowNeedsHelp
|
|
to handle the additional case of apps using modal window kinds, but
|
|
never calling _ModalDialog.
|
|
<10> 10/29/90 KSM <dba>Remove some dead code. Update to look for the modal dialog bit
|
|
before handling menus. Enable edit menu iff edit text is active.
|
|
<9> 10/15/90 JSM Really change InvalMenuBar to InvalidMenuBar.
|
|
<8> 10/15/90 JL Changing InvalMenuBar to InvalidMenuBar.
|
|
<7> 7/31/90 KSM Fix edit menu analysis state handling.
|
|
<6> 7/13/90 RLC Fix bug in testing menuselect result, hiword will be zero, but
|
|
entire longword might not be.
|
|
<5> 7/13/90 KSM Fix edit menu enabling check. Remove extra InvalMenuBar call in
|
|
EnableTheEditMenu.
|
|
<4> 7/10/90 dba get rid of C warnings
|
|
<3> 7/2/90 KSM Add edit menu handling.
|
|
<2> 6/8/90 KSM Update to use new IsFrontWindow modal calls.
|
|
<1> 6/1/90 KSM First checked in.
|
|
|
|
To Do:
|
|
add a MENU resource to indicate names of Edit menu items
|
|
find items from the Edit menu to enable them
|
|
use knowledge about Dialog Manager to know if Edit menu items should be enabled
|
|
note that we should *only* enable edit menus if the frontmost window is a
|
|
windowKind == dialogKind and there is an appropriate active editText field
|
|
(a visible TextEdit record that is currently active)
|
|
enable help menu
|
|
pass Cut, Copy, Paste, Clear, Select All through dialog filter as command keys
|
|
make a separate patch to Dialog Manager to make it handle command keys
|
|
use a global flag to prevent from saving the menu state twice
|
|
??? save menu state in a global instead of returning it as a function result
|
|
find all the *** and get rid of them
|
|
*/
|
|
|
|
/*
|
|
Modal Dialog Menu Access
|
|
Theory of Operation (Volume 1, Chapter 1, section 1)
|
|
|
|
The state of the world is Ònormal.Ó
|
|
STATE TRANSITION TABLE
|
|
|
|
State Event Event Event MenuSelect FlushEvents SysBeep
|
|
=MouseDn =NullEvt =Other (from App) (from anyone) (from App)
|
|
----- --------- --------- --------- ----------- ------------- -------------
|
|
0 1 0 0 0 0 0
|
|
1 0 3 0 0 0 2
|
|
2 0 3 0 0 0 2
|
|
3 0 0 0 0 0 0
|
|
|
|
What this means is:
|
|
State 0: This is the normal state of this code. If we see a mousedown in the menubar, we might
|
|
want to handle the menuselect call, but the app might already be doing this. So we save this
|
|
event and move to state 1.
|
|
|
|
State 1: We have seen a mousedown, but we are waiting to see if the application
|
|
is handling menus during modal dialogs. If we see the app call menuselect, we know it is
|
|
handling menus and return to state 0. If we see a flushevents call, we always go to state 0
|
|
and forget any event information we saved coming to this state. If we see a SysBeep, it might
|
|
be that that ModalDialog filter proc is complaining we clicked out of the dialog, or we may just
|
|
have gotten an extra beep. The SysBeep is "saved" and we go to state 2. A null event assumes
|
|
that the app had the change to handle the menus, but did not - so we assume it won't, go to
|
|
state 3.
|
|
|
|
State 2: We saw a sysbeep. If we see a null event, we have "eaten" the sysbeep and go to state
|
|
3. If we see another SysBeep, we Beep (for the one that got us to this state) and save off the
|
|
new SysBeep and stay in this state.
|
|
|
|
State 3: We've done our normal code and go back to state 0. This is implemented in the opposite
|
|
order, in that, we set the state to zero as we proceed on into the regular code.
|
|
|
|
------------------------------------------
|
|
In general, new patches do the following:
|
|
|
|
FlushEvents: go to state zero
|
|
MenuSelect: go to state zero (if the app called it)
|
|
SysBeep: if state 1, don't beep and go to state 2
|
|
if state 2, beep and stay in state 2
|
|
FilterEvent if state 0, mousedown goes to state 1
|
|
if state 1, null event goes to state 3, otherwise state 0
|
|
if state 2, null event goes to state 3, otherwise state 0
|
|
if state 3, we'll be on our way to state 0 anyway.
|
|
|
|
|
|
*/
|
|
|
|
#include <Dialogs.h>
|
|
#include <Events.h>
|
|
#include <Memory.h>
|
|
#include <Menus.h>
|
|
#include <Processes.h>
|
|
#include <TextUtils.h>
|
|
#include <Windows.h>
|
|
|
|
#include <DialogsPriv.h>
|
|
#include <MenuMgrPriv.h>
|
|
|
|
#define kFunctionKey 0x10
|
|
#define kCut 0x78
|
|
#define kCopy 0x63
|
|
#define kPaste 0x76
|
|
|
|
// Menu Mgr. data structures
|
|
|
|
typedef struct
|
|
{
|
|
short lastMenu;
|
|
short lastRight;
|
|
short reserved;
|
|
}
|
|
MenuListHeader;
|
|
|
|
typedef struct
|
|
{
|
|
MenuHandle handle;
|
|
short left;
|
|
}
|
|
MenuListEntry;
|
|
|
|
|
|
// menu bar iteration
|
|
|
|
MenuListHeader** GetMenuList(void);
|
|
MenuListEntry* GetNextMenu(short* offset);
|
|
|
|
|
|
// other menu operations
|
|
|
|
Boolean MenuBarEmpty(void);
|
|
Boolean PtInMenuBar(Point);
|
|
Boolean IsThisASystemMenu(short menuID);
|
|
Boolean IsModal(WindowPtr);
|
|
|
|
MenuHandle FindMenuByTitle(const unsigned char* title);
|
|
MenuHandle FindAppleMenu(void);
|
|
long GetMenuFlags(MenuHandle);
|
|
|
|
void DisableAppMenus(void);
|
|
void EnableTheEditMenu(void);
|
|
|
|
|
|
// routines to save enable state of all menus in the menu bar
|
|
|
|
Handle SaveMenusEnableState(void);
|
|
|
|
|
|
// globals (implemented in assembly) to keep our state
|
|
|
|
enum
|
|
{
|
|
kApplicationHandlesMenus,
|
|
kHandleSystemMenusDisabled,
|
|
kHandleMenusEditMenuDisabled,
|
|
kHandleMenusEditMenuEnabled,
|
|
};
|
|
typedef short TAnalyzedWindowState;
|
|
|
|
typedef struct
|
|
{
|
|
MenuHandle handle;
|
|
long savedEnableFlags;
|
|
}
|
|
MenuStateEntry;
|
|
|
|
pascal WindowPtr GetAnalyzedWindow(void);
|
|
pascal void SetAnalyzedWindow(WindowPtr);
|
|
|
|
pascal TAnalyzedWindowState GetAnalyzedWindowState(void);
|
|
pascal void SetAnalyzedWindowState(TAnalyzedWindowState);
|
|
|
|
pascal Handle GetSavedMenuState(void);
|
|
pascal void SetSavedMenuState(Handle);
|
|
|
|
|
|
// call to enable all menus for us
|
|
|
|
pascal void ModalDialogMenuSetup(Boolean nowModal)
|
|
= {0xAA67};
|
|
|
|
|
|
// heuristics used by the patches
|
|
|
|
pascal TAnalyzedWindowState ActiveWindowNeedsHelp(void);
|
|
|
|
|
|
// routines called by assembly language
|
|
|
|
pascal Handle SetSaveMenusEnableState(TAnalyzedWindowState state); // save state and enable selected menus
|
|
pascal void RestoreMenusEnableState(Handle state);
|
|
pascal void FilterEvent(EventRecord*);
|
|
|
|
|
|
// implementations
|
|
|
|
MenuListHeader** GetMenuList(void)
|
|
{
|
|
long result = (* (long*) 0xA1C);
|
|
if (result & 1)
|
|
return 0;
|
|
else
|
|
return (MenuListHeader**) result;
|
|
}
|
|
|
|
MenuListEntry* GetNextMenu(short* offset)
|
|
{
|
|
MenuListHeader** list = GetMenuList();
|
|
|
|
if (list == 0)
|
|
return 0;
|
|
*offset += sizeof(MenuListEntry);
|
|
if (*offset > (**list).lastMenu)
|
|
return 0;
|
|
else
|
|
return (MenuListEntry*) (((char*) *list) + *offset);
|
|
}
|
|
|
|
Boolean MenuBarEmpty(void)
|
|
{
|
|
short offset = 0;
|
|
return GetNextMenu(&offset) == 0; // no next menu means no menus in bar
|
|
}
|
|
|
|
|
|
Handle SaveMenusEnableState(void)
|
|
{
|
|
short offset;
|
|
MenuListEntry* mlEntry;
|
|
Handle handle;
|
|
offset = 0;
|
|
|
|
// First check to see if we already had saved the state (reentrant check)
|
|
if (GetSavedMenuState())
|
|
return 0;
|
|
|
|
// make a handle for saved enable states
|
|
|
|
handle = NewHandle(0);
|
|
if (handle == 0)
|
|
return 0;
|
|
|
|
// traverse the menus, saving state
|
|
|
|
while (mlEntry = GetNextMenu(&offset))
|
|
{
|
|
MenuStateEntry saved;
|
|
MenuHandle menu;
|
|
|
|
// make the saved state, and append it to the handle
|
|
|
|
menu = mlEntry->handle;
|
|
saved.handle = menu;
|
|
saved.savedEnableFlags = (**menu).enableFlags;
|
|
if (PtrAndHand((Ptr) &saved, handle, sizeof(MenuStateEntry)) != noErr)
|
|
{
|
|
DisposHandle(handle);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// Be sure to save the state in our global
|
|
SetSavedMenuState(handle);
|
|
|
|
return handle;
|
|
}
|
|
|
|
pascal void RestoreMenusEnableState(Handle state)
|
|
{
|
|
short offset = 0;
|
|
MenuListEntry* mlEntry;
|
|
|
|
// traverse the menus, restoring all the enable flags
|
|
|
|
while (mlEntry = GetNextMenu(&offset))
|
|
{
|
|
MenuHandle handle = mlEntry->handle;
|
|
MenuStateEntry* stateEntry = (MenuStateEntry*) *state;
|
|
MenuStateEntry* afterLast = (MenuStateEntry*) (((char*) stateEntry) + GetHandleSize(state));
|
|
|
|
// search through the state handle for saved state for this menu
|
|
|
|
while (stateEntry < afterLast)
|
|
{
|
|
if (stateEntry->handle == handle)
|
|
{
|
|
// found it, jam it in enable flags and continue (unless system menu)
|
|
|
|
if (!IsThisASystemMenu((**handle).menuID))
|
|
(**handle).enableFlags = stateEntry->savedEnableFlags;
|
|
break;
|
|
}
|
|
stateEntry++;
|
|
}
|
|
}
|
|
|
|
DisposHandle(state);
|
|
|
|
// Be sure to clean up our global
|
|
SetSavedMenuState(0);
|
|
ModalDialogMenuSetup(false); // Tell system menus to return to normal state
|
|
}
|
|
|
|
|
|
void DisableAppMenus(void)
|
|
{
|
|
short offset = 0;
|
|
MenuListEntry* mlEntry;
|
|
|
|
// traverse the menus, setting all the enable flags to zero (unless system menu)
|
|
while (mlEntry = GetNextMenu(&offset))
|
|
{
|
|
if (!IsThisASystemMenu((**(mlEntry->handle)).menuID))
|
|
(**(mlEntry->handle)).enableFlags = 0;
|
|
}
|
|
}
|
|
|
|
|
|
Boolean ThereIsAnActiveEditTextFieldInThisWindow(WindowPtr active)
|
|
{
|
|
if (((WindowPeek)active)->windowKind == dialogKind)
|
|
{
|
|
// For some reason, NewDialog does not set up the editField in the DialogRecord.
|
|
// The next DialogMgr call does though, hence this peculiar call to GetDItem.
|
|
// Additionally, call SelIText on a stattext field points editField to that
|
|
// statText field, which belies the name editField.
|
|
short kind;
|
|
Handle h;
|
|
Rect r;
|
|
register short editField = ((DialogPeek)active)->editField; // Get the edit field locally
|
|
if (editField < 0) editField = 0; // Force into range
|
|
GetDItem(active, ++editField, &kind, &h, &r); // Inc. editField before use
|
|
// Check for editField erroneously pointing to a statText field (MPW 3.2 case)
|
|
if ((editField < 0) || ((kind & 0x7f) == editText))
|
|
if (((DialogPeek)active)->editField >= 0)
|
|
if ((**(((DialogPeek)active)->textH)).active != 0)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
pascal Handle SetSaveMenusEnableState(TAnalyzedWindowState state)
|
|
{
|
|
/*
|
|
3 cases: regular window (do nothing)
|
|
modal window w/o _ModalDialog call (setup system menus)
|
|
_ModalDialog called (setup all menus)
|
|
*/
|
|
Handle result = nil;
|
|
|
|
if (state != kApplicationHandlesMenus)
|
|
{
|
|
// These 2 calls need to be in the opposite order in restore
|
|
ModalDialogMenuSetup(true); // System menus always need to be set up <18>
|
|
result = SaveMenusEnableState();
|
|
if (result)
|
|
{
|
|
// we have some kind of modal situation; check if we should setup all menus
|
|
if (state != kHandleSystemMenusDisabled)
|
|
{
|
|
// kHandleMenusEditMenuDisabled or kHandleMenusEditMenuEnabled: setup all the menus
|
|
DisableAppMenus();
|
|
if (state == kHandleMenusEditMenuEnabled)
|
|
EnableTheEditMenu();
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
void EnableTheEditMenu()
|
|
{
|
|
MenuListEntry* mlEntry;
|
|
short offset = 0;
|
|
|
|
while (mlEntry = GetNextMenu(&offset))
|
|
{
|
|
// Walk across the menus and look for Cut, Copy, and Paste (and maybe Undo) ...
|
|
MenuHandle menu = mlEntry->handle;
|
|
short items = CountMItems(menu);
|
|
short i = (short) ((items - 2) + 1); // Skip the last 2 items, since we are looking for a cluster of 3
|
|
if (i > (3 + 1)) i = (3 + 1); // Look at the first 3 items of each menu at most
|
|
while (--i > 0) // Start at the bottom of the menu, since cmd-X is usually item 3
|
|
{
|
|
short cmdChar;
|
|
GetItemCmd(menu, i, &cmdChar);
|
|
if (cmdChar == 'X')
|
|
{
|
|
long flagsToSet = (7 << i) + 1; // Compute flagsToSet now before incrementing i
|
|
GetItemCmd(menu, ++i, &cmdChar); // Check the next item (should be Copy)
|
|
if (cmdChar == 'C') // We found cmd-C, find Paste
|
|
{
|
|
GetItemCmd(menu, ++i, &cmdChar);
|
|
if (cmdChar == 'V') // We found cmd-V! This is Edit menu
|
|
(**menu).enableFlags |= flagsToSet; // So, set the flags
|
|
}
|
|
return; // Once we find cmd-X, donÕt look any more
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
MenuHandle FindMenuByTitle(const unsigned char* title)
|
|
{
|
|
short offset = 0;
|
|
MenuListEntry* mlEntry;
|
|
|
|
// traverse the menus, searching for the proper menu item
|
|
|
|
while (mlEntry = GetNextMenu(&offset))
|
|
{
|
|
MenuHandle menu = mlEntry->handle;
|
|
if (EqualString((**menu).menuData, title, false, false))
|
|
return menu;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
pascal TAnalyzedWindowState ActiveWindowNeedsHelp(void)
|
|
{
|
|
WindowPtr active;
|
|
TAnalyzedWindowState oldState;
|
|
TAnalyzedWindowState newState;
|
|
ProcessSerialNumber ourPSN;
|
|
ProcessSerialNumber currentPSN;
|
|
Boolean inFront;
|
|
|
|
if (MenuBarEmpty()) // short-circuit when there are no menus
|
|
return false;
|
|
|
|
// short circuit when current application is not frontmost since its menubar is not visible
|
|
inFront = false;
|
|
(void) GetFrontProcess(&ourPSN);
|
|
currentPSN.highLongOfPSN = 0;
|
|
currentPSN.lowLongOfPSN = kCurrentProcess;
|
|
(void) SameProcess(¤tPSN, &ourPSN, &inFront);
|
|
if (inFront == false)
|
|
return false;
|
|
|
|
active = FrontWindow();
|
|
oldState = GetAnalyzedWindowState();
|
|
|
|
if (active != GetAnalyzedWindow())
|
|
{
|
|
Boolean calledModalDialog;
|
|
|
|
// latch onto the active window
|
|
|
|
SetAnalyzedWindow(active);
|
|
SetAnalyzedWindowState(kApplicationHandlesMenus);
|
|
if (active)
|
|
{
|
|
|
|
// <18> <KSM The rest of the code in this block is change>
|
|
// Any window that is a modal dialog (WDEF 0 and variant=dBoxProc) window,
|
|
// or was the the active window at the time _ModalDialog was called
|
|
// requires us to disallow switching out (i.e., we must disable the Process menu).
|
|
// IsModal() OR _ModalDialog implies set up System Menus for a modal dialog
|
|
// But ONLY if _ModalDialog was called for this window should we check to see
|
|
// if we should handle the menus on the application's behalf.
|
|
|
|
// Find out if we called ModalDialog on this window
|
|
calledModalDialog = ((((WindowPeek)active)->spareFlag & systemHandlesMenusMask) != 0);
|
|
|
|
// Should we disable System Menus (either case)?
|
|
if (IsModal(active) || calledModalDialog)
|
|
SetAnalyzedWindowState(kHandleSystemMenusDisabled); // disable System Menus
|
|
|
|
// Should we handle menus for the application (only if ModalDialog was called)?
|
|
if (calledModalDialog)
|
|
{
|
|
// if application handles menus, Apple menu
|
|
// (or at least About item) will be disabled
|
|
|
|
MenuHandle appleMenu = FindAppleMenu();
|
|
long appleMenuFlags = GetMenuFlags(appleMenu);
|
|
if (appleMenu && (appleMenuFlags & 1) && (appleMenuFlags & 2))
|
|
{
|
|
// the application doesnÕt handle menus, we will
|
|
if (ThereIsAnActiveEditTextFieldInThisWindow(active))
|
|
SetAnalyzedWindowState(kHandleMenusEditMenuEnabled);
|
|
else
|
|
SetAnalyzedWindowState(kHandleMenusEditMenuDisabled);
|
|
// since we allow choices from the menu bar, unhilite the menu to make that obvious
|
|
HiliteMenu(0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
newState = GetAnalyzedWindowState();
|
|
|
|
// if the state has changed, menu titles may have dimmed/undimmed so redraw them
|
|
|
|
if (oldState != newState)
|
|
InvalMenuBar();
|
|
|
|
// return true if we are handling menus
|
|
|
|
return newState;
|
|
}
|
|
|
|
pascal void FilterEvent(EventRecord* event)
|
|
{
|
|
if ((event->what == nullEvent) || (event->what == updateEvt))
|
|
(void) ActiveWindowNeedsHelp();
|
|
else if (event->what == mouseDown)
|
|
{
|
|
if (PtInMenuBar(event->where))
|
|
{
|
|
TAnalyzedWindowState state = ActiveWindowNeedsHelp();
|
|
if ((state == kHandleMenusEditMenuEnabled) || (state == kHandleMenusEditMenuDisabled))
|
|
{
|
|
long result;
|
|
register short menuID;
|
|
event->what = nullEvent;
|
|
|
|
// track the menus
|
|
|
|
result = MenuSelect(event->where);
|
|
if (menuID = (short) (result >> 16))
|
|
{
|
|
short cmdChar;
|
|
GetItemCmd(GetMHandle(menuID), (short) result, &cmdChar);
|
|
// following is a compatibility hack for Word which does not respect enableFlags
|
|
if (cmdChar != 0)
|
|
{
|
|
EvQElPtr postedEvent;
|
|
if (PPostEvent(keyDown, cmdChar, &postedEvent) != noErr)
|
|
// if the event was not posted, unhilite the menu now
|
|
HiliteMenu(0);
|
|
else
|
|
// otherwise, wait for MenuKey to unhilite it
|
|
postedEvent->evtQModifiers = cmdKey;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (event->what == keyDown)
|
|
{
|
|
if ((event->modifiers & cmdKey) || ((char) event->message == kFunctionKey))
|
|
{
|
|
TAnalyzedWindowState state = ActiveWindowNeedsHelp();
|
|
if ((state == kHandleMenusEditMenuEnabled) || (state == kHandleMenusEditMenuDisabled))
|
|
{
|
|
long result;
|
|
unsigned char key = (char) event->message;
|
|
|
|
if (key == kFunctionKey)
|
|
{
|
|
unsigned char virtualKey = (event->message & keyCodeMask) >> 8;
|
|
|
|
switch (virtualKey)
|
|
{
|
|
case kCut:
|
|
key = 'X';
|
|
break;
|
|
|
|
case kCopy:
|
|
key = 'C';
|
|
break;
|
|
|
|
case kPaste:
|
|
key = 'V';
|
|
break;
|
|
|
|
default:
|
|
key = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// just hilite the menus when the relevant key is pressed
|
|
|
|
if (key && (result = MenuKey(key)))
|
|
{
|
|
long dummy;
|
|
Delay(8, &dummy);
|
|
}
|
|
HiliteMenu(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (event->what != nullEvent)
|
|
SetAnalyzedWindow((WindowPtr) 1); // set to something that is never a window
|
|
}
|
|
|
|
long GetMenuFlags(MenuHandle menu)
|
|
{
|
|
if (menu)
|
|
{
|
|
Handle savedFlags = GetSavedMenuState();
|
|
if (savedFlags)
|
|
{
|
|
MenuStateEntry* stateEntry = (MenuStateEntry*) *savedFlags;
|
|
MenuStateEntry* afterLast = (MenuStateEntry*) (((char*) stateEntry) + GetHandleSize(savedFlags));
|
|
|
|
// search through the state handle for saved state for this menu
|
|
|
|
while (stateEntry < afterLast)
|
|
{
|
|
if (stateEntry->handle == menu)
|
|
// found it, return saved enable flags
|
|
return stateEntry->savedEnableFlags;
|
|
++stateEntry;
|
|
}
|
|
}
|
|
return (**menu).enableFlags; // didnÕt find a saved state, so return the flags from the menu
|
|
}
|
|
return 0; // didnÕt find a menu, so return nothing enabled
|
|
}
|
|
|
|
MenuHandle FindAppleMenu(void)
|
|
{
|
|
// *** use MENU resource
|
|
return FindMenuByTitle("\p\024");
|
|
}
|
|
|
|
Boolean PtInMenuBar(Point pt)
|
|
{
|
|
Rect mbRect;
|
|
(void) GetMBARRect(&mbRect);
|
|
return PtInRect(pt, &mbRect);
|
|
}
|
|
|
|
Boolean IsThisASystemMenu(short menuID)
|
|
{
|
|
Boolean isSys;
|
|
if (IsSystemMenu(menuID, &isSys) != noErr)
|
|
return 0;
|
|
return isSys;
|
|
}
|
|
|
|
Boolean IsModal(WindowPtr active)
|
|
{
|
|
short class;
|
|
if (GetWindowModalClass(active,&class) != noErr)
|
|
return false;
|
|
return (class == dBoxProc);
|
|
}
|