home *** CD-ROM | disk | FTP | other *** search
Text File | 1985-11-16 | 24.9 KB | 1,004 lines |
- /* Sample desk accessory using DA.h (tabs=4) */
-
- /* (C) Copyright 1985 by Roy A. Leban
- *
- * This program is free. It is not, however, Public Domain.
- * You may distribute it free of charge to anyone, provided that
- * this comment, as well as the copyright notice is left intact.
- * If you modify this sample program and distribute it, you
- * must include comments to indicate which changes are yours.
- * You may not sell this source file without my permission.
- * You may, however, modify this program and incorporate into
- * any Desk Accessory you want (which you may sell if you wish).
- * If you do so, you must include a credit notice which says:
- * "Portions of this program Copyright 1985 by Roy A. Leban"
- * You must include this notice whether or not you sell the DA.
- * If you distribute the source to your DA in any fashion, you
- * must include this entire comment. You may, of course, include
- * any copyright of your own, with any appropriate notice.
- * You may not publish this DA in any magazine, electronic, printed
- * or otherwise, without my permission. This does not include posting
- * on public or private bulletin boards or conferencing systems.
- *
- */
-
- /*
- * This program is designed to be a simple Desk Accessory which
- * implements all the parts of a DA. Basically, it does nothing,
- * but it does it very well. It includes support for all events,
- * Horizontal and Vertical Scroll Bars and the Grow Box. More
- * Controls can be added fairly easily. The entire DA fits in
- * approximately 5K. It is written for Manx Aztec C and
- * has been completely tested with version 1.06F. It should work
- * fine with other C compilers as well, but I don't know what changes
- * would be necessary. Obviously, the header file might need to
- * be changed to pass the arguments correctly. Most of the
- * functionality is fairly obvious. Comments are placed where
- * things may not be so clear. Routines which have no functionality
- * in the sample DA, such as Cut/Copy/Paste and MouseEvent (in content),
- * have a call to the routine NotUsed(), which simply calls SysBeep(1).
- * In a functioning DA, you should modify the NotUsed function as
- * appropriate or remove it entirely. I can't guarantee this code is
- * perfect, but I have written several sophisticated DA's based
- * on it. If you have questions, you can call or write me at:
- * Roy A. Leban
- * 314 Packard, #3
- * Ann Arbor, Michigan 48104
- * (313)761-5869
- * I'll try to help if I can, but I won't write your DA's for you.
- * Have fun.
- *
- */
-
- /*
- * Notes on the Driver Flags and Data:
- *
- * dNeedLock
- * This is necessary for re-entrant DA's to work
- * properly, because of a problem in the Desk Manager.
- * When the inner call returns, the Desk Manager unlocks
- * the driver, not noticing the outer call.
- * dNeedTime
- * This causes drvrCtl to get called frequently without
- * user intervention, useful for doing things like
- * calling TEIdle. drvrDelay contains the frequency
- * in Clock Ticks. Note that you may not get called
- * that frequently, depending on the Application, but
- * you won't be called more frequently. A drvrDelay
- * of 0 means you'll get called as often as possible.
- * dNeedGoodBye
- * Means that your application gets a GoodBye "kiss"
- * if the Application quites while your DA is open.
- * dCtlEnable
- * Enables the drvrCtl (Control) calls.
- * drvrEMask
- * This is the mask of events you'll handle. You'll
- * get Update and Activate Events no matter what.
- */
-
- #asm
- drvrFlags equ $7400 ; drvrFlags: dNeedLock + dNeedTime +
- ; dNeedGoodBye + dCtlEnable
- drvrDelay equ 6 ; drvrDelay: Call every 1/10th second
- drvrEMask equ $002A ; drvrEMask: MouseDown + KeyDown + AutoKey
- #endasm
-
- #include <DA.h>
-
-
- #define _DRIVER
- #include <types.h>
- #include <quickdraw.h>
- #include <toolutil.h>
- #include <window.h>
- #include <control.h>
- #include <menu.h>
- #include <memory.h>
- #include <osutil.h>
- #include <event.h>
- #include <resource.h>
- #include <packages.h>
- #include <pb.h>
- #include <desk.h>
- #include <scrap.h>
-
- #define NULL 0L
-
- /*
- * General note concerning data: If you have pre-initialized data
- * which you modify, it may not be restored when the DA is restarted.
- * It is only restored if the driver is flushed from memory.
- */
-
- /*
- * The following hex data defines a + cursor which will appear
- * inside the DA window. This hex data was extracted from a
- * ResEdit "Open General" box. You can also use CURS resources
- * if you wish.
- */
- static Cursor theCursor = {
- 0x0000, 0x0100, 0x0100, 0x0100,
- 0x0100, 0x0100, 0x0100, 0x7FFC,
- 0x0100, 0x0100, 0x0100, 0x0100,
- 0x0100, 0x0100, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0007, 0x0007 };
-
- static int theID; /* DA resource information */
- static ResType theType;
- static Str255 theName;
-
- static char Active = FALSE; /* DA Window Active */
-
- #define BufferSize 1L /* Size of extra buffer */
- #define ExtraSpace 2048L /* Extra space needed to execute */
-
- static Handle BufferHandle; /* Same as dCtl->dCtlStorage */
- static char *BufferPtr; /* Valid while buffer locked */
- static int NLock; /* Number of LockBuffers */
-
- static WindowRecord deskRecord; /* Window Record for DA Window */
- static Rect StdSize = { 50, 50, 250, 250}; /* Change as desired */
- static Rect SizeLimits = { 80, 80, 300, 500};
- static int Width;
- static int Height;
-
- #define QuitItem 1 /* See Menu in Sample.r */
- #define AboutItem 3
- static int MenuRsrc; /* Resource ID of Menu */
- static MenuHandle DeskMenu = NULL; /* Handle of menu */
- static char MenuPresent = FALSE; /* Menu is currently enabled */
- static char KeepMenu; /* Keep menu during dialog box */
-
- #define GrowBoxSize 16
- static char Grow = TRUE; /* Grow Box exists */
- static char GrowDrawn; /* Grow Box has been drawn */
- static Rect GrowBox; /* Box for CursorSelect */
-
- #define ControlWidth 16
- #define enableControl 0
- #define disableControl 255
- static char Vflag = TRUE; /* Vertical Scroll Bar exists */
- static char Hflag = TRUE; /* Horizontal Scrol Bar exists */
- static ControlHandle Vscroll,Hscroll; /* Handles for Scroll Bars */
- static Rect Vbox,Hbox; /* Boxes for CursorSelect */
- static int Vvalue,Hvalue; /* Current Scroll Bar Values */
- static int Vinit = 0; /* Arbitrary values.. */
- static int Vmin = 0; /* ..Change these as appropriate */
- static int Vmax = 100;
- static int Vpage = 20;
- static int Hinit = 0;
- static int Hmin = 0;
- static int Hmax = 100;
- static int Hpage = 20;
-
- static GrafPort *infoWindow;
- static WindowRecord infoRecord;
- static Rect infoSize = { 80, 106, 255, 406 };
- static PicHandle infoPicture;
- static int infoPICT;
-
- static Rect tempRect;
-
- /* Declarations of routines that return values */
- WindowPtr GetDeskWindow();
- Str255 *PascalString();
- char *CString();
- char Truth();
-
-
- drvrOpen(dCtl,Pb)
- register DCEPtr dCtl;
- register ParmBlkPtr Pb;
- {
- register WindowPtr deskWindow;
- int bit;
-
- if (dCtl->dCtlWindow != NULL) { /* Window allocated already? */
- SelectWindow(dCtl->dCtlWindow); /* Yes..bring to front */
- Active = TRUE;
- return;
- }
-
- GetResInfo(dCtl->dCtlDriver,&theID,&theType,&theName);
- MenuRsrc = -16384 + (32 * theID) + 0; /* DA Menu */
- infoPICT = -16384 + (32 * theID) + 1; /* About... Picture, if any */
- /* Rsrc2 = -16384 + (32 * theID) + 2; */
-
- if (!AllocBuffers(dCtl)) { /* Try to Allocate Buffer(s) */
- Active = FALSE;
- SysBeep(3); /* Not enough memory - Don't Load */
- return;
- }
-
- deskWindow = GetDeskWindow(dCtl->dCtlRefNum);
-
- GetDeskMenu(dCtl);
-
- ControlInit(deskWindow);
- GrowInit();
- GrowIcon(deskWindow);
-
- Enable(deskWindow);
- Refresh(deskWindow,TRUE);
-
- dCtl->dCtlWindow = deskWindow; /* Other routines can now execute */
- Active = TRUE; /* ..and Window is active */
- }
-
- drvrPrime(dCtl,Pb)
- register DCEPtr dCtl;
- register ParmBlkPtr Pb;
- {
- /* Should never get called in a DA */
- }
-
- drvrCtl(dCtl,Pb)
- register DCEPtr dCtl;
- register ParmBlkPtr Pb;
- {
- register int code;
- Point pos;
-
- if (dCtl->dCtlWindow == NULL) /* Check if we have a window yet.. */
- return; /* If not..drvrOpen hasn't finished */
-
- code = Pb->u.cp.csCode;
-
- /*
- * Special case the Cursor Select events, since they're so
- * frequent. We get called all the time, not just while our
- * window is active. If the DA isn't the active window, we
- * return immediately.
- */
- if (code == accCursor) {
- if (Active) {
- CursorSelect(dCtl,Pb);
- return;
- }
- }
-
- /*
- * Set the Port to our window, unless it's GoodBye, in
- * which case it's possible that the application blindly
- * closed our window for us.
- */
- if (code != -1)
- SetPort(dCtl->dCtlWindow);
-
- switch(code) {
- case accRun: RunEvent(dCtl,Pb); break;
- case accEvent: DeskEvent(dCtl,Pb); break;
- case accMenu: MenuEvent(dCtl,Pb); break;
- case accUndo: UndoEvent(dCtl,Pb); break;
- case accCut: CutEvent(dCtl,Pb); break;
- case accCopy: CopyEvent(dCtl,Pb); break;
- case accPaste: PasteEvent(dCtl,Pb); break;
- case accClear: ClearEvent(dCtl,Pb); break;
- case -1: GoodBye(dCtl,Pb); break;
- }
- }
-
- drvrStatus(dCtl,Pb)
- register DCEPtr dCtl;
- register ParmBlkPtr Pb;
- {
- /* Should never get called in a DA */
- }
-
- drvrClose(dCtl,Pb)
- register DCEPtr dCtl;
- register ParmBlkPtr Pb;
- {
- register WindowPtr deskWindow;
-
- if (dCtl->dCtlWindow == NULL)
- return;
-
- deskWindow = dCtl->dCtlWindow;
- dCtl->dCtlWindow = NULL;
-
- ReleaseBuffers(dCtl);
- QuitWindow(deskWindow);
- if (MenuPresent)
- RemoveMenu();
- }
-
-
- /*
- * Event Management (called by drvrCtl)
- */
-
- CursorSelect(dCtl,Pb)
- register DCEPtr dCtl;
- register ParmBlkPtr Pb;
- {
- Point loc;
-
- SetPort(dCtl->dCtlWindow);
- GetMouse(&loc);
-
- if (PtInRect(pass(loc), &(dCtl->dCtlWindow->portRect))) {
- /*
- * If the mouse is in the window, see if it's in a control
- * or the Grow Box. If it is, then the cursor should be the
- * normal cursor anyway. The Grow Box area is checked if
- * there isn't a Grow Box, but both Scroll Bars exist,
- * in which case the space is empty.
- */
- if ((Grow || (Vflag && Hflag)) && PtInRect(pass(loc),&GrowBox))
- InitCursor();
- else if (Vflag && PtInRect(pass(loc),&Vbox))
- InitCursor();
- else if (Hflag && PtInRect(pass(loc),&Hbox))
- InitCursor();
- else
- SetCursor(&theCursor);
- }
- else {
- InitCursor();
- }
- }
-
- RunEvent(dCtl,Pb)
- register DCEPtr dCtl;
- register ParmBlkPtr Pb;
- {
- /*
- * This is the routine called if dNeedTime is set.
- * We don't call NotUsed() here because that would cause
- * an almost continuous beep to be sounded.
- */
- }
-
- DeskEvent(dCtl,Pb)
- register DCEPtr dCtl;
- register ParmBlkPtr Pb;
- {
- register EventRecord *e;
- register WindowPtr deskWindow;
-
- e = *(EventRecord **)&Pb->u.cp.csParam;
-
- switch (e->what) {
- case mouseDown:
- MouseEvent(dCtl,Pb,&(e->where));
- break;
- case keyDown:
- KeyEvent(dCtl,Pb,FALSE);
- break;
- case autoKey:
- KeyEvent(dCtl,Pb,TRUE);
- break;
- case activateEvt:
- if (e->modifiers & 1)
- Enable(dCtl->dCtlWindow);
- else
- Disable(dCtl->dCtlWindow);
- break;
- case updateEvt:
- deskWindow = dCtl->dCtlWindow;
- BeginUpdate(deskWindow);
- GrowIcon(deskWindow);
- DrawControls(deskWindow);
- Refresh(deskWindow,FALSE);
- EndUpdate(deskWindow);
- break;
- default:
- SysBeep(1);
- break; /* Shouldn't get any other events */
- }
- }
-
- MenuEvent(dCtl,Pb) /* Menu selection made */
- register DCEPtr dCtl;
- register ParmBlkPtr Pb;
- {
- int theItem;
- WindowPtr deskWindow;
-
- theItem = ((int *)&Pb->u.cp.csParam)[1];
-
- switch(theItem) {
- case QuitItem:
- CloseDeskAcc(dCtl->dCtlRefNum); /* Strange, but it works */
- break;
- case AboutItem:
- About(dCtl->dCtlWindow);
- break;
- }
-
- HiliteMenu(0);
- } /* MenuEvent */
-
- UndoEvent(dCtl,Pb)
- register DCEPtr dCtl;
- register ParmBlkPtr Pb;
- {
- NotUsed();
- }
-
- CutEvent(dCtl,Pb)
- register DCEPtr dCtl;
- register ParmBlkPtr Pb;
- {
- NotUsed();
- }
-
- CopyEvent(dCtl,Pb)
- register DCEPtr dCtl;
- register ParmBlkPtr Pb;
- {
- NotUsed();
- }
-
- PasteEvent(dCtl,Pb)
- register DCEPtr dCtl;
- register ParmBlkPtr Pb;
- {
- NotUsed();
- }
-
- ClearEvent(dCtl,Pb)
- register DCEPtr dCtl;
- register ParmBlkPtr Pb;
- {
- NotUsed();
- }
-
- GoodBye(dCtl,Pb)
- register DCEPtr dCtl;
- register ParmBlkPtr Pb;
- {
- /*
- * Called when the Application quits without closing the
- * DA. It's a good idea to check if the window still
- * exists before using it, as it may have been closed by
- * the application. Because of this, drvrCtl does not
- * do a SetPort before calling this routine. Note that
- * QuitWindow checks to make sure the window still exists
- * before disposing of it.
- */
- QuitWindow(dCtl->dCtlWindow);
- }
-
- /*
- * Secondary Event Routines
- */
-
- MouseEvent(dCtl,Pb,locp)
- register DCEPtr dCtl;
- register ParmBlkPtr Pb;
- Point *locp;
- {
- Point loc;
- int code,page,offset;
- long GrowVal;
- ControlHandle whichControl;
- char flag;
- int CurVal,MinVal,MaxVal,NewVal,*valp;
-
- loc = *locp;
- SetPort(dCtl->dCtlWindow);
- GlobalToLocal(&loc); /* Convert to window-relative */
-
- code = FindControl(pass(loc),dCtl->dCtlWindow,&whichControl);
-
- /*
- * If you have any other controls, you need to insert code
- * to check for them here.
- */
- if (whichControl == Vscroll)
- valp = &Vvalue;
- else
- valp = &Hvalue;
- if (code == inThumb) { /* Pressed in thumb */
- code = TrackControl(whichControl,pass(loc),-1L);
- if (code != 0) {
- *valp = GetCtlValue(whichControl);
- Refresh(dCtl->dCtlWindow,FALSE);
- }
- return;
- }
- else if ((code == inUpButton) || (code == inDownButton) ||
- (code == inPageUp) || (code == inPageDown)) {
- if (whichControl == Vscroll)
- page = Vpage;
- else
- page = Hpage;
- switch (code) {
- case inUpButton: offset = -1; break;
- case inDownButton: offset = 1; break;
- case inPageUp: offset = -page; break;
- case inPageDown: offset = page; break;
- }
- flag = TRUE;
- while (flag) {
- if (TestControl(whichControl,pass(loc)) == code) {
- HiliteControl(whichControl,code);
- CurVal = GetCtlValue(whichControl);
- MinVal = GetCtlMin(whichControl);
- MaxVal = GetCtlMax(whichControl);
- NewVal = CurVal + offset;
- if ((NewVal > MinVal && NewVal < MaxVal) ||
- (CurVal != MinVal && CurVal != MaxVal)) {
- SetCtlValue(whichControl,NewVal);
- *valp = GetCtlValue(whichControl);
- Refresh(dCtl->dCtlWindow,FALSE);
- }
- }
- else {
- HiliteControl(whichControl,0);
- }
- GetMouse(&loc);
- flag = StillDown();
- }
- HiliteControl(whichControl,0);
- return;
- }
-
- if (Grow && PtInRect(pass(loc),&GrowBox)) { /* In grow box? */
- LocalToGlobal(&loc); /* GrowWindow wants global */
- GrowVal = GrowWindow(dCtl->dCtlWindow,pass(loc),&SizeLimits);
- if (GrowVal != 0) {
- Width = (int)(GrowVal & 0xFFFF);
- Height = (int)(GrowVal >> 16);
- SizeWindow(dCtl->dCtlWindow,Width,Height,TRUE);
- GrowIcon(dCtl->dCtlWindow); /* Draw new Grow Box */
- ChangeControls(dCtl->dCtlWindow); /* Draw new controls */
- Refresh(dCtl->dCtlWindow,FALSE); /* Refresh window */
- }
- return;
- }
-
- /* Mouse pressed in content */
- NotUsed();
-
- }
-
- KeyEvent(dCtl,Pb,autoFlag)
- register DCEPtr dCtl;
- register ParmBlkPtr Pb;
- char autoFlag; /* TRUE if from AutoKey event */
- {
- NotUsed();
- }
-
- About(oldWindow)
- WindowPtr oldWindow;
- {
- Handle tempHandle;
- long size;
- char pic;
-
- HideCursor();
- infoWindow = NewWindow(&infoRecord, &infoSize, "\P",
- TRUE, altDBoxProc, -1L, FALSE, 6L);
- SelectWindow(infoWindow);
- ShowWindow(infoWindow);
- SetPort(infoWindow);
- SetResLoad(FALSE);
- infoPicture = GetResource('PICT',infoPICT); /* Picture? */
- if (infoPicture == NULL) {
- pic = FALSE; /* No picture */
- SetResLoad(TRUE);
- }
- else {
- size = SizeResource(infoPicture);
- SetResLoad(TRUE);
- tempHandle = NewHandle(size+256);
- if (tempHandle != 0L) {
- pic = TRUE; /* Picture available */
- DisposHandle(tempHandle);
- }
- else {
- pic = FALSE; /* Not enough memory */
- }
- }
- if (pic) {
- LoadResource(infoPicture);
- DrawPicture(infoPicture,&(*infoPicture)->picFrame);
- }
- else {
- /*
- * This code gets executed if you don't have an Info
- * Picture, or if there's not enough memory to load it.
- * Replace this with your About... message. If you
- * don't want a Picture, you can remove the code above.
- */
- TextFont(0); /* Chicago */
- TextFace(0); /* Normal */
- TextSize(12); /* 12 Point */
- CenterString(50,300,"\PSample DA by Roy A. Leban");
- CenterString(130,300,"\P\251Copyright 1985 by Roy A. Leban");
- }
-
- while (!Button())
- ; /* Wait until button pressed - any animation goes here */
- while (Button())
- ; /* ... and released */
- FlushEvents(mDownMask+mUpMask,0);
- HideWindow(infoWindow);
- SetPort(oldWindow);
- CloseWindow(infoWindow);
- ShowCursor();
- }
-
- CenterString(y,width,s)
- int y,width;
- Str255 *s;
- {
- int swidth;
-
- swidth = StringWidth(s);
- MoveTo((width-swidth)/2,y);
- DrawString(s);
- }
-
- /*
- * Window Management Routines
- */
-
- WindowPtr GetDeskWindow(RefNum)
- int RefNum;
- {
- register WindowPtr deskWindow;
-
- deskWindow = NewWindow(&deskRecord, &StdSize, "\PSample",
- TRUE, documentProc, -1L, TRUE, NULL);
- SetPort(deskWindow);
- ((WindowPeek)deskWindow)->windowKind = RefNum;
-
- Width = StdSize.right-StdSize.left;
- Height = StdSize.bottom-StdSize.top;
-
- GrowDrawn = FALSE;
- }
-
- Enable(deskWindow) /* Enable Window */
- register WindowPtr deskWindow;
- {
- GrowIcon(deskWindow);
- Hilite(enableControl);
- AddMenu();
- Active = TRUE;
- }
-
- Disable(deskWindow) /* Disable Window */
- register WindowPtr deskWindow;
- {
- GrowIcon(deskWindow);
- Hilite(disableControl);
- Active = FALSE;
- RemoveMenu();
- }
-
- Refresh(deskWindow,firstFlag) /* Refresh Window */
- register WindowPtr deskWindow;
- char firstFlag;
- {
- /*
- * This is called in several places: When the window
- * is created; when an Update event occurs and when
- * one of the scroll bars is scrolled or the window is
- * resized. The firstFlag parameter is TRUE if this
- * is the first time Refresh is being called (right
- * after the window is opened). Refresh should
- * perform whatever action is necessary to draw the
- * window contents. It also may be desirable to call
- * this routine in other places to keep the places where
- * the window contents are changed centralized.
- */
- NotUsed();
- }
-
- QuitWindow(deskWindow) /* Close window if it still exists */
- register WindowPtr deskWindow;
- {
- register WindowPtr tempWindow;
-
- tempWindow = FrontWindow();
- while (tempWindow != NULL && tempWindow != deskWindow)
- tempWindow = ((WindowPeek)tempWindow)->nextWindow;
- if (tempWindow != NULL) {
- KillControls(deskWindow); /* Not really necessary */
- CloseWindow(deskWindow);
- }
- }
-
- /*
- * Menu Management Routines
- *
- * The KeepMenu flag should be set whenever a dialog box
- * is used as a result of a Menu Selection. This will
- * result in the menu remaining highlighted during the
- * dialog box (and until the menu action is completed).
- */
-
- GetDeskMenu(dCtl)
- register DCEPtr dCtl;
- {
- DeskMenu = GetMenu(MenuRsrc);
- dCtl->dCtlMenu = MenuRsrc; /* Change to avoid collision */
- (*DeskMenu)->menuID = MenuRsrc; /* Use Resource ID for Menu ID */
- MenuPresent = FALSE;
- KeepMenu = FALSE;
- /*
- * It is necessary to perform any initial enabling, disabling
- * or checking of menu items now, because the Menu isn't reloaded
- * each time the DA is restarted. Thus, the menu will appear as
- * it did the last time the DA was closed.
- */
- }
-
- AddMenu() { /* Add Scissors menu */
- if (!KeepMenu) {
- InsertMenu(DeskMenu, 0); /* Add new menu at end */
- DrawMenuBar();
- MenuPresent = TRUE;
- }
- }
-
- RemoveMenu() { /* Remove Scissors menu */
- if (!KeepMenu) {
- DeleteMenu(MenuRsrc);
- DrawMenuBar();
- MenuPresent = FALSE;
- }
- }
-
- /*
- * Control and Grow Box Management Routines
- *
- * The Control routines are grouped with the Grow Box support
- * routines because there is a lot of interaction between them.
- *
- * The Control routines will draw vertical and horizontal scroll
- * bars if Vflag and Hflag are TRUE. If there is only one
- * control and no grow box, the control extends the full width
- * or height of the window. Controls may be changed on the fly
- * by changing Vflag or Hflag and calling ChangeControls.
- * To change the control values, change Vvalue and/or Hvalue
- * and call ChangeControls. Note that the controls exist
- * even if they're not used.
- *
- * GrowIcon draws the Grow Box, if Grow is TRUE. Note
- * that it draws only the Grow Box and not the scroll bar
- * lines. The Grow Box may be modified on the fly by
- * changing Grow and calling GrowIcon. This routine should
- * be called when the window changes size or Grow is changed.
- */
-
- ControlInit(deskWindow)
- WindowPtr deskWindow;
- {
- ControlSize();
-
- Vvalue = Vinit;
- Hvalue = Hinit;
-
- Vscroll = NewControl(deskWindow, &Vbox, "\P", Truth(Vflag),
- Vinit, Vmin, Vmax, scrollBarProc, 0L);
- Hscroll = NewControl(deskWindow, &Hbox, "\P", Truth(Hflag),
- Hinit, Hmin, Hmax, scrollBarProc, 1L);
- }
-
- Hilite(n)
- int n;
- {
- HiliteControl(Vscroll,n);
- HiliteControl(Hscroll,n);
- }
-
- ChangeControls(deskWindow)
- register WindowPtr deskWindow;
- {
- Rect v,h;
- char vf,hf;
-
- v = Vbox; /* Old Locations */
- h = Hbox;
-
- ControlSize();
-
- vf = !EqualRect(&v,&Vbox); /* TRUE if moved or resized */
- hf = !EqualRect(&h,&Hbox);
-
- /* Hide before changing. Note that HideControl alters the Grow Box */
- if (vf || !Vflag) {
- HideControl(Vscroll);
- if (GrowDrawn) ShowGrowIcon(deskWindow);
- }
- if (hf || !Hflag ) {
- HideControl(Hscroll);
- if (GrowDrawn) ShowGrowIcon(deskWindow);
- }
-
- if (vf) {
- MoveControl(Vscroll,Vbox.left,Vbox.top);
- SizeControl(Vscroll,16,Vbox.bottom-Vbox.top);
- }
- if (hf) {
- MoveControl(Hscroll,Hbox.left,Hbox.top);
- SizeControl(Hscroll,Hbox.right-Hbox.left,16);
- }
-
- SetCtlValue(Vscroll,Vvalue);
- SetCtlValue(Hscroll,Hvalue);
-
- if (Vflag) {
- ShowControl(Vscroll);
- ValidRect(&Vbox);
- }
- if (Hflag) {
- ShowControl(Hscroll);
- ValidRect(&Hbox);
- }
- }
-
- ControlSize() {
- /* This code must be adjusted if you change the origin */
- SetRect(&Vbox, Width-ControlWidth+1,-1,
- Width+1,Height-ControlWidth+2);
- SetRect(&Hbox, -1,Height-ControlWidth+1,
- Width-ControlWidth+2,Height+1);
-
- if (!Grow) { /* No Grow Box - see if only one control */
- if (!Vflag) /* If so..the Control expands. */
- Hbox.right += GrowBoxSize;
- else if (!Hflag)
- Vbox.bottom += GrowBoxSize;
- }
- }
-
- GrowInit() {
- SetRect(&GrowBox,0,0,0,0);
- GrowDrawn = FALSE;
- }
-
- GrowIcon(deskWindow)
- register WindowPtr deskWindow;
- {
- if (GrowDrawn) { /* Erase previous Grow Box */
- if (Vflag) ++GrowBox.top;
- if (Hflag) ++GrowBox.left;
- EraseRect(&GrowBox);
- InvalRect(&GrowBox);
- GrowDrawn = FALSE;
- }
-
- /* This code must be adjusted if you change the origin */
- SetRect(&GrowBox, Width-GrowBoxSize+1,Height-GrowBoxSize+1,
- Width,Height);
-
- if (Grow) {
- if ((Vflag || Hflag) && !(Vflag && Hflag))
- ChangeControls(deskWindow);
- ShowGrowIcon(deskWindow);
- GrowDrawn = TRUE;
- }
- else if (Vflag && Hflag) { /* Erase space between Scroll Bars */
- tempRect = GrowBox;
- ++tempRect.top;
- ++tempRect.left;
- EraseRect(&tempRect);
- ValidRect(&GrowBox);
- GrowDrawn = FALSE;
- }
- else if (Vflag || Hflag) { /* Control expands to cover Grow area */
- ChangeControls(deskWindow);
- ValidRect(&GrowBox);
- GrowDrawn = FALSE;
- }
- else { /* No Grow Box; No space reserved */
- GrowDrawn = FALSE;
- }
- }
-
- ShowGrowIcon(deskWindow)
- register WindowPtr deskWindow;
- {
- RgnHandle oldClip;
-
- oldClip = NewRgn();
- GetClip(oldClip);
- ClipRect(&GrowBox);
- DrawGrowIcon(deskWindow);
- SetClip(oldClip);
- DisposeRgn(oldClip);
- ValidRect(&GrowBox);
- }
-
- /*
- * Buffer Management Routines.
- *
- * The LockBuffers and UnlockBuffers routines should be
- * called whenever it is desired to make heavy use of
- * the buffer. After a LockBuffers, the variable BufferPtr
- * will contain a pointer to the actual buffer. Note that
- * Lock/Unlock calls may be nested, if desired. This is
- * essential for re-entrant code to work correctly.
- */
-
- AllocBuffers(dCtl) /* Allocate buffer space */
- register DCEPtr dCtl;
- {
- int i;
- Handle tempHandle;
-
- NLock = 0;
- BufferHandle = NewHandle(BufferSize);
- if (BufferHandle != NULL) {
- tempHandle = NewHandle(ExtraSpace); /* Space for stack, etc.? */
- if (tempHandle != NULL) {
- DisposHandle(tempHandle);
- dCtl->dCtlStorage = BufferHandle;
- return(TRUE);
- }
- DisposHandle(BufferHandle);
- }
- dCtl->dCtlStorage = NULL;
- return(FALSE); /* Couldn't allocate anything */
- }
-
- ReleaseBuffers(dCtl) /* Release the bitmap image */
- register DCEPtr dCtl;
- {
- DisposHandle(BufferHandle);
- dCtl->dCtlStorage = NULL;
- NLock = 0;
- }
-
- LockBuffers(dCtl) /* Lock buffers while it's in use */
- register DCEPtr dCtl;
- {
- ++NLock;
- HLock(BufferHandle);
- BufferPtr = *(char **)BufferHandle;
- }
-
- UnlockBuffers(dCtl) /* Unlock Buffers when not in use */
- register DCEPtr dCtl;
- {
- if (NLock == 0 || --NLock == 0) {
- HUnlock(BufferHandle);
- }
- }
-
-
- /* General Purpose Utility Routines */
-
- static char StringBuffer[256];
-
- NotUsed() {
- SysBeep(1);
- }
-
- /* Convert C String to Pascal string and return */
- Str255 *PascalString(str)
- char *str;
- {
- strcpy(StringBuffer,str);
- ctop(StringBuffer);
- return(StringBuffer);
- }
-
- /* Convert Pascal String to C string and return */
- char *CString(str)
- char *str;
- {
- strncpy(StringBuffer,str,256);
- ptoc(StringBuffer);
- return(StringBuffer);
- }
-
- /* Used for calling ToolBox routines with C char flags */
- char Truth(value)
- char value;
- {
- return(value?TRUE:FALSE);
- }
-