TweetFollow Us on Twitter

Window Defs
Volume Number:2
Issue Number:10
Column Tag:Pascal Procedures

Window Definition Routines

By Darryl Lovato, TML Systems, Inc., MacTutor Contributing Editor

In my first article describing definition routines, I stated that the best way to create a Definition Routine was to develop the routine as a procedure or function in your code, and when it is finished, make it into its respective resource (MDEF, WDEF, CDEF, LDEF). This finished resource can then be installed into your application and used just as you would a standard Definition Routine. There seems to be some confusion about this.

Creating the routine within your program requires that you do some hacking that isn't very nice, and slightly buggy, but it usually works. The reason you would want to create the routine as part of your code is because it's much faster to compile a definition procedure as part of your code as opposed to compiling the procedure into a resource, installing it, and then running the program that uses it.

As my first article explained, there are several ways to create the Definition Routine as part of your program. The way I choose to include the Definition Routine is shown below:

.....
var {our menu handle}
 myMenuHdl : MenuHandle;
.....
{this is the proc that will become a resource}
procedure TheMenuProc(.....);
begin
.....
end;
.....
 {first, we need to get a menu handle!}
myMenuHdl := GetNewMenu(.....);
 {second, we create a new handle that will be the  handle to our routine. 
}
myMenuHdl^^.menuProc := NewHandle(0);
 {third, we make the handle point to a pointer to  our routine. This, 
in effect makes a handle to our  routine (which is what we went through 
all this  for!).  We can do this because the routine is in the 
 first code segment that is always locked.}
myMenuHdl^^.menuProc^ := Ptr(@TheMenuProc);

Mike Shulster's approach to creating a definition routine is a bit different, but works just as well. He makes a 6 byte resource, MDEF, WDEF, etc. All the resource contains is a JMP XXXXXXXX instruction. After he gets the handle to the routine, he patches the contents of the resource so that it will to jump back to his code!!! This method is shown below.

.....
var {our menu handle}
 myMenuHdl : MenuHandle;
.....
{this is the proc that will become a resource}
procedure TheMenuProc(.....);
begin
.....
end;
.....
 {first, we need to get a menu handle.  This will  read the 6 byte "defintion" 
resource and place a handle to it in the menu record}
myMenuHdl := GetNewMenu(.....);
 {Now we need to patch the resource's  JMP         XXXXXXXX instruction 
so that it will jump to our Definition Routine.  This is done by making 
a blind pointer}

 {get a ptr to the resource data}
MyPtr := Pointer(myMenuHdl^^.menuProc^);
  {skip JMP instruction but not address}
MyPtr := Pointer(Ord4(myPtr) + 2);
 {and stuff the address of the menu proc in the    XXXXXXXX portion of 
the resource}
MyPtr^ := Ord4(@TheMenuProc);
 {the resource data now consists of a jump back to       the applications 
code that implements the  definition routine.}

These methods should only be used during development!

Normally, a fairly large program consists of more than one code segment, therefore you can never be sure if the procedure is going to be part of segment one (which is locked). You could Hlock the code segment the code is a part of, but this would result in heap fragmentation which is a BIG NO NO!

How do you compile the Definition Procedure into a resource? TML Pascal allows you to do this very easily. When I wrote this, mid-August, the only other compiler that I know of that had this capability was Lisa Pascal.

A TML Pascal shell is shown below for a program that is to be compiled into a resource. Note: it must be compiled with the create desk accessory option checked.

program TheDefProcProgram;

{$C type id [attribute] [name]}
{$H ''}

{----------------------- RESOURCE STARTS HERE --}
procedure TheDefProc(.....);
  const
  type
  var
begin
end;
{------------------------- RESOURCE ENDS HERE --}

begin {no main program allowed}
end.

The type, is the resource type, id is the resource id, the name and attribute fields are optional and are used to set the resources name and attributes. Always remember to compile your tested Definition Routines into a resource when they are finished! The $H '' tells the compiler that the desk accessory header should not be linked to the Definition Routine. [The $C directive tells the compiler to create a code resource out of the first procedure. -Ed]

There are a number of GREAT things that can be done with definition routines. By the way, have any of you seen dBase Mac? The PopUps used in dBase Mac are custom Control Definitions, which we cover next month!

Introduction to Wdef Routines

This month we are covering Window Definition Routines. What is a window definition routine? It is a procedure that defines a particular type of window. The routine controls the way windows are drawn, the regions of the window, the highlighting, how they are grown, etc. In general, Window Definition routines define windows' appearance and behavior. The standard type of Macintosh window has been pre-defined for you and is stored in the system file. You may however want to define your own type of window. The windows in Microsoft's Flight Simulator are good examples of non-standard windows.

The window definition procedure I decided to use for an example doesn't create a non-standard window but it shows exactly how the standard menu definition works! The standard definition routine was written in 68000 Assembler, by Andy Hertzfeld (my hero), but ours will be written entirely in TML Pascal. There isn't any noticeable speed difference between the standard Menu Def and our imitation.

