home *** CD-ROM | disk | FTP | other *** search
- {************************************************}
- { }
- { Turbo Pascal 6.0 }
- { Turbo Vision Demo }
- { Copyright (c) 1990 by Borland International }
- { }
- {************************************************}
-
- UNIT HelpFile;
-
- {$F+,O+,X+,S-,D-}
-
- INTERFACE
-
- USES Objects, Drivers, Views;
-
- CONST
- CHelpColor = #$37#$3F#$3A#$13#$13#$30#$3E#$1E;
- CHelpBlackWhite = #$07#$0F#$07#$70#$70#$07#$0F#$70;
- CHelpMonochrome = #$07#$0F#$07#$70#$70#$07#$0F#$70;
- CHelpViewer = #6#7#8;
- CHelpWindow = #64#65#66#67#68#69#70#71;
-
- TYPE
-
- { TParagraph }
-
- PParagraph = ^TParagraph;
- TParagraph = RECORD
- Next : PParagraph;
- Wrap : BOOLEAN;
- Size : WORD;
- TEXT : RECORD END;
- END;
-
- { THelpTopic }
-
- TCrossRef = RECORD
- Ref : INTEGER;
- Offset : INTEGER;
- LENGTH : BYTE;
- END;
-
- PCrossRefs = ^TCrossRefs;
- TCrossRefs = ARRAY[1..10000] OF TCrossRef;
- TCrossRefHandler = PROCEDURE(VAR S : TStream; XRefValue : INTEGER);
-
- PHelpTopic = ^THelpTopic;
- THelpTopic = OBJECT(TObject)
- CONSTRUCTOR Init;
- CONSTRUCTOR Load(VAR S : TStream);
- DESTRUCTOR Done; VIRTUAL;
- PROCEDURE AddCrossRef(Ref : TCrossRef);
- PROCEDURE AddParagraph(P : PParagraph);
- PROCEDURE GetCrossRef(I : INTEGER; VAR Loc : TPoint; VAR LENGTH : BYTE;
- VAR Ref : INTEGER);
- FUNCTION GetLine(Line : INTEGER) : STRING;
- FUNCTION GetNumCrossRefs : INTEGER;
- FUNCTION NumLines : INTEGER;
- PROCEDURE SetCrossRef(I : INTEGER; VAR Ref : TCrossRef);
- PROCEDURE SetNumCrossRefs(I : INTEGER);
- PROCEDURE SetWidth(AWidth : INTEGER);
- PROCEDURE Store(VAR S : TStream);
- PRIVATE
- Paragraphs : PParagraph;
- NumRefs : INTEGER;
- CrossRefs : PCrossRefs;
- Width : INTEGER;
- LastOffset : INTEGER;
- LastLine : INTEGER;
- LastParagraph : PParagraph;
- FUNCTION WrapText(VAR TEXT; Size : INTEGER; VAR Offset : INTEGER;
- Wrap : BOOLEAN) : STRING;
- END;
-
- { THelpIndex }
-
- PIndexArray = ^TIndexArray;
- TIndexArray = ARRAY[0..16380] OF LONGINT;
-
- PHelpIndex = ^THelpIndex;
- THelpIndex = OBJECT(TObject)
- Size : WORD;
- Index : PIndexArray;
- CONSTRUCTOR Init;
- CONSTRUCTOR Load(VAR S : TStream);
- DESTRUCTOR Done; VIRTUAL;
- FUNCTION Position(I : INTEGER) : LONGINT;
- PROCEDURE Add(I : INTEGER; VAL : LONGINT);
- PROCEDURE Store(VAR S : TStream);
- END;
-
- { THelpFile }
-
- PHelpFile = ^THelpFile;
- THelpFile = OBJECT(TObject)
- Stream : PStream;
- Modified : BOOLEAN;
- CONSTRUCTOR Init(S : PStream);
- DESTRUCTOR Done; VIRTUAL;
- FUNCTION GetTopic(I : INTEGER) : PHelpTopic;
- FUNCTION InvalidTopic : PHelpTopic;
- PROCEDURE RecordPositionInIndex(I : INTEGER);
- PROCEDURE PutTopic(Topic : PHelpTopic);
- PRIVATE
- Index : PHelpIndex;
- IndexPos : LONGINT;
- END;
-
- { THelpViewer }
-
- PHelpViewer = ^THelpViewer;
- THelpViewer = OBJECT(TScroller)
- HFile : PHelpFile;
- Topic : PHelpTopic;
- Selected : INTEGER;
- CONSTRUCTOR Init(VAR Bounds : TRect; AHScrollBar,
- AVScrollBar : PScrollBar; AHelpFile : PHelpFile; Context : WORD);
- DESTRUCTOR Done; VIRTUAL;
- PROCEDURE ChangeBounds(VAR Bounds : TRect); VIRTUAL;
- PROCEDURE Draw; VIRTUAL;
- FUNCTION GetPalette : PPalette; VIRTUAL;
- PROCEDURE HandleEvent(VAR Event : TEvent); VIRTUAL;
- END;
-
- { THelpWindow }
-
- PHelpWindow = ^THelpWindow;
- THelpWindow = OBJECT(TWindow)
- CONSTRUCTOR Init(HFile : PHelpFile; Context : WORD);
- FUNCTION GetPalette : PPalette; VIRTUAL;
- END;
-
- CONST
-
- RHelpTopic : TStreamRec = (
- ObjType : 10000;
- VmtLink : OFS(TypeOf(THelpTopic)^);
- Load : @THelpTopic.Load;
- Store : @THelpTopic.Store
- );
- RHelpIndex : TStreamRec = (
- ObjType : 10001;
- VmtLink : OFS(TypeOf(THelpIndex)^);
- Load : @THelpIndex.Load;
- Store : @THelpIndex.Store
- );
-
- PROCEDURE RegisterHelpFile;
-
- PROCEDURE NotAssigned(VAR S : TStream; Value : INTEGER);
-
- CONST
- CrossRefHandler : TCrossRefHandler = NotAssigned;
-
- IMPLEMENTATION
-
- { THelpTopic }
-
- CONSTRUCTOR THelpTopic.Init;
- BEGIN
- TObject.Init;
- LastLine := MAXINT;
- END;
-
- CONSTRUCTOR THelpTopic.Load(VAR S : TStream);
-
- PROCEDURE ReadParagraphs;
- VAR
- I, Size : INTEGER;
- PP : ^PParagraph;
- BEGIN
- S.READ(I, SIZEOF(I));
- PP := @Paragraphs;
- WHILE I > 0 DO
- BEGIN
- S.READ(Size, SIZEOF(Size));
- GETMEM(PP^, SIZEOF(PP^^)+Size);
- PP^^.Size := Size;
- S.READ(PP^^.Wrap, SIZEOF(BOOLEAN));
- S.READ(PP^^.TEXT, Size);
- PP := @PP^^.Next;
- DEC(I);
- END;
- PP^ := NIL;
- END;
-
- PROCEDURE ReadCrossRefs;
- BEGIN
- S.READ(NumRefs, SIZEOF(INTEGER));
- GETMEM(CrossRefs, SIZEOF(TCrossRef)*NumRefs);
- S.READ(CrossRefs^, SIZEOF(TCrossRef)*NumRefs);
- END;
-
- BEGIN
- ReadParagraphs;
- ReadCrossRefs;
- Width := 0;
- LastLine := MAXINT;
- END;
-
- DESTRUCTOR THelpTopic.Done;
-
- PROCEDURE DisposeParagraphs;
- VAR
- P, T : PParagraph;
- BEGIN
- P := Paragraphs;
- WHILE P <> NIL DO
- BEGIN
- T := P;
- P := P^.Next;
- FREEMEM(T, SIZEOF(T^)+T^.Size);
- END;
- END;
-
- BEGIN
- DisposeParagraphs;
- FREEMEM(CrossRefs, SIZEOF(TCrossRef)*NumRefs);
- TObject.Done
- END;
-
- PROCEDURE THelpTopic.AddCrossRef(Ref : TCrossRef);
- VAR
- P : PCrossRefs;
- BEGIN
- GETMEM(P, (NumRefs+1)*SIZEOF(TCrossRef));
- IF NumRefs > 0 THEN
- BEGIN
- MOVE(CrossRefs^, P^, NumRefs*SIZEOF(TCrossRef));
- FREEMEM(CrossRefs, NumRefs*SIZEOF(TCrossRef));
- END;
- CrossRefs^[NumRefs] := Ref;
- INC(NumRefs);
- END;
-
- PROCEDURE THelpTopic.AddParagraph(P : PParagraph);
- VAR
- PP : ^PParagraph;
- BEGIN
- PP := @Paragraphs;
- WHILE PP^ <> NIL DO
- PP := @PP^^.Next;
- PP^ := P;
- P^.Next := NIL;
- END;
-
- PROCEDURE THelpTopic.GetCrossRef(I : INTEGER; VAR Loc : TPoint;
- VAR LENGTH : BYTE; VAR Ref : INTEGER);
- VAR
- OldOffset, CurOffset, Offset, ParaOffset : INTEGER;
- P : PParagraph;
- Line : INTEGER;
- BEGIN
- ParaOffset := 0;
- CurOffset := 0;
- OldOffset := 0;
- Line := 0;
- Offset := CrossRefs^[I].Offset;
- P := Paragraphs;
- WHILE ParaOffset+CurOffset < Offset DO
- BEGIN
- OldOffset := ParaOffset+CurOffset;
- WrapText(P^.TEXT, P^.Size, CurOffset, P^.Wrap);
- INC(Line);
- IF CurOffset >= P^.Size THEN
- BEGIN
- INC(ParaOffset, P^.Size);
- P := P^.Next;
- CurOffset := 0;
- END;
- END;
- Loc.X := Offset-OldOffset-1;
- Loc.Y := Line;
- LENGTH := CrossRefs^[I].LENGTH;
- Ref := CrossRefs^[I].Ref;
- END;
-
- FUNCTION THelpTopic.GetLine(Line : INTEGER) : STRING;
- VAR
- Offset, I : INTEGER;
- P : PParagraph;
- BEGIN
- IF LastLine < Line THEN
- BEGIN
- I := Line;
- DEC(Line, LastLine);
- LastLine := I;
- Offset := LastOffset;
- P := LastParagraph;
- END
- ELSE
- BEGIN
- P := Paragraphs;
- Offset := 0;
- LastLine := Line;
- END;
- GetLine := '';
- WHILE (P <> NIL) DO
- BEGIN
- WHILE Offset < P^.Size DO
- BEGIN
- DEC(Line);
- GetLine := WrapText(P^.TEXT, P^.Size, Offset, P^.Wrap);
- IF Line = 0 THEN
- BEGIN
- LastOffset := Offset;
- LastParagraph := P;
- EXIT;
- END;
- END;
- P := P^.Next;
- Offset := 0;
- END;
- GetLine := '';
- END;
-
- FUNCTION THelpTopic.GetNumCrossRefs : INTEGER;
- BEGIN
- GetNumCrossRefs := NumRefs;
- END;
-
- FUNCTION THelpTopic.NumLines : INTEGER;
- VAR
- Offset, Lines : INTEGER;
- P : PParagraph;
- BEGIN
- Offset := 0;
- Lines := 0;
- P := Paragraphs;
- WHILE P <> NIL DO
- BEGIN
- Offset := 0;
- WHILE Offset < P^.Size DO
- BEGIN
- INC(Lines);
- WrapText(P^.TEXT, P^.Size, Offset, P^.Wrap);
- END;
- P := P^.Next;
- END;
- NumLines := Lines;
- END;
-
- PROCEDURE THelpTopic.SetCrossRef(I : INTEGER; VAR Ref : TCrossRef);
- BEGIN
- IF I <= NumRefs THEN CrossRefs^[I] := Ref;
- END;
-
- PROCEDURE THelpTopic.SetNumCrossRefs(I : INTEGER);
- VAR
- P : PCrossRefs;
- BEGIN
- IF NumRefs = I THEN EXIT;
- GETMEM(P, I*SIZEOF(TCrossRef));
- IF NumRefs > 0 THEN
- BEGIN
- IF I > NumRefs THEN MOVE(CrossRefs^, P^, NumRefs*SIZEOF(TCrossRef))
- ELSE MOVE(CrossRefs^, P^, I*SIZEOF(TCrossRef));
- FREEMEM(CrossRefs, NumRefs*SIZEOF(TCrossRef));
- END;
- CrossRefs := P;
- NumRefs := I;
- END;
-
- PROCEDURE THelpTopic.SetWidth(AWidth : INTEGER);
- BEGIN
- Width := AWidth;
- END;
-
- PROCEDURE THelpTopic.Store(VAR S : TStream);
-
- PROCEDURE WriteParagraphs;
- VAR
- I : INTEGER;
- P : PParagraph;
- BEGIN
- P := Paragraphs;
- I := 0;
- WHILE P <> NIL DO
- BEGIN
- INC(I);
- P := P^.Next;
- END;
- S.WRITE(I, SIZEOF(I));
- P := Paragraphs;
- WHILE P <> NIL DO
- BEGIN
- S.WRITE(P^.Size, SIZEOF(INTEGER));
- S.WRITE(P^.Wrap, SIZEOF(BOOLEAN));
- S.WRITE(P^.TEXT, P^.Size);
- P := P^.Next;
- END;
- END;
-
- PROCEDURE WriteCrossRefs;
- VAR
- I : INTEGER;
- BEGIN
- S.WRITE(NumRefs, SIZEOF(INTEGER));
- IF @CrossRefHandler = @NotAssigned THEN
- S.WRITE(CrossRefs^, SIZEOF(TCrossRef)*NumRefs)
- ELSE
- FOR I := 1 TO NumRefs DO
- BEGIN
- CrossRefHandler(S, CrossRefs^[I].Ref);
- S.WRITE(CrossRefs^[I].Offset, SIZEOF(INTEGER)+SIZEOF(BYTE));
- END;
- END;
-
- BEGIN
- WriteParagraphs;
- WriteCrossRefs;
- END;
-
- FUNCTION THelpTopic.WrapText(VAR TEXT; Size : INTEGER;
- VAR Offset : INTEGER; Wrap : BOOLEAN) : STRING;
- TYPE
- PCArray = ^CArray;
- CArray = ARRAY[0..32767] OF CHAR;
- VAR
- Line : STRING;
- I, P : INTEGER;
-
- FUNCTION IsBlank(Ch : CHAR) : BOOLEAN;
- BEGIN
- IsBlank := (Ch = ' ') OR(Ch = #13) OR(Ch = #10);
- END;
-
- FUNCTION Scan(VAR P; Offset : INTEGER; C : CHAR) : INTEGER; ASSEMBLER;
- ASM
- CLD
- LES DI,P
- ADD DI,&Offset
- MOV CX,256
- MOV AL, C
- REPNE SCASB
- SUB CX,256
- NEG CX
- XCHG AX,CX
- END;
-
- PROCEDURE TextToLine(VAR TEXT; Offset, LENGTH : INTEGER; VAR Line : STRING);
- ASSEMBLER;
- ASM
- CLD
- PUSH DS
- LDS SI,Text
- ADD SI,&Offset
- LES DI,Line
- MOV AX,Length
- STOSB
- XCHG AX,CX
- REP MOVSB
- POP DS
- END;
-
- BEGIN
- I := Scan(TEXT, Offset, #13);
- IF I+Offset > Size THEN I := Size-Offset;
- IF (I >= Width) AND Wrap THEN
- BEGIN
- I := Offset+Width;
- IF I > Size THEN I := Size
- ELSE
- BEGIN
- WHILE (I > Offset) AND NOT IsBlank(PCArray(@TEXT)^[I]) DO DEC(I);
- IF I = Offset THEN I := Offset+Width
- ELSE INC(I);
- END;
- IF I = Offset THEN I := Offset+Width;
- DEC(I, Offset);
- END;
- TextToLine(TEXT, Offset, I, Line);
- IF Line[LENGTH(Line)] = #13 THEN DEC(Line[0]);
- INC(Offset, I);
- WrapText := Line;
- END;
-
- { THelpIndex }
-
- CONSTRUCTOR THelpIndex.Init;
- BEGIN
- TObject.Init;
- Size := 0;
- Index := NIL;
- END;
-
- CONSTRUCTOR THelpIndex.Load(VAR S : TStream);
- BEGIN
- S.READ(Size, SIZEOF(Size));
- IF Size = 0 THEN Index := NIL
- ELSE
- BEGIN
- GETMEM(Index, SIZEOF(LONGINT)*Size);
- S.READ(Index^, SIZEOF(LONGINT)*Size);
- END;
- END;
-
- DESTRUCTOR THelpIndex.Done;
- BEGIN
- FREEMEM(Index, SIZEOF(LONGINT)*Size);
- TObject.Done;
- END;
-
- FUNCTION THelpIndex.Position(I : INTEGER) : LONGINT;
- BEGIN
- IF I < Size THEN Position := Index^[I]
- ELSE Position := -1;
- END;
-
- PROCEDURE THelpIndex.Add(I : INTEGER; VAL : LONGINT);
- CONST
- Delta = 10;
- VAR
- P : PIndexArray;
- NewSize : INTEGER;
- BEGIN
- IF I >= Size THEN
- BEGIN
- NewSize := (I+Delta) DIV Delta*Delta;
- GETMEM(P, NewSize*SIZEOF(LONGINT));
- IF P <> NIL THEN
- BEGIN
- MOVE(Index^, P^, Size*SIZEOF(LONGINT));
- FILLCHAR(P^[Size], (NewSize-Size)*SIZEOF(LONGINT), $FF);
- END;
- IF Size > 0 THEN FREEMEM(Index, Size*SIZEOF(LONGINT));
- Index := P;
- Size := NewSize;
- END;
- Index^[I] := VAL;
- END;
-
- PROCEDURE THelpIndex.Store(VAR S : TStream);
- BEGIN
- S.WRITE(Size, SIZEOF(Size));
- S.WRITE(Index^, SIZEOF(LONGINT)*Size);
- END;
-
- { THelpFile }
-
- CONST
- MagicHeader = $46484246; {'FBHF'}
-
- CONSTRUCTOR THelpFile.Init(S : PStream);
- VAR
- Magic : LONGINT;
- BEGIN
- Magic := 0;
- S^.SEEK(0);
- IF S^.GetSize > SIZEOF(Magic) THEN
- S^.READ(Magic, SIZEOF(Magic));
- IF Magic <> MagicHeader THEN
- BEGIN
- IndexPos := 12;
- S^.SEEK(IndexPos);
- Index := NEW(PHelpIndex, Init);
- Modified := TRUE;
- END
- ELSE
- BEGIN
- S^.SEEK(8);
- S^.READ(IndexPos, SIZEOF(IndexPos));
- S^.SEEK(IndexPos);
- Index := PHelpIndex(S^.Get);
- Modified := FALSE;
- END;
- Stream := S;
- END;
-
- DESTRUCTOR THelpFile.Done;
- VAR
- Magic, Size : LONGINT;
- BEGIN
- IF Modified THEN
- BEGIN
- Stream^.SEEK(IndexPos);
- Stream^.Put(Index);
- Stream^.SEEK(0);
- Magic := MagicHeader;
- Size := Stream^.GetSize-8;
- Stream^.WRITE(Magic, SIZEOF(Magic));
- Stream^.WRITE(Size, SIZEOF(Size));
- Stream^.WRITE(IndexPos, SIZEOF(IndexPos));
- END;
- DISPOSE(Stream, Done);
- DISPOSE(Index, Done);
- END;
-
- FUNCTION THelpFile.GetTopic(I : INTEGER) : PHelpTopic;
- VAR
- POS : LONGINT;
- BEGIN
- POS := Index^.Position(I);
- IF POS > 0 THEN
- BEGIN
- Stream^.SEEK(POS);
- GetTopic := PHelpTopic(Stream^.Get);
- END
- ELSE GetTopic := InvalidTopic;
- END;
-
- FUNCTION THelpFile.InvalidTopic : PHelpTopic;
- VAR
- Topic : PHelpTopic;
- Para : PParagraph;
- CONST
- InvalidStr = #13' No help available in this context.';
- InvalidText : ARRAY[1..LENGTH(InvalidStr)] OF CHAR = InvalidStr;
- BEGIN
- Topic := NEW(PHelpTopic, Init);
- GETMEM(Para, SIZEOF(Para^)+SIZEOF(InvalidText));
- Para^.Size := SIZEOF(InvalidText);
- Para^.Wrap := FALSE;
- Para^.Next := NIL;
- MOVE(InvalidText, Para^.TEXT, SIZEOF(InvalidText));
- Topic^.AddParagraph(Para);
- InvalidTopic := Topic;
- END;
-
- PROCEDURE THelpFile.RecordPositionInIndex(I : INTEGER);
- BEGIN
- Index^.Add(I, IndexPos);
- Modified := TRUE;
- END;
-
- PROCEDURE THelpFile.PutTopic(Topic : PHelpTopic);
- BEGIN
- Stream^.SEEK(IndexPos);
- Stream^.Put(Topic);
- IndexPos := Stream^.GetPos;
- Modified := TRUE;
- END;
-
- { THelpViewer }
-
- CONSTRUCTOR THelpViewer.Init(VAR Bounds : TRect; AHScrollBar,
- AVScrollBar : PScrollBar; AHelpFile : PHelpFile; Context : WORD);
- BEGIN
- TScroller.Init(Bounds, AHScrollBar, AVScrollBar);
- Options := Options OR ofSelectable;
- GrowMode := gfGrowHiX+gfGrowHiY;
- HFile := AHelpFile;
- Topic := AHelpFile^.GetTopic(Context);
- Topic^.SetWidth(Size.X);
- SetLimit(78, Topic^.NumLines);
- Selected := 1;
- END;
-
- DESTRUCTOR THelpViewer.Done;
- BEGIN
- TScroller.Done;
- DISPOSE(HFile, Done);
- DISPOSE(Topic, Done);
- END;
-
- PROCEDURE THelpViewer.ChangeBounds(VAR Bounds : TRect);
- BEGIN
- TScroller.ChangeBounds(Bounds);
- Topic^.SetWidth(Size.X);
- SetLimit(Limit.X, Topic^.NumLines);
- END;
-
- PROCEDURE THelpViewer.Draw;
- VAR
- B : TDrawBuffer;
- Line : STRING;
- I, J, L : INTEGER;
- KeyCount : INTEGER;
- Normal, Keyword, SelKeyword, C : BYTE;
- KeyPoint : TPoint;
- KeyLength : BYTE;
- KeyRef : INTEGER;
- BEGIN
- Normal := GetColor(1);
- Keyword := GetColor(2);
- SelKeyword := GetColor(3);
- KeyCount := 0;
- KeyPoint.X := 0;
- KeyPoint.Y := 0;
- Topic^.SetWidth(Size.X);
- IF Topic^.GetNumCrossRefs > 0 THEN
- REPEAT
- INC(KeyCount);
- Topic^.GetCrossRef(KeyCount, KeyPoint, KeyLength, KeyRef);
- UNTIL (KeyCount >= Topic^.GetNumCrossRefs) OR(KeyPoint.Y > Delta.Y);
- FOR I := 1 TO Size.Y DO
- BEGIN
- MoveChar(B, ' ', Normal, Size.X);
- Line := Topic^.GetLine(I+Delta.Y);
- MoveStr(B, COPY(Line, Delta.X+1, Size.X), Normal);
- WHILE I+Delta.Y = KeyPoint.Y DO
- BEGIN
- L := KeyLength;
- IF KeyPoint.X < Delta.X THEN
- BEGIN
- DEC(L, Delta.X-KeyPoint.X);
- KeyPoint.X := Delta.X;
- END;
- IF KeyCount = Selected THEN C := SelKeyword
- ELSE C := Keyword;
- FOR J := 0 TO L-1 DO
- WordRec(B[KeyPoint.X-Delta.X+J]).HI := C;
- INC(KeyCount);
- IF KeyCount <= Topic^.GetNumCrossRefs THEN
- Topic^.GetCrossRef(KeyCount, KeyPoint, KeyLength, KeyRef)
- ELSE KeyPoint.Y := 0;
- END;
- WriteLine(0, I-1, Size.X, 1, B);
- END;
- END;
-
- FUNCTION THelpViewer.GetPalette : PPalette;
- CONST
- P : STRING[LENGTH(CHelpViewer)] = CHelpViewer;
- BEGIN
- GetPalette := @P;
- END;
-
- PROCEDURE THelpViewer.HandleEvent(VAR Event : TEvent);
- VAR
- KeyPoint, Mouse : TPoint;
- KeyLength : BYTE;
- KeyRef : INTEGER;
- KeyCount : INTEGER;
-
- PROCEDURE MakeSelectVisible;
- VAR
- D : TPoint;
- BEGIN
- Topic^.GetCrossRef(Selected, KeyPoint, KeyLength, KeyRef);
- D := Delta;
- IF KeyPoint.X < D.X THEN D.X := KeyPoint.X;
- IF KeyPoint.X > D.X+Size.X THEN D.X := KeyPoint.X-Size.X;
- IF KeyPoint.Y < D.Y THEN D.Y := KeyPoint.Y;
- IF KeyPoint.Y > D.Y+Size.Y THEN D.Y := KeyPoint.Y-Size.Y;
- IF (D.X <> Delta.X) OR(D.Y <> Delta.Y) THEN ScrollTo(D.X, D.Y);
- END;
-
- PROCEDURE SwitchToTopic(KeyRef : INTEGER);
- BEGIN
- IF Topic <> NIL THEN DISPOSE(Topic, Done);
- Topic := HFile^.GetTopic(KeyRef);
- Topic^.SetWidth(Size.X);
- ScrollTo(0, 0);
- SetLimit(Limit.X, Topic^.NumLines);
- Selected := 1;
- DrawView;
- END;
-
- BEGIN
- TScroller.HandleEvent(Event);
- CASE Event.What OF
- evKeyDown :
- BEGIN
- CASE Event.KeyCode OF
- kbTab :
- BEGIN
- INC(Selected);
- IF Selected > Topic^.GetNumCrossRefs THEN Selected := 1;
- MakeSelectVisible;
- END;
- kbShiftTab :
- BEGIN
- DEC(Selected);
- IF Selected = 0 THEN Selected := Topic^.GetNumCrossRefs;
- MakeSelectVisible;
- END;
- kbEnter :
- BEGIN
- IF Selected <= Topic^.GetNumCrossRefs THEN
- BEGIN
- Topic^.GetCrossRef(Selected, KeyPoint, KeyLength, KeyRef);
- SwitchToTopic(KeyRef);
- END;
- END;
- kbEsc :
- BEGIN
- Event.What := evCommand;
- Event.Command := cmClose;
- PutEvent(Event);
- END;
- ELSE
- EXIT;
- END;
- DrawView;
- ClearEvent(Event);
- END;
- evMouseDown :
- BEGIN
- MakeLocal(Event.Where, Mouse);
- INC(Mouse.X, Delta.X); INC(Mouse.Y, Delta.Y);
- KeyCount := 0;
- REPEAT
- INC(KeyCount);
- IF KeyCount > Topic^.GetNumCrossRefs THEN EXIT;
- Topic^.GetCrossRef(KeyCount, KeyPoint, KeyLength, KeyRef);
- UNTIL (KeyPoint.Y = Mouse.Y+1) AND(Mouse.X >= KeyPoint.X) AND
- (Mouse.X < KeyPoint.X+KeyLength);
- Selected := KeyCount;
- DrawView;
- IF Event.DOUBLE THEN SwitchToTopic(KeyRef);
- ClearEvent(Event);
- END;
- evCommand :
- IF (Event.Command = cmClose) AND(Owner^.State AND sfModal <> 0) THEN
- BEGIN
- EndModal(cmClose);
- ClearEvent(Event);
- END;
- END;
- END;
-
- { THelpWindow }
-
- CONSTRUCTOR THelpWindow.Init(HFile : PHelpFile; Context : WORD);
- VAR
- R : TRect;
- BEGIN
- R.ASSIGN(0, 0, 50, 18);
- TWindow.Init(R, 'Help', wnNoNumber);
- Options := Options OR ofCentered;
- R.Grow(-2, -1);
- INSERT(NEW(PHelpViewer, Init(R,
- StandardScrollBar(sbHorizontal+sbHandleKeyboard),
- StandardScrollBar(sbVertical+sbHandleKeyboard), HFile, Context)));
- END;
-
- FUNCTION THelpWindow.GetPalette : PPalette;
- CONST
- P : STRING[LENGTH(CHelpWindow)] = CHelpWindow;
- BEGIN
- GetPalette := @P;
- END;
-
- PROCEDURE RegisterHelpFile;
- BEGIN
- RegisterType(RHelpTopic);
- RegisterType(RHelpIndex);
- END;
-
- PROCEDURE NotAssigned(VAR S : TStream; Value : INTEGER);
- BEGIN
- END;
-
- END.