PopUpMenuWithCurFont.c

/*
    File:       PopUpMenuWithCurFont.c
 
    Contains:   PopUpMenuSelectWithCurFont demonstrates which low memory globals
                (and possibly even nastier things) one must twiddle in order to
                control the font used by MDEF 0 during PopUpMenuSelect. Note that
                aside from the compatibility code associated with HOSTED_BY_FONT_MISCREANT,
                this code roughly parallels what the popup menu CDEF (ID 63) does.
                If at all possible you should make use of the CDEF, because when
                Engineering breaks the low memory trick, we can fix the CDEF, but
                we can't fix your code.
 
    Written by: Pete Gontier    
 
    Copyright:  Copyright © 1996-1999 by Apple Computer, Inc., All Rights Reserved.
 
                You may incorporate this Apple sample source code into your program(s) without
                restriction. This Apple sample source code has been provided "AS IS" and the
                responsibility for its operation is yours. You are not permitted to redistribute
                this Apple sample source code as "Apple sample source code" after having made
                changes. If you're going to re-distribute the source, we require that you make
                it clear in the source that the code was descended from Apple sample source
                code, but that you've made changes.
 
    Change History (most recent first):
                8/9/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
                02/26/97    PG              Somehow the files on the CD had become
                                            confused. Verified everything still works.
 
                03/25/96    PG              Was calling DeleteMenu with magic number.
                                            Fixed bizarre menu bar offset problem.
                                            Thanks to Harold Ekstrom.
    
                
*/
 
#define SystemSevenOrLater      1
#define CGLUESUPPORTED          0
#define OLDROUTINENAMES         0
#define OLDROUTINELOCATIONS     0
 
#ifndef __FONTS__
#   include <Fonts.h>
#endif
 
#ifndef __DIALOGS__
#   include <Dialogs.h>
#endif
 
#ifndef __RESOURCES__
#   include <Resources.h>
#endif
 
#ifndef __LOWMEM__
#   include <LowMem.h>
#endif
 
    //
    //  HOSTED_BY_FONT_MISCREANT
    //
    //  If you are writing an external code resource (filter,
    //  XCMD, etc.), and this code isn't giving you any joy,
    //  let HOSTED_BY_FONT_MISCREANT be 1 and see if that helps.
    //  Some extension hosts set up a hostile font environment.
    //  Your lack of joy is their fault, and they force you
    //  to assume even more compatibility risk than you would
    //  by using this code without HOSTED_BY_FONT_MISCREANT
    //  defined. On the other hand, we *are* weaving a tangled
    //  web by twiddling low memory, and sometimes one must pay
    //  the price for this sort of behavior.
    //
 
#define HOSTED_BY_FONT_MISCREANT 0
 
#if HOSTED_BY_FONT_MISCREANT
 
static pascal GrafPtr GetSomeWindowManagerPort (void)
{
    //
    //  Produces a pointer to the Window Manager port or
    //  Color Window Manager Port. You can test the returned
    //  GrafPtr to see whether it's colored or not, but
    //  many callers won't care.
    //
 
    GrafPtr result = nil;
 
    SysEnvRec theWorld;
 
    //
    //  Yes, SysEnvirons is deprecated. But it still works,
    //  and it's a cheap way to buy backward compatibility
    //  if you only need to know whether CQD support exists.
    //
 
    if (SysEnvirons (1, &theWorld))
        DebugStr ("\pWhoa! Panic! SysEnvirons failed?!");
    else if (theWorld.hasColorQD)
        GetCWMgrPort ((CGrafPtr *) &result);
    else
        GetWMgrPort (&result);
 
    return result;
}
 
#endif
 
static pascal void PopUpMenuSelectWithCurFont
    (MenuRef popUpMenuRef, Point where, unsigned short prevSelection)
{
    GrafPtr hostPort;
 
    short oldSysFont = LMGetSysFontFam ( );
    short oldSysSize = LMGetSysFontSize ( );
 
    GetPort (&hostPort);
 
    //
    //  Believe it or not, it's important to insert
    //  the menu before diddling the font characteristics.
    //
 
    InsertMenu (popUpMenuRef,hierMenu);
 
    LMSetSysFontFam (hostPort->txFont);
    LMSetSysFontSize (hostPort->txSize);
    LMSetLastSPExtra (-1);
 
#if HOSTED_BY_FONT_MISCREANT
    SetPort (GetSomeWindowManagerPort ( ));
    TextFont (0);
    TextSize (0);
    SetPort (hostPort);
#endif
 
    PopUpMenuSelect (popUpMenuRef, where.v, where.h, prevSelection);
 
    LMSetSysFontFam (oldSysFont);
    LMSetSysFontSize (oldSysSize);
    LMSetLastSPExtra (-1);
 
    DeleteMenu ((**popUpMenuRef).menuID);
}
 
//////////////////////////////////////////////////////////////////////
//
//  Below please find the usual sort of application boilerplate.
//
//////////////////////////////////////////////////////////////////////
 
static pascal OSErr InitMac (void)
{
    MaxApplZone ( );
    InitGraf (&(qd.thePort));
    InitFonts ( );
    InitWindows ( );
    InitMenus ( );
    TEInit ( );
    InitDialogs (nil);
 
    return noErr;
}
 
static pascal Boolean ModalFilterProc (DialogPtr theDialog, EventRecord *theEvent, short *)
{
    Boolean result = false;
 
    if (theEvent->what == mouseDown)
    {
        Point localWhere = theEvent->where;
        GrafPtr savePort;
    
        GetPort (&savePort);
        SetPort (theDialog);
        GlobalToLocal (&localWhere);
    
        if (FindDialogItem (theDialog, localWhere) == 1)
        {
            MenuRef popUpMenuRef = GetMenu (128);
            if (popUpMenuRef)
            {
                short txFont = theDialog->txFont;
                short txSize = theDialog->txSize;
                short iType; Handle iHandle; Rect iRect;
                Point popWhere;
 
                GetDialogItem (theDialog,2,&iType,&iHandle,&iRect);
 
                popWhere.v = iRect.bottom;
                popWhere.h = iRect.left + 2;
                LocalToGlobal (&popWhere);
 
                InvertRect (&iRect);
                    TextFont (kFontIDGeneva);
                        TextSize (9);
                            PopUpMenuSelectWithCurFont (popUpMenuRef,popWhere,0);
                        TextSize (txSize);
                    TextFont (txFont);
                InvertRect (&iRect);
 
                ReleaseResource ((Handle) popUpMenuRef);
            }
        }
    
        SetPort (savePort);
    }
 
    return result;
}
 
static pascal Boolean SetUpMenuBar (void)
{
    Boolean result = false;
    Handle mBar = GetNewMBar (128);
    if (!ResError ( ) && mBar)
    {
        SetMenuBar (mBar);
        AppendResMenu (GetMenuHandle (130), 'DRVR');
        DrawMenuBar ( );
        result = true;
        ReleaseResource (mBar);
    }
    return result;
}
 
void main (void)
{
    if (!InitMac ( ) && SetUpMenuBar ( ))
    {
        DialogRef dlgRef = GetNewDialog (128,nil,nil);
        if (dlgRef)
        {
            short itemHit;
            ModalDialog (NewModalFilterProc(ModalFilterProc),&itemHit);
            DisposeDialog (dlgRef);
        }
    }
}