home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
pascal
/
library
/
dos
/
ootp
/
chap07
/
mywindow.pas
< prev
Wrap
Pascal/Delphi Source File
|
1990-04-16
|
12KB
|
454 lines
unit Mywindow; { Listing 7-4 }
{$A+,B-,D+,E+,F+,I+,L+,N-,O-,R-,S+,V+}
{$M 16384,0,655360}
interface
uses Graph, ListObj, Crt, Mouse, Dos;
const
PathToDriver : string = 'C:\TP';
type
ScreenPtr = ^Screen;
GWindowPtr = ^GWindow;
Proc = procedure;
ProcPtr = ^Proc;
VPort = object
Value : ViewPortType;
procedure Init( Left, Top, Right, Bottom : integer;
ClipQ, SetQ : boolean );
procedure SetValue;
procedure GetValue( var AValue : ViewPortType );
end;
Screen = object(List)
SViewPort : VPort;
SColor : integer;
SFill : integer;
SLine : integer;
MouseToken : GWindowPtr;
MouseX : integer;
MouseY : integer;
CloseHead : boolean;
procedure Init( L,T,R,B,Color,Fill,Line : integer;
Clip : boolean );
procedure RestoreVP;
procedure UpdateMouse;
procedure DefaultMouseAction;
end;
GWindow = object(Node)
GWViewPort : VPort;
WindName : string;
BelowGWArea : pointer;
BelowGWSize : word;
GWFillS : integer;
GWFillC : integer;
GWColor1 : integer;
ParentScr : ScreenPtr;
constructor Init( FillStyle, FillColor, BColor1 : integer;
PScreen : ScreenPtr; WLabel : string );
destructor Done;
procedure PrependToList( var AList : List );
function InboundMouse : boolean;
procedure MouseAction;
procedure LocalMouseCoords( var x, y : integer );
end;
procedure mstart;
procedure EntryPoint;
procedure SetMouseHandler( mask : integer );
var
S,T : Screen;
GraphDriver, Graphmode : integer;
implementation
var
xpos, ypos : integer;
ConMask : integer;
index : integer;
function FindAll( pNode : pointer ) : boolean;
begin
FindAll := true;
end;
function FindMouse( ANode : pointer ) : boolean;
var pGW : GWindowPtr;
begin
pGW := ANode;
if pGW^.InBoundMouse = true then
begin
pGW^.ParentScr^.MouseToken := pGW;
FindMouse := true;
end
else
FindMouse := false;
end;
{$L MTEST5.OBJ}
{$F-}
procedure mstart; external;
{$F+}
procedure SetMouseHandler( mask : integer );
var R : registers;
begin
R.AX := $C;
R.BX := $0;
R.CX := mask;
R.DX := Ofs(mstart);
R.ES := Seg(mstart);
Intr( $33, R );
end;
procedure Screen.Init( L,T,R,B,Color,Fill,Line : integer;
Clip : boolean );
var
UMP : array[0..3] of byte;
a,c : word;
UMPDest : pointer;
i : integer;
begin
List.Init; {Initialize the list part of the Screen object }
{ Initialize the mouse and set the mouse handler with all bits in }
{ the condition mask set }
FindObjectDemon := FindMouse;
{ The mouse shall look like an arrow. }
{MouseArrowCursor;}
SViewPort.Init( L, T, R, B, Clip, true );
if MouseInit = true then SetMouseHandler( 30 );
{ should be 30 if you don't want to track movement; 31 if you do }
SColor := Color;
SFill := Fill;
SLine := Line;
CloseHead := false;
SetFillStyle( Fill, Color );
SetLineStyle( Line, 0, white );
bar( L, T, R, B );
MouseToken := nil;
MouseShow;
end;
procedure Screen.DefaultMouseAction;
var
pNewWindow : GWindowPtr;
begin
SetMouseHandler(0);
if MouseRPressed = true then
begin
sound(300);delay(40);nosound;
New(pNewWindow,
Init( solidfill, blue, white, @S, 'Window #'));
end;
SetMouseHandler(30);
end;
procedure Screen.RestoreVP; {restores the screen's viewport }
begin
SViewPort.SetValue;
end;
{ The handler set in Screen.Init calls this function. Anytime the
mouse moves or if any buttons are pushed, this routine gets called. }
procedure Screen.UpdateMouse;
var
VP :ViewPortType;
begin
if FindObject = true then
begin
GetViewSettings(VP);
MouseToken := GetCursor;
MouseToken^.GWViewPort.SetValue;
MouseToken^.MouseAction;
with VP do
SetViewPort( x1, y1, x2, y2, true );
if CloseHead = true then { if top window requests closing }
begin
MouseToken := PopFirst;
Dispose(MouseToken,Done); { Close the window }
CloseHead := false; { reset request flag }
end;
end
else
DefaultMouseAction;
end;
procedure GetGWCoords( var x1, y1, x2, y2 : integer);
var t, a1, a2, b1, b2 : integer;
color : word;
P : array[0..4] of pointer;
LS : LineSettingsType;
function Max( x, y : integer ): integer;
begin
if x > y then Max := x else Max := y;
end;
function Min( x, y : integer) : integer;
begin
if x < y then Min := x else Min := y;
end;
procedure Shadow( x1, y1, x2, y2 : integer );
begin
Mark(P[0]);
GetMem( P[1], ImageSize( x1, y1, x2, y1) );
GetImage( x1, y1, x2, y1, P[1]^ ); { top }
GetMem( P[2], ImageSize( x2, y2, x2, y1) );
GetImage( x2, y2, x2, y1, P[2]^ ); {right}
GetMem( P[3], ImageSize( x1, y1, x1, y2) );
GetImage( x1, y1, x1, y2, P[3]^ ); { left }
GetMem( P[4], ImageSize( x1, y2, x2, y2) );
GetImage( x1, y2, x2, y2, P[4]^ ); {bottom }
Rectangle( x1, y1, x2, y2 );
PutImage( Min(x1, x2), y1, P[1]^, NormalPut );
PutImage( x2, Min( y1, y2 ), P[2]^, NormalPut );
PutImage( x1, Min( y1, y2), P[3]^, NormalPut );
PutImage( Min(x1,x2), y2, P[4]^, NormalPut );
Release(P[0]);
end;
begin
MouseCoords( x1, y1); {grab the x,y coordinates!}
repeat
until MouseLPressed = true;
MouseHide;
repeat
MouseCoords(x2,y2);
Shadow(x1, y1, x2, y2);
until MouseLReleased = true;
if x1 > x2 then begin
t := x1;
x1 := x2;
x2 := t;
end;
if y1 > y2 then begin
t := y1;
y1 := y2;
y2 := t;
end;
end;
constructor GWindow.Init( FillStyle, FillColor,
BColor1 : integer;
PScreen : ScreenPtr; WLabel : string );
var OldVPort : VPort;
OldColor : integer;
OldFill : FillSettingsType;
L, T, R, B : integer;
srg : string;
function SaveArea( L, T, R, B : integer ) : boolean;
begin
BelowGWSize := ImageSize( L, T, R, B);
GetMem( BelowGWArea, BelowGWSize );
if (BelowGWArea = nil) or (BelowGWSize < 255) then
SaveArea := false
else begin
GetImage( L, T, R, B, BelowGWArea^ );
SaveArea := true;
end;
end;
procedure AdrToHexStr( Adr : pointer; var s : string );
var
r : array[1..9] of byte;
tmp : word;
i : integer;
begin
tmp := Seg( Adr^ );
r[4] := (tmp and $F);
r[3] := (tmp and $F0) shr 4;
r[2] := (tmp and $F00) shr 8;
r[1] := (tmp and $F000) shr 12;
tmp := Ofs( Adr^ );
r[9] := (tmp and $F);
r[8] := (tmp and $F0) shr 4;
r[7] := (tmp and $F00) shr 8;
r[6] := (tmp and $F000) shr 12;
r[5] := 0;
for i := 1 to 9 do
if r[i] < 10 then
s[i] := Chr($30 + r[i])
else
s[i] := Chr($37 + r[i]);
s[5] := ':';
s[0] := Chr(9);
end;
begin
Node.Init( SizeOf( Self ) );
GetFillSettings( OldFill );
GWFillS := FillStyle; { Save fill style }
GWFillC := FillColor;
GWColor1 := BColor1; { Save primary fill color }
Str( index, srg );
Windname := WLabel+srg;
Inc(index);
OldColor := GetColor;
ParentScr := PScreen; { Save pointer to parent screen }
GetViewSettings(OldVPort.Value);
ParentScr^.RestoreVP; { Restore parent screen viewport }
GetGWCoords( L, T, R, B );
if not SaveArea( L, T, R, B ) then
begin
sound(600);delay(100);nosound;
OldVPort.SetValue;
MoveTo( 0,0 );
GWindow.Done;
MouseShow;
fail;
end
else
begin
SetColor(GWColor1); { set window's color }
SetFillStyle(GWFillS,GWFillC); { set window's fill data }
SetLineStyle(Solidln,0,NormWidth); { set generic line style }
Bar3D( L, T, R, B, 0, false ); { draw window }
Line( L, T+(2*TextHeight(WindName)), R, T+(2*TextHeight(WindName)) );
GWViewPort.Init( L, T, R, B, true, true ); { store & set }
SetTextJustify( CenterText, CenterText );
OutTextXY( Round((R-L)/2), TextHeight(WindName), WindName);
AdrToHexStr(HeapPtr, srg);
OutTextXY( Round((R-L)/2), Round((B-T)/2), srg );
Str(BelowGWSize, srg);
OutTextXY( 40, 40, srg );
PrependToList( ParentScr^ ); { add this window to screen's tally }
SetColor( OldColor ); { restore old color... }
SetFillStyle( OldFill.Pattern, OldFill.Color ); { ...and fill }
end;
{MouseArrowCursor;}
MouseShow;
end;
destructor GWindow.Done;
begin
GWViewPort.SetValue;
MouseHide;
if BelowGWArea <> nil then
begin
PutImage(0,0,BelowGWArea^,CopyPut);
FreeMem( BelowGWArea, BelowGWSize );
end;
MouseShow;
end;
function GWindow.InboundMouse : boolean;
begin
if (GWViewPort.Value.x1 <= ParentScr^.MouseX) and
(GWViewPort.Value.x2 >= ParentScr^.MouseX) and
(GWViewPort.Value.y1 <= ParentScr^.MouseY) and
(GWViewPort.Value.y2 >= ParentScr^.MouseY) then
InboundMouse := true
else
InboundMouse := false;
end;
procedure GWindow.PrependToList( var AList : List );
begin
Node.PrependToList( AList );
MouseShow;
end;
procedure GWindow.LocalMouseCoords( var x, y : integer );
var
VP :ViewPortType;
begin
GWViewPort.GetValue(VP);
MouseCoords( x, y );
ParentScr^.MouseX := x;
ParentScr^.MouseY := y;
with VP do
begin
x := x - x1;
y := y - y1;
end;
end;
procedure GWindow.MouseAction;
var
x,y :integer;
str : string;
begin
while MouseLPressed = true do
begin
LocalMouseCoords(x,y);
MouseHide;
if (ParentScr^.FindObject = true) then
begin
if @Self = ParentScr^.MouseToken then
begin
PutPixel(x,y,white);
end;
end;
MouseShow;
end;
while MouseRPressed = true do
begin
sound(400);delay(100); nosound;
if @Self = ParentScr^.Head then
ParentScr^.CloseHead := true;
end;
end;
procedure VPort.Init( Left, Top, Right, Bottom : integer;
ClipQ, SetQ : boolean );
begin
Value.x1 := Left;
Value.y1 := Top;
Value.x2 := Right;
Value.y2 := Bottom;
Value.Clip := ClipQ;
if SetQ = true then
SetValue;
end;
procedure VPort.SetValue;
begin
SetViewPort( Value.x1, Value.y1, Value.x2, Value.y2, Value.Clip );
end;
procedure VPort.GetValue( var AValue : ViewPortType );
begin
GetViewSettings( AValue );
end;
{$F+}
procedure EntryPoint;
{$F-}
begin
S.MouseX := xpos;
S.MouseY := ypos;
S.UpdateMouse;
end;
{$F+}
function HeapFunc( size : word ) : integer;
{$F-}
begin
HeapFunc := 1;
end;
begin
HeapError := @HeapFunc;
index := 1;
GraphDriver := Detect; { Detect the graphics driver }
InitGraph( GraphDriver, GraphMode, PathToDriver ); { Initialize graphics }
S.Init( 0, 0, GetMaxX, GetMaxY, cyan, solidfill, solidln, true );
end.