The pascal definition and general outline for a Window Definition function follows:

function MyWindowDef(varCode : Integer;
 theWindow : WindowPtr;
 message : Integer;
 param : LongInt) : LongInt;
type
  RectPtr = ^Rect;
var
  aRectPtr : RectPtr;
procedure DoDraw(aWindow : WindowPtr; param : LongInt);
  begin
  ... {draw window - check param to draw go-away or frame}
  end
function DoHit(aWindow : WindowPtr; param : LongInt) : LongInt;
  begin
  ... {check to see if the point is in window, return region}
  end;
procedure DoCalcRgn(aWindow : WindowPtr);
  begin
  ... { calculate the windows structure and content rgns}
  end;
procedure DoInit(aWindow : WindowPtr);
  begin
  ... { allocate any additional storage needed for window}
  end;
procedure DoDispose(aWindow : WindowPtr);
  begin
  ... { dispose of what you created in DoInit}
  end;
procedure DoGrow(aWindow : WindowPtr; aRect : Rect);
  begin
  ... {draw the grow- outline of the window in the rect}
  end;
procedure DoGIcon(aWindow : WindowPtr);
  begin
  ... {draw the grow icon}
  end;
begin
  case message of
    wDrawMsg :
        DoDraw(theWindow, param);
    wHitMsg :
        MyWindowDef := DoHit(theWindow, param);
    wCalcRgnMsg :
        DoCalcRgn(theWindow);
    wInitMsg :
        DoInit(theWindow);
    wDisposeMsg :
        DoDispose(theWindow);
    wGrowMsg  :
      begin
        aRectPtr := RectPtr(param);
        DoGrow(theWindow, aRectPtr^);
      end;
    wGIconMsg :
        DoGIcon(theWindow);
  end;
end;

The Parameters

The varCode parameter tells the window definition routine what variation of the window we are doing. For example, in the standard round-corner document window, the varCode parameter tells the definition function the radius of the corners.

The window manager gets the varCode in the following ways: When you create a window from a resource, you specify the definition ID in the Window Record. The definition ID is actually the resource ID of the window definition function in the upper 12 bits, and the varCode in the lower 4 bits:

The Window manager calls the Resource manager with

defHandle := GetResource('WDEF',resourceID);

and stores the result in the windowDefProc field of the window record in the following format.

The variation code is then passed to the Window Definition function.

TheWindow is a Pointer to the window the message effects. Remember that type-casting the window pointer, which is a GrafPtr, into a Window Peek, is done by the following:

aWindowPeekVar := WindowPeek(aWindowPtrVar);

The message parameter tells you what operation you are to perform. The possible messages are: wDraw, wHit, wCalcRgns, wNew, wDispose, wGrow, and wDrawGIcon.

The param parameter is used to pass all kinds of stuff to your definition funtion. For instance, in the draw routine, you check the value of it to see if you are to draw the entire frame or just "toggle" the highlight state of the window's go-away box. In the grow message, it is a pointer to a rect and in the hit message it is the point in which the mouse button was pressed.

DoDraw Procedure

The DoDraw procedure is called in response to a wDraw message. It examines the value of param, if it is equal to wInGoAway then it toggles the state of the go-away box. In our example we do the highlighting differently, we just call InvertRect to toggle the state. If the value of param is 0, then we draw the entire window frame. The current port will already be set to the WindowMgrPort. If the go-away flag is true in the window record, we also draw the go-away region. If the highlighted field is true, we "highlight" the title bar, this shows the user that this window is the currently active one.

DoHit Function

The DoHit procedure is called in response to a wHit message. It is past the point (global coords) in the param parameter. It should determine where the point "hit" and return one of the following: 1) It should return wNoHit if it wasn't in the window. 2) It should return wInContent if the point was in the content region, and 3) it should return wInGrow if it was in the grow Region. It should also return wInGoAway if it was in the go-away rgn. The constants wInGrow and wInGoAway should only be returned if the window is active (highlighted = true).

DoCalcRgns Procedure

The DoCalcRgns procedure calculates the window's content and structure regions. The structure region is the entire window, including the title bar (if any), any shading, and the frame lines. In short it is the entire window. The content region is the area in which all drawing to the window will be clipped. It is always a sub-set of the structure region. Both of the regions are calculated from the windows portRect. The results of these calulations are stored in the windows strucRgn and contRgn fields.

The DoInit Procedure

The DoInit procedure is not used in our example. Its reason for being there, however, is to allow a definition procedure to create any additional data structures it may need. A handle to these data structures is stored in the dataHandle field of the window record. I used this feature when creating one of the TML Examples. The example creates a non-standard window, with highlighting like that on the Lisa (whoops.. Mac-XL). Its main feature is that it has a menu bar underneath the window's title bar, allowing each window to have its own menus. Anyway, in that example, I needed to store a bunch of menu handles when the window is created, and this message allowed me to do that.

