home *** CD-ROM | disk | FTP | other *** search
/ ftp.mactech.com 2010 / ftp.mactech.com.tar / ftp.mactech.com / macintosh-pascal / macintoshp-1.2-demos.sit.hqx / chap04pascal_demo / WindowsPascal.p next >
Text File  |  1999-04-05  |  15KB  |  652 lines

  1. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊
  2. // WindowsPascal.p
  3. // ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊
  4. // 
  5. // This program:
  6. //
  7. // •    Allows the user to open any number of zoomDocProc windows, up to the maximum
  8. //        specified in the global variable kMaxWindows, using the File menu Open Command or
  9. //        its keyboard equivalent.
  10. //
  11. // •    Allows the user to close opened windows using the close box, the File menu Close
  12. //         command or the Close command's keyboard equivalent.
  13. //
  14. // •    Adds menu items representing each window to a Windows    menu as each window is
  15. //        opened  (A keyboard equivalent is included in each menu item for windows 1 to 9.)
  16. //
  17. // •    Deletes menu items from the Windows menu as each window is closed.
  18. //
  19. // •    Fills each window with one of the system patterns as a means of proving, for 
  20. //        demonstration purposes, the window update process.
  21. //
  22. // •    Facilitates activation of a window by mouse selection.
  23. //
  24. // •    Facilitates activation of a window by Windows menu selection.
  25. //
  26. // •    Correctly performs all dragging, zooming and sizing operations.
  27. //
  28. // The program utilizes the following resources:
  29. //
  30. // •    An 'MBAR' resource, and 'MENU' resources for Apple, File, Edit and Windows menus 
  31. //        (preload, non-purgeable).  
  32. //
  33. // •    A 'WIND' resource (purgeable) (initially not visible).  
  34. //
  35. // •    An 'ALRT' resource and 'DITL' resource for use by Stop Alerts (purgeable).  
  36. //
  37. // •    A 'STR#' resource containing strings for the Stop Alerts (purgeable).  
  38. //
  39. // •    A 'SIZE' resource with the acceptSuspendResumeEvents and doesActivateOnFGSwitch
  40. //        flags set.      
  41. //
  42. // ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ }
  43.  
  44. program WindowsPascal(input, output);
  45.  
  46. { ………………………………………………………………………………………………………………… include the following Universal Interfaces }
  47.  
  48. uses
  49.  
  50.     Windows, Fonts, Menus, TextEdit, Quickdraw, Dialogs, QuickdrawText, Processes, Types,
  51.     Memory, Events, TextUtils, ToolUtils, OSUtils, Devices, Segload, Sound;
  52.  
  53. { ………………………………………………………………………………………………………………………………………………… define the following constants }
  54.  
  55. const
  56.  
  57.  mApple = 128;
  58.   iAbout = 1;
  59.  mFile = 129;
  60.  mEdit = 130;
  61.   iNew = 1;
  62.   iClose = 4;
  63.   iQuit = 11;
  64.  mWindows = 131;
  65.  
  66.  rNewWindow = 128;
  67.  rMenubar = 128;
  68.  rAlertBox = 128;    
  69.  rStringList = 128;
  70.   sUntitled = 1;
  71.   eMaxWindows = 2;
  72.   eFailWindow = 3;
  73.   eFailMenus = 4;
  74.   eFailMemory = 5;
  75.   
  76.  kMaxWindows = 10;
  77.  kMaxLong = $7FFFFFFF;
  78.  
  79. { ……………………………………………………………………………………………………………………………………………………………………………………… global variables }
  80.  
  81. var
  82.  
  83. gDone : Boolean;
  84. gInBackground : Boolean;
  85. gPreAllocatedBlockPtr : Ptr;
  86. gUntitledWindowNumber : longint;
  87. gCurrentNumberOfWindows : longint;
  88. gWindowPtrArray : array [0..kMaxWindows + 2] of WindowPtr;
  89.  
  90. menubarHdl : Handle;
  91. menuHdl : MenuHandle;
  92. a : integer;
  93.  
  94. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoInitManagers }
  95.  
  96. procedure DoInitManagers;
  97.  
  98.     begin
  99.     MaxApplZone;
  100.     MoreMasters;
  101.     MoreMasters;
  102.     InitGraf(@qd.thePort);
  103.     InitFonts;
  104.     InitWindows;
  105.     InitMenus;
  106.     TEInit;
  107.     InitDialogs(nil);
  108.  
  109.     InitCursor;    
  110.     FlushEvents(everyEvent, 0);
  111.     end;
  112.         {of procedure DoInitManagers}
  113.  
  114. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoError }
  115.  
  116. procedure  DoError(errorType : integer);
  117.  
  118.     var
  119.     errorMessage : string;
  120.     ignored : integer;
  121.  
  122.     begin
  123.     GetIndString(errorMessage, rStringList, errorType);
  124.     ParamText(errorMessage, '', '', '');
  125.  
  126.     if (errorType = eMaxWindows)
  127.         then     ignored := CautionAlert(rAlertBox, nil)
  128.         
  129.         else    begin
  130.                 ignored := StopAlert(rAlertBox, nil);
  131.                 ExitToShell;    
  132.                 end;
  133.     end;
  134.         {of procedure DoError}
  135.  
  136. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoUpDateWindow }
  137.  
  138. procedure DoUpdateWindow(eventRec : EventRecord);
  139.  
  140.     var
  141.     myWindowPtr : WindowPtr;
  142.     paintRect : Rect;
  143.     windowRefCon : longint;
  144.     fillPattern : Pattern;
  145.     
  146.     begin
  147.     myWindowPtr := WindowPtr(eventRec.message);
  148.     SetPort(myWindowPtr);    
  149.  
  150.     paintRect := myWindowPtr^.portRect;
  151.     paintRect.right := paintRect.right - 15;
  152.     paintRect.bottom := paintRect.bottom - 15;
  153.  
  154.     windowRefCon := GetWRefCon(myWindowPtr);
  155.  
  156.     GetIndPattern(fillPattern, 0, windowRefCon + 9);
  157.  
  158.     FillRect(paintRect, fillPattern);
  159.     end;
  160.         {of procedure DoUpdateWindow}
  161.  
  162. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoUpdate }
  163.  
  164. procedure DoUpdate(eventRec : EventRecord);
  165.  
  166.     var
  167.     myWindowPtr : WindowPtr;
  168.     
  169.     begin
  170.     myWindowPtr := WindowPtr(eventRec.message);
  171.  
  172.     BeginUpdate(myWindowPtr);
  173.  
  174.     if not (EmptyRgn(myWindowPtr^.visRgn)) then
  175.         begin
  176.         SetPort(myWindowPtr);
  177.         EraseRgn(myWindowPtr^.visRgn);
  178.         DoUpdateWindow(eventRec);
  179.         DrawGrowIcon(myWindowPtr);
  180.         end;
  181.  
  182.     EndUpdate(myWindowPtr);
  183.     end;
  184.         {of procedure DoUpdate}
  185.  
  186. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoActivateWindow }
  187.  
  188. procedure DoActivateWindow(myWindowPtr : WindowPtr; becomingActive : Boolean);
  189.     
  190.     var
  191.     windowsMenu : MenuHandle;
  192.     menuItem, a : integer;
  193.     
  194.     begin
  195.     a := 1;
  196.  
  197.     windowsMenu := GetMenuHandle(mWindows);
  198.  
  199.     while (gWindowPtrArray[a] <> myWindowPtr) do
  200.         a := a + 1;        
  201.     menuItem := a;
  202.     
  203.     if (becomingActive) 
  204.         then CheckItem(windowsMenu, menuItem, true)
  205.         else CheckItem(windowsMenu, menuItem, false);
  206.     
  207.     DrawGrowIcon(myWindowPtr);
  208.     end;
  209.         {of procedure DoActivateWindow}
  210.  
  211. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoActivate }
  212.  
  213. procedure DoActivate(eventRec : EventRecord);
  214.  
  215.     var
  216.     myWindowPtr : WindowPtr;
  217.     becomingActive : Boolean;
  218.  
  219.     begin
  220.     myWindowPtr := WindowPtr(eventRec.message);
  221.  
  222.     becomingActive := boolean(BAnd(eventRec.modifiers, activeFlag) <> 0);
  223.  
  224.     DoActivateWindow(myWindowPtr, becomingActive);
  225.     end;
  226.         {of procedure DoActivate}
  227.  
  228. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoOSEvent }
  229.  
  230. procedure DoOSEvent(eventRec : EventRecord);
  231.  
  232.     begin
  233.     case BAnd(BSR(eventRec.message, 24), $000000FF) of
  234.  
  235.         suspendResumeMessage:
  236.             begin
  237.             if (gCurrentNumberOfWindows > 0) then
  238.                 begin
  239.                 DrawGrowIcon(FrontWindow);
  240.                 gInBackground := boolean(BAnd(eventRec.message, resumeFlag));
  241.                 DoActivateWindow(FrontWindow, not(gInBackground));
  242.                 end;
  243.             end;
  244.         end;
  245.             {of case statement}
  246.     end;
  247.         {of procedure DoOSEvent}
  248.  
  249. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ SetStandardState }
  250.  
  251. procedure SetStandardState(myWindowPtr : WindowPtr);
  252.  
  253.     var
  254.     windowRecPtr: WindowPeek;
  255.     winStateDataPtr : WStateDataPtr;
  256.     tempRect : Rect;
  257.  
  258.     begin
  259.     tempRect := qd.screenBits.bounds;    
  260.     windowRecPtr := WindowPeek(myWindowPtr);
  261.     winStateDataPtr := WStateDataPtr(Handle(windowRecPtr^.dataHandle^));
  262.  
  263.     SetRect(winStateDataPtr^.stdState, tempRect.left + 40, tempRect.top + 60,
  264.                     tempRect.right - 40, tempRect.bottom - 40);
  265.     end;
  266.         {of procedure SetStandardState}
  267.  
  268. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoNewWindow }
  269.  
  270. procedure DoNewWindow;
  271.  
  272.     var
  273.     myWindowPtr : WindowPtr;
  274.     untitledString : string;
  275.     numberAsString : string;
  276.     titleString : string;
  277.     windowsMenu : MenuHandle;
  278.  
  279.     begin
  280.     
  281.     if (gCurrentNumberOfWindows = kMaxWindows) then
  282.         begin
  283.         DoError(eMaxWindows);
  284.         Exit(DoNewWindow);
  285.         end;
  286.         
  287.     myWindowPtr := GetNewCWindow(rNewWindow, gPreAllocatedBlockPtr, WindowPtr(-1));
  288.     if (myWindowPtr = nil) then
  289.         DoError(eFailWindow);
  290.     
  291.     gPreAllocatedBlockPtr := nil;
  292.  
  293.     GetIndString(untitledString, rStringList, sUntitled);
  294.     gUntitledWindowNumber := gUntitledWindowNumber + 1;
  295.     NumToString(gUntitledWindowNumber, numberAsString);
  296.     titleString := Concat(untitledString, numberAsString);
  297.     SetWTitle(myWindowPtr, titleString);
  298.  
  299.     SetStandardState(myWindowPtr);
  300.  
  301.     ShowWindow(myWindowPtr);
  302.  
  303.     if (gUntitledWindowNumber < 10) then
  304.         begin
  305.         untitledString := Concat(titleString, '/');
  306.         NumToString(gUntitledWindowNumber, numberAsString);
  307.         titleString := Concat(untitledString, numberAsString);
  308.         end;
  309.         
  310.     windowsMenu := GetMenu(mWindows);
  311.     InsertMenuItem(windowsMenu, titleString, CountMItems(windowsMenu));        
  312.     
  313.     SetWRefCon(myWindowPtr, gCurrentNumberOfWindows);
  314.     
  315.     gCurrentNumberOfWindows := gCurrentNumberOfWindows + 1;
  316.     gWindowPtrArray[gCurrentNumberOfWindows] := myWindowPtr;    
  317.  
  318.     if (gCurrentNumberOfWindows = 1) then
  319.         begin
  320.         EnableItem(GetMenu(mFile), iClose);
  321.         EnableItem(GetMenu(mWindows), 0);
  322.         DrawMenuBar;
  323.         end;
  324.     end;
  325.         {procedure DoNewWindow}
  326.  
  327. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoCloseWindow }
  328.  
  329. procedure DoCloseWindow;
  330.  
  331.     var
  332.     myWindowPtr : WindowPtr;
  333.     windowsMenu : MenuHandle;
  334.     a : integer;
  335.     
  336.     begin
  337.     a := 1;
  338.     
  339.     myWindowPtr := FrontWindow;
  340.     CloseWindow(myWindowPtr);
  341.     DisposePtr(Ptr(WindowPeek(myWindowPtr)));
  342.     gCurrentNumberOfWindows := gCurrentNumberOfWindows - 1;
  343.  
  344.     windowsMenu := GetMenu(mWindows);
  345.     while (gWindowPtrArray[a] <> myWindowPtr) do
  346.         a := a + 1;
  347.     gWindowPtrArray[a] := nil;
  348.     DeleteMenuItem(windowsMenu, a);
  349.  
  350.     for a := 1 to (kMaxWindows + 1) do
  351.         if (gWindowPtrArray[a] = nil) then
  352.             begin
  353.             gWindowPtrArray[a] := gWindowPtrArray[a + 1];
  354.             gWindowPtrArray[a + 1] := nil;
  355.             end;
  356.  
  357.     if (gCurrentNumberOfWindows = 0) then
  358.         begin
  359.         DisableItem(GetMenu(mFile), iClose);
  360.         DisableItem(GetMenu(mWindows), 0);
  361.         DrawMenuBar;
  362.         end;
  363.     end;
  364.         {of procedure DoCloseWindow}
  365.  
  366. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ InvalidateScrollBarArea }
  367.  
  368. procedure InvalidateScrollBarArea(myWindowPtr : WindowPtr);
  369.  
  370.     var
  371.     tempRect : Rect;
  372.     
  373.     begin
  374.     SetPort(myWindowPtr);
  375.  
  376.     tempRect := myWindowPtr^.portRect;
  377.     tempRect.left := tempRect.right - 15;
  378.     InvalRect(tempRect);
  379.  
  380.     tempRect := myWindowPtr^.portRect;
  381.     tempRect.top := tempRect.bottom - 15;
  382.     InvalRect(tempRect);
  383.     end;
  384.         {of procedure InvalidateScrollBarArea}    
  385.  
  386. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoFileMenu }
  387.  
  388. procedure DoFileMenu(menuItem : integer);
  389.  
  390.     begin
  391.     case menuItem of
  392.  
  393.         iNew:
  394.             begin
  395.             DoNewWindow;
  396.             end;
  397.         
  398.         iClose:
  399.             begin
  400.             DoCloseWindow;
  401.             end;            
  402.             
  403.         iQuit:
  404.             begin
  405.             gDone := true;
  406.             end;
  407.             
  408.         end;
  409.             {of case statement}
  410.     end;
  411.         {of procedure DoFileMenu}
  412.  
  413. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoWindowsMenu }
  414.  
  415. procedure DoWindowsMenu(menuItem : integer);
  416.  
  417.     var
  418.     myWindowPtr : WindowPtr;
  419.  
  420.     begin
  421.     myWindowPtr := gWindowPtrArray[menuItem];
  422.     SelectWindow(myWindowPtr);    
  423.     end;
  424.         {of procedure DoWindowsMenu}
  425.  
  426. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoMenuChoice }
  427.  
  428. procedure DoMenuChoice(menuChoice : longint);
  429.  
  430.     var
  431.     menuID, menuItem : integer;
  432.     itemName : string;
  433.     daDriverRefNum : integer;
  434.     
  435.     begin        
  436.     menuID := HiWord(menuChoice);
  437.     menuItem := LoWord(menuChoice);
  438.  
  439.     if (menuID = 0) then
  440.         Exit(DoMenuChoice);
  441.  
  442.     case menuID of
  443.  
  444.         mApple:
  445.             begin
  446.             if (menuItem = iAbout) 
  447.                 then     SysBeep(10)
  448.                 
  449.                 else    begin
  450.                         GetMenuItemText(GetMenuHandle(mApple), menuItem, itemName);
  451.                         daDriverRefNum := OpenDeskAcc(itemName);
  452.                         end;
  453.             end;
  454.             
  455.         mFile:
  456.             begin
  457.             DoFileMenu(menuItem);
  458.             end;
  459.             
  460.         mWindows:
  461.             begin
  462.             DoWindowsMenu(menuItem);
  463.             end;        
  464.         
  465.         end;
  466.             {of case statement}
  467.  
  468.     HiliteMenu(0);
  469.     end;
  470.         {of procedure DoMenuChoice}
  471.  
  472. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoMouseDown }
  473.  
  474. procedure DoMouseDown(eventRec : EventRecord);
  475.  
  476.     var
  477.     myWindowPtr : WindowPtr;
  478.     partCode : integer;
  479.     growRect : Rect;
  480.     newSize : longint;
  481.     
  482.     begin
  483.     partCode := FindWindow(eventRec.where, myWindowPtr);
  484.     
  485.     case partCode of
  486.  
  487.         inMenuBar:
  488.             begin
  489.             DoMenuChoice(MenuSelect(eventRec.where));
  490.             end;
  491.             
  492.         inSysWindow:
  493.             begin
  494.             SystemClick(eventRec, myWindowPtr);
  495.             end;
  496.  
  497.         inContent:
  498.             begin
  499.             if (myWindowPtr <> FrontWindow) then
  500.                 SelectWindow(myWindowPtr);
  501.             end;
  502.             
  503.         inDrag:
  504.             begin
  505.             DragWindow(WindowRef(myWindowPtr), eventRec.where, qd.screenBits.bounds);
  506.             end;
  507.  
  508.         inGoAway:
  509.             begin
  510.             if TrackGoAway(myWindowPtr, eventRec.where) then
  511.                 DoCloseWindow;
  512.             end;
  513.  
  514.         inGrow:
  515.             begin
  516.             growRect := qd.screenBits.bounds;
  517.             growRect.top := 80; 
  518.             growRect.left := 160;
  519.             newSize := GrowWindow(myWindowPtr, eventRec.where, growRect);
  520.             if (newSize <> 0) then
  521.                 begin
  522.                 InvalidateScrollBarArea(myWindowPtr);
  523.                 SizeWindow(myWindowPtr, LoWord(newSize), HiWord(newSize), true);
  524.                 InvalidateScrollBarArea(myWindowPtr);
  525.                 end;
  526.             end;
  527.  
  528.         inZoomIn, inZoomOut:
  529.             begin
  530.             if (TrackBox(myWindowPtr, eventRec.where, partCode)) then
  531.                 begin
  532.                 SetPort(myWindowPtr);
  533.                 EraseRect(myWindowPtr^.portRect);
  534.                 ZoomWindow(myWindowPtr, partCode, false);
  535.                 InvalRect(myWindowPtr^.portRect);
  536.                 end;
  537.             end;
  538.             
  539.         end;
  540.             {of case statement}
  541.     end;
  542.         {of procedure DoMouseDown}
  543.         
  544. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoEvents }
  545.  
  546. procedure DoEvents(eventRec : EventRecord);
  547.  
  548.     var
  549.     charCode : char;
  550.  
  551.     begin
  552.     case (eventRec.what) of
  553.         mouseDown:
  554.             begin
  555.             DoMouseDown(eventRec);
  556.             end;
  557.  
  558.         keyDown, autoKey:
  559.             begin
  560.             charCode := chr(BAnd(eventRec.message, charCodeMask));
  561.             if (BAnd(eventRec.modifiers, cmdKey) <> 0) then
  562.                 DoMenuChoice(MenuKey(charCode));
  563.             end;
  564.  
  565.         updateEvt:
  566.             begin
  567.             DoUpdate(eventRec);
  568.             end;
  569.  
  570.         activateEvt:
  571.             begin
  572.             DoActivate(eventRec);
  573.             end;
  574.  
  575.         osEvt:
  576.             begin
  577.             DoOSEvent(eventRec);
  578.             HiliteMenu(0);
  579.             end;
  580.         end;
  581.             {of case statement}
  582.     end;
  583.         {of procedure DoEvents}
  584. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ EventLoop }
  585.  
  586. procedure EventLoop;
  587.  
  588.     var
  589.     eventRec : EventRecord;
  590.  
  591.     begin
  592.     gDone := false;
  593.     
  594.     while (not gDone) do
  595.         begin
  596.         if (WaitNextEvent(everyEvent, eventRec, kMaxLong, nil)) then
  597.             DoEvents(eventRec);
  598.  
  599.         if (gPreAllocatedBlockPtr = nil) then
  600.             begin
  601.             gPreAllocatedBlockPtr := NewPtr(sizeof(WindowRecord));
  602.             if (gPreAllocatedBlockPtr = nil) then
  603.                 DoError(eFailMemory);
  604.             end;
  605.         end;
  606.             {of while loop}
  607.     end;
  608.         {of procedure EventLoop}
  609.                 
  610. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ start of main program }
  611.  
  612. begin
  613.  
  614.     gUntitledWindowNumber := 0;
  615.     gCurrentNumberOfWindows := 0;
  616.  
  617.     { ……………………………………………………… get nonrelocatable block low in heap for first window record }
  618.     
  619.     gPreAllocatedBlockPtr := NewPtr(sizeof(WindowRecord));
  620.     if (gPreAllocatedBlockPtr = nil) then 
  621.         DoError(eFailMemory);
  622.  
  623.     { …………………………………………………………………………………………………………………………………………………………………… initialize managers }
  624.  
  625.     DoInitManagers;
  626.  
  627.     { …………………………………………………………………………………………………………………………………………………… set up menu bar and menus }
  628.     
  629.     menubarHdl := GetNewMBar(rMenubar);
  630.     if (menubarHdl = nil) then
  631.         DoError(eFailMenus);
  632.     SetMenuBar(menubarHdl);
  633.     DrawMenuBar;
  634.  
  635.     menuHdl := GetMenuHandle(mApple);
  636.     if (menuHdl = nil) 
  637.         then DoError(eFailMenus)
  638.         else AppendResMenu(menuHdl, 'DRVR');
  639.  
  640.     { …………………………………………………………………………………………………………………………………… initialize window pointer array }
  641.  
  642.     for a := 0 to (kMaxWindows + 2) do
  643.         gWindowPtrArray[a] := nil;
  644.  
  645.     { ……………………………………………………………………………………………………………………………………………………………………………… enter eventLoop }
  646.  
  647.     EventLoop;
  648.  
  649. end.
  650.     {of program WindowsPascal}
  651.     
  652. { ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ }