home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-09-25 | 14.9 KB | 464 lines | [TEXT/CWIE] |
- UNIT MercutioAPI;
-
- {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
- {x x}
- {x Developer's Programming Interface for the Mercutio MDEF x}
- {x ©1992-1996 Ramon M. Felciano, All Rights Reserved x}
- {x x}
- {x some original inline assembly courtesy of John Cavallino x}
- {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
-
- INTERFACE
- {$ALIGN MAC68K}
- USES
- Types, Memory, QuickDraw, Resources, Events, Menus, ToolUtils, MixedMode;
- CONST
-
- customDefProcSig = 'CUST';
- areYouCustomMsg = ord('*') * 256 + ord('*');
- getVersionMsg = ord('*') * 256 + ord('v');
- getCopyrightMsg = ord('C') * 256 + ord('C');
- setCallbackMsg = ord('*') * 256 + ord('c');
- stripCustomDataMsg = ord('*') * 256 + ord('d');
- setPrefsMsg = ord('*') * 256 + ord('p');
- setKeyGraphicsMsg = ord('*') * 256 + ord('g');
- setSmallIconIDMsg = ord('*') * 256 + ord('i');
-
- mMenuKeyMsg = ord('S') * 256 + ord('K'); {see if key press is key-equiv for this menu}
- mDrawItemStateMsg = ord('S') * 256 + ord('D'); { draw the specified item in the specifed box }
- mCountItemsMsg = ord('S') * 256 + ord('C'); { return count of items in menu }
-
- cbBasicDataOnlyMsg = 1;
- cbIconOnlyMsg = 2;
- cbGetLongestItemMsg = 3;
-
- TYPE
- flexStyle = PACKED RECORD CASE Boolean OF
- false : ( s : Style );
- true : ( val : SignedByte );
- END;
-
- MenuPrefsHandle = ^MenuPrefsPtr;
- MenuPrefsPtr = ^MenuPrefsRec;
- MenuPrefsRec = PACKED RECORD
- isDynamicFlag, forceNewGroupFlag, useCallbackFlag, controlKeyFlag, optionKeyFlag, shiftKeyFlag, cmdKeyFlag, unused: flexStyle;
- requiredModifiers: integer;
- unused2 : UInt32; { reserved for future use }
- unused3 : UInt32; { reserved for future use }
- END;
-
- {ItemFlagsRec: additional fields supported by Mercutio MDEFs}
- ItemFlagsPtr = ^ItemFlagsRec;
- ItemFlagsRec = PACKED RECORD
- { high byte }
- forceNewGroup: boolean;
- isDynamic: boolean;
- useCallback: boolean;
- controlKey: boolean;
- optionKey: boolean;
- unused10: boolean;
- shiftKey: boolean;
- cmdKey: boolean;
-
- { low byte }
- isHier: boolean;
- changedByCallback: boolean;
- Enabled: boolean;
- hilited: boolean;
- iconIsSmall: boolean;
- hasIcon: boolean;
- sameAlternateAsLastTime:boolean;
- dontDisposeIcon: boolean;
- END;
-
- {StdItemData: record structure from the standard menu item structure}
- RichItemData = PACKED RECORD
- iconID: Byte; { resource ID of the icon to display (0 if none) }
- keyEq: char; { keyboard equivalent (or special control value) }
- mark: char; { mark character, (chr(0) if none) }
- textStyle: flexStyle; { text style of the item }
- itemID: integer; { index position within the menu }
- itemRect: Rect; { where the item will be drawn }
- flags: ItemFlagsRec; { special Mercutio flags }
- iconType: ResType; { resource type of the icon (used for disposing of icon data)}
- hIcon: Handle; { Handle to the icon data }
- pString: StringPtr; { points to itemStr, or to string in MenuHandle }
- itemStr: Str255; { used for callback string passing }
- cbMsg: integer; { callback message }
- END;
- RichItemPtr = ^RichItemData;
-
- CONST
- uppMercutioCallbackProcInfo = $00000E80; { UPP for Mercutio callback procedure }
-
- TYPE
- {$IFC PROCTYPE }
- MercutioCallbackProcPtr = PROCEDURE (menuID: integer; previousModifiers: integer; VAR itemData: RichItemData);
- {$ELSEC}
- MercutioCallbackProcPtr = ProcPtr; { PROCEDURE MyGetItemInfo (menuID: integer; previousModifiers: integer; VAR itemData: RichItemData); }
- {$ENDC}
- MercutioCallbackUPP = UniversalProcPtr;
-
-
- {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
- {x}
- {x MDEF_MenuKey is a replacement for the standard toolbox call MenuKey for use with the}
- {x Mercutio MDEF. Given the keypress message and modifiers parameters from a standard event, it }
- {x checks to see if the keypress is a key-equivalent for a particular menuitem. If you are currently}
- {x using custom menus (i.e. menus using a Mercutio MDEF), pass the Handle to one of these menus in}
- {x hMenu. If you are not using custom menus, pass in NIL or another menu, and MDEF_MenuKey will use the}
- {x standard MenuKey function to interpret the keypress.}
- {x}
- {x As with MenuKey, MDEF_MenuKey returns the menu ID in high word of the result, and the menu}
- {x item in the low word.}
- {x}
- {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
-
- FUNCTION MDEF_MenuKey (theMessage: longint; theModifiers: integer; hMenu: MenuHandle): longint;
-
-
- {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
- {x}
- {x These routines allow you to retrieve the Copyright and Version information}
- {x embedded within the MDEF. The Version information is returned as a longint,}
- {x which can be typecast to a normal version resource.}
- {x}
- {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
-
- FUNCTION MDEF_GetCopyright (menu: MenuHandle): Str255;
- FUNCTION MDEF_GetVersion (menu: MenuHandle): longint;
-
-
- {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
- {x}
- {x MDEF_CalcItemSize will calculate the height and width for a given menu item. It assumes the top and}
- {x left fields of theRect are filled in; the MDEF will fill in the bottom and right.}
- {x}
- {x MDEF_DrawItem will draw a given item in the rectangle you specify. You can indicate whether the}
- {x the item should be hilited or enabled.}
- {x}
- {x MDEF_DrawItemState is similar but allows you to draw the item disabled or hilited.}
- {x}
- {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
-
- PROCEDURE MDEF_CalcItemSize (menu: MenuHandle; item: integer; VAR theRect: Rect);
- PROCEDURE MDEF_DrawItem (menu: MenuHandle; item: integer; destRect: Rect);
- PROCEDURE MDEF_DrawItemState (menu: MenuHandle; item: integer; destRect: Rect; hilited, enabled: boolean);
-
- {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
- {x}
- {x MDEF_StripCustomMenuData will remove any custom data allocated by the Mercutio MDEFs. Use this}
- {x before writing a MENU resource to disk (esp. if you are using callbacks)}
- {x}
- {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
- PROCEDURE MDEF_StripCustomMenuData (menu: MenuHandle);
-
-
-
- {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
- {x}
- {x MDEF_SetCallbackProc sets the procedure that will be called for each item before it is drawn. The}
- {x procedure is also called during the SizeMenu message call.}
- {x}
- {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
- PROCEDURE MDEF_SetCallbackProc (menu: MenuHandle; theProc: MercutioCallbackUPP);
-
-
- {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
- {x}
- {x MDEF_SetMenuPrefs lets you determine which style bits for the menuItems will be interepreted}
- {x as feature flags for the MDEF.}
- {x}
- {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
- PROCEDURE MDEF_SetMenuPrefs (menu: MenuHandle; pPrefs: MenuPrefsPtr);
-
- PROCEDURE MDEF_SetKeyGraphicsPreference (menu: MenuHandle; preferGraphics: boolean);
- PROCEDURE MDEF_SetSmallIconIDPreference (menu: MenuHandle; iconsSmallAboveID: integer);
-
- FUNCTION NewMercutioCallback(userRoutine: MercutioCallbackProcPtr) : MercutioCallbackUPP;
- {$IFC NOT GENERATINGCFM }
- INLINE $2E9F;
- {$ENDC}
-
- PROCEDURE CallGetItemInfo (menuID: integer; previousModifiers: integer; VAR itemData: RichItemData; defProc: ProcPtr);
- {$IFC NOT GENERATINGCFM }
- INLINE $205F, $4E90; { move.l (SP)+,A0; jsr (A0) }
- {$ENDC}
-
- PROCEDURE CallMDEF (message: integer; theMenu: MenuHandle; VAR menuRect: Rect; hitPt: Point; VAR whichItem: integer; defProc: ProcPtr);
- {$IFC NOT GENERATINGCFM }
- INLINE $205F, $4E90; { move.l (SP)+,A0; jsr (A0) }
- {$ENDC}
-
- IMPLEMENTATION
-
- {$IFC GENERATINGCFM }
- FUNCTION NewMercutioCallback(userRoutine: MercutioCallbackProcPtr) : MercutioCallbackUPP;
- BEGIN
- NewMercutioCallback := NewRoutineDescriptor(ProcPtr(@userRoutine), uppMercutioCallbackProcInfo, GetCurrentArchitecture);
- END;
-
- PROCEDURE CallGetItemInfo (menuID: integer; previousModifiers: integer; VAR itemData: RichItemData; defProc: MercutioCallbackUPP);
- VAR
- callbackUPP : MercutioCallbackUPP;
- result : longint;
- BEGIN
- callbackUPP := NewMercutioCallback(NewRoutineDescriptor(defProc, uppMercutioCallbackProcInfo, kM68kISA));
- result := CallUniversalProc(UniversalProcPtr(defProc), uppMercutioCallbackProcInfo, menuID, previousModifiers, itemData );
- DisposeRoutineDescriptor(callbackUPP);
- END;
-
- PROCEDURE CallMDEF (message: integer; theMenu: MenuHandle; VAR menuRect: Rect; hitPt: Point; VAR whichItem: integer; defProc: MercutioCallbackUPP);
- VAR
- menuProcUPP : MenuDefUPP;
- BEGIN
- menuProcUPP := MenuDefUPP(NewRoutineDescriptor(defProc, uppMenuDefProcInfo, kM68kISA));
- CallMenuDefProc(message, theMenu, menuRect, hitPt, whichItem, menuProcUPP);
- DisposeRoutineDescriptor(menuProcUPP);
- END;
- {$ENDC}
-
-
-
- PROCEDURE MDEF_SetMenuPrefs (menu: MenuHandle; pPrefs: MenuPrefsPtr);
- VAR
- state: SignedByte;
- proc: Handle;
- dummyRect: Rect;
- dummyInt: integer;
- BEGIN
- proc := menu^^.menuProc;
- state := HGetState(proc);
- HLock(proc);
- dummyInt := 0;
- dummyRect.topLeft := Point(longint(0));
- dummyRect.botRight := Point(longint(0));
- CallMDEF(setPrefsMsg, menu, dummyRect, Point(pPrefs), dummyInt, proc^);
- HSetState(proc, state);
- CalcMenuSize(menu); { size may have changed based on new Prefs }
- END;
-
-
- PROCEDURE MDEF_SetKeyGraphicsPreference (menu: MenuHandle; preferGraphics: boolean);
- VAR
- state: SignedByte;
- proc: Handle;
- dummyRect: Rect;
- dummyPt: Point;
- dummyInt: integer;
- BEGIN
- proc := menu^^.menuProc;
- state := HGetState(proc);
- HLock(proc);
- dummyPt.h := Byte(preferGraphics);
- dummyPt.v := 0;
- CallMDEF(setKeyGraphicsMsg, menu, dummyRect, dummyPt, dummyInt, proc^);
- HSetState(proc, state);
- END;
-
-
- PROCEDURE MDEF_SetSmallIconIDPreference (menu: MenuHandle; iconsSmallAboveID: integer);
- VAR
- state: SignedByte;
- proc: Handle;
- dummyRect: Rect;
- dummyPt: Point;
- BEGIN
- proc := menu^^.menuProc;
- state := HGetState(proc);
- HLock(proc);
- dummyPt := Point(longint(0));
- dummyRect.topLeft := Point(longint(0));
- dummyRect.botRight := Point(longint(0));
- CallMDEF(setSmallIconIDMsg, menu, dummyRect, dummyPt, iconsSmallAboveID, proc^);
- HSetState(proc, state);
- END;
-
-
- { PROCEDURE MDEF_SetCallbackProc (menu: MenuHandle; theProc: ProcPtr);}
- PROCEDURE MDEF_SetCallbackProc (menu: MenuHandle; theProc: MercutioCallbackUPP);
- VAR
- state: SignedByte;
- proc: Handle;
- dummyRect: Rect;
- dummyInt: integer;
- BEGIN
- proc := menu^^.menuProc;
- state := HGetState(proc);
- HLock(proc);
- dummyInt := 0;
- dummyRect.topLeft := Point(longint(0));
- dummyRect.botRight := Point(longint(0));
- CallMDEF(setCallbackMsg, menu, dummyRect, Point(theProc), dummyInt, proc^);
-
- HSetState(proc, state);
- END;
-
-
-
- PROCEDURE MDEF_StripCustomMenuData (menu: MenuHandle);
- VAR
- state: SignedByte;
- proc: Handle;
- dummyPt: Point;
- dummyItem: integer;
- dummyRect: Rect;
- BEGIN
- dummyPt.h := 0;
- dummyPt.v := 0;
- proc := menu^^.menuProc;
- state := HGetState(proc);
- HLock(proc);
- CallMDEF(stripCustomDataMsg, menu, dummyRect, dummyPt, dummyItem, proc^);
- HSetState(proc, state);
- END;
-
-
-
- PROCEDURE MDEF_DrawItem (menu: MenuHandle; item: integer; destRect: Rect);
- VAR
- state: SignedByte;
- proc: Handle;
- dummyPt: Point;
- BEGIN
- dummyPt.h := 0;
- dummyPt.v := 0;
- proc := menu^^.menuProc;
- state := HGetState(proc);
- HLock(proc);
- CallMDEF(mDrawItemMsg, menu, destRect, dummyPt, item, proc^);
- HSetState(proc, state);
- END;
-
-
-
- PROCEDURE MDEF_DrawItemState (menu: MenuHandle; item: integer; destRect: Rect; hilited, enabled: boolean);
- VAR
- state: SignedByte;
- proc: Handle;
- dummyPt: Point;
- BEGIN
- proc := menu^^.menuProc;
- state := HGetState(proc);
- HLock(proc);
- dummyPt.h := Byte(hilited);
- dummyPt.v := Byte(enabled);
- CallMDEF(mDrawItemStateMsg, menu, destRect, dummyPt, item, proc^);
- HSetState(proc, state);
- END;
-
-
-
- PROCEDURE MDEF_CalcItemSize (menu: MenuHandle; item: integer; VAR theRect: Rect);
- VAR
- state: SignedByte;
- proc: Handle;
- dummyPt: Point;
- BEGIN
- dummyPt.h := 0;
- dummyPt.v := 0;
- proc := menu^^.menuProc;
- state := HGetState(proc);
- HLock(proc);
- CallMDEF(mCalcItemMsg, menu, theRect, dummyPt, item, proc^);
- HSetState(proc, state);
- END;
-
-
-
- FUNCTION MDEF_IsCustom (menu: MenuHandle): boolean;
- {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
- {x}
- {x MDEF_IsCustom returns true if hMenu is controlled by a custom MDEF. This relies on my}
- {x convention of returning the customDefProcSig constant in the Rect parameter: this obtuse}
- {x convention should be unique enough that only my custom MDEFs behave this way.}
- {x}
- {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
- VAR
- state: SignedByte;
- proc: Handle;
- dummy: Rect;
- dummyInt: integer;
- hRes: Handle;
- BEGIN
- proc := menu^^.menuProc;
- hRes := GetResource('MDEF', 0);
- IF hRes^ = proc^ THEN
- MDEF_IsCustom := false
- ELSE
- BEGIN
- state := HGetState(proc);
- HLock(proc);
- dummy.topLeft := Point(longint(0));
- CallMDEF(areYouCustomMsg, menu, dummy, Point(longint(0)), dummyInt, proc^);
- HSetState(proc, state);
- MDEF_IsCustom := longint(dummy.topLeft) = longint(customDefProcSig);
- END;
- END;
-
-
- FUNCTION MDEF_GetVersion (menu: MenuHandle): longint;
- VAR
- state: SignedByte;
- proc: Handle;
- dummy: Rect;
- dummyInt: integer;
- BEGIN
- proc := menu^^.menuProc;
- state := HGetState(proc);
- HLock(proc);
- dummy.topLeft := Point(longint(0));
- CallMDEF(getVersionMsg, menu, dummy, Point(longint(0)), dummyInt, proc^);
- HSetState(proc, state);
- MDEF_GetVersion := longint(dummy.topLeft);
- END;
-
- FUNCTION MDEF_GetCopyright (menu: MenuHandle): Str255;
- VAR
- state: SignedByte;
- proc: Handle;
- dummy: Rect;
- dummyInt: integer;
- hCopyright: StringHandle;
- s : Str255;
- BEGIN
- s := '';
- proc := menu^^.menuProc;
- state := HGetState(proc);
- HLock(proc);
- dummy.topLeft := Point(longint(0));
- CallMDEF(getCopyrightMsg, menu, dummy, Point(longint(0)), dummyInt, proc^);
- HSetState(proc, state);
- hCopyright := StringHandle(dummy.topLeft);
- IF hCopyright <> NIL THEN
- s := hCopyright^^;
- DisposeHandle(Handle(hCopyright));
- MDEF_GetCopyright := s;
- END;
-
-
-
- FUNCTION MDEF_MenuKey (theMessage: longint; theModifiers: integer; hMenu: MenuHandle) : longint;
- VAR
- state: SignedByte;
- proc: Handle;
- dummyRect: Rect;
- BEGIN
- IF ((hMenu = NIL) | (NOT MDEF_IsCustom(hMenu))) THEN
- MDEF_MenuKey := MenuKey(char(BitAnd(theMessage, charCodeMask)))
- ELSE
- BEGIN
- proc := hMenu^^.menuProc;
- state := HGetState(proc);
- HLock(proc);
- dummyRect.topLeft := Point(longint(0));
- CallMDEF(mMenuKeyMsg, hMenu, dummyRect, Point(theMessage), theModifiers, proc^);
- HSetState(proc, state);
- MDEF_MenuKey := longint(dummyRect.topLeft);
- END;
- END;
-
-
- {$ALIGN RESET}
- END.
-