DoDispose Procedure

The DoDispose procedure simply "un-o's" anything the DoInit procedure does. For instance, in the example I explained above, it calls DisposMenu for all the menus I created in the DoInit procedure. The DoDispose procedure, as you may have guessed, is called as a result of a CloseWindow or DisposeWindow call.

DoGrow Procedure

The DoGrow procedure is called after the Window definition function has returned a inGrow result from the Hit test routine. The window manager then sets the grafPort to the window manager port, the pen mode to notPatXor, and the penPat to gray. Then, as long as the user has the mouse down, the window manager repeatedly calls the definition function with the wGrow message. The DoGrow procedure must then draw the grow-image of the window, scaled to the rect which is passed by pointer in the param parameter. Our routine draws the outline of the entire window. It also shows the lines which delimit the title bar and the scroll bar areas.

DrawGIcon Procedure

The DrawGIcon procedure checks to see if the window is active. If active, it draws the grow icon in a manner that shows the window can be grown. If it is inactive, the DrawGIcon procedure draws the grow icon area in a manner which shows the window temporarily cannot be sized.

{
#RegWDEF.Pas
#
#This program illustrates the use of a standard Window 
#Definition routine.  It behaves exactly like the standard 
#window definition procedure. -=< almost >=-
#This example was written by Darryl Lovato.        
#Copyright (c) 1986 by TML Systems 
#
}

program RegWDEF; { the beginning}

{$I MemTypes.ipas} { read the memory defs}
{$I QuickDraw.ipas } { read the quickdraw defs}
{$I OSIntf.ipas  } { read operating system defs}
{$I Toolintf.ipas} { read the toolbox equates}

{$T APPL RWDF    } { set the type and creator}
{$B+    } { set the bundle bit}
{$L RegWDEFRes   } { link the resource file too...}

{
#    Global Contants Follow
}
const
  AppleMenuID = 1; { the Apple menu}
    AboutRegWDEFID = 1; { the About item}
  FileMenuID = 2;{ the File menu}
    QuitID = 1;  { the Quit item}
  EditMenuID = 3;{ the Edit menu}
  
  WindResID = 1; { the resource id of my window}
  AboutID = 3000;{ About Dialog id}

{
#   Global Variables Follow
}
var
  myMenus : Array[AppleMenuID..EditMenuID] of MenuHandle; 
  Done : Boolean;{ true when user selects quit}
  RegWDEFWindow : WindowPtr; {the window}
  GrowArea : rect; { rect wind can be grown}
  DragArea : rect; { rect wind can be dragged}
  myWindowPeek : WindowPeek;{ to get at the windows fields}
{
#
#    MyWindowDef function
}
function MyWindowDef(varCode : Integer;
 theWindow : WindowPtr;
 message : Integer;
 param : LongInt)
 : LongInt;
{------------- Semi-global types within the WDEF -------------}
type
  RectPtr = ^Rect;
{----------- Semi-global vars within the WDEF ------------}
var
  aRectPtr : RectPtr;
  myWindowPeek : WindowPeek;

{------------- DoDrawMessage procedure ---------------}
procedure DoDrawMessage(WindToDraw : WindowPtr;
   DrawParam : LongInt);
var
  TitleBarRect : Rect;
  CurrentY : Integer;
  index : Integer;
  GoAwayBox : Rect;

procedure DrawWindowTitle(aWindowPeek : WindowPeek;            
 theBox : Rect);
var
  TitleWidth : Integer;
  TitleBarWidth : Integer;
  leftEdge : Integer;
  eraseR : Rect;

begin
  TitleWidth := StringWidth(aWindowPeek^.titleHandle^^);
  TitleBarWidth := theBox.right - theBox.left;
  leftEdge := (TitleBarWidth - TitleWidth) DIV 2;
  if aWindowPeek^.GoAwayFlag then
    if leftEdge < 32 then
      leftEdge := 32;
  leftEdge := leftEdge + theBox.left; {local to global!!!}
  eraseR := theBox;
  InsetRect(eraseR,1,1);
  eraseR.left := leftEdge - 6;
  eraseR.right := leftEdge + TitleWidth + 6;
  EraseRect(eraseR);
  MoveTo(leftEdge,theBox.bottom - 5);
  DrawString(aWindowPeek^.titleHandle^^);
end;

