unit HexEdit;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;type
TCaretStyle = (csFull , csLeftLine , csBottomLine ); TBlock = record
BX: Integer;
BY: Integer;
end; THexEdit = class(TCustomControl)
private
FActive: Boolean;
FReadOnly: Boolean;
FTopLine: Integer;
FLeftCol: Integer;
FCurrentLine: Integer;
FCurrentCol: Integer;
FUpdateByte: Byte;
FVisibleLines: Integer;
FVisibleCols: Integer;
FLineCount: Integer;
FColCount: Integer;
FBytesPerLine: Integer;
FItemHeight: Integer;
FItemWidth: Integer;
FFileColors: array[0..2] of TColor;
FShowCharacters: Boolean;
FShowAddress: Boolean;
FBorder: TBorderStyle;
FCaretRow,FCaretCol: Integer;
FLineAddr: array[0..15] of char;
FTextWidth: Integer;
FCaretCreate: Boolean;
FLButtonDown: Boolean;
FBlockBegin: TBlock;
FBlockEnd: TBlock;
//FSelStartCol,FSelStartLine: Integer;
//FSelectStartCol,FSelectStartLine: Integer;
//FOldSelectEndCol,FOldSelectEndLine: Integer;
//FSelectEndCol,FSelectEndLine: Integer;
FMStream: TMemoryStream;
FModified: Boolean;
FInvertRgn: HRGN;
FOnMouseDown: TNotifyEvent;
FOffset: Integer;
FCurrentByteValue: Byte;
FOnKeyDown: TNotifyEvent;
FCurrentCardinalValue: Cardinal;
FCurrentWordValue: Word;
procedure CalcPaintParams;
//procedure SetReadOnly(Value: Boolean);
procedure SetTopLine(Value: Integer);
procedure SetCurrentCol(Value: Integer);
procedure SetCurrentLine(Value: Integer);
procedure SetFileColor(Index: Integer; Value: TColor);
function GetFileColor(Index: Integer): TColor;
procedure SetShowCharacters(Value: Boolean);
procedure SetShowAddress(Value: Boolean);
procedure SetBorder(Value: TBorderStyle);
procedure SetAddress(Value: Pointer);
function GetDataSize: Integer;
procedure SetDataSize(Value: Integer);
procedure AdjustScrollBars;
function LineAddr(Index: Integer): PChar;
function LineData(Index: Integer): PChar;
function LineChars(Index: Integer): PChar;
function ScrollIntoView: Boolean;
// procedure InvalidateLine(Index: Integer);
procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
procedure CMEnter(var Message: TCMGotFocus); message CM_ENTER;
procedure CMExit(var Message: TCMLostFocus); message CM_EXIT;
procedure WMSize(var Message: TWMSize); message WM_SIZE;
procedure WMVScroll(var Message: TWMVScroll); message WM_VSCROLL;
procedure WMHScroll(var Message: TWMHScroll); message WM_HSCROLL;
procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;
//procedure WMKeyDown(var Message: TWMKeyDown); message WM_KEYDOWN;
procedure WMSetFocus(var Msg: TWMSetFocus); message WM_SETFOCUS;
procedure WMKillFocus(var Msg: TWMKillFocus); message WM_KILLFOCUS;
procedure SetCaretPosition;
procedure SetCaretCol(Value: Integer);
procedure SetCaretRow(Value: Integer);
procedure SetLeftCol(Value: Integer);
procedure PaintCell(ACol,ARow: Integer); overload;
procedure PaintCell; overload;
procedure PaintLine(Index: Integer);
procedure SetSelction;
function GetRgn(var StartCol,StartLine,EndCol,EndLine: Integer): HRgn;
procedure SetOffset(const Value: Integer);
procedure SetCurrentByteValue(Value: Byte);
procedure SetCurrentCardinalValue(Value: Cardinal);
procedure SetCurrentWordValue(Value: Word);
protected
procedure CreateParams(var Params: TCreateParams); override;
procedure Paint; override;
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
procedure UpdateView;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure LoadFromFile(const FileName: TFileName);
procedure LoadFromStream(Stream: TStream);
procedure SaveToFile(const FileName: TFileName);
procedure SaveToStream(Stream: TStream);
property CurrentLine: Integer read FCurrentLine write SetCurrentLine;
property CaretCol: Integer read FCaretCol write SetCaretCol;
property CurrentCol: Integer read FCurrentCol write SetCurrentCol;
property CaretRow: Integer read FCaretRow write SetCaretRow;
property LeftCol: Integer read FLeftCol write SetLeftCol;
property Offset: Integer read FOffset write SetOffset;
property CurrentByteValue: Byte read FCurrentByteValue write SetCurrentByteValue;
property CurrentWordValue: Word read FCurrentWordValue write SetCurrentWordValue;
property CurrentCardinalValue: Cardinal read FCurrentCardinalValue write SetCurrentCardinalValue;
//property DataSize: Integer read GetDataSize write SetDataSize;
property Modified: Boolean read FModified;
published
property Align;
property Border: TBorderStyle read FBorder write SetBorder default bsNone;
property Color default clWhite;
property Ctl3D;
property Font;
property PopupMenu;
property ReadOnly: Boolean read FReadOnly write FReadOnly;
property TabOrder;
property TabStop;
property ShowAddress: Boolean read FShowAddress write SetShowAddress default True;
property ShowCharacters: Boolean read FShowCharacters write SetShowCharacters default True;
property AddressColor: TColor index 0 read GetFileColor write SetFileColor default clBlack;
property HexDataColor: TColor index 1 read GetFileColor write SetFileColor default clBlack;
property AnsiCharColor: TColor index 2 read GetFileColor write SetFileColor default clBlack;
property OnMouseDown: TNotifyEvent read FOnMouseDown write FOnMouseDown;
property OnKeyDown: TNotifyEvent read FOnKeyDown write FOnKeyDown;
end;const
MAXDIGITS = 16;
AlphaDigit = [48..57,65..70,96..105];procedure Register;implementationprocedure Register;
begin
RegisterComponents('LCC', [THexEdit]);
end;{ THexEdit }constructor THexEdit.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
ControlStyle := [csFramed];
FBorder := bsNone;
Color := clWhite;
FShowAddress := True;
FShowCharacters := True;
Width := 300;
Height := 200;
FBytesPerLine:=16;
FVisibleLines:=16;
FItemHeight:=12;
FItemWidth:=18;
FCaretCreate:=False;
FLButtonDown:=False;
FMStream:=TMemoryStream.Create;
FModified:=False;
end;destructor THexEdit.Destroy;
begin
FMStream.Free;
inherited Destroy;
end;
procedure THexEdit.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
//CreateSubClass(Params, 'RICHEDIT');
with Params do
begin
Style := Style or WS_TABSTOP or WS_VSCROLL or WS_HSCROLL;
WindowClass.style := CS_DBLCLKS;
if FBorder = bsSingle then
if NewStyleControls and Ctl3D then
begin
Style := Style and not WS_BORDER;
ExStyle := ExStyle or WS_EX_CLIENTEDGE;
end
else
Style := Style and not WS_BORDER;
end;end;{procedure THexEdit.SetReadOnly(Value: Boolean);
begin
if
end;}{ VCL Command Messages }procedure THexEdit.CMFontChanged(var Message: TMessage);
begin
inherited;
Canvas.Font := Self.Font;
FItemHeight := Canvas.TextHeight('A');// + 2;
FItemWidth := Canvas.TextWidth('D');
CalcPaintParams;
AdjustScrollBars;
end;procedure THexEdit.CMEnter;
begin
inherited;
{ InvalidateLineMarker; }
end;procedure THexEdit.CMExit;
begin
inherited;
{ InvalidateLineMarker; }
end;{ Windows Messages }procedure THexEdit.WMSize(var Message: TWMSize);
begin
inherited;
CalcPaintParams;
AdjustScrollBars;
end;procedure THexEdit.WMGetDlgCode(var Message: TWMGetDlgCode);
begin
Message.Result := DLGC_WANTARROWS;
end;procedure THexEdit.SetLeftCol(Value: Integer);
var
R: TRect;
begin
if Value <> FLeftCol then
begin
SetScrollPos(Handle, SB_HORZ, Value, True);
R := Bounds(0, 0, ClientWidth , ClientHeight);
ScrollWindow(Handle, FItemWidth * (FLeftCol - Value),0, @R, nil);
FLeftCol := Value;
end;
end;procedure THexEdit.WMHScroll(var Message: TWMHScroll);
var
NewLeftCol: Integer;
//R: TRect;
begin
inherited;
NewLeftCol := FLeftCol;
case Message.ScrollCode of
SB_LINEDOWN: Inc(NewLeftCol);
SB_LINEUP: Dec(NewLeftCol);
SB_PAGEDOWN: Inc(NewLeftCol, FVisibleCols - 1);
SB_PAGEUP: Dec(NewLeftCol, FVisibleCols - 1);
SB_THUMBPOSITION, SB_THUMBTRACK: NewLeftCol := Message.Pos;
end; if NewLeftCol < 0 then NewLeftCol := 0;
if NewLeftCol >= 82 then
NewLeftCol := 81;
FCaretCol:=FCaretCol+LeftCol-NewLeftCol;
SetCaretPosition;
LeftCol:=NewLeftCol;
end;
procedure THexEdit.WMVScroll(var Message: TWMVScroll);
var
NewTopLine: Integer;
LinesMoved: Integer;
R: TRect;
begin
inherited;
NewTopLine := FTopLine;
case Message.ScrollCode of
SB_LINEDOWN: Inc(NewTopLine);
SB_LINEUP: Dec(NewTopLine);
SB_PAGEDOWN: Inc(NewTopLine, FVisibleLines - 1);
SB_PAGEUP: Dec(NewTopLine, FVisibleLines - 1);
SB_THUMBPOSITION, SB_THUMBTRACK: NewTopLine := Message.Pos;
end; if NewTopLine < 0 then NewTopLine := 0;
if NewTopLine >= FLineCount then
NewTopLine := FLineCount - 1; if NewTopLine <> FTopLine then
begin
//FCaretRow:=FCaretRow+FTopLine-NewTopLine; LinesMoved := FTopLine - NewTopLine;
FTopLine := NewTopLine;
SetScrollPos(Handle, SB_VERT, FTopLine, True);
SetCaretPosition;
if Abs(LinesMoved) = 1 then
begin
if LinesMoved=1 then
begin
R := Bounds(0, 0, ClientWidth, ClientHeight - FItemHeight);
ScrollWindow(Handle, 0, FItemHeight * LinesMoved, @R, nil);
PaintLine(FTopLine+FVisibleLines+1);
end
else
begin
R := Bounds(0, FItemHeight, ClientWidth, ClientHeight);
ScrollWindow(Handle, 0, FItemHeight * LinesMoved, @R, nil);
PaintLine(FTopLine-1);
end;
end
else Invalidate;
end;
end;{ Painting Related }procedure THexEdit.CalcPaintParams;
const
Divisor: array[boolean] of Integer = (3,4);
var
CharsPerLine: Integer;begin
if FItemHeight < 1 then Exit;
FVisibleLines := (ClientHeight div FItemHeight);
FVisibleCols := (ClientWidth div FItemWidth)+1;
CharsPerLine := ClientWidth div FItemWidth;
if FShowAddress then Dec(CharsPerLine, 10);
FLineCount := ((FMStream.Size-15) div FBytesPerLine)+2;
if FMStream.Size>0 then FColCount := 82;
AdjustScrollBars;
end;{procedure THexEdit.InvalidateLine(Index: Integer);
var
R: TRect;
begin
if (Index >= FTopLine) and (Index <= FTopLine + FVisibleLines - 1) then
begin
R := Rect(0, 0, ClientWidth, FItemHeight);
OffsetRect(R, 0, (Index - FTopLine) * FItemHeight);
Windows.InvalidateRect(Handle, @R, False);
end;
end;}procedure THexEdit.AdjustScrollBars;
var
ScrollInfo: TScrollInfo;
begin
ScrollInfo.fMask:=SIF_ALL;
ScrollInfo.nPage:=FVisibleLines;
ScrollInfo.nMin:=0;
ScrollInfo.nMax:=FLineCount;//-FVisibleLines;
ScrollInfo.nPos:=0;
SetScrollInfo(Handle,SB_VERT,ScrollInfo,True);
ScrollInfo.fMask:=SIF_ALL;
ScrollInfo.nPage:=FVisibleCols;
ScrollInfo.nMin:=0;
ScrollInfo.nMax:=FColCount;//-FVisibleCols;// - (ClientWidth div FItemWidth);
ScrollInfo.nPos:=0;
SetScrollInfo(Handle,SB_HORZ,ScrollInfo,True);
LeftCol:=0;
end;function THexEdit.ScrollIntoView: Boolean;
begin
Result := False;
if FCurrentLine < FTopLine then
begin
Result := True;
SetTopLine(FCurrentLine);
end
else if FCurrentLine >= (FTopLine + FVisibleLines) - 1 then
begin
SetTopLine(FCurrentLine - (FVisibleLines - 2));
Result := True;
end;
end;procedure THexEdit.SetTopLine(Value: Integer);
var
LinesMoved: Integer;
R: TRect;
begin
if Value <> FTopLine then
begin
if Value < 0 then Value := 0;
if Value >= FLineCount then Value := FLineCount - 1; LinesMoved := FTopLine - Value;
FTopLine := Value;
SetScrollPos(Handle, SB_VERT, FTopLine, True);
if Abs(LinesMoved) = 1 then
begin
R:=Bounds(0,0,ClientWidth,ClientHeight);
ScrollWindow(Handle, 0, FItemHeight*LinesMoved,@R,nil);
PaintLine(Value);
end
else Invalidate;
end;
end;procedure THexEdit.SetCurrentLine(Value: Integer);
var
R: TRect;
nLineMove: Integer;
begin
if Value <> FCurrentLine then
begin
if Value < 0 then Value := 0;
if Value >= FLineCount then Value := FLineCount - 1;
nLineMove:=FCurrentLine-Value;
//SetTopLine(FTopLine+nLineMove);
if (Value>=FTopLine+FVisibleLines) or (Value<FTopLine) then
if Abs(nLineMove)=1 then
begin
SetTopLine(FTopLine-nLineMove);
//SetScrollPos(Handle,SB_VERT,FTopLine,True);
{R:=Bounds(0,0,ClientWidth,ClientHeight);
ScrollWindow(Handle, 0, FItemHeight*nLineMove,@R,nil);
PaintLine(Value);}
end
else
begin
SetTopLine(FTopLine-nLineMove);
end;
FCurrentLine:=Value;
SetCaretPosition;
end;
end;procedure THexEdit.PaintCell;
begin
HideCaret(Handle);
TextOut(Canvas.Handle,((FCurrentCol div 3)*3-FLeftCol)*FItemWidth,(FCurrentLine-FTopLine)*FItemHeight,PChar(IntToHex(FUpdateByte,2)),2);
TextOut(Canvas.Handle,(63-FLeftCol)*FItemWidth,(FCurrentLine-FTopLine)*FItemHeight,LineChars(FCurrentLine),19);
ShowCaret(Handle);
end;procedure THexEdit.PaintCell(ACol,ARow: Integer);
begin
HideCaret(Handle);
TextOut(Canvas.Handle,((ACol div 3)*3-FLeftCol)*FItemWidth,(ARow-FTopLine)*FItemHeight,PChar(IntToHex(FUpdateByte,2)),2);
TextOut(Canvas.Handle,(63-FLeftCol)*FItemWidth,(ARow-FTopLine)*FItemHeight,LineChars(ARow),19);
ShowCaret(Handle);
end;procedure THexEdit.PaintLine(Index: Integer);
var
R: TRect;
AddressWidth: Integer;
TabStop: Integer;
ByteCnt: Integer;
//OldColor,OldBrushColor: TColor;
begin
HideCaret(Handle);
R := Bounds(1, FItemHeight*Index, FItemWidth*82, FItemHeight);
if FShowAddress then AddressWidth := FItemWidth*12
else AddressWidth := 0;
TabStop := FItemWidth*3;
ByteCnt := FBytesPerLine;
if (Index + FTopLine < FLineCount) and (Index+FTopLine>=0) then
begin
R.Left := R.Left-FItemWidth*FLeftCol;
if FShowAddress then
begin
Canvas.Font.Color := FFileColors[0];
ExtTextOut(Canvas.Handle, R.Left, R.Top, ETO_OPAQUE or ETO_CLIPPED, @R, LineAddr(Index+FTopLine), 10, nil);
R.Left := R.Left + AddressWidth;
end;
{OldBrushColor:=Canvas.Brush.Color;
OldColor:=Canvas.Font.Color;
if ((FBlockBegin.BY<Index) and (FBlockEnd.BY>Index)) or
((FBlockBegin.BY>Index) and (FBlockEnd.BY<Index)) then
begin
Canvas.Brush.Color:=clBlack;
Canvas.Font.Color:=clWhite;
end
else
begin
Canvas.Brush.Color:=clWhite;
Canvas.Font.Color:=clBlack;
end;}
if (Index+FTopLine = FLineCount-1) and ((FMStream.Size mod FBytesPerLine) > 0) then
ByteCnt := FMStream.Size mod FBytesPerLine;
TabbedTextOut(Canvas.Handle, R.Left, R.Top, LineData(Index+FTopLine),
(ByteCnt*3)+3, 1, TabStop, R.Left);
//Canvas.Font.Color := OldColor;
//Canvas.Brush.Color:=OldBrushColor;
if FShowCharacters then
begin
R.Left := R.Left + (FItemWidth*(FBytesPerLine*3+3));
Canvas.Font.Color := FFileColors[2];
ExtTextOut(Canvas.Handle, R.Left, R.Top, ETO_OPAQUE or ETO_CLIPPED, @R, LineChars(Index+FTopLine), ByteCnt+3, nil);
end;
end
else ExtTextOut(Canvas.Handle, R.Left, R.Top, ETO_OPAQUE or ETO_CLIPPED,
@R, nil, 0, nil);
ShowCaret(Handle);
end;procedure THexEdit.Paint;
{var
R: TRect;
I: Integer;
AddressWidth: Integer;
TabStop: Integer;
ByteCnt: Integer;}
var
I: Integer;
begin
inherited Paint;
Canvas.Brush.Color := Self.Color;
if FMStream.Size>0 then
for I := -1 to FVisibleLines+1 do
begin
PaintLine(I);
end;
{Canvas.Brush.Color := Self.Color;
if FShowAddress then AddressWidth := FItemWidth*12
else AddressWidth := 0;
//R := Bounds(1, 0, ClientWidth, FItemHeight);
R := Bounds(1, 0, FItemWidth*82, FItemHeight);
TabStop := FItemWidth*3;
Canvas.Font.Color := FFileColors[1];
ByteCnt := FBytesPerLine;
for I := 0 to FVisibleLines - 1 do
begin
R.Left := 1;
if I + FTopLine < FLineCount then
begin
R.Left := R.Left-FItemWidth*FLeftCol;
if FShowAddress then
begin
Canvas.Font.Color := FFileColors[0];
//R.Right := R.Left + AddressWidth;
ExtTextOut(Canvas.Handle, R.Left, R.Top, ETO_OPAQUE or ETO_CLIPPED, @R, LineAddr(I+FTopLine), 10, nil);
R.Left := R.Left + AddressWidth;
//R.Right := ClientWidth;
Canvas.Font.Color := FFileColors[1];
end;
if (I+FTopLine = FLineCount-1) and ((DataSize mod FBytesPerLine) > 0) then
ByteCnt := DataSize mod FBytesPerLine;
TabbedTextOut(Canvas.Handle, R.Left, R.Top, LineData(I+FTopLine),
(ByteCnt*3)+3, 1, TabStop, R.Left);
if FShowCharacters then
begin
R.Left := R.Left + (FItemWidth*(FBytesPerLine*3+3));
Canvas.Font.Color := FFileColors[2];
ExtTextOut(Canvas.Handle, R.Left, R.Top, ETO_OPAQUE or ETO_CLIPPED, @R, LineChars(I+FTopLine), ByteCnt+3, nil);
//Beep;
end;
end
else ExtTextOut(Canvas.Handle, R.Left, R.Top, ETO_OPAQUE or ETO_CLIPPED,
@R, nil, 0, nil);
OffsetRect(R, 0, FItemHeight);
end;}
end;{ Event Overrides }function GetDigit(Key: Word): Integer;
begin
Result:=Key-48;
if Result>9 then
begin
Result:=Key-55;
if Result>16 then
Result:=Key-96;
end;
end;procedure THexEdit.KeyDown(var Key: Word; Shift: TShiftState);
var
nB: Byte;
nCol: Integer;
begin
inherited KeyDown(Key, Shift);
//procedure THexEdit.WMKeyDown(var Message: TWMKeyDown);
//var
//nB: Byte;
//begin
if not FActive then Exit;
if FReadOnly then Exit;
case Key of //Message.CharCode
VK_DOWN:
begin
//CaretRow := CaretRow + 1;
CurrentLine := CurrentLine + 1;
SetCaretPosition;
end;
VK_UP:
begin
//CaretRow := CaretRow - 1;
CurrentLine := CurrentLine - 1;
SetCaretPosition;
end;
VK_NEXT: CurrentLine := CurrentLine + FVisibleLines;
VK_PRIOR: CurrentLine := CurrentLine - FVisibleLines;
VK_HOME:
begin
FCurrentCol := 12;
SetCaretPosition;
end;
VK_END:
begin
FCurrentCol := 62;
SetCaretPosition;
end;
VK_LEFT:
begin
if FCurrentCol=39 then FCurrentCol:=36;
if (CurrentCol mod 3)=0 then CurrentCol:=CurrentCol-2
else CurrentCol:=CurrentCol-1;
SetCaretPosition;
end;
VK_RIGHT:
begin
CurrentCol:=CurrentCol+1;
SetCaretPosition;
end
else
begin
if Key In AlphaDigit then
begin
if FTopLine>FCurrentLine then SetTopLine(FCurrentLine)
else if FTopLine<=FCurrentLine-FVisibleLines then SetTopLine(FCurrentLine-FVisibleLines+2);
SetCaretPosition;
nCol:=(FCurrentCol div 3)-4;
if FCurrentCol>=39 then nCol:=nCol-1;
FMStream.Position:=FCurrentLine*FBytesPerLine+nCol;//FTopLine+FCaretRow
FMStream.Read(nB,1);
if (FCurrentCol mod 3)=0 then
begin
nB:=nB and $F;
nB:=nB +(GetDigit(Key) shl 4);
end
else
begin
nB:=nB and $F0;
nB:=nB +GetDigit(Key);
end;
FMStream.Position:=FMStream.Position-1;
FMStream.Write(nB,1);
FUpdateByte:=nB;
PaintCell;
CurrentCol:=CurrentCol+1;
//CaretCol:=CaretCol+1;
//if FVisibleCols+FLeftCol<=FCaretCol then
//LeftCol:=FCaretCol-FVisibleCols+1;
FModified:=False;
end
else
begin
inherited;
end;
end;
end;
if Assigned(FOnKeyDown) then FOnKeyDown(Self);
end;function THexEdit.GetRgn(var StartCol,StartLine,EndCol,EndLine: Integer): HRgn;
var
rgn: HRgn;
YOffset1,yOffset,y1,y2: Integer;
Points: array[0..7] of TPoint;
nIndex,nTemp: Integer;
s: string;
begin
YOffset1:=EndLine-StartLine;
if Yoffset1<0 then
begin
nTemp:=EndLine;
EndLine:=StartLine;
StartLine:=nTemp;
YOffset1:=-YOffset1;
end;
if (YOffset1>2) then
begin
if YOffset1>0 then
begin
yOffset:=1;
y1:=62;
y2:=12;
end;
//else
//begin
//y1:=12;
//y2:=62;
//yOffset:=-1;
//end;
nIndex:=0;
Points[nIndex].X:=StartCol*FItemWidth;
Points[nIndex].Y:=StartLine*FItemHeight;
s:=s+IntToStr(Points[nIndex].X)+','+IntToStr(Points[nIndex].Y)+' ';
Inc(nIndex); Points[nIndex].X:=y1*FItemWidth;
Points[nIndex].Y:=StartLine*FItemHeight;
s:=s+IntToStr(Points[nIndex].X)+','+IntToStr(Points[nIndex].Y)+' ';
Inc(nIndex); Points[nIndex].X:=y1*FItemWidth;
Points[nIndex].Y:=(EndLine-yOffset)*FItemHeight;
s:=s+IntToStr(Points[nIndex].X)+','+IntToStr(Points[nIndex].Y)+' ';
Inc(nIndex); Points[nIndex].X:=EndLine*FItemWidth;
Points[nIndex].Y:=(EndLine-yOffset)*FItemHeight;
s:=s+IntToStr(Points[nIndex].X)+','+IntToStr(Points[nIndex].Y)+' ';
Inc(nIndex); Points[nIndex].X:=EndLine*FItemWidth;
Points[nIndex].Y:=EndLine*FItemHeight;
s:=s+IntToStr(Points[nIndex].X)+','+IntToStr(Points[nIndex].Y)+' ';
Inc(nIndex);
Points[nIndex].X:=y2*FItemWidth;
Points[nIndex].Y:=EndLine*FItemHeight;
s:=s+IntToStr(Points[nIndex].X)+','+IntToStr(Points[nIndex].Y)+' ';
Inc(nIndex); Points[nIndex].X:=y2*FItemWidth;
Points[nIndex].Y:=(StartLine+yOffset)*FItemHeight;
s:=s+IntToStr(Points[nIndex].X)+','+IntToStr(Points[nIndex].Y)+' ';
Inc(nIndex); Points[nIndex].X:=StartCol*FItemWidth;
Points[nIndex].Y:=(StartLine+yOffset)*FItemHeight;
s:=s+'('+IntToStr(Points[nIndex].X)+','+IntToStr(Points[nIndex].Y)+') ';
Inc(nIndex);
rgn:=CreatePolygonRgn(Points,nIndex,ALTERNATE);
StartCol:=EndCol;
StartLine:=EndLine;//-yOffset;
//if yOffset>0 then Dec(StartLine);
end;
{else
rgn:=CreateRectRgn(StartCol*FItemWidth,StartLine*FItemHeight,
EndLine*FItemWidth,EndLine*FItemHeight);}
Result:=rgn;
end;procedure THexEdit.SetSelction;
var
rgn: HRgn;
begin
//rgn:=GetRgn(FSelectStartCol,FSelectStartLine,FSelectEndCol,FSelectEndLine);
//InvertRgn(Canvas.Handle,FInvertRgn);
//InvertRgn(Canvas.Handle,rgn);
//FInvertRgn:=rgn;
end;procedure THexEdit.MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin
inherited MouseDown(Button, Shift, X, Y);
if not Focused then SetFocus;
FActive:=True;
if FColCount>0 then
begin
if (Button = mbLeft) and FActive then
begin
InvertRgn(Canvas.Handle,FInvertRgn);
FInvertRgn:=CreateRectRgn(0,0,0,0);
FCurrentLine:=(Y div FItemHeight)+FTopLine;
FCurrentCol:=(X div FItemWidth)+FLeftCol;
if FCurrentCol<12 then FCurrentCol:=12
else if FCurrentCol>62 then FCurrentCol:=62
else if (FCurrentCol>34) and (FCurrentCol<39) then FCurrentCol:=39;
if FCurrentCol mod 3=2 then FCurrentCol:=FCurrentCol-1; SetCaretPosition;
FLButtonDown:=True;
FBlockBegin.BX:=FCurrentCol;
FBlockBegin.BY:=FCurrentLine;
FBlockEnd:=FBlockBegin;
FOffset:=FCurrentLine*16+((FCurrentCol-12) div 3);
if FCurrentCol>=39 then Dec(FOffset);
//FSelectStartCol:=;
//FSelectStartLine:=FCurrentLine;
//FSelStartCol:=FCurrentCol;
//FSelStartLine:=FCurrentLine;
end;
if Assigned(FOnMouseDown) then FOnMouseDown(Self);
end
else
HideCaret(Handle)
end;procedure THexEdit.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
nCol,nLine: Integer;
begin
inherited MouseUp(Button, Shift, X, Y);
nCol:=((X-1) div FItemWidth)+FLeftCol;
nLine:=((Y-1) div FItemHeight)+FTopLine+1;
if nCol<12 then nCol:=12
else if nCol>62 then nCol:=62
else if (nCol>35) and (nCol<39) then nCol:=39;
if nCol mod 3=2 then nCol:=nCol-1;
//if nCol>FBlockBegin.BX then Inc(nCol)
//else Dec(nCol);
//if nLine>FBlockBegin.BY then Inc(nLine)
//else Dec(nCol); FBlockEnd.BX:= nCol;
FBlockEnd.BY:= nLine;
FLButtonDown:=False;
end;procedure THexEdit.MouseMove(Shift: TShiftState; X, Y: Integer);
var
nCol,nLine: Integer;
begin
inherited MouseMove(Shift, X, Y);
{if FLButtonDown then
begin
nCol:=((X-1) div FItemWidth)+FLeftCol;
nLine:=((Y-1) div FItemHeight)+FTopLine;
if nCol<12 then nCol:=12
else if nCol>62 then nCol:=62
else if (nCol>35) and (nCol<39) then nCol:=39;
if nCol mod 3=2 then nCol:=nCol-1;
//if nCol>FBlockBegin.BX then Inc(nCol)
//else Dec(nCol);
//if nLine>FBlockBegin.BY then Inc(nLine)
//else Dec(nLine);
FBlockEnd.BX:= nCol;
FBlockEnd.BY:= nLine;
PaintLine(nLine-1);
end;}
end;procedure THexEdit.WMSetFocus(var Msg: TWMSetFocus);
begin
inherited;
CreateCaret(Handle,HBitmap(nil),8,FItemHeight);
SetCaretPosition;
ShowCaret (Handle);
//Invalidate;
end;procedure THexEdit.WMKillFocus(var Msg: TWMKillFocus);
begin
inherited;
InvertRgn(Canvas.Handle,FInvertRgn);
FInvertRgn:=CreateRectRgn(0,0,0,0);
HideCaret(Handle);
DestroyCaret();
//Invalidate;
end;
{ Property Set/Get Routines }procedure THexEdit.SetBorder(Value: TBorderStyle);
begin
if Value <> FBorder then
begin
FBorder := Value;
RecreateWnd;
end;
end;procedure THexEdit.SetShowAddress(Value: Boolean);
begin
if FShowAddress <> Value then
begin
FShowAddress := Value;
Invalidate;
end;
end;procedure THexEdit.SetShowCharacters(Value: Boolean);
begin
if Value <> FShowCharacters then
begin
FShowCharacters := Value;
Invalidate;
end;
end;procedure THexEdit.SetFileColor(Index: Integer; Value: TColor);
begin
if FFileColors[Index] <> Value then
begin
FFileColors[Index] := Value;
Invalidate;
end;
end;function THexEdit.GetFileColor(Index: Integer): TColor;
begin
Result := FFileColors[Index];
end;procedure THexEdit.SetAddress(Value: Pointer);
begin
FActive := Value <> nil;
//FAddress := Value;
Invalidate;
end;function THexEdit.GetDataSize: Integer;
begin
Result:=FMStream.Size;
end;procedure THexEdit.SetDataSize(Value: Integer);
begin
//FDataSize := Value;
CalcPaintParams;
Invalidate;
//AdjustScrollBars;
end;function THexEdit.LineAddr(Index: Integer): PChar;
begin
Result :=PChar('0x'+IntToHex(Index*FBytesPerLine,8)+' ');
end;function THexEdit.LineData(Index: Integer): PChar;
var
sHex: string;
nB: Byte;
i: Integer;
begin
FMStream.Position:=Index*FBytesPerLine;
for i:=0 to FBytesPerLine-1 do
begin
FMStream.Read(nB,1);
AppendStr(sHex,IntToHex(nB,2));
AppendStr(sHex,' ');
if i=7 then AppendStr(sHex,' ');
end;
Result := PChar(sHex);
end;function THexEdit.LineChars(Index: Integer): PChar;
var
sChar: string;
i: Integer;
nB: Byte;
begin
sChar:=' ';
FMStream.Position:=Index*FBytesPerLine;
for i:=0 to FBytesPerLine-1 do
begin
FMStream.Read(nB,1);
if (nB>=$20) and (nB<$FF) then AppendStr(sChar,chr(nB))
else AppendStr(sChar,'.');
end;
Result := PChar(sChar);
end;procedure THexEdit.LoadFromFile(const FileName: TFileName);
begin
FMStream.LoadFromFile(FileName);
UpdateView;
FModified:=False;
end;procedure THexEdit.LoadFromStream(Stream: TStream);
begin
FMStream.LoadFromStream(Stream);
UpdateView;
FModified:=False;
end;procedure THexEdit.UpdateView;
begin
FTopLine:=0;
CalcPaintParams;
Invalidate;
end;procedure THexEdit.SetCaretPosition;
var
nCol: Integer;
begin
HideCaret(Handle);
{if FCaretCol<12 then FCaretCol:=12
else if FCaretCol>61 then FCaretCol:=61;
if (FCaretCol mod 3)=2 then Inc(FCaretCol);
if (FCaretCol>35) and (FCaretCol<39) then FCaretCol:=39;
if FCaretRow>=FVisibleLines then
begin
FCaretRow:=FVisibleLines-1;
CurrentLine:=CurrentLine+1;
end
else if FCaretRow<0 then
begin
FCaretRow:=0;
CurrentLine:=CurrentLine-1;
end;}
//SetCaretPos(FCaretCol*FItemWidth,FCaretRow*FItemHeight);
nCol:=(FCurrentCol div 3)-4;
if FCurrentCol>=39 then nCol:=nCol-1;
FOffset:=FCurrentLine*FBytesPerLine+nCol;
FMStream.Position:=FOffset;
FMStream.Read(FCurrentWordValue,2);
FMStream.Position:=FOffset;
FMStream.Read(FCurrentCardinalValue,4);
FMStream.Position:=FOffset;
FMStream.Read(FCurrentByteValue,1);
if FCurrentLine>((FMStream.Size-15) div 16)+1 then
begin
FCurrentLine:=((FMStream.Size-15) div 16)+1;
if FCurrentCol>(FMStream.Size mod 16)*3+12 then FCurrentCol:=(FMStream.Size mod 16)*3+12;
if (FCurrentCol>34) and (FCurrentCol<39) then FCurrentCol:=34;
end
else if FCurrentLine=((FMStream.Size-15) div 16)+1 then
begin
if FCurrentCol>(FMStream.Size mod 16)*3+12 then FCurrentCol:=(FMStream.Size mod 16)*3+12;
if (FCurrentCol>34) and (FCurrentCol<39) then FCurrentCol:=34;
end;
SetCaretPos((FCurrentCol-FLeftCol)*FItemWidth,(FCurrentLine-FTopLine)*FItemHeight);
ShowCaret(Handle);
end;procedure THexEdit.SetCurrentCol(Value: Integer);
begin
if Value<>FCurrentCol then
begin
FCurrentCol:=Value;
if FCurrentCol>=62 then
begin
FCurrentCol:=12;
CurrentLine:=CurrentLine+1;
end
else if (FCurrentCol>34) and (FCurrentCol<39) then
FCurrentCol:=39
else if FCurrentCol<12 then
begin
FCurrentCol:=61;
CurrentLine:=CurrentLine-1;
end;
if (FCurrentCol mod 3)=2 then
Inc(FCurrentCol);
if FCurrentCol-FLeftCol+1>=FVisibleCols then
begin
LeftCol:=FCurrentCol-FVisibleCols+4;
end
else if FCurrentCol<FLeftCol then
LeftCol:=FCurrentCol;
{FCaretCol:=FCurrentCol-FLeftCol;
if FCaretRow<0 then
begin
SetTopLine(FCurrentLine);
FCaretRow:=0;
end
else if FCaretRow>FTopLine+FVisibleLines then
begin
SetTopLine(FCurrentLine-FVisibleLines);
FCaretRow:=FVisibleLines-1;
end;}
end;
end;procedure THexEdit.SetCaretCol(Value: Integer);
begin
if Value<>FCaretCol then
begin
FCurrentCol:=FLeftCol+Value;
if FCurrentCol>=62 then
begin
FCurrentCol:=12;
CaretRow:=CaretRow+1;
end
else if (FCurrentCol>34) and (FCurrentCol<39) then
FCurrentCol:=39
else if FCurrentCol<12 then
begin
FCurrentCol:=61;
CaretRow:=CaretRow-1;
end;
if (FCurrentCol mod 3)=2 then
Inc(FCurrentCol);
if FCurrentCol-FLeftCol+1>=FVisibleCols then
begin
LeftCol:=FCurrentCol-FVisibleCols+4;
end
else if FCurrentCol<FLeftCol then
LeftCol:=FCurrentCol;
FCaretCol:=FCurrentCol-FLeftCol;
if FCaretRow<0 then
begin
SetTopLine(FCurrentLine);
FCaretRow:=0;
end
else if FCaretRow>FTopLine+FVisibleLines then
begin
SetTopLine(FCurrentLine-FVisibleLines);
FCaretRow:=FVisibleLines-1;
end;
end;
end;procedure THexEdit.SetCaretRow(Value: Integer);
begin
if Value<>FCaretRow then
begin
FCaretRow:=Value;
CurrentLine:=FCaretRow+FTopLine;
end;
end;
procedure THexEdit.SaveToFile(const FileName: TFileName);
begin
FMStream.SaveToFile(FileName);
end;procedure THexEdit.SaveToStream(Stream: TStream);
begin
FMStream.SaveToStream(Stream);
end;procedure THexEdit.SetOffset(const Value: Integer);
begin
FOffset := Value;
CurrentLine:=FOffset div 16;
CaretCol:=FOffset mod 16;
end;procedure THexEdit.SetCurrentByteValue(Value: Byte);
begin
FCurrentByteValue:=Value;
FMStream.Read(Value,1);
end;procedure THexEdit.SetCurrentCardinalValue(Value: Cardinal);
begin
FCurrentCardinalValue := Value;
FMStream.Read(Value,4);
end;procedure THexEdit.SetCurrentWordValue(Value: Word);
begin
FCurrentWordValue := Value;
FMStream.Read(Value,2);
end;end.
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;type
TCaretStyle = (csFull , csLeftLine , csBottomLine ); TBlock = record
BX: Integer;
BY: Integer;
end; THexEdit = class(TCustomControl)
private
FActive: Boolean;
FReadOnly: Boolean;
FTopLine: Integer;
FLeftCol: Integer;
FCurrentLine: Integer;
FCurrentCol: Integer;
FUpdateByte: Byte;
FVisibleLines: Integer;
FVisibleCols: Integer;
FLineCount: Integer;
FColCount: Integer;
FBytesPerLine: Integer;
FItemHeight: Integer;
FItemWidth: Integer;
FFileColors: array[0..2] of TColor;
FShowCharacters: Boolean;
FShowAddress: Boolean;
FBorder: TBorderStyle;
FCaretRow,FCaretCol: Integer;
FLineAddr: array[0..15] of char;
FTextWidth: Integer;
FCaretCreate: Boolean;
FLButtonDown: Boolean;
FBlockBegin: TBlock;
FBlockEnd: TBlock;
//FSelStartCol,FSelStartLine: Integer;
//FSelectStartCol,FSelectStartLine: Integer;
//FOldSelectEndCol,FOldSelectEndLine: Integer;
//FSelectEndCol,FSelectEndLine: Integer;
FMStream: TMemoryStream;
FModified: Boolean;
FInvertRgn: HRGN;
FOnMouseDown: TNotifyEvent;
FOffset: Integer;
FCurrentByteValue: Byte;
FOnKeyDown: TNotifyEvent;
FCurrentCardinalValue: Cardinal;
FCurrentWordValue: Word;
procedure CalcPaintParams;
//procedure SetReadOnly(Value: Boolean);
procedure SetTopLine(Value: Integer);
procedure SetCurrentCol(Value: Integer);
procedure SetCurrentLine(Value: Integer);
procedure SetFileColor(Index: Integer; Value: TColor);
function GetFileColor(Index: Integer): TColor;
procedure SetShowCharacters(Value: Boolean);
procedure SetShowAddress(Value: Boolean);
procedure SetBorder(Value: TBorderStyle);
procedure SetAddress(Value: Pointer);
function GetDataSize: Integer;
procedure SetDataSize(Value: Integer);
procedure AdjustScrollBars;
function LineAddr(Index: Integer): PChar;
function LineData(Index: Integer): PChar;
function LineChars(Index: Integer): PChar;
function ScrollIntoView: Boolean;
// procedure InvalidateLine(Index: Integer);
procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
procedure CMEnter(var Message: TCMGotFocus); message CM_ENTER;
procedure CMExit(var Message: TCMLostFocus); message CM_EXIT;
procedure WMSize(var Message: TWMSize); message WM_SIZE;
procedure WMVScroll(var Message: TWMVScroll); message WM_VSCROLL;
procedure WMHScroll(var Message: TWMHScroll); message WM_HSCROLL;
procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;
//procedure WMKeyDown(var Message: TWMKeyDown); message WM_KEYDOWN;
procedure WMSetFocus(var Msg: TWMSetFocus); message WM_SETFOCUS;
procedure WMKillFocus(var Msg: TWMKillFocus); message WM_KILLFOCUS;
procedure SetCaretPosition;
procedure SetCaretCol(Value: Integer);
procedure SetCaretRow(Value: Integer);
procedure SetLeftCol(Value: Integer);
procedure PaintCell(ACol,ARow: Integer); overload;
procedure PaintCell; overload;
procedure PaintLine(Index: Integer);
procedure SetSelction;
function GetRgn(var StartCol,StartLine,EndCol,EndLine: Integer): HRgn;
procedure SetOffset(const Value: Integer);
procedure SetCurrentByteValue(Value: Byte);
procedure SetCurrentCardinalValue(Value: Cardinal);
procedure SetCurrentWordValue(Value: Word);
protected
procedure CreateParams(var Params: TCreateParams); override;
procedure Paint; override;
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
procedure UpdateView;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure LoadFromFile(const FileName: TFileName);
procedure LoadFromStream(Stream: TStream);
procedure SaveToFile(const FileName: TFileName);
procedure SaveToStream(Stream: TStream);
property CurrentLine: Integer read FCurrentLine write SetCurrentLine;
property CaretCol: Integer read FCaretCol write SetCaretCol;
property CurrentCol: Integer read FCurrentCol write SetCurrentCol;
property CaretRow: Integer read FCaretRow write SetCaretRow;
property LeftCol: Integer read FLeftCol write SetLeftCol;
property Offset: Integer read FOffset write SetOffset;
property CurrentByteValue: Byte read FCurrentByteValue write SetCurrentByteValue;
property CurrentWordValue: Word read FCurrentWordValue write SetCurrentWordValue;
property CurrentCardinalValue: Cardinal read FCurrentCardinalValue write SetCurrentCardinalValue;
//property DataSize: Integer read GetDataSize write SetDataSize;
property Modified: Boolean read FModified;
published
property Align;
property Border: TBorderStyle read FBorder write SetBorder default bsNone;
property Color default clWhite;
property Ctl3D;
property Font;
property PopupMenu;
property ReadOnly: Boolean read FReadOnly write FReadOnly;
property TabOrder;
property TabStop;
property ShowAddress: Boolean read FShowAddress write SetShowAddress default True;
property ShowCharacters: Boolean read FShowCharacters write SetShowCharacters default True;
property AddressColor: TColor index 0 read GetFileColor write SetFileColor default clBlack;
property HexDataColor: TColor index 1 read GetFileColor write SetFileColor default clBlack;
property AnsiCharColor: TColor index 2 read GetFileColor write SetFileColor default clBlack;
property OnMouseDown: TNotifyEvent read FOnMouseDown write FOnMouseDown;
property OnKeyDown: TNotifyEvent read FOnKeyDown write FOnKeyDown;
end;const
MAXDIGITS = 16;
AlphaDigit = [48..57,65..70,96..105];procedure Register;implementationprocedure Register;
begin
RegisterComponents('LCC', [THexEdit]);
end;{ THexEdit }constructor THexEdit.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
ControlStyle := [csFramed];
FBorder := bsNone;
Color := clWhite;
FShowAddress := True;
FShowCharacters := True;
Width := 300;
Height := 200;
FBytesPerLine:=16;
FVisibleLines:=16;
FItemHeight:=12;
FItemWidth:=18;
FCaretCreate:=False;
FLButtonDown:=False;
FMStream:=TMemoryStream.Create;
FModified:=False;
end;destructor THexEdit.Destroy;
begin
FMStream.Free;
inherited Destroy;
end;
procedure THexEdit.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
//CreateSubClass(Params, 'RICHEDIT');
with Params do
begin
Style := Style or WS_TABSTOP or WS_VSCROLL or WS_HSCROLL;
WindowClass.style := CS_DBLCLKS;
if FBorder = bsSingle then
if NewStyleControls and Ctl3D then
begin
Style := Style and not WS_BORDER;
ExStyle := ExStyle or WS_EX_CLIENTEDGE;
end
else
Style := Style and not WS_BORDER;
end;end;{procedure THexEdit.SetReadOnly(Value: Boolean);
begin
if
end;}{ VCL Command Messages }procedure THexEdit.CMFontChanged(var Message: TMessage);
begin
inherited;
Canvas.Font := Self.Font;
FItemHeight := Canvas.TextHeight('A');// + 2;
FItemWidth := Canvas.TextWidth('D');
CalcPaintParams;
AdjustScrollBars;
end;procedure THexEdit.CMEnter;
begin
inherited;
{ InvalidateLineMarker; }
end;procedure THexEdit.CMExit;
begin
inherited;
{ InvalidateLineMarker; }
end;{ Windows Messages }procedure THexEdit.WMSize(var Message: TWMSize);
begin
inherited;
CalcPaintParams;
AdjustScrollBars;
end;procedure THexEdit.WMGetDlgCode(var Message: TWMGetDlgCode);
begin
Message.Result := DLGC_WANTARROWS;
end;procedure THexEdit.SetLeftCol(Value: Integer);
var
R: TRect;
begin
if Value <> FLeftCol then
begin
SetScrollPos(Handle, SB_HORZ, Value, True);
R := Bounds(0, 0, ClientWidth , ClientHeight);
ScrollWindow(Handle, FItemWidth * (FLeftCol - Value),0, @R, nil);
FLeftCol := Value;
end;
end;procedure THexEdit.WMHScroll(var Message: TWMHScroll);
var
NewLeftCol: Integer;
//R: TRect;
begin
inherited;
NewLeftCol := FLeftCol;
case Message.ScrollCode of
SB_LINEDOWN: Inc(NewLeftCol);
SB_LINEUP: Dec(NewLeftCol);
SB_PAGEDOWN: Inc(NewLeftCol, FVisibleCols - 1);
SB_PAGEUP: Dec(NewLeftCol, FVisibleCols - 1);
SB_THUMBPOSITION, SB_THUMBTRACK: NewLeftCol := Message.Pos;
end; if NewLeftCol < 0 then NewLeftCol := 0;
if NewLeftCol >= 82 then
NewLeftCol := 81;
FCaretCol:=FCaretCol+LeftCol-NewLeftCol;
SetCaretPosition;
LeftCol:=NewLeftCol;
end;
procedure THexEdit.WMVScroll(var Message: TWMVScroll);
var
NewTopLine: Integer;
LinesMoved: Integer;
R: TRect;
begin
inherited;
NewTopLine := FTopLine;
case Message.ScrollCode of
SB_LINEDOWN: Inc(NewTopLine);
SB_LINEUP: Dec(NewTopLine);
SB_PAGEDOWN: Inc(NewTopLine, FVisibleLines - 1);
SB_PAGEUP: Dec(NewTopLine, FVisibleLines - 1);
SB_THUMBPOSITION, SB_THUMBTRACK: NewTopLine := Message.Pos;
end; if NewTopLine < 0 then NewTopLine := 0;
if NewTopLine >= FLineCount then
NewTopLine := FLineCount - 1; if NewTopLine <> FTopLine then
begin
//FCaretRow:=FCaretRow+FTopLine-NewTopLine; LinesMoved := FTopLine - NewTopLine;
FTopLine := NewTopLine;
SetScrollPos(Handle, SB_VERT, FTopLine, True);
SetCaretPosition;
if Abs(LinesMoved) = 1 then
begin
if LinesMoved=1 then
begin
R := Bounds(0, 0, ClientWidth, ClientHeight - FItemHeight);
ScrollWindow(Handle, 0, FItemHeight * LinesMoved, @R, nil);
PaintLine(FTopLine+FVisibleLines+1);
end
else
begin
R := Bounds(0, FItemHeight, ClientWidth, ClientHeight);
ScrollWindow(Handle, 0, FItemHeight * LinesMoved, @R, nil);
PaintLine(FTopLine-1);
end;
end
else Invalidate;
end;
end;{ Painting Related }procedure THexEdit.CalcPaintParams;
const
Divisor: array[boolean] of Integer = (3,4);
var
CharsPerLine: Integer;begin
if FItemHeight < 1 then Exit;
FVisibleLines := (ClientHeight div FItemHeight);
FVisibleCols := (ClientWidth div FItemWidth)+1;
CharsPerLine := ClientWidth div FItemWidth;
if FShowAddress then Dec(CharsPerLine, 10);
FLineCount := ((FMStream.Size-15) div FBytesPerLine)+2;
if FMStream.Size>0 then FColCount := 82;
AdjustScrollBars;
end;{procedure THexEdit.InvalidateLine(Index: Integer);
var
R: TRect;
begin
if (Index >= FTopLine) and (Index <= FTopLine + FVisibleLines - 1) then
begin
R := Rect(0, 0, ClientWidth, FItemHeight);
OffsetRect(R, 0, (Index - FTopLine) * FItemHeight);
Windows.InvalidateRect(Handle, @R, False);
end;
end;}procedure THexEdit.AdjustScrollBars;
var
ScrollInfo: TScrollInfo;
begin
ScrollInfo.fMask:=SIF_ALL;
ScrollInfo.nPage:=FVisibleLines;
ScrollInfo.nMin:=0;
ScrollInfo.nMax:=FLineCount;//-FVisibleLines;
ScrollInfo.nPos:=0;
SetScrollInfo(Handle,SB_VERT,ScrollInfo,True);
ScrollInfo.fMask:=SIF_ALL;
ScrollInfo.nPage:=FVisibleCols;
ScrollInfo.nMin:=0;
ScrollInfo.nMax:=FColCount;//-FVisibleCols;// - (ClientWidth div FItemWidth);
ScrollInfo.nPos:=0;
SetScrollInfo(Handle,SB_HORZ,ScrollInfo,True);
LeftCol:=0;
end;function THexEdit.ScrollIntoView: Boolean;
begin
Result := False;
if FCurrentLine < FTopLine then
begin
Result := True;
SetTopLine(FCurrentLine);
end
else if FCurrentLine >= (FTopLine + FVisibleLines) - 1 then
begin
SetTopLine(FCurrentLine - (FVisibleLines - 2));
Result := True;
end;
end;procedure THexEdit.SetTopLine(Value: Integer);
var
LinesMoved: Integer;
R: TRect;
begin
if Value <> FTopLine then
begin
if Value < 0 then Value := 0;
if Value >= FLineCount then Value := FLineCount - 1; LinesMoved := FTopLine - Value;
FTopLine := Value;
SetScrollPos(Handle, SB_VERT, FTopLine, True);
if Abs(LinesMoved) = 1 then
begin
R:=Bounds(0,0,ClientWidth,ClientHeight);
ScrollWindow(Handle, 0, FItemHeight*LinesMoved,@R,nil);
PaintLine(Value);
end
else Invalidate;
end;
end;procedure THexEdit.SetCurrentLine(Value: Integer);
var
R: TRect;
nLineMove: Integer;
begin
if Value <> FCurrentLine then
begin
if Value < 0 then Value := 0;
if Value >= FLineCount then Value := FLineCount - 1;
nLineMove:=FCurrentLine-Value;
//SetTopLine(FTopLine+nLineMove);
if (Value>=FTopLine+FVisibleLines) or (Value<FTopLine) then
if Abs(nLineMove)=1 then
begin
SetTopLine(FTopLine-nLineMove);
//SetScrollPos(Handle,SB_VERT,FTopLine,True);
{R:=Bounds(0,0,ClientWidth,ClientHeight);
ScrollWindow(Handle, 0, FItemHeight*nLineMove,@R,nil);
PaintLine(Value);}
end
else
begin
SetTopLine(FTopLine-nLineMove);
end;
FCurrentLine:=Value;
SetCaretPosition;
end;
end;procedure THexEdit.PaintCell;
begin
HideCaret(Handle);
TextOut(Canvas.Handle,((FCurrentCol div 3)*3-FLeftCol)*FItemWidth,(FCurrentLine-FTopLine)*FItemHeight,PChar(IntToHex(FUpdateByte,2)),2);
TextOut(Canvas.Handle,(63-FLeftCol)*FItemWidth,(FCurrentLine-FTopLine)*FItemHeight,LineChars(FCurrentLine),19);
ShowCaret(Handle);
end;procedure THexEdit.PaintCell(ACol,ARow: Integer);
begin
HideCaret(Handle);
TextOut(Canvas.Handle,((ACol div 3)*3-FLeftCol)*FItemWidth,(ARow-FTopLine)*FItemHeight,PChar(IntToHex(FUpdateByte,2)),2);
TextOut(Canvas.Handle,(63-FLeftCol)*FItemWidth,(ARow-FTopLine)*FItemHeight,LineChars(ARow),19);
ShowCaret(Handle);
end;procedure THexEdit.PaintLine(Index: Integer);
var
R: TRect;
AddressWidth: Integer;
TabStop: Integer;
ByteCnt: Integer;
//OldColor,OldBrushColor: TColor;
begin
HideCaret(Handle);
R := Bounds(1, FItemHeight*Index, FItemWidth*82, FItemHeight);
if FShowAddress then AddressWidth := FItemWidth*12
else AddressWidth := 0;
TabStop := FItemWidth*3;
ByteCnt := FBytesPerLine;
if (Index + FTopLine < FLineCount) and (Index+FTopLine>=0) then
begin
R.Left := R.Left-FItemWidth*FLeftCol;
if FShowAddress then
begin
Canvas.Font.Color := FFileColors[0];
ExtTextOut(Canvas.Handle, R.Left, R.Top, ETO_OPAQUE or ETO_CLIPPED, @R, LineAddr(Index+FTopLine), 10, nil);
R.Left := R.Left + AddressWidth;
end;
{OldBrushColor:=Canvas.Brush.Color;
OldColor:=Canvas.Font.Color;
if ((FBlockBegin.BY<Index) and (FBlockEnd.BY>Index)) or
((FBlockBegin.BY>Index) and (FBlockEnd.BY<Index)) then
begin
Canvas.Brush.Color:=clBlack;
Canvas.Font.Color:=clWhite;
end
else
begin
Canvas.Brush.Color:=clWhite;
Canvas.Font.Color:=clBlack;
end;}
if (Index+FTopLine = FLineCount-1) and ((FMStream.Size mod FBytesPerLine) > 0) then
ByteCnt := FMStream.Size mod FBytesPerLine;
TabbedTextOut(Canvas.Handle, R.Left, R.Top, LineData(Index+FTopLine),
(ByteCnt*3)+3, 1, TabStop, R.Left);
//Canvas.Font.Color := OldColor;
//Canvas.Brush.Color:=OldBrushColor;
if FShowCharacters then
begin
R.Left := R.Left + (FItemWidth*(FBytesPerLine*3+3));
Canvas.Font.Color := FFileColors[2];
ExtTextOut(Canvas.Handle, R.Left, R.Top, ETO_OPAQUE or ETO_CLIPPED, @R, LineChars(Index+FTopLine), ByteCnt+3, nil);
end;
end
else ExtTextOut(Canvas.Handle, R.Left, R.Top, ETO_OPAQUE or ETO_CLIPPED,
@R, nil, 0, nil);
ShowCaret(Handle);
end;procedure THexEdit.Paint;
{var
R: TRect;
I: Integer;
AddressWidth: Integer;
TabStop: Integer;
ByteCnt: Integer;}
var
I: Integer;
begin
inherited Paint;
Canvas.Brush.Color := Self.Color;
if FMStream.Size>0 then
for I := -1 to FVisibleLines+1 do
begin
PaintLine(I);
end;
{Canvas.Brush.Color := Self.Color;
if FShowAddress then AddressWidth := FItemWidth*12
else AddressWidth := 0;
//R := Bounds(1, 0, ClientWidth, FItemHeight);
R := Bounds(1, 0, FItemWidth*82, FItemHeight);
TabStop := FItemWidth*3;
Canvas.Font.Color := FFileColors[1];
ByteCnt := FBytesPerLine;
for I := 0 to FVisibleLines - 1 do
begin
R.Left := 1;
if I + FTopLine < FLineCount then
begin
R.Left := R.Left-FItemWidth*FLeftCol;
if FShowAddress then
begin
Canvas.Font.Color := FFileColors[0];
//R.Right := R.Left + AddressWidth;
ExtTextOut(Canvas.Handle, R.Left, R.Top, ETO_OPAQUE or ETO_CLIPPED, @R, LineAddr(I+FTopLine), 10, nil);
R.Left := R.Left + AddressWidth;
//R.Right := ClientWidth;
Canvas.Font.Color := FFileColors[1];
end;
if (I+FTopLine = FLineCount-1) and ((DataSize mod FBytesPerLine) > 0) then
ByteCnt := DataSize mod FBytesPerLine;
TabbedTextOut(Canvas.Handle, R.Left, R.Top, LineData(I+FTopLine),
(ByteCnt*3)+3, 1, TabStop, R.Left);
if FShowCharacters then
begin
R.Left := R.Left + (FItemWidth*(FBytesPerLine*3+3));
Canvas.Font.Color := FFileColors[2];
ExtTextOut(Canvas.Handle, R.Left, R.Top, ETO_OPAQUE or ETO_CLIPPED, @R, LineChars(I+FTopLine), ByteCnt+3, nil);
//Beep;
end;
end
else ExtTextOut(Canvas.Handle, R.Left, R.Top, ETO_OPAQUE or ETO_CLIPPED,
@R, nil, 0, nil);
OffsetRect(R, 0, FItemHeight);
end;}
end;{ Event Overrides }function GetDigit(Key: Word): Integer;
begin
Result:=Key-48;
if Result>9 then
begin
Result:=Key-55;
if Result>16 then
Result:=Key-96;
end;
end;procedure THexEdit.KeyDown(var Key: Word; Shift: TShiftState);
var
nB: Byte;
nCol: Integer;
begin
inherited KeyDown(Key, Shift);
//procedure THexEdit.WMKeyDown(var Message: TWMKeyDown);
//var
//nB: Byte;
//begin
if not FActive then Exit;
if FReadOnly then Exit;
case Key of //Message.CharCode
VK_DOWN:
begin
//CaretRow := CaretRow + 1;
CurrentLine := CurrentLine + 1;
SetCaretPosition;
end;
VK_UP:
begin
//CaretRow := CaretRow - 1;
CurrentLine := CurrentLine - 1;
SetCaretPosition;
end;
VK_NEXT: CurrentLine := CurrentLine + FVisibleLines;
VK_PRIOR: CurrentLine := CurrentLine - FVisibleLines;
VK_HOME:
begin
FCurrentCol := 12;
SetCaretPosition;
end;
VK_END:
begin
FCurrentCol := 62;
SetCaretPosition;
end;
VK_LEFT:
begin
if FCurrentCol=39 then FCurrentCol:=36;
if (CurrentCol mod 3)=0 then CurrentCol:=CurrentCol-2
else CurrentCol:=CurrentCol-1;
SetCaretPosition;
end;
VK_RIGHT:
begin
CurrentCol:=CurrentCol+1;
SetCaretPosition;
end
else
begin
if Key In AlphaDigit then
begin
if FTopLine>FCurrentLine then SetTopLine(FCurrentLine)
else if FTopLine<=FCurrentLine-FVisibleLines then SetTopLine(FCurrentLine-FVisibleLines+2);
SetCaretPosition;
nCol:=(FCurrentCol div 3)-4;
if FCurrentCol>=39 then nCol:=nCol-1;
FMStream.Position:=FCurrentLine*FBytesPerLine+nCol;//FTopLine+FCaretRow
FMStream.Read(nB,1);
if (FCurrentCol mod 3)=0 then
begin
nB:=nB and $F;
nB:=nB +(GetDigit(Key) shl 4);
end
else
begin
nB:=nB and $F0;
nB:=nB +GetDigit(Key);
end;
FMStream.Position:=FMStream.Position-1;
FMStream.Write(nB,1);
FUpdateByte:=nB;
PaintCell;
CurrentCol:=CurrentCol+1;
//CaretCol:=CaretCol+1;
//if FVisibleCols+FLeftCol<=FCaretCol then
//LeftCol:=FCaretCol-FVisibleCols+1;
FModified:=False;
end
else
begin
inherited;
end;
end;
end;
if Assigned(FOnKeyDown) then FOnKeyDown(Self);
end;function THexEdit.GetRgn(var StartCol,StartLine,EndCol,EndLine: Integer): HRgn;
var
rgn: HRgn;
YOffset1,yOffset,y1,y2: Integer;
Points: array[0..7] of TPoint;
nIndex,nTemp: Integer;
s: string;
begin
YOffset1:=EndLine-StartLine;
if Yoffset1<0 then
begin
nTemp:=EndLine;
EndLine:=StartLine;
StartLine:=nTemp;
YOffset1:=-YOffset1;
end;
if (YOffset1>2) then
begin
if YOffset1>0 then
begin
yOffset:=1;
y1:=62;
y2:=12;
end;
//else
//begin
//y1:=12;
//y2:=62;
//yOffset:=-1;
//end;
nIndex:=0;
Points[nIndex].X:=StartCol*FItemWidth;
Points[nIndex].Y:=StartLine*FItemHeight;
s:=s+IntToStr(Points[nIndex].X)+','+IntToStr(Points[nIndex].Y)+' ';
Inc(nIndex); Points[nIndex].X:=y1*FItemWidth;
Points[nIndex].Y:=StartLine*FItemHeight;
s:=s+IntToStr(Points[nIndex].X)+','+IntToStr(Points[nIndex].Y)+' ';
Inc(nIndex); Points[nIndex].X:=y1*FItemWidth;
Points[nIndex].Y:=(EndLine-yOffset)*FItemHeight;
s:=s+IntToStr(Points[nIndex].X)+','+IntToStr(Points[nIndex].Y)+' ';
Inc(nIndex); Points[nIndex].X:=EndLine*FItemWidth;
Points[nIndex].Y:=(EndLine-yOffset)*FItemHeight;
s:=s+IntToStr(Points[nIndex].X)+','+IntToStr(Points[nIndex].Y)+' ';
Inc(nIndex); Points[nIndex].X:=EndLine*FItemWidth;
Points[nIndex].Y:=EndLine*FItemHeight;
s:=s+IntToStr(Points[nIndex].X)+','+IntToStr(Points[nIndex].Y)+' ';
Inc(nIndex);
Points[nIndex].X:=y2*FItemWidth;
Points[nIndex].Y:=EndLine*FItemHeight;
s:=s+IntToStr(Points[nIndex].X)+','+IntToStr(Points[nIndex].Y)+' ';
Inc(nIndex); Points[nIndex].X:=y2*FItemWidth;
Points[nIndex].Y:=(StartLine+yOffset)*FItemHeight;
s:=s+IntToStr(Points[nIndex].X)+','+IntToStr(Points[nIndex].Y)+' ';
Inc(nIndex); Points[nIndex].X:=StartCol*FItemWidth;
Points[nIndex].Y:=(StartLine+yOffset)*FItemHeight;
s:=s+'('+IntToStr(Points[nIndex].X)+','+IntToStr(Points[nIndex].Y)+') ';
Inc(nIndex);
rgn:=CreatePolygonRgn(Points,nIndex,ALTERNATE);
StartCol:=EndCol;
StartLine:=EndLine;//-yOffset;
//if yOffset>0 then Dec(StartLine);
end;
{else
rgn:=CreateRectRgn(StartCol*FItemWidth,StartLine*FItemHeight,
EndLine*FItemWidth,EndLine*FItemHeight);}
Result:=rgn;
end;procedure THexEdit.SetSelction;
var
rgn: HRgn;
begin
//rgn:=GetRgn(FSelectStartCol,FSelectStartLine,FSelectEndCol,FSelectEndLine);
//InvertRgn(Canvas.Handle,FInvertRgn);
//InvertRgn(Canvas.Handle,rgn);
//FInvertRgn:=rgn;
end;procedure THexEdit.MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin
inherited MouseDown(Button, Shift, X, Y);
if not Focused then SetFocus;
FActive:=True;
if FColCount>0 then
begin
if (Button = mbLeft) and FActive then
begin
InvertRgn(Canvas.Handle,FInvertRgn);
FInvertRgn:=CreateRectRgn(0,0,0,0);
FCurrentLine:=(Y div FItemHeight)+FTopLine;
FCurrentCol:=(X div FItemWidth)+FLeftCol;
if FCurrentCol<12 then FCurrentCol:=12
else if FCurrentCol>62 then FCurrentCol:=62
else if (FCurrentCol>34) and (FCurrentCol<39) then FCurrentCol:=39;
if FCurrentCol mod 3=2 then FCurrentCol:=FCurrentCol-1; SetCaretPosition;
FLButtonDown:=True;
FBlockBegin.BX:=FCurrentCol;
FBlockBegin.BY:=FCurrentLine;
FBlockEnd:=FBlockBegin;
FOffset:=FCurrentLine*16+((FCurrentCol-12) div 3);
if FCurrentCol>=39 then Dec(FOffset);
//FSelectStartCol:=;
//FSelectStartLine:=FCurrentLine;
//FSelStartCol:=FCurrentCol;
//FSelStartLine:=FCurrentLine;
end;
if Assigned(FOnMouseDown) then FOnMouseDown(Self);
end
else
HideCaret(Handle)
end;procedure THexEdit.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
nCol,nLine: Integer;
begin
inherited MouseUp(Button, Shift, X, Y);
nCol:=((X-1) div FItemWidth)+FLeftCol;
nLine:=((Y-1) div FItemHeight)+FTopLine+1;
if nCol<12 then nCol:=12
else if nCol>62 then nCol:=62
else if (nCol>35) and (nCol<39) then nCol:=39;
if nCol mod 3=2 then nCol:=nCol-1;
//if nCol>FBlockBegin.BX then Inc(nCol)
//else Dec(nCol);
//if nLine>FBlockBegin.BY then Inc(nLine)
//else Dec(nCol); FBlockEnd.BX:= nCol;
FBlockEnd.BY:= nLine;
FLButtonDown:=False;
end;procedure THexEdit.MouseMove(Shift: TShiftState; X, Y: Integer);
var
nCol,nLine: Integer;
begin
inherited MouseMove(Shift, X, Y);
{if FLButtonDown then
begin
nCol:=((X-1) div FItemWidth)+FLeftCol;
nLine:=((Y-1) div FItemHeight)+FTopLine;
if nCol<12 then nCol:=12
else if nCol>62 then nCol:=62
else if (nCol>35) and (nCol<39) then nCol:=39;
if nCol mod 3=2 then nCol:=nCol-1;
//if nCol>FBlockBegin.BX then Inc(nCol)
//else Dec(nCol);
//if nLine>FBlockBegin.BY then Inc(nLine)
//else Dec(nLine);
FBlockEnd.BX:= nCol;
FBlockEnd.BY:= nLine;
PaintLine(nLine-1);
end;}
end;procedure THexEdit.WMSetFocus(var Msg: TWMSetFocus);
begin
inherited;
CreateCaret(Handle,HBitmap(nil),8,FItemHeight);
SetCaretPosition;
ShowCaret (Handle);
//Invalidate;
end;procedure THexEdit.WMKillFocus(var Msg: TWMKillFocus);
begin
inherited;
InvertRgn(Canvas.Handle,FInvertRgn);
FInvertRgn:=CreateRectRgn(0,0,0,0);
HideCaret(Handle);
DestroyCaret();
//Invalidate;
end;
{ Property Set/Get Routines }procedure THexEdit.SetBorder(Value: TBorderStyle);
begin
if Value <> FBorder then
begin
FBorder := Value;
RecreateWnd;
end;
end;procedure THexEdit.SetShowAddress(Value: Boolean);
begin
if FShowAddress <> Value then
begin
FShowAddress := Value;
Invalidate;
end;
end;procedure THexEdit.SetShowCharacters(Value: Boolean);
begin
if Value <> FShowCharacters then
begin
FShowCharacters := Value;
Invalidate;
end;
end;procedure THexEdit.SetFileColor(Index: Integer; Value: TColor);
begin
if FFileColors[Index] <> Value then
begin
FFileColors[Index] := Value;
Invalidate;
end;
end;function THexEdit.GetFileColor(Index: Integer): TColor;
begin
Result := FFileColors[Index];
end;procedure THexEdit.SetAddress(Value: Pointer);
begin
FActive := Value <> nil;
//FAddress := Value;
Invalidate;
end;function THexEdit.GetDataSize: Integer;
begin
Result:=FMStream.Size;
end;procedure THexEdit.SetDataSize(Value: Integer);
begin
//FDataSize := Value;
CalcPaintParams;
Invalidate;
//AdjustScrollBars;
end;function THexEdit.LineAddr(Index: Integer): PChar;
begin
Result :=PChar('0x'+IntToHex(Index*FBytesPerLine,8)+' ');
end;function THexEdit.LineData(Index: Integer): PChar;
var
sHex: string;
nB: Byte;
i: Integer;
begin
FMStream.Position:=Index*FBytesPerLine;
for i:=0 to FBytesPerLine-1 do
begin
FMStream.Read(nB,1);
AppendStr(sHex,IntToHex(nB,2));
AppendStr(sHex,' ');
if i=7 then AppendStr(sHex,' ');
end;
Result := PChar(sHex);
end;function THexEdit.LineChars(Index: Integer): PChar;
var
sChar: string;
i: Integer;
nB: Byte;
begin
sChar:=' ';
FMStream.Position:=Index*FBytesPerLine;
for i:=0 to FBytesPerLine-1 do
begin
FMStream.Read(nB,1);
if (nB>=$20) and (nB<$FF) then AppendStr(sChar,chr(nB))
else AppendStr(sChar,'.');
end;
Result := PChar(sChar);
end;procedure THexEdit.LoadFromFile(const FileName: TFileName);
begin
FMStream.LoadFromFile(FileName);
UpdateView;
FModified:=False;
end;procedure THexEdit.LoadFromStream(Stream: TStream);
begin
FMStream.LoadFromStream(Stream);
UpdateView;
FModified:=False;
end;procedure THexEdit.UpdateView;
begin
FTopLine:=0;
CalcPaintParams;
Invalidate;
end;procedure THexEdit.SetCaretPosition;
var
nCol: Integer;
begin
HideCaret(Handle);
{if FCaretCol<12 then FCaretCol:=12
else if FCaretCol>61 then FCaretCol:=61;
if (FCaretCol mod 3)=2 then Inc(FCaretCol);
if (FCaretCol>35) and (FCaretCol<39) then FCaretCol:=39;
if FCaretRow>=FVisibleLines then
begin
FCaretRow:=FVisibleLines-1;
CurrentLine:=CurrentLine+1;
end
else if FCaretRow<0 then
begin
FCaretRow:=0;
CurrentLine:=CurrentLine-1;
end;}
//SetCaretPos(FCaretCol*FItemWidth,FCaretRow*FItemHeight);
nCol:=(FCurrentCol div 3)-4;
if FCurrentCol>=39 then nCol:=nCol-1;
FOffset:=FCurrentLine*FBytesPerLine+nCol;
FMStream.Position:=FOffset;
FMStream.Read(FCurrentWordValue,2);
FMStream.Position:=FOffset;
FMStream.Read(FCurrentCardinalValue,4);
FMStream.Position:=FOffset;
FMStream.Read(FCurrentByteValue,1);
if FCurrentLine>((FMStream.Size-15) div 16)+1 then
begin
FCurrentLine:=((FMStream.Size-15) div 16)+1;
if FCurrentCol>(FMStream.Size mod 16)*3+12 then FCurrentCol:=(FMStream.Size mod 16)*3+12;
if (FCurrentCol>34) and (FCurrentCol<39) then FCurrentCol:=34;
end
else if FCurrentLine=((FMStream.Size-15) div 16)+1 then
begin
if FCurrentCol>(FMStream.Size mod 16)*3+12 then FCurrentCol:=(FMStream.Size mod 16)*3+12;
if (FCurrentCol>34) and (FCurrentCol<39) then FCurrentCol:=34;
end;
SetCaretPos((FCurrentCol-FLeftCol)*FItemWidth,(FCurrentLine-FTopLine)*FItemHeight);
ShowCaret(Handle);
end;procedure THexEdit.SetCurrentCol(Value: Integer);
begin
if Value<>FCurrentCol then
begin
FCurrentCol:=Value;
if FCurrentCol>=62 then
begin
FCurrentCol:=12;
CurrentLine:=CurrentLine+1;
end
else if (FCurrentCol>34) and (FCurrentCol<39) then
FCurrentCol:=39
else if FCurrentCol<12 then
begin
FCurrentCol:=61;
CurrentLine:=CurrentLine-1;
end;
if (FCurrentCol mod 3)=2 then
Inc(FCurrentCol);
if FCurrentCol-FLeftCol+1>=FVisibleCols then
begin
LeftCol:=FCurrentCol-FVisibleCols+4;
end
else if FCurrentCol<FLeftCol then
LeftCol:=FCurrentCol;
{FCaretCol:=FCurrentCol-FLeftCol;
if FCaretRow<0 then
begin
SetTopLine(FCurrentLine);
FCaretRow:=0;
end
else if FCaretRow>FTopLine+FVisibleLines then
begin
SetTopLine(FCurrentLine-FVisibleLines);
FCaretRow:=FVisibleLines-1;
end;}
end;
end;procedure THexEdit.SetCaretCol(Value: Integer);
begin
if Value<>FCaretCol then
begin
FCurrentCol:=FLeftCol+Value;
if FCurrentCol>=62 then
begin
FCurrentCol:=12;
CaretRow:=CaretRow+1;
end
else if (FCurrentCol>34) and (FCurrentCol<39) then
FCurrentCol:=39
else if FCurrentCol<12 then
begin
FCurrentCol:=61;
CaretRow:=CaretRow-1;
end;
if (FCurrentCol mod 3)=2 then
Inc(FCurrentCol);
if FCurrentCol-FLeftCol+1>=FVisibleCols then
begin
LeftCol:=FCurrentCol-FVisibleCols+4;
end
else if FCurrentCol<FLeftCol then
LeftCol:=FCurrentCol;
FCaretCol:=FCurrentCol-FLeftCol;
if FCaretRow<0 then
begin
SetTopLine(FCurrentLine);
FCaretRow:=0;
end
else if FCaretRow>FTopLine+FVisibleLines then
begin
SetTopLine(FCurrentLine-FVisibleLines);
FCaretRow:=FVisibleLines-1;
end;
end;
end;procedure THexEdit.SetCaretRow(Value: Integer);
begin
if Value<>FCaretRow then
begin
FCaretRow:=Value;
CurrentLine:=FCaretRow+FTopLine;
end;
end;
procedure THexEdit.SaveToFile(const FileName: TFileName);
begin
FMStream.SaveToFile(FileName);
end;procedure THexEdit.SaveToStream(Stream: TStream);
begin
FMStream.SaveToStream(Stream);
end;procedure THexEdit.SetOffset(const Value: Integer);
begin
FOffset := Value;
CurrentLine:=FOffset div 16;
CaretCol:=FOffset mod 16;
end;procedure THexEdit.SetCurrentByteValue(Value: Byte);
begin
FCurrentByteValue:=Value;
FMStream.Read(Value,1);
end;procedure THexEdit.SetCurrentCardinalValue(Value: Cardinal);
begin
FCurrentCardinalValue := Value;
FMStream.Read(Value,4);
end;procedure THexEdit.SetCurrentWordValue(Value: Word);
begin
FCurrentWordValue := Value;
FMStream.Read(Value,2);
end;end.
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货