⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hexedit.pas

📁 === === === MiniHex 1.61 源程序说明 ============================== “$(MiniHex)Source”目录中的所有
💻 PAS
📖 第 1 页 / 共 5 页
字号:
    if (X >= X1) and (X <= X2) then
    begin
      Col := I;
      CurInHex := False;
      CurInHigh := False;
      Break;
    end;
  end;
  Result := (OffRow <> -1) and (Col <> -1) and
    (GetDLen(FTopRow + OffRow, Col, CurInHigh) <= GetDataSize * 2);
end;

procedure TCustomHexEdit.MoveCaret(DLenOffset: Integer; Force: Boolean);
var
  OldDLen, DLen, AbsRow, OffRow, Col: Integer;
  OldTopRow: Integer;
  CurInHigh: Boolean;
begin
  OldTopRow := FTopRow;
  PosToDLen(DLen, FCurRow, FCurCol, FCurInHigh);
  OldDLen := DLen;
  DLen := DLen + DLenOffset;
  if DLen < 1 then DLen := 1
  else if DLen > GetDataSize * 2 then DLen := GetDataSize * 2;
  if (DLen = OldDLen) and not Force then Exit;

  DLenToPos(AbsRow, Col, CurInHigh, DLen);
  OffRow := AbsRow - FTopRow;

  DrawCurItemHighlight(False);
  DrawCurItem(False);

  FCurRow := AbsRow;
  FCurCol := Col;
  FCurInHigh := CurInHigh;

  if OffRow < 0 then
  begin
    FTopRow := AbsRow;
  end
  else if OffRow >= FVisRowCount then
  begin
    FTopRow := AbsRow - FVisRowCount + 1;
  end;

  DrawCurItem(True);
  DrawCurItemHighlight(True);

  if FTopRow <> OldTopRow then DrawAllRow;
  UpdateScrollPos(skVertical, FTopRow);
  DoOnCaretMove;
end;

procedure TCustomHexEdit.MoveCaretTo(DLen: Integer; Force: Boolean);
var
  CurDLen: Integer;
begin
  if DLen < 1 then DLen := 1;
  if DLen > GetDataSize * 2 then DLen := GetDataSize * 2;
  CurDLen := GetDLen;
  MoveCaret(DLen - CurDLen, Force);
end;

procedure TCustomHexEdit.RestrictCaret;
var
  DLen, AbsRow, Col: Integer;
  CurInHigh: Boolean;
begin
  if GetOffset > GetDataSize - 1 then
  begin
    DLen := OffsetToDLen(GetDataSize - 1);
    DLenToPos(AbsRow, Col, CurInHigh, DLen);
    FCurRow := AbsRow;
    FCurCol := Col;
  end;
end;

function TCustomHexEdit.CheckCaretInWindow: Boolean;
begin
  Result := (FCurRow >= FTopRow) and (FCurRow <= FTopRow + FVisRowCount - 1);
end;

procedure TCustomHexEdit.AdjustSelectionA(Offset1, Offset2: Integer);
begin
  if not (hoAllowSelect in FOptions) or
    not (hoShowCaret in FOptions) then Exit;

  if not FSelection.Active then
  begin
    SetSelection(Offset1, Offset2, False);
  end else
  begin
    if FSelection.StartOffset = Offset1 then
      SetSelectionStart(Offset2, False)
    else if FSelection.EndOffset = Offset1 then
      SetSelectionEnd(Offset2, False)
    else if Offset2 >= 0 then
      SetSelection(Offset2, Offset1, False);
  end;
end;

procedure TCustomHexEdit.AdjustSelectionB(Offset1, Offset2: Integer);
begin
  if not (hoAllowSelect in FOptions) or
    not (hoShowCaret in FOptions) then Exit;

  if not FSelection.Active then
  begin
    SetSelection(Offset1, Offset2, False);
  end else
  begin
    if FSelection.EndOffset = Offset1 then
      SetSelectionEnd(Offset2, False)
    else if  FSelection.StartOffset = Offset1 then
      SetSelectionStart(Offset2, False)
    else if Offset2 < GetDataSize then
      SetSelection(Offset1, Offset2, False);
  end;