begin
  myWindowPeek := WindowPeek(WindToDraw);
  if myWindowPeek^.visible then  {if the wind is visible, draw it}
    begin
      TitleBarRect := myWindowPeek^.strucRgn^^.rgnBBox;
      if DrawParam <> 0 then {we just need to toggle goAway box}
        begin {make room for title bar}
   TitleBarRect.bottom := TitleBarRect.top + 19;
   GoAwayBox := TitleBarRect;
   GoAwayBox.top := GoAwayBox.top + 4;
   GoAwayBox.left := GoAwayBox.left + 8;
   GoAwayBox.bottom := GoAwayBox.bottom - 4;
   GoAwayBox.right := GoAwayBox.left + 13;
   InsetRect(GoAwayBox,2,1); { move in on the sides}
   InvertRect(GoAwayBox);
 end {of if DrawParam = inGoAway}
      else {we need to draw window frame, and possibly hilite it}
        begin
   PenNormal;

   FrameRect(TitleBarRect);
   {make room for title bar}
   TitleBarRect.bottom := TitleBarRect.top + 19;

   FrameRect(TitleBarRect);
   InsetRect(TitleBarRect,1,1); {shrink by 1}
   EraseRect(TitleBarRect);
   InsetRect(TitleBarRect,-1,-1); {expand by 1}

   if myWindowPeek^.hilited then { add hiliting }
     begin
       currentY := TitleBarRect.top + 4; {draw the pattern}
       for index := 1 to 6 do 
         begin
   MoveTo(TitleBarRect.left + 2, currentY);
   LineTo(TitleBarRect.right - 3, currentY);
   currentY := currentY + 2;
 end;
       {draw title}
       DrawWindowTitle(myWindowPeek,TitleBarRect);
       if myWindowPeek^.GoAwayFlag then {goaway }
         begin
   GoAwayBox := TitleBarRect;
   GoAwayBox.top := GoAwayBox.top + 4;
   GoAwayBox.left := GoAwayBox.left + 8;
   GoAwayBox.bottom := GoAwayBox.bottom - 4;
   GoAwayBox.right := GoAwayBox.left + 13;
   EraseRect(GoAwayBox);
   InsetRect(GoAwayBox,1,0); { move in on sides}
   FrameRect(GoAwayBox); {and draw the box}
 end;
     end
   else {just draw the title}
     DrawWindowTitle(myWindowPeek,TitleBarRect);
 end; {of if DrawParam = inGoAway then.. else...}
    end; {of if window is visible...}
end;

{--------------- DoHitMessage function ---------------}

function DoHitMessage(WindToTest : WindowPtr;
 theParam : LongInt) : LongInt;
var
  globalPt : Point;
  aRect : Rect;
  GoAwayBox : Rect;
  aWindowPeek : WindowPeek;
  tempRect : Rect;
