{************************************************} { } { Turbo Vision File Manager Demo } { Copyright (c) 1992 by Borland International } { } {************************************************} {$X+} unit ViewHex; interface uses Drivers, Objects, Memory, Views; type PHexViewer = ^THexViewer; THexViewer = object(TScroller) FileBuf: Pointer; BufSize: Word; MaxLines: Integer; constructor Init(var Bounds:TRect; AVScrollBar: PScrollBar; const Name: FNameStr); destructor Done; virtual; procedure Draw; virtual; end; PHexWindow = ^THexWindow; THexWindow = object(TWindow) Interior: PHexViewer; constructor Init(var Bounds: TRect; Filename: FNameStr); destructor Done; virtual; procedure SizeLimits(var Min, Max: TPoint); virtual; function GetPalette: PPalette; virtual; end; implementation uses MsgBox; type String2 = String[2]; PByteBuffer = ^TByteBuffer; TByteBuffer = array[0..$FFFE] of Byte; { Store hex characters directly into the string location pointed to by P } { No bounds checking done! } procedure AddHexByte(B: Byte; P: Pointer); const HexChars : array[0..15] of char = '0123456789ABCDEF'; type P2Char = ^T2Char; T2Char = array[0..1] of Char; begin P2Char(P)^[0] := HexChars[ (B and $F0) shr 4 ]; P2Char(P)^[1] := HexChars[ B and $0F ]; end; { THexViewer } constructor THexViewer.Init(var Bounds:TRect; AVScrollBar: PScrollBar; const Name: FNameStr); var F: File; Result: Word; FSize : Longint; Msg: String; SaveMode : Byte; begin inherited Init(Bounds, nil, AVScrollBar); GrowMode := gfGrowHiX + gfGrowHiY; Options := Options or ofTileable; FileBuf := nil; BufSize := 0; Msg := ''; { no errors encountered } { open the file } SaveMode := FileMode; FileMode := 0; { make sure we open as Read-Only } Assign(F, Name); {$I-} Reset(F,1); {$I+} FileMode := SaveMode; Result := IOResult; if Result = 0 then begin FSize := FileSize(F); if FSize > $FFFE then begin FSize := $FFFE; Msg := 'File is larger than 64k. Display will be truncated'; end; if FSize > MaxAvail - LowMemSize then { use standard safety size } begin FSize := MaxAvail - LowMemSize; if FSize > 0 then Msg := 'File too large for available memory. Display will be truncated.' else Msg := 'Not enough memory for safety pool!'; end; if FSize > 0 then begin GetMem(FileBuf, FSize); BlockRead(F, FileBuf^, FSize, Result); BufSize := FSize; end; Close(F); end else Msg := 'Unable to open this file!'; { Display any message that was generated } if Msg <> '' then MessageBox(Msg, nil, mfInformation+mfOKButton); MaxLines := BufSize div 16; if BufSize mod 16 > 0 then Inc(MaxLines); SetLimit(0, MaxLines); end; destructor THexViewer.Done; begin if (BufSize > 0) and (FileBuf <> nil) then FreeMem(FileBuf, BufSize); inherited Done; end; procedure THexViewer.Draw; const VWidth = 69; { total width of view } HStart = 7; { starting column of hex dump } CStart = 56; { starting column of character dump } LineChar = #179; { vertical line character } var B: TDrawBuffer; S: String; C: Word; Offset: Word; x,y : Byte; i,byt: Byte; L: Longint; begin C := GetColor(1); for y := 0 to Size.Y-1 do begin FillChar(S[1], VWidth, 32); S[0] := Char(VWidth); MoveChar(B, #32, C, Size.X); Offset := (Delta.Y + Y) * 16; if (Delta.Y + Y) < MaxLines then begin L := (Delta.Y + Y) * 16; FormatStr(S, '%04x:', L); S[0] := Char(VWidth); i := HStart; for x := 0 to 15 do begin if Offset + x < BufSize then begin byt := PByteBuffer(FileBuf)^[Offset+x]; AddHexByte(byt, @S[i]); S[CStart + x] := Char(byt); Inc(i,3); end; end; end; S[CStart - 1] := LineChar; MoveStr(B, S, C); WriteLine(0,Y,Size.X,1,B); end; end; { THexWindow } constructor THexWindow.Init(var Bounds: TRect; Filename: FNameStr); var R: TRect; SB: PScrollBar; begin inherited Init(Bounds, Filename, wnNoNumber); GetExtent(R); SB := StandardScrollBar(sbVertical + sbHandleKeyboard); Insert(SB); R.Grow(-1,-1); Interior := New(PHexViewer, Init(R, SB, Filename)); Insert(Interior); end; destructor THexWindow.Done; begin if Interior <> nil then Dispose(Interior, Done); inherited Done; end; procedure THexWindow.SizeLimits(var Min, Max: TPoint); begin inherited SizeLimits(Min, Max); Max.X := 72; end; function THexWindow.GetPalette: PPalette; const MyPal : String[Length(CGrayWindow)] = CCyanWindow; begin GetPalette := @MyPal; end; end. { unit }