end;

procedure TCustomHexEdit.SetSelection(StartOffset, EndOffset: Integer; Redraw: Boolean);
var
  OldSelection: TSelection;
begin
  OldSelection := FSelection;
  FSelection.Active := True;
  FSelection.StartOffset := StartOffset;
  FSelection.EndOffset := EndOffset;
  RestrictSelection;
  if Redraw then DoPaint;
  if not CompareMem(Pointer(@OldSelection), Pointer(@FSelection), SizeOf(TSelection)) then
    DoOnSelectionChange;
end;

procedure TCustomHexEdit.SetSelectionStart(StartOffset: Integer; Redraw: Boolean);
begin
  if StartOffset < 0 then StartOffset := 0;
  if StartOffset > GetDataSize - 1 then StartOffset := GetDataSize - 1;

  FSelection.StartOffset := StartOffset;
  if FSelection.StartOffset > FSelection.EndOffset then
    FSelection.Active := False
  else
    FSelection.Active := True;
  if Redraw then DoPaint;
  DoOnSelectionChange;
end;

procedure TCustomHexEdit.SetSelectionEnd(EndOffset: Integer; Redraw: Boolean);
begin
  if EndOffset < 0 then EndOffset := 0;
  if EndOffset > GetDataSize - 1 then EndOffset := GetDataSize - 1;

  FSelection.EndOffset := EndOffset;
  if FSelection.StartOffset > FSelection.EndOffset then
    FSelection.Active := False
  else
    FSelection.Active := True;
  if Redraw then DoPaint;
  DoOnSelectionChange;
end;

procedure TCustomHexEdit.SetSelectionVisible(Value: Boolean);
begin
  if FSelection.Active <> Value then
  begin
    FSelection.Active := Value;
    RestrictSelection;
    DoPaint;
    DoOnSelectionChange;
  end;
end;

procedure TCustomHexEdit.CancelSelection(Redraw: Boolean);
begin
  if FSelection.Active then
  begin
    FSelection.Active := False;
    if Redraw then DoPaint;
    DoOnSelectionChange;
  end;
end;

procedure TCustomHexEdit.CancelSelByUser(Redraw: Boolean);
begin
  if hoAutoHideSelection in FOptions then
    CancelSelection(Redraw);
end;

procedure TCustomHexEdit.RestrictSelection;
begin
  if FSelection.Active then
  begin
    if FSelection.StartOffset > FSelection.EndOffset then
      SwapInt(FSelection.StartOffset, FSelection.EndOffset);
    if FSelection.StartOffset < 0 then
      FSelection.StartOffset := 0;
    if FSelection.EndOffset > GetDataSize - 1 then
      FSelection.EndOffset := GetDataSize - 1;
    if FSelection.StartOffset > FSelection.EndOffset then
      FSelection.Active := False;
  end;
end;

function TCustomHexEdit.CheckInSelection(Offset: Integer): Boolean;
begin
  Result := FSelection.Active;
  if Result then
    Result := (Offset >= FSelection.StartOffset) and (Offset <= FSelection.EndOffset);
end;

procedure TCustomHexEdit.GetOffsetRange(var StartOffset, EndOffset: Integer;
  OnlyBlock, FromCursor: Boolean);
var
  CurOffset: Integer;