begin
  globalPt.h := LoWord(theParam);
  globalPt.v := HiWord(theParam);
  aWindowPeek := WindowPeek(WindToTest);
  aRect := aWindowPeek^.strucRgn^^.rgnBBox;
  aRect.bottom := aRect.top + 19; {create tBar Rect}
  tempRect := aWindowPeek^.strucRgn^^.rgnBBox;
  if PtInRect(globalPt,tempRect) then {in structure rgn?}
    begin
      tempRect := aWindowPeek^.contRgn^^.rgnBBox;
      if PtInRect(globalPt,tempRect) then {if in content rgn}
        begin
   if aWindowPeek^.hilited then {check the content box}
     begin
       aRect := aWindowPeek^.contRgn^^.rgnBBox;
       aRect.top := aRect.bottom - 15;{rect in low right}
       aRect.left := aRect.right - 15;
       if PtInRect(globalPt,aRect) then {it was in drag box}
         DoHitMessage := wInGrow
       else
         DoHitMessage := wInContent;
     end
   else
     DoHitMessage := wInContent;
 end
      else if PtInRect(globalPt,aRect) then {in drag or go-away}
        begin
   if aWindowPeek^.hilited then {check go-away box}
     begin
       GoAwayBox := aRect;
       GoAwayBox.top := GoAwayBox.top + 4;
       GoAwayBox.left := GoAwayBox.left + 8;
       GoAwayBox.bottom := GoAwayBox.bottom - 4;
       GoAwayBox.right := GoAwayBox.left + 13;
       InsetRect(GoAwayBox,1,0); { move in on the sides}
       if PtInRect(globalPt,GoAwayBox) then {in drag box}
         DoHitMessage := wInGoAway
       else
         DoHitMessage := wInDrag;
     end
   else
     DoHitMessage := wInDrag;
 end
      else {it was in our window frame}
        DoHitMessage := wNoHit;
    end
  else {it wasn't in our window at all}
    DoHitMessage := wNoHit;
end;

{------------ DoCalcRgnsMessage procedure -------------}
procedure DoCalcRgnsMessage(WindToCalc : WindowPtr);
var
  tempRect : Rect;
  aWindowPeek : WindowPeek;
  aRgn : RgnHandle;
begin
  tempRect := WindToCalc^.PortRect;
  
  OffsetRect(tempRect, -WindToCalc^.PortBits.Bounds.Left,
     -WindToCalc^.PortBits.Bounds.Top);
 
  aWindowPeek := WindowPeek(WindToCalc);
  RectRgn(aWindowPeek^.contRgn,tempRect); {content rgn}
  
  InsetRect(tempRect,-1,-1);
  tempRect.top := tempRect.top - 18; {make room for title bar}
  RectRgn(aWindowPeek^.strucRgn,tempRect); {struct rgn}
end;

{--------------- DoGrowMessage procedure -------------}
procedure DoGrowMessage(WindToGrow : WindowPtr;
   theGrowRect : Rect);

begin {note: we really dont need the window ptr, just the rect}
  theGrowRect.top := theGrowRect.top - 19;
  FrameRect(theGrowRect);
  theGrowRect.top := theGrowRect.top + 18;
  MoveTo(theGrowRect.left,theGrowRect.top); {drag area}
  LineTo(theGrowRect.right,theGrowRect.top);
  MoveTo(theGrowRect.right -15,theGrowRect.top); 
  LineTo(theGrowRect.right - 15, theGrowRect.bottom);
  MoveTo(theGrowRect.left,theGrowRect.bottom - 15);
  LineTo(theGrowRect.right,theGrowRect.bottom - 15);
end;

{------------ DoDrawSizeMessage procedure ------------}
procedure DoDrawSizeMessage(WindToDraw : WindowPtr);
var
  tempRect : Rect;
  boxRect : Rect;
begin
  SetPort(WindToDraw);
  tempRect := WindToDraw^.PortRect;
  tempRect.left := tempRect.right - 15;
  tempRect.top := tempRect.bottom - 15;
  boxRect := tempRect; {the grow icon area}

  myWindowPeek := WindowPeek(WindToDraw);
  
  tempRect.top := WindToDraw^.PortRect.top; {scroll frame}
  EraseRect(tempRect);
  MoveTo(tempRect.left,tempRect.top);
  LineTo(tempRect.left,tempRect.bottom);
  tempRect.right := tempRect.right - 15;
  tempRect.top := tempRect.bottom - 15;
  tempRect.left := WindToDraw^.PortRect.left;
  EraseRect(tempRect);
  tempRect.right := tempRect.right + 15;
  MoveTo(tempRect.left,tempRect.top);
  LineTo(tempRect.right,tempRect.top);

  if myWindowPeek^.hilited then {draw the grow icon}
    begin
      InsetRect(boxRect,1,1);
      boxRect.top := boxRect.top + 4;
      boxRect.left := boxRect.left + 4;
      FrameRect(boxRect);
      boxRect.right := boxRect.right - 2;
      boxRect.bottom := boxRect.bottom - 2;
      OffsetRect(boxRect,-2,-2);
      EraseRect(boxRect);
      FrameRect(boxRect);
     end
  else {erase the grow icon}
    begin
      InsetRect(boxRect,1,1);
      EraseRect(boxRect);
    end;
end;

{--------------- Main Proc within WDEF ----------------}

begin {case out on message & jump to appropriate routine}
  MyWindowDef := 0; {but first init result}
  case message of
    wDraw : { draw window frame}
      begin
        DoDrawMessage(theWindow, param);
      end;
    wHit :{ tell what rgn the mouse was pressed in}
      begin
        MyWindowDef := DoHitMessage(theWindow,param);
      end;
    wCalcRgns :  { calculate structRgn and contRgn}
      begin
        DoCalcRgnsMessage(theWindow);
      end;
    wNew :{ do any additional initialization}
      begin { we dont need to do any}
      end;
    wDispose : { do any additional disposal actions}
      begin { we dont need to do any}
      end;
    wGrow : { draw window's grow image}
      begin
        aRectPtr := RectPtr(param);
        DoGrowMessage(theWindow,aRectPtr^);
      end;
    wDrawGIcon : { draw size box in content rgn}
      begin
        DoDrawSizeMessage(theWindow);
      end;
  end;
end;

{#
#     ShowAbout procedure
#}

procedure ShowAbout; { give me some credit}
var
  theDlog : DialogPtr;
  theItem : Integer;
begin
  theDlog := GetNewDialog(AboutID,nil,Pointer(-1));
  ModalDialog(nil,theItem);
  DisposDialog(theDlog);
end;

procedure ProcessMenu(codeWord:Longint);
var
  menuNum : Integer;
  itemNum : Integer;
  NameHolder : str255;
  dummy : Integer;
  yuck : boolean;
begin
  if codeWord <> 0 then { nothing was selected}
    begin
      menuNum := HiWord(codeWord);
      itemNum := LoWord(codeWord);
      case menuNum of { the different menus}
        AppleMenuID :
   begin
     if itemNum < 3 then
       begin
         ShowAbout;
       end
     else
       begin
         GetItem(myMenus[AppleMenuID],
 itemNum,NameHolder);
 dummy := OpenDeskAcc(NameHolder);
       end;
   end;
 FileMenuID : 
   begin
     Done := true;
   end;
 EditMenuID :
   begin
     yuck := SystemEdit(itemNum - 1);
   end;
      end;
      HiliteMenu(0);
    end;
end;

procedure DealWithMouseDowns(theEvent: EventRecord);
var
  location : Integer;
  windowPointedTo : WindowPtr;
  mouseLoc : point;
  windowLoc : integer;
  VandH : Longint;
  Height : Integer;
  Width : Integer;

begin
  mouseLoc := theEvent.where;
  windowLoc := FindWindow(mouseLoc,windowPointedTo);
  case windowLoc of
    inMenuBar : 
      begin
        ProcessMenu(MenuSelect(mouseLoc));
      end;
    inSysWindow : 
      begin
        SystemClick(theEvent,windowPointedTo);
      end;
    inContent :
      begin
        if windowPointedTo <> FrontWindow then
   begin
     SelectWindow(windowPointedTo);
   end;
      end;
    inGrow :
      begin
        if windowPointedTo <> FrontWindow then
   begin
     SelectWindow(windowPointedTo);
   end
 else
   begin
     GrowArea.left := 150;
     GrowArea.top := 50;
     VandH := GrowWindow(windowPointedTo,
 mouseLoc,GrowArea);
     if VandH <> 0 then
       begin
         Height := HiWord(VandH);
 Width := LoWord(VandH);
 if Height< 50 then
   Height := 50;
 if Width < 150 then
   Width  := 150;
         SizeWindow(windowPointedTo,Width,Height,true);
         InvalRect(windowPointedTo^.portRect); 
      end;
   end;
      end;
    inDrag : 
      begin
        DragWindow(windowPointedTo,mouseLoc,DragArea);
 SelectWindow(windowPointedTo);
      end;
    inGoAway :
      begin
        if TrackGoAway(windowPointedTo,mouseLoc) then
   Done := true;
      end;
  end;
end;

procedure DealWithKeyDowns(theEvent: EventRecord);
type
  Trick = packed record
    case boolean of
      true : (long : Longint);
      false : (chr3,chr2,chr1,chr0 : char)
    end;
var
  CharCode : char;
  TrickVar : Trick;
begin
  TrickVar.long := theEvent.message;
  CharCode := TrickVar.chr0;
  if BitAnd(theEvent.modifiers,CmdKey) = CmdKey  then 
    begin
      ProcessMenu(MenuKey(CharCode));
    end;
end;

procedure DealWithActivates(theEvent: EventRecord);
var
  TargetWindow : WindowPtr;

begin
  TargetWindow := WindowPtr(theEvent.message);
  DrawGrowIcon(TargetWindow);
  if Odd(theEvent.modifiers) then
    begin
      SetPort(TargetWindow);
    end;
end;

procedure DealWithUpdates(theEvent: EventRecord);
var
  UpDateWindow : WindowPtr;
  tempPort : WindowPtr;

begin
  UpDateWindow := WindowPtr(theEvent.message);
  GetPort(tempPort);
    SetPort(UpDateWindow);
    BeginUpDate(UpDateWindow);
      EraseRect(UpDateWindow^.portRect);
      FillRect(RegWDEFWindow^.PortRect,ltGray);
      DrawGrowIcon(UpDateWindow);
    EndUpDate(UpDateWindow);
  SetPort(tempPort);
end;

{# MainEventLoop procedure
#
#}
procedure MainEventLoop;
var
  Event : EventRecord;
  ProcessIt : boolean;
begin
  repeat
    SystemTask;
    ProcessIt := GetNextEvent(everyEvent, Event); 
    if ProcessIt then
      begin
        case Event.what of
   mouseDown : DealWithMouseDowns(Event);
   AutoKey : DealWithKeyDowns(Event);
   KeyDown : DealWithKeyDowns(Event);
   ActivateEvt : DealWithActivates(Event);
   UpdateEvt : DealWithUpdates(Event);
 end;
      end;
  until Done;
end;

procedure SetupMemory;
var
  x : Longint;
begin
  x := ORD4(ApplicZone) + 128000;
  SetApplLimit(Pointer(x));
  MaxApplZone;
  MoreMasters;
  MoreMasters;
  MoreMasters;
end;

procedure SetupLimits;  { set up the dragging growing rects}
var
  Screen : Rect;
begin
  Screen := ScreenBits.bounds;
  with Screen do
    begin
      SetRect(DragArea,left+4,top+24,right-4,bottom-4);
      SetRect(GrowArea,left,top+24,right,bottom);
    end;
end;

procedure MakeMenus; { get the menus }
var
  index : Integer;
begin
  for index := AppleMenuID to EditMenuID do
    begin
      myMenus[index] := GetMenu(index);
      InsertMenu(myMenus[index],0);
    end;
  AddResMenu(myMenus[AppleMenuID],'DRVR');
  DrawMenuBar;
end;
{#################################################
#Program Execution Starts Here
###################################################}
begin
  Done := false; { we just started!!!}
  FlushEvents(everyEvent,0);{ get rid of lingering events}

  InitGraf(@thePort);{ we need QuickDraw}
  InitFonts;{ we need Fonts}
  InitWindows;   { we need Windows}
  InitMenus;{ we need Menus}
  TEInit; { we need Text Edit}
  InitDialogs(nil);{ we need Dialogs}
  InitCursor;    { show the cursor}

  SetupLimits;   { initialize the screen sizes}
  SetupMemory;   { do some memory management}
  MakeMenus;{ go create the menus}
  
  RegWDEFWindow := GetNewWindow(WindResID,
 nil,Pointer(-1));
  myWindowPeek := WindowPeek(RegWDEFWindow); 
  {note, the window is created invisible}
  
  myWindowPeek^.windowDefProc := NewHandle(0);
  myWindowPeek^.windowDefProc^ := Ptr(@MyWindowDef);
  
  ShowWindow(RegWDEFWindow); {....now we can show it!}
  SetPort(RegWDEFWindow);
  FillRect(RegWDEFWindow^.PortRect,ltGray);
  
  MainEventLoop; { ...and take care of business}
end.
 
AAPL
$116.47
Apple Inc.
+0.16
MSFT
$47.98
Microsoft Corpora
-0.72
GOOG
$537.50
Google Inc.
+2.67

MacTech Search:
Community Search:

Software Updates via MacUpdate

Cobook 3.0.7 - Intelligent address book....
Cobook Contacts is an intuitive, engaging address book. Solve the problem of contact management with Cobook Contacts and its simple interface and powerful syncing and integration possibilities.... Read more
StatsBar 1.9 - Monitor system processes...
StatsBar gives you a comprehensive and detailed analysis of the following areas of your Mac: CPU usage Memory usage Disk usage Network and bandwidth usage Battery power and health (MacBooks only)... Read more
Cyberduck 4.6 - FTP and SFTP browser. (F...
Cyberduck is a robust FTP/FTP-TLS/SFTP browser for the Mac whose lack of visual clutter and cleverly intuitive features make it easy to use. Support for external editors and system technologies such... Read more
Maya 2015 - Professional 3D modeling and...
Maya is an award-winning software and powerful, integrated 3D modeling, animation, visual effects, and rendering solution. Because Maya is based on an open architecture, all your work can be scripted... Read more
Evernote 6.0.1 - Create searchable notes...
Evernote allows you to easily capture information in any environment using whatever device or platform you find most convenient, and makes this information accessible and searchable at anytime, from... Read more
calibre 2.11 - Complete e-library manage...
Calibre is a complete e-book library manager. Organize your collection, convert your books to multiple formats, and sync with all of your devices. Let Calibre be your multi-tasking digital... Read more
Herald 5.0.1 - Notification plugin for M...
Note: Versions 2.1.3 (for OS X 10.7), 3.0.6 (for OS X 10.8), and 4.0.8 (for OS X 10.9) are no longer supported by the developer. Herald is a notification plugin for Mail.app, Apple's Mac OS X email... Read more
Firetask 3.7 - Innovative task managemen...
Firetask uniquely combines the advantages of classical priority-and-due-date-based task management with GTD. Stay focused and on top of your commitments - Firetask's "Today" view shows all relevant... Read more
TechTool Pro 7.0.6 - Hard drive and syst...
TechTool Pro is now 7, and this is the most advanced version of the acclaimed Macintosh troubleshooting utility created in its 20-year history. Micromat has redeveloped TechTool Pro 7 to be fully 64... Read more
PhotoDesk 3.0.1 - Instagram client for p...
PhotoDesk lets you view, like, comment, and download Instagram pictures/videos! (NO Uploads! / Image Posting! Instagram forbids that! AND you *need* an *existing* Instagram account). But you can do... Read more

Latest Forum Discussions

See All

Ubisoft Gives Everyone Two New Ways to E...
Ubisoft Gives Everyone Two New Ways to Earn In-Game Stuff for Far Cry 4 Posted by Jessica Fisher on November 21st, 2014 [ permalink ] | Read more »
Golfinity – Tips, Tricks, Strategies, an...
Dig this: Would you like to know what we thought of being an infinite golfer? Check out our Golfinity review! Golfinity offers unlimited ways to test your skills at golf. Here are a few ways to make sure your score doesn’t get too high and your... | Read more »
Dark Hearts, The Sequel to Haunting Meli...
Dark Hearts, The Sequel to Haunting Melissa, is Available Now Posted by Jessica Fisher on November 21st, 2014 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
Meowza! Toyze Brings Talking Tom to Life...
Meowza! | Read more »
Square Enix Announces New Tactical RPG f...
Square Enix Announces New Tactical RPG for Mobile, Heavenstrike Rivals. Posted by Jessica Fisher on November 21st, 2014 [ permalink ] With their epic stories and gorgeous graphics, | Read more »
Quest for Revenge (Games)
Quest for Revenge 1.0.0 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0.0 (iTunes) Description: The great Kingdom of the west has fallen. The gods ignore the prayers of the desperate. A dark warlord has extinguished... | Read more »
Threadz is a New Writing Adventure for Y...
Threadz is a New Writing Adventure for You and Your Friends Posted by Jessica Fisher on November 21st, 2014 [ permalink ] In the tradition of round-robin storytelling, | Read more »
SteelSeries Stratus XL Hardware Review
Made by: SteelSeries Price: $59.99 Hardware/iOS Integration Rating: 4 out of 5 stars Usability Rating: 4.5 out of 5 stars Reuse Value Rating: 4.25 out of 5 stars Build Quality Rating: 4.5 out of 5 stars Overall Rating: 4.31 out of 5 stars | Read more »
ACDSee (Photography)
ACDSee 1.0.0 Device: iOS iPhone Category: Photography Price: $1.99, Version: 1.0.0 (iTunes) Description: Capture, perfect, and share your photos with ACDSee. The ACDSee iPhone app combines an innovative camera, a powerful photo... | Read more »
ProTube for YouTube (Entertainment)
ProTube for YouTube 2.0.2 Device: iOS Universal Category: Entertainment Price: $1.99, Version: 2.0.2 (iTunes) Description: ProTube is the ultimate, fully featured YouTube app. With it's highly polished design, ProTube offers ad-free... | Read more »

Price Scanner via MacPrices.net

15″ 2.2GHz Retina MacBook Pro on sale for $17...
 B&H Photo has the 2014 15″ 2.2GHz Retina MacBook Pro on sale today for $1749. Shipping is free, and B&H charges NY sales tax only. B&H will also include free copies of Parallels Desktop... Read more
27-inch 3.5GHz 5K iMac in stock today and on...
 B&H Photo has the new 27″ 3.5GHz 5K iMac in stock today and on sale for $2299 including free shipping plus NY sales tax only. Their price is $200 off MSRP, and it’s the lowest price available... Read more
21-inch 1.4GHz iMac on sale for $979, save $1...
B&H Photo has the new 21″ 1.4GHz iMac on sale for $979.99 including free shipping plus NY sales tax only. Their price is $120 off MSRP. B&H will also include free copies of Parallels Desktop... Read more
13-inch 1.4GHz/256GB MacBook Air on sale for...
B&H Photo has lowered their price on the 13″ 1.4GHz/256GB MacBook Air to $1059.99 including free shipping plus NY sales tax only. Their price is $140 off MSRP, and it’s the lowest price for this... Read more
Save up to $400 with Apple refurbished 2014 1...
The Apple Store has restocked Apple Certified Refurbished 2014 15″ Retina MacBook Pros for up to $400 off the cost of new models. An Apple one-year warranty is included with each model, and shipping... Read more
New 13-inch 1.4GHz MacBook Air on sale for $8...
 Adorama has the 2014 13″ 1.4GHz/128GB MacBook Air on sale for $899.99 including free shipping plus NY & NJ tax only. Their price is $100 off MSRP. B&H Photo has the 13″ 1.4GHz/128GB MacBook... Read more
Apple Expected to Reverse Nine-Month Tablet S...
Apple and Samsung combined accounted for 62 percent of the nearly 36 million branded tablets shipped in 3Q 2014, according to early vendor shipment share estimates from market intelligence firm ABI... Read more
Stratos: 30 Percent of US Smartphone Owners t...
Stratos, Inc., creator of the Bluetooth Connected Card Platform, has announced results from its 2014 Holiday Mobile Payments Survey. The consumer survey found that nearly one out of three (30 percent... Read more
2014 1.4GHz Mac mini on sale for $449, save $...
 B&H Photo has lowered their price on the new 1.4GHz Mac mini to $449.99 including free shipping plus NY tax only. Their price is $50 off MSRP, and it’s the lowest price available for this new... Read more
Check Apple prices on any device with the iTr...
MacPrices is proud to offer readers a free iOS app (iPhones, iPads, & iPod touch) and Android app (Google Play and Amazon App Store) called iTracx, which allows you to glance at today’s lowest... Read more

Jobs Board

*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
*Apple* Solutions Consultant (ASC)- Retail S...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
Project Manager, *Apple* Financial Services...
**Job Summary** Apple Financial Services (AFS) offers consumers, businesses and educational institutions ways to finance Apple purchases. We work with national and Read more
*Apple* Store Leader Program - College Gradu...
Job Description: Job Summary As an Apple Store Leader Program agent, you can continue your education as you major in the art of leadership at the Apple Store. You'll Read more
*Apple* Retail - Multiple Positions (US) - A...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.