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 >
Wrap
Text File
|
1999-04-05
|
15KB
|
652 lines
{ ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊
// WindowsPascal.p
// ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊
//
// This program:
//
// • Allows the user to open any number of zoomDocProc windows, up to the maximum
// specified in the global variable kMaxWindows, using the File menu Open Command or
// its keyboard equivalent.
//
// • Allows the user to close opened windows using the close box, the File menu Close
// command or the Close command's keyboard equivalent.
//
// • Adds menu items representing each window to a Windows menu as each window is
// opened (A keyboard equivalent is included in each menu item for windows 1 to 9.)
//
// • Deletes menu items from the Windows menu as each window is closed.
//
// • Fills each window with one of the system patterns as a means of proving, for
// demonstration purposes, the window update process.
//
// • Facilitates activation of a window by mouse selection.
//
// • Facilitates activation of a window by Windows menu selection.
//
// • Correctly performs all dragging, zooming and sizing operations.
//
// The program utilizes the following resources:
//
// • An 'MBAR' resource, and 'MENU' resources for Apple, File, Edit and Windows menus
// (preload, non-purgeable).
//
// • A 'WIND' resource (purgeable) (initially not visible).
//
// • An 'ALRT' resource and 'DITL' resource for use by Stop Alerts (purgeable).
//
// • A 'STR#' resource containing strings for the Stop Alerts (purgeable).
//
// • A 'SIZE' resource with the acceptSuspendResumeEvents and doesActivateOnFGSwitch
// flags set.
//
// ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ }
program WindowsPascal(input, output);
{ ………………………………………………………………………………………………………………… include the following Universal Interfaces }
uses
Windows, Fonts, Menus, TextEdit, Quickdraw, Dialogs, QuickdrawText, Processes, Types,
Memory, Events, TextUtils, ToolUtils, OSUtils, Devices, Segload, Sound;
{ ………………………………………………………………………………………………………………………………………………… define the following constants }
const
mApple = 128;
iAbout = 1;
mFile = 129;
mEdit = 130;
iNew = 1;
iClose = 4;
iQuit = 11;
mWindows = 131;
rNewWindow = 128;
rMenubar = 128;
rAlertBox = 128;
rStringList = 128;
sUntitled = 1;
eMaxWindows = 2;
eFailWindow = 3;
eFailMenus = 4;
eFailMemory = 5;
kMaxWindows = 10;
kMaxLong = $7FFFFFFF;
{ ……………………………………………………………………………………………………………………………………………………………………………………… global variables }
var
gDone : Boolean;
gInBackground : Boolean;
gPreAllocatedBlockPtr : Ptr;
gUntitledWindowNumber : longint;
gCurrentNumberOfWindows : longint;
gWindowPtrArray : array [0..kMaxWindows + 2] of WindowPtr;
menubarHdl : Handle;
menuHdl : MenuHandle;
a : integer;
{ ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoInitManagers }
procedure DoInitManagers;
begin
MaxApplZone;
MoreMasters;
MoreMasters;
InitGraf(@qd.thePort);
InitFonts;
InitWindows;
InitMenus;
TEInit;
InitDialogs(nil);
InitCursor;
FlushEvents(everyEvent, 0);
end;
{of procedure DoInitManagers}
{ ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoError }
procedure DoError(errorType : integer);
var
errorMessage : string;
ignored : integer;
begin
GetIndString(errorMessage, rStringList, errorType);
ParamText(errorMessage, '', '', '');
if (errorType = eMaxWindows)
then ignored := CautionAlert(rAlertBox, nil)
else begin
ignored := StopAlert(rAlertBox, nil);
ExitToShell;
end;
end;
{of procedure DoError}
{ ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoUpDateWindow }
procedure DoUpdateWindow(eventRec : EventRecord);
var
myWindowPtr : WindowPtr;
paintRect : Rect;
windowRefCon : longint;
fillPattern : Pattern;
begin
myWindowPtr := WindowPtr(eventRec.message);
SetPort(myWindowPtr);
paintRect := myWindowPtr^.portRect;
paintRect.right := paintRect.right - 15;
paintRect.bottom := paintRect.bottom - 15;
windowRefCon := GetWRefCon(myWindowPtr);
GetIndPattern(fillPattern, 0, windowRefCon + 9);
FillRect(paintRect, fillPattern);
end;
{of procedure DoUpdateWindow}
{ ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoUpdate }
procedure DoUpdate(eventRec : EventRecord);
var
myWindowPtr : WindowPtr;
begin
myWindowPtr := WindowPtr(eventRec.message);
BeginUpdate(myWindowPtr);
if not (EmptyRgn(myWindowPtr^.visRgn)) then
begin
SetPort(myWindowPtr);
EraseRgn(myWindowPtr^.visRgn);
DoUpdateWindow(eventRec);
DrawGrowIcon(myWindowPtr);
end;
EndUpdate(myWindowPtr);
end;
{of procedure DoUpdate}
{ ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoActivateWindow }
procedure DoActivateWindow(myWindowPtr : WindowPtr; becomingActive : Boolean);
var
windowsMenu : MenuHandle;
menuItem, a : integer;
begin
a := 1;
windowsMenu := GetMenuHandle(mWindows);
while (gWindowPtrArray[a] <> myWindowPtr) do
a := a + 1;
menuItem := a;
if (becomingActive)
then CheckItem(windowsMenu, menuItem, true)
else CheckItem(windowsMenu, menuItem, false);
DrawGrowIcon(myWindowPtr);
end;
{of procedure DoActivateWindow}
{ ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoActivate }
procedure DoActivate(eventRec : EventRecord);
var
myWindowPtr : WindowPtr;
becomingActive : Boolean;
begin
myWindowPtr := WindowPtr(eventRec.message);
becomingActive := boolean(BAnd(eventRec.modifiers, activeFlag) <> 0);
DoActivateWindow(myWindowPtr, becomingActive);
end;
{of procedure DoActivate}
{ ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoOSEvent }
procedure DoOSEvent(eventRec : EventRecord);
begin
case BAnd(BSR(eventRec.message, 24), $000000FF) of
suspendResumeMessage:
begin
if (gCurrentNumberOfWindows > 0) then
begin
DrawGrowIcon(FrontWindow);
gInBackground := boolean(BAnd(eventRec.message, resumeFlag));
DoActivateWindow(FrontWindow, not(gInBackground));
end;
end;
end;
{of case statement}
end;
{of procedure DoOSEvent}
{ ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ SetStandardState }
procedure SetStandardState(myWindowPtr : WindowPtr);
var
windowRecPtr: WindowPeek;
winStateDataPtr : WStateDataPtr;
tempRect : Rect;
begin
tempRect := qd.screenBits.bounds;
windowRecPtr := WindowPeek(myWindowPtr);
winStateDataPtr := WStateDataPtr(Handle(windowRecPtr^.dataHandle^));
SetRect(winStateDataPtr^.stdState, tempRect.left + 40, tempRect.top + 60,
tempRect.right - 40, tempRect.bottom - 40);
end;
{of procedure SetStandardState}
{ ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoNewWindow }
procedure DoNewWindow;
var
myWindowPtr : WindowPtr;
untitledString : string;
numberAsString : string;
titleString : string;
windowsMenu : MenuHandle;
begin
if (gCurrentNumberOfWindows = kMaxWindows) then
begin
DoError(eMaxWindows);
Exit(DoNewWindow);
end;
myWindowPtr := GetNewCWindow(rNewWindow, gPreAllocatedBlockPtr, WindowPtr(-1));
if (myWindowPtr = nil) then
DoError(eFailWindow);
gPreAllocatedBlockPtr := nil;
GetIndString(untitledString, rStringList, sUntitled);
gUntitledWindowNumber := gUntitledWindowNumber + 1;
NumToString(gUntitledWindowNumber, numberAsString);
titleString := Concat(untitledString, numberAsString);
SetWTitle(myWindowPtr, titleString);
SetStandardState(myWindowPtr);
ShowWindow(myWindowPtr);
if (gUntitledWindowNumber < 10) then
begin
untitledString := Concat(titleString, '/');
NumToString(gUntitledWindowNumber, numberAsString);
titleString := Concat(untitledString, numberAsString);
end;
windowsMenu := GetMenu(mWindows);
InsertMenuItem(windowsMenu, titleString, CountMItems(windowsMenu));
SetWRefCon(myWindowPtr, gCurrentNumberOfWindows);
gCurrentNumberOfWindows := gCurrentNumberOfWindows + 1;
gWindowPtrArray[gCurrentNumberOfWindows] := myWindowPtr;
if (gCurrentNumberOfWindows = 1) then
begin
EnableItem(GetMenu(mFile), iClose);
EnableItem(GetMenu(mWindows), 0);
DrawMenuBar;
end;
end;
{procedure DoNewWindow}
{ ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoCloseWindow }
procedure DoCloseWindow;
var
myWindowPtr : WindowPtr;
windowsMenu : MenuHandle;
a : integer;
begin
a := 1;
myWindowPtr := FrontWindow;
CloseWindow(myWindowPtr);
DisposePtr(Ptr(WindowPeek(myWindowPtr)));
gCurrentNumberOfWindows := gCurrentNumberOfWindows - 1;
windowsMenu := GetMenu(mWindows);
while (gWindowPtrArray[a] <> myWindowPtr) do
a := a + 1;
gWindowPtrArray[a] := nil;
DeleteMenuItem(windowsMenu, a);
for a := 1 to (kMaxWindows + 1) do
if (gWindowPtrArray[a] = nil) then
begin
gWindowPtrArray[a] := gWindowPtrArray[a + 1];
gWindowPtrArray[a + 1] := nil;
end;
if (gCurrentNumberOfWindows = 0) then
begin
DisableItem(GetMenu(mFile), iClose);
DisableItem(GetMenu(mWindows), 0);
DrawMenuBar;
end;
end;
{of procedure DoCloseWindow}
{ ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ InvalidateScrollBarArea }
procedure InvalidateScrollBarArea(myWindowPtr : WindowPtr);
var
tempRect : Rect;
begin
SetPort(myWindowPtr);
tempRect := myWindowPtr^.portRect;
tempRect.left := tempRect.right - 15;
InvalRect(tempRect);
tempRect := myWindowPtr^.portRect;
tempRect.top := tempRect.bottom - 15;
InvalRect(tempRect);
end;
{of procedure InvalidateScrollBarArea}
{ ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoFileMenu }
procedure DoFileMenu(menuItem : integer);
begin
case menuItem of
iNew:
begin
DoNewWindow;
end;
iClose:
begin
DoCloseWindow;
end;
iQuit:
begin
gDone := true;
end;
end;
{of case statement}
end;
{of procedure DoFileMenu}
{ ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoWindowsMenu }
procedure DoWindowsMenu(menuItem : integer);
var
myWindowPtr : WindowPtr;
begin
myWindowPtr := gWindowPtrArray[menuItem];
SelectWindow(myWindowPtr);
end;
{of procedure DoWindowsMenu}
{ ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoMenuChoice }
procedure DoMenuChoice(menuChoice : longint);
var
menuID, menuItem : integer;
itemName : string;
daDriverRefNum : integer;
begin
menuID := HiWord(menuChoice);
menuItem := LoWord(menuChoice);
if (menuID = 0) then
Exit(DoMenuChoice);
case menuID of
mApple:
begin
if (menuItem = iAbout)
then SysBeep(10)
else begin
GetMenuItemText(GetMenuHandle(mApple), menuItem, itemName);
daDriverRefNum := OpenDeskAcc(itemName);
end;
end;
mFile:
begin
DoFileMenu(menuItem);
end;
mWindows:
begin
DoWindowsMenu(menuItem);
end;
end;
{of case statement}
HiliteMenu(0);
end;
{of procedure DoMenuChoice}
{ ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoMouseDown }
procedure DoMouseDown(eventRec : EventRecord);
var
myWindowPtr : WindowPtr;
partCode : integer;
growRect : Rect;
newSize : longint;
begin
partCode := FindWindow(eventRec.where, myWindowPtr);
case partCode of
inMenuBar:
begin
DoMenuChoice(MenuSelect(eventRec.where));
end;
inSysWindow:
begin
SystemClick(eventRec, myWindowPtr);
end;
inContent:
begin
if (myWindowPtr <> FrontWindow) then
SelectWindow(myWindowPtr);
end;
inDrag:
begin
DragWindow(WindowRef(myWindowPtr), eventRec.where, qd.screenBits.bounds);
end;
inGoAway:
begin
if TrackGoAway(myWindowPtr, eventRec.where) then
DoCloseWindow;
end;
inGrow:
begin
growRect := qd.screenBits.bounds;
growRect.top := 80;
growRect.left := 160;
newSize := GrowWindow(myWindowPtr, eventRec.where, growRect);
if (newSize <> 0) then
begin
InvalidateScrollBarArea(myWindowPtr);
SizeWindow(myWindowPtr, LoWord(newSize), HiWord(newSize), true);
InvalidateScrollBarArea(myWindowPtr);
end;
end;
inZoomIn, inZoomOut:
begin
if (TrackBox(myWindowPtr, eventRec.where, partCode)) then
begin
SetPort(myWindowPtr);
EraseRect(myWindowPtr^.portRect);
ZoomWindow(myWindowPtr, partCode, false);
InvalRect(myWindowPtr^.portRect);
end;
end;
end;
{of case statement}
end;
{of procedure DoMouseDown}
{ ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ DoEvents }
procedure DoEvents(eventRec : EventRecord);
var
charCode : char;
begin
case (eventRec.what) of
mouseDown:
begin
DoMouseDown(eventRec);
end;
keyDown, autoKey:
begin
charCode := chr(BAnd(eventRec.message, charCodeMask));
if (BAnd(eventRec.modifiers, cmdKey) <> 0) then
DoMenuChoice(MenuKey(charCode));
end;
updateEvt:
begin
DoUpdate(eventRec);
end;
activateEvt:
begin
DoActivate(eventRec);
end;
osEvt:
begin
DoOSEvent(eventRec);
HiliteMenu(0);
end;
end;
{of case statement}
end;
{of procedure DoEvents}
{ ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ EventLoop }
procedure EventLoop;
var
eventRec : EventRecord;
begin
gDone := false;
while (not gDone) do
begin
if (WaitNextEvent(everyEvent, eventRec, kMaxLong, nil)) then
DoEvents(eventRec);
if (gPreAllocatedBlockPtr = nil) then
begin
gPreAllocatedBlockPtr := NewPtr(sizeof(WindowRecord));
if (gPreAllocatedBlockPtr = nil) then
DoError(eFailMemory);
end;
end;
{of while loop}
end;
{of procedure EventLoop}
{ ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ start of main program }
begin
gUntitledWindowNumber := 0;
gCurrentNumberOfWindows := 0;
{ ……………………………………………………… get nonrelocatable block low in heap for first window record }
gPreAllocatedBlockPtr := NewPtr(sizeof(WindowRecord));
if (gPreAllocatedBlockPtr = nil) then
DoError(eFailMemory);
{ …………………………………………………………………………………………………………………………………………………………………… initialize managers }
DoInitManagers;
{ …………………………………………………………………………………………………………………………………………………… set up menu bar and menus }
menubarHdl := GetNewMBar(rMenubar);
if (menubarHdl = nil) then
DoError(eFailMenus);
SetMenuBar(menubarHdl);
DrawMenuBar;
menuHdl := GetMenuHandle(mApple);
if (menuHdl = nil)
then DoError(eFailMenus)
else AppendResMenu(menuHdl, 'DRVR');
{ …………………………………………………………………………………………………………………………………… initialize window pointer array }
for a := 0 to (kMaxWindows + 2) do
gWindowPtrArray[a] := nil;
{ ……………………………………………………………………………………………………………………………………………………………………………… enter eventLoop }
EventLoop;
end.
{of program WindowsPascal}
{ ◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊◊ }