IMPLEMENTATION MODULE MsgBox2; (* * REPERTOIRE * Release 1.6 * By Charles Bradford and Cole Brecheen * (c) Copyright 1985-1992 PMI * Green Bay, Wisconsin * All rights reserved * (414) 468-6040 * * $Header: D:/logfiles/mods/msgbox2.mov 1.5 10 Mar 1991 15:29:52 coleb $ * *) IMPORT ControlUtils; IMPORT DspFiles; IMPORT FramePainter; IMPORT FrameManager; IMPORT GenLists; IMPORT InputManager; IMPORT ListUtils; IMPORT M2Strings; IMPORT Numbers; IMPORT NumTypes; IMPORT PosUtils; IMPORT ScrnTypes; IMPORT ScrnUtl1; IMPORT ScrnUtl2; IMPORT SYSTEM; IMPORT VWindows; VAR Initialized : BOOLEAN; PROCEDURE Init(); BEGIN IF Initialized THEN RETURN; ELSE Initialized := TRUE; END; ControlUtils.Init(); DspFiles.Init(); FramePainter.Init(); FrameManager.Init(); GenLists.Init(); InputManager.Init(); ListUtils.Init(); M2Strings.Init(); Numbers.Init(); NumTypes.Init(); PosUtils.Init(); ScrnTypes.Init(); ScrnUtl1.Init(); ScrnUtl2.Init(); VWindows.Init(); END Init; PROCEDURE sub( n1, n2: CARDINAL ): CARDINAL; BEGIN IF n1 > n2 THEN RETURN n1 - n2; ELSE RETURN 0; END; END sub; CONST lftcol = 4; toprow = 3; rtcol = 42; btmrow = 14; midcol = 24; midrow = 9; (* These define starting points for msg box areas that we use if we can't put the box inside the current frame. *) PROCEDURE FindExteriorCoords( locatn: VWindows.Compass; ListWidth, ListHeight: CARDINAL; VAR col1, row1, col2, row2: CARDINAL ); BEGIN CASE locatn OF VWindows.West, VWindows.NW, VWindows.SW : col1 := lftcol; | VWindows.North, VWindows.South : col1 := midcol; | VWindows.East, VWindows.NE, VWindows.SE : col1 := rtcol; END; CASE locatn OF VWindows.North, VWindows.NW, VWindows.NE : row1 := toprow; | VWindows.East, VWindows.West : row1 := midrow; | VWindows.South, VWindows.SE, VWindows.SW : row1 := btmrow; END; col2 := col1 + ListWidth + 3; row2 := row1 + ListHeight + 3; END FindExteriorCoords; PROCEDURE FindBestCoords( TheFrame: ScrnTypes.DisplayFrame; locatn: VWindows.Compass; ListWidth, ListHeight : CARDINAL; VAR col1, row1, col2, row2: CARDINAL ); VAR width, height : CARDINAL; BEGIN width := TheFrame^.endcol - TheFrame^.startcol + 1; height := TheFrame^.endrow - TheFrame^.startrow + 1; CASE locatn OF VWindows.West, VWindows.NW, VWindows.SW : col1 := TheFrame^.startcol + 4; col2 := TheFrame^.startcol + (width DIV 2); | VWindows.East, VWindows.NE, VWindows.SE : col1 := sub( TheFrame^.endcol, width DIV 2 ); col2 := sub( TheFrame^.endcol, 4 ); ELSE col1 := TheFrame^.startcol + (width DIV 4); col2 := sub( TheFrame^.endcol, width DIV 4 ); END; CASE locatn OF VWindows.North, VWindows.NW, VWindows.NE : row1 := TheFrame^.startrow + 4; row2 := TheFrame^.startrow + (height DIV 2); | VWindows.South, VWindows.SE, VWindows.SW : row1 := sub( TheFrame^.endrow, height DIV 2 ); row2 := sub( TheFrame^.endrow, 4 ); ELSE row1 := TheFrame^.startrow + (height DIV 4); row2 := sub( TheFrame^.endrow, height DIV 4 ); END; IF (row1 >= row2) OR (col1 >= col2) THEN FindExteriorCoords( locatn, ListWidth, ListHeight, col1, row1, col2, row2 ); END; END FindBestCoords; PROCEDURE LstMsgBox( TheFrame: ScrnTypes.DisplayFrame; locatn : VWindows.Compass; VAR TheList: GenLists.GenList ); VAR MsgFrame: ScrnTypes.DisplayFrame; LinesAdded, BytesAdded : INTEGER; StartLine, CursorLine, CursorCol, col1, row1, col2, row2 : CARDINAL; BytePos: LONGINT; DummyName: ScrnTypes.AFrameName; BEGIN StartLine := 1; CursorLine := 1; CursorCol := 1; BytePos := NumTypes.L0; ListUtils.ReformPara( TheList, 0, 32, StartLine, CursorLine, CursorCol, LinesAdded, BytesAdded, BytePos ); (* We're reformatting twice here -- first to help us find a good location for the window, and second to determine how large the window should be. *) FindBestCoords( TheFrame, locatn, ListUtils.LongestLine(TheList), GenLists.ListLength(TheList), col1, row1, col2, row2 ); ScrnTypes.InitDisplayFrame( MsgFrame, TheFrame^.WindowHandle ); StartLine := 1; CursorLine := 1; CursorCol := 1; BytePos := NumTypes.L0; ListUtils.ReformPara( TheList, 0, (col2 - col1) - 1, StartLine, CursorLine, CursorCol, LinesAdded, BytesAdded, BytePos ); row2 := Numbers.Min( row2, row1 + GenLists.ListLength(TheList) + 1 ); row2 := Numbers.Max( row2, row1 + 3 ); (*Make sure we've got at least a two line window.*) MsgFrame^.startcol := col1; MsgFrame^.startrow := row1; MsgFrame^.endcol := col2; MsgFrame^.endrow := row2; MsgFrame^.action := 'I'; MsgFrame^.normfor := TheFrame^.msgfor; MsgFrame^.normbak := TheFrame^.msgbak; MsgFrame^.normatrb := TheFrame^.msgatrb; ScrnUtl1.SetNormalColors( MsgFrame ); ScrnUtl2.ListToFrame( TheList, MsgFrame ); FramePainter.ShowDisplayFrame( MsgFrame, 0, 0, 0, 0 ); InputManager.ControlFrame( MsgFrame, 1, '', FALSE, DummyName ); FrameManager.EraseFrame( MsgFrame ); ScrnUtl2.CloseDisplayFrame( MsgFrame ); InputManager.LookAlive( TheFrame ); END LstMsgBox; PROCEDURE StrMsgBox( TheFrame: ScrnTypes.DisplayFrame; locatn : VWindows.Compass; TheStr : ARRAY OF CHAR ); VAR TmpList: GenLists.GenList; BEGIN GenLists.NewList( TmpList ); GenLists.ListInsert( TheStr, GenLists.StrCode, TmpList, 1 ); LstMsgBox( TheFrame, locatn, TmpList ); GenLists.DisposeList( TmpList ); END StrMsgBox; PROCEDURE LstMsgBoxExterior( TheFrame: ScrnTypes.DisplayFrame; locatn : VWindows.Compass; VAR TheList: GenLists.GenList ); VAR MsgFrame: ScrnTypes.DisplayFrame; LinesAdded, BytesAdded : INTEGER; StartLine, CursorLine, CursorCol, col1, row1, col2, row2 : CARDINAL; BytePos: LONGINT; DummyName: ScrnTypes.AFrameName; BEGIN StartLine := 1; CursorLine := 1; CursorCol := 1; BytePos := NumTypes.L0; ListUtils.ReformPara( TheList, 0, 32, StartLine, CursorLine, CursorCol, LinesAdded, BytesAdded, BytePos ); (* We're reformatting twice here -- first to help us find a good location for the window, and second to determine how large the window should be. *) StartLine := 1; (* Reset StartLine because it moves to end of paragraph in ReformPara above. *) FindExteriorCoords( locatn, ListUtils.LongestLine(TheList), GenLists.ListLength(TheList), col1, row1, col2, row2 ); ScrnTypes.InitDisplayFrame( MsgFrame, TheFrame^.WindowHandle ); StartLine := 1; CursorLine := 1; CursorCol := 1; BytePos := NumTypes.L0; ListUtils.ReformPara( TheList, 0, (col2 - col1) - 1, StartLine, CursorLine, CursorCol, LinesAdded, BytesAdded, BytePos ); row2 := Numbers.Min( row2, row1 + GenLists.ListLength(TheList) + 1 ); row2 := Numbers.Max( row2, row1 + 3 ); (*Make sure we've got at least a two line window.*) MsgFrame^.startcol := col1; MsgFrame^.startrow := row1; MsgFrame^.endcol := col2; MsgFrame^.endrow := row2; MsgFrame^.action := 'I'; MsgFrame^.normfor := TheFrame^.msgfor; MsgFrame^.normbak := TheFrame^.msgbak; MsgFrame^.normatrb := TheFrame^.msgatrb; ScrnUtl1.SetNormalColors( MsgFrame ); ScrnUtl2.ListToFrame( TheList, MsgFrame ); FramePainter.ShowDisplayFrame( MsgFrame, 0, 0, 0, 0 ); InputManager.ControlFrame( MsgFrame, 1, '', FALSE, DummyName ); FrameManager.EraseFrame( MsgFrame ); ScrnUtl2.CloseDisplayFrame( MsgFrame ); InputManager.LookAlive( TheFrame ); END LstMsgBoxExterior; PROCEDURE StrMsgBoxExterior( TheFrame: ScrnTypes.DisplayFrame; locatn : VWindows.Compass; TheStr : ARRAY OF CHAR ); VAR TmpList: GenLists.GenList; BEGIN GenLists.NewList( TmpList ); GenLists.ListInsert( TheStr, GenLists.StrCode, TmpList, 1 ); LstMsgBoxExterior( TheFrame, locatn, TmpList ); GenLists.DisposeList( TmpList ); END StrMsgBoxExterior; PROCEDURE MsgOkay( TheFrame: ScrnTypes.DisplayFrame; locatn : VWindows.Compass; TheStr : ARRAY OF CHAR ): BOOLEAN; VAR TmpList: GenLists.GenList; MsgFrame: ScrnTypes.DisplayFrame; LinesAdded, BytesAdded : INTEGER; StartLine, CursorLine, CursorCol, col1, row1, col2, row2, ListEnd : CARDINAL; BytePos: LONGINT; NextFrame: ScrnTypes.AFrameName; blank: CHAR; BEGIN blank := ' '; GenLists.NewList( TmpList ); GenLists.ListInsert( TheStr, GenLists.StrCode, TmpList, 1 ); ListUtils.InsertIntoElmt( TmpList, 1, SYSTEM.ADR(blank), 1, 0 ); (* We insert a blank so that ReformPara will know to put a leading blank on each line; keeps message from crowding left edge of box. *) StartLine := 1; CursorLine := 1; CursorCol := 1; BytePos := NumTypes.L0; ListUtils.ReformPara( TmpList, 1, 32, StartLine, CursorLine, CursorCol, LinesAdded, BytesAdded, BytePos ); (* We're reformatting twice here -- first to help us find a good location for the window, and second to determine how large the window should be. *) StartLine := 1; (* Reset StartLine because it moves to end of paragraph in ReformPara above. *) FindExteriorCoords( locatn, ListUtils.LongestLine(TmpList), GenLists.ListLength(TmpList), col1, row1, col2, row2 ); ListUtils.ReformPara( TmpList, 1, (col2 - col1) - 1, StartLine, CursorLine, CursorCol, LinesAdded, BytesAdded, BytePos ); ListEnd := GenLists.ListLength(TmpList); ScrnTypes.InitDisplayFrame( MsgFrame, TheFrame^.WindowHandle ); row2 := Numbers.Min( row2, row1 + ListEnd + 3 ); row2 := Numbers.Max( row2, row1 + 3 ); (*Make sure we've got at least a two line window.*) MsgFrame^.startcol := col1; MsgFrame^.startrow := row1; MsgFrame^.endcol := col2; MsgFrame^.endrow := row2; MsgFrame^.action := 'I'; MsgFrame^.EntryBox := VWindows.SingleBox; MsgFrame^.normfor := TheFrame^.msgfor; MsgFrame^.normbak := TheFrame^.msgbak; MsgFrame^.normatrb := TheFrame^.msgatrb; ScrnUtl1.SetNormalColors( MsgFrame ); ScrnUtl2.ListToFrame( TmpList, MsgFrame ); ControlUtils.AddMenuItem( MsgFrame, 4, ListEnd + 3, 'Okay', 4, ORD('O'), 'Okay' ); ControlUtils.AddMenuItem( MsgFrame, 12, ListEnd + 3, 'Cancel', 6, ORD('C'), 'Cancel' ); FramePainter.ShowDisplayFrame( MsgFrame, 0, 0, 0, 0 ); InputManager.ControlFrame( MsgFrame, 1, '', FALSE, NextFrame ); FrameManager.EraseFrame( MsgFrame ); ScrnUtl2.CloseDisplayFrame( MsgFrame ); InputManager.LookAlive( TheFrame ); GenLists.DisposeList( TmpList ); RETURN PosUtils.Equal( NextFrame, 'Okay' ); END MsgOkay; BEGIN Initialized := FALSE; Init(); END MsgBox2.