begin
  CurOffset := GetOffset;
  if OnlyBlock then
  begin
    if FSelection.Active then
    begin
      if FromCursor then
      begin
        if (CurOffset >= FSelection.StartOffset) and
          (CurOffset <= FSelection.EndOffset) then
        begin
          StartOffset := CurOffset + 1;
          EndOffset := FSelection.EndOffset;
        end else
        begin
          StartOffset := FSelection.StartOffset;
          EndOffset := FSelection.EndOffset;
        end;
      end else
      begin
        StartOffset := FSelection.StartOffset;
        EndOffset := FSelection.EndOffset;
      end;
    end else
    begin
      StartOffset := 0;
      EndOffset := -1;
    end;
  end else
  begin
    if FromCursor then
      StartOffset := CurOffset + 1
    else
      StartOffset := 0;
    EndOffset := GetDataSize - 1;
  end;
end;

procedure TCustomHexEdit.UpdateVertScrollBar;
var
  Max, Page: Integer;
begin
  if (ScrollBars in [ssNone, ssHorizontal]) or
    not HandleAllocated or not Showing then Exit;

  if csDesigning in ComponentState then
  begin
    UpdateScrollMax(skVertical, 1);
    UpdateScrollPage(skVertical, 0);
  end else
  begin
    Max := FRowCount - 2;
    if Max < 1 then Max := 1;
    UpdateScrollMax(skVertical, Max);

    Page := FVisRowCount - 1;
    if Page < 1 then Page := 1;
    UpdateScrollPage(skVertical, Page);
  end;
end;

procedure TCustomHexEdit.UpdateHorzScrollBar;
var
  Max: Integer;
begin
  if (ScrollBars in [ssNone, ssVertical]) or
    not HandleAllocated or not Showing then Exit;

  if csDesigning in ComponentState then
  begin
    UpdateScrollMax(skHorizontal, 1);
    UpdateScrollPage(skHorizontal, 0);
  end else
  begin
    if ClientWidth < GetRowTotalWidth then
      Max := GetRowTotalWidth div FCharWidth - 1
    else
      Max := 0;
    UpdateScrollMax(skHorizontal, Max);
    UpdateScrollPage(skHorizontal, ClientWidth div FCharWidth - 1);
  end;
end;

procedure TCustomHexEdit.UpdateScrollPage(AScrollKind: TScrollKind; APage: Integer);
var
  ScrInfo: TScrollInfo;
  BarFlag: Integer;
begin
  if AScrollKind = skHorizontal then
    BarFlag := SB_HORZ
  else
    BarFlag := SB_VERT;

  if APage < 0 then APage := 0;

  FillChar(ScrInfo, SizeOf(ScrInfo), 0);
  ScrInfo.cbSize := SizeOf(ScrInfo);
  ScrInfo.fMask := SIF_DISABLENOSCROLL or SIF_PAGE;
  ScrInfo.nPage := APage;

  SetScrollInfo(Handle, BarFlag, ScrInfo, True);
end;

procedure TCustomHexEdit.UpdateScrollMax(AScrollKind: TScrollKind; AMax: Integer);
var
  BarFlag: Integer;
begin
  if AScrollKind = skHorizontal then
    BarFlag := SB_HORZ
  else
    BarFlag := SB_VERT;

  if AMax < 0 then AMax := 0;
  SetScrollRange(Handle, BarFlag, 0, AMax, True);
end;

procedure TCustomHexEdit.UpdateScrollPos(AScrollKind: TScrollKind; APos: Integer);
var
  BarFlag: Integer;
begin
  if AScrollKind = skHorizontal then
    BarFlag := SB_HORZ
  else
    BarFlag := SB_VERT;

  if APos < 0 then APos := 0;
  SetScrollPos(Handle, BarFlag, APos, True);
end;

procedure TCustomHexEdit.DrawText(X, Y: Integer; S: string; CharAttr: TCharAttr);
begin
  Canvas.Brush.Color := CharAttr.BColor;
  Canvas.Font.Color := CharAttr.FColor;
  Canvas.TextOut(X - FCharWidth * FLeftCol, Y, S);
end;

procedure TCustomHexEdit.DrawAddrRow(OffRow, AbsRow: Integer);
var
  S: string;
  X, Y: Integer;
