oz@yetti.UUCP (Ozan Yigit) (05/07/86)
Here is Mike Shuster's pop-up menu procedure in
Aztec C, enclosed in its test routine. Can you
believe it ?? The sources !!!! Thnx Mike !!
oZ
--------------------- popup.c -------------------------
/*
* Mike Shuster's pop-up menu
* routines in Aztec C.
*
* Conversion by: oZ
*
* For detailed discussion & explanation,
* See MACTutor Vol. 1 #13 (Dec. 1985)
* Pp. 15-22
*
* Differences:
*
* Under Aztec C, we do not need the extra
* baggage of "envelopes" to make a pascal-type
* procedure call. We have a type "pascal" which
* tells the compiler to use pascal call type.
* Thus, instead of using an envelope, we call
* the routine stored in menuProc handle directly.
* Neat huh ?
*
*/
#include <memory.h>
#include <resource.h>
#include <quickdraw.h>
#include <window.h>
#include <textedit.h>
#include <menu.h>
#include <desk.h>
#include <event.h>
#include <osutil.h>
#include <inits.h>
#define GETSYSPTR ((SysPtr) 0x1f8)
#define mDrawMsg 0
#define mChooseMsg 1
#define mSizeMsg 2
#define POINTERH (*themenu)->menuWidth-4
#define POINTERV 8
#define MENUV 20
#define FRAMEH 2
#define FRAMEV 2
#define BDELAY 2L
#define MENUPROC (*mproc)
static pin(i, l, u)
{
if (i<l)
return l;
else if (i>u)
return u;
else
return i;
}
long PopUpSelect(themenu, hitpt)
MenuHandle themenu;
Point *hitpt;
{
GrafPtr port;
GrafPtr wmgrport;
BitMap **themenubits;
BitMap *menubits;
int rowbytes;
int rows;
Rect menurect;
int whichitem;
int blink;
long nilpt;
long moupt;
pascal void (*mproc)();
if (!WaitMouseUp())
return(0L);
SetRect(&menurect,0,MENUV,(*themenu)->menuWidth,MENUV+(*themenu)->menuHeight);
InsetRect(&menurect, -FRAMEH, -FRAMEV);
rowbytes=((menurect.right-menurect.left+15)>>4)<<1;
rows=menurect.bottom-menurect.top;
themenubits=(BitMap**)NewHandle(rowbytes*rows+(long)sizeof(BitMap));
if (!themenubits)
return(0L);
HLock(themenubits);
menubits=*themenubits;
menubits->baseAddr = (char *) (menubits+1);
menubits->rowBytes = rowbytes;
menubits->bounds=menurect;
GetPort(&port);
GetWMgrPort(&wmgrport);
SetPort(wmgrport);
SetOrigin(
pin(POINTERH - hitpt->h,
(*themenu)->menuWidth-wmgrport->portRect.right+
FRAMEH, 1-FRAMEH),
pin(MENUV+POINTERV-hitpt->v,
MENUV+(*themenu)->menuHeight-wmgrport->portRect.bottom+
FRAMEV, 1-FRAMEV));
ClipRect(&wmgrport->portRect);
CopyBits(&wmgrport->portBits, menubits, &menubits->bounds,
&menubits->bounds, 0, 0L);
InsetRect(&menurect, FRAMEH, FRAMEV);
EraseRect(&menurect);
InsetRect(&menurect, -1, -1);
FrameRect(&menurect);
InsetRect(&menurect, 1, 1);
PenNormal();
MoveTo(menurect.left+1, menurect.bottom+1);
Line((*themenu)->menuWidth, 0);
Line(0,-(*themenu)->menuHeight);
ClipRect(&menurect);
LoadResource((*themenu)->menuProc);
HLock((*themenu)->menuProc);
mproc = ((*themenu)->menuProc)[0];
whichitem = 0;
moupt = 0L;
MENUPROC(mDrawMsg, themenu, &menurect, moupt, &whichitem);
do {
MENUPROC(mChooseMsg, themenu, &menurect, moupt, &whichitem);
GetMouse(&moupt);
} while (WaitMouseUp());
if(whichitem) {
for(blink=GETSYSPTR->misc>>2&0x3; blink; blink--) {
nilpt=0L;
MENUPROC(mChooseMsg, themenu, &menurect,
nilpt, &whichitem);
Delay(BDELAY, &nilpt);
MENUPROC(mChooseMsg, themenu, &menurect,
moupt, &whichitem);
Delay(BDELAY, &nilpt);
}
}
HUnlock((*themenu)->menuProc);
ClipRect(&wmgrport->portRect);
CopyBits(menubits, &wmgrport->portBits,
&menubits->bounds, &menubits->bounds, 0, 0L);
HUnlock(themenubits);
DisposHandle(themenubits);
SetOrigin(0,0);
ClipRect(&wmgrport->portRect);
SetPort(port);
return (whichitem ? ((long)(*themenu)->menuID<<16)+whichitem : 0L);
}
main(){
MenuHandle menu;
EventRecord event;
GrafPtr port;
Rect box;
char temp;
InitGraf(&thePort);
InitFonts();
InitWindows();
InitMenus();
TEInit();
InitDialogs(0L);
InitCursor();
GetWMgrPort(&port);
SetPort(port);
ClipRect(&port->portRect);
SetRect(&box, 32, 32, 64, 64);
PlotIcon(&box, GetIcon(0));
menu = NewMenu(1, "");
AppendMenu(menu, "\PBeep;Quit");
while(1) {
SystemTask();
temp = GetNextEvent(everyEvent, &event);
if(event.what == mouseDown) {
if(PtInRect(pass(event.where), &box)) {
switch(LoWord(PopUpSelect(menu, &event.where)))
{
case 1:
SysBeep(4);
break;
case 2:
_exit(0);
break;
}
}
}
}
}
--
The best way to have a Usenet: [decvax|ihnp4]!utzoo!yetti!oz
good idea is to have a Bitnet: oz@[yusol|yuyetti].BITNET
lot of ideas. Phonet: [416] 667-3976