begin
  X := GetAddrAreaLeft;
  Y := OffRow * FCharHeight;

  Canvas.Brush.Color := FColors.AddressColor.BColor;
  Canvas.FillRect(Rect(0, Y, FMargin, Y + FCharHeight));

  S := IntToHex(AbsRow * 16, 8) + ': ';
  DrawText(X, Y, S, FColors.AddressColor);
end;

procedure TCustomHexEdit.DrawHexRow(OffRow, AbsRow: Integer);
var
  S, S1: string;
  X, Y: Integer;
  I, Offset: Integer;
  CharAttr: TCharAttr;
begin
  X := GetHexAreaLeft;
  Y := OffRow * FCharHeight;
  S := GetHexAreaStr(AbsRow);

  for I := 0 to 15 do
  begin
    Offset := GetOffset(AbsRow, I);
    CharAttr := GetCharAttrByRowCol(AbsRow, I, True);
    if (Offset <> FSelection.EndOffset) and (I <> 15) then
    begin
      S1 := Copy(S, I*3+1, 3);
      DrawText(X+I*FCharWidth*3, Y, S1, CharAttr);
    end else
    begin
      S1 := Copy(S, I*3+1, 2);
      DrawText(X+I*FCharWidth*3, Y, S1, CharAttr);
      S1 := Copy(S, I*3+3, 1);
      DrawText(X+I*FCharWidth*3+FCharWidth*2, Y, S1, FColors.HexColor);
    end;
  end;
end;

procedure TCustomHexEdit.DrawChrRow(OffRow, AbsRow: Integer);
var
  S: string;
  S1: array[1..3] of string;
  I, J, Offset: Integer;
  DrawSelection, InSelection: Boolean;
  CharAttr: TCharAttr;
begin
  S := GetChrAreaStr(AbsRow);

  //画右边的空白区域
  Canvas.Brush.Color := FColors.CharColor.BColor;
  Canvas.FillRect(Rect(GetChrAreaLeft + FCharWidth * (Length(S) - FLeftCol),
    OffRow * FCharHeight, ClientWidth, (OffRow+1) * FCharHeight));

  if not FSelection.Active then DrawSelection := False
  else
  begin
    if (GetOffset(AbsRow, 0) <= FSelection.EndOffset) and
       (GetOffset(AbsRow, 15) >= FSelection.StartOffset) then
         DrawSelection := True
    else
         DrawSelection := False;
  end;

  if DrawSelection then
  begin
    J := 1;
    S1[1] := '';    S1[2] := '';    S1[3] := '';
    for I := 0 to 15 do
    begin
      Offset := GetOffset(AbsRow, I);
      InSelection := (Offset <= FSelection.EndOffset) and (Offset >= FSelection.StartOffset);
      if InSelection then J := 2;
      if Offset > FSelection.EndOffset then J := 3;
      S1[J] := S1[J] + S[I + 1];
    end;
    J := 0;
    for I := 1 to 3 do
    begin
      if I = 2 then CharAttr := FColors.SelectionColor
      else CharAttr := FColors.CharColor;
      DrawStrForChrRow(S1[I], OffRow, J, CharAttr);
      J := J + Length(S1[I]);
    end;
  end else
    DrawStrForChrRow(S, OffRow, 0, FColors.CharColor);
end;

procedure TCustomHexEdit.DrawStrForChrRow(S: string; OffRow, Col: Integer; CharAttr: TCharAttr);
var
  I, J, X, Y: Integer;
  S1: string;
begin
  if S = '' then Exit;
  X := GetChrAreaLeft + FCharWidth * Col;
  Y := OffRow * FCharHeight;
  case FDrawCharStyle of
    dcGeneral:
      for I := 1 to Length(S) do
      begin
        DrawText(X+FCharWidth*(I-1), Y, S[I], CharAttr);
      end;
    dcDotForSpec:
      for I := 1 to Length(S) do
      begin
        if IsSpecChar(S[I]) then

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -