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

📄 hexedit.pas

📁 === === === MiniHex 1.61 源程序说明 ============================== “$(MiniHex)Source”目录中的所有
💻 PAS
📖 第 1 页 / 共 5 页
字号:
          S1 := '.'
        else
          S1 := S[I];
        DrawText(X+FCharWidth*(I-1), Y, S1, CharAttr);
      end;
    dcDblByteChar:
      begin
        I := 1;  J := 0;
        while I <= Length(S) do
        begin
          S1 := S[I];
          if I < Length(S) then
          begin
            S1 := S1 + S[I + 1];
            Inc(I);
          end;
          DrawText(X+FCharWidth*J, Y, StringOfChar(' ', Length(S1)), CharAttr);
          DrawText(X+FCharWidth*J, Y, S1, CharAttr);
          Inc(I);
          Inc(J, 2);
        end;
      end;
      // 如果用一句DrawText画出所有字符,则有可能被截断
      //DrawText(X, Y, S, CharAttr);
  end;
end;

procedure TCustomHexEdit.DrawOneRow(OffRow, AbsRow: Integer);
begin
  DrawAddrRow(OffRow, AbsRow);
  DrawHexRow(OffRow, AbsRow);
  DrawChrRow(OffRow, AbsRow);
end;

procedure TCustomHexEdit.DrawSpcRow(OffRow: Integer);
var
  X, Y: Integer;
begin
  X := GetAddrAreaLeft;
  Y := OffRow * FCharHeight;
  DrawText(X, Y, StringOfChar(' ', 74), FColors.HexColor);
end;

procedure TCustomHexEdit.DrawHexItem(OffRow, Col: Integer; HexCharAttr: TCharAttr);
var
  X, Y: Integer;
  RowPointer: PChar;
begin
  X := GetHexAreaLeft + FCharWidth * (Col*3);
  Y := OffRow * FCharHeight;
  RowPointer := GetRowColPointer(FTopRow + OffRow, Col);
  if GetOffset(FTopRow + OffRow, Col) < GetDataSize then
    DrawText(X, Y, IntToHex(Integer(RowPointer^), 2), HexCharAttr)
  else
    DrawText(X, Y, '  ', HexCharAttr);
end;

procedure TCustomHexEdit.DrawChrItem(OffRow, Col: Integer; ChrCharAttr: TCharAttr);
var
  RowPointer: PChar;
begin
  RowPointer := GetRowColPointer(FTopRow + OffRow, Col);
  if GetOffset(FTopRow + OffRow, Col) < GetDataSize then
    DrawStrForChrRow(RowPointer^, OffRow, Col, ChrCharAttr)
  else
    DrawStrForChrRow(' ', OffRow, Col, ChrCharAttr);
end;

procedure TCustomHexEdit.DrawItem(OffRow, Col: Integer; HexCharAttr, ChrCharAttr: TCharAttr);
var
  X, Y: Integer;
  RowPointer: PChar;
begin
  X := GetHexAreaLeft + FCharWidth * (Col*3);
  Y := OffRow * FCharHeight;
  RowPointer := GetRowColPointer(FTopRow + OffRow, Col);
  if GetOffset(FTopRow + OffRow, Col) < GetDataSize then
  begin
    DrawText(X, Y, IntToHex(Integer(RowPointer^), 2), HexCharAttr);
    DrawStrForChrRow(RowPointer^, OffRow, Col, ChrCharAttr);
  end else
  begin
    DrawText(X, Y, '  ', HexCharAttr);
    DrawStrForChrRow(' ', OffRow, Col, ChrCharAttr);
  end;
end;

procedure TCustomHexEdit.DrawCurItem(Show: Boolean);
var
  OffRow: Integer;
  X: Integer;
begin
  if not FFocused or not (hoShowCaret in FOptions) then Exit;

  OffRow := FCurRow - FTopRow;
  if Show then
  begin
    if FCurInHex then
    begin
      DrawChrItem(OffRow, FCurCol, FColors.CaretColor);
      X := (FCurCol*3 - FLeftCol) * FCharWidth;
      if not FCurInHigh then Inc(X, FCharWidth);
      SetCaretPos(GetHexAreaLeft + X, OffRow * FCharHeight);
      ShowCaret(Handle);
    end else
    begin
      DrawHexItem(OffRow, FCurCol, FColors.CaretColor);
      SetCaretPos(GetChrAreaLeft + (FCurCol - FLeftCol) * FCharWidth, OffRow * FCharHeight);
      ShowCaret(Handle);
    end;
  end else
  begin
    HideCaret(Handle);
    DrawItem(OffRow, FCurCol, GetCharAttrByRowCol(FCurRow, FCurCol, True),
      GetCharAttrByRowCol(FCurRow, FCurCol, True));
  end;
end;

procedure TCustomHexEdit.DrawCurItemHighlight(Show: Boolean);
var
  OffRow: Integer;
begin
  if FFocused or not (hoShowCaret in FOptions) then Exit;

  OffRow := FCurRow - FTopRow;
  if Show then
  begin
    DrawChrItem(OffRow, FCurCol, FColors.CaretColor);
    DrawHexItem(OffRow, FCurCol, FColors.CaretColor);
  end else
  begin
    DrawItem(OffRow, FCurCol, GetCharAttrByRowCol(FCurRow, FCurCol, True),
      GetCharAttrByRowCol(FCurRow, FCurCol, True));
  end;
end;

procedure TCustomHexEdit.DrawAllRow();
var
  AbsRow: Integer;
  I: Integer;
begin
  DrawCurItemHighlight(False);
  DrawCurItem(False);
  
  for I := 0 to FVisRowCount do  // 本来是FVisRowCount-1, 但底下要多画一行
  begin
    AbsRow := FTopRow + I;
    if AbsRow < FRowCount then
      DrawOneRow(I, AbsRow)
    else
      DrawSpcRow(I);
  end;

  DrawCurItem(True);
  DrawCurItemHighlight(True);
end;

procedure TCustomHexEdit.DoUpKey(ShiftPressed: Boolean);
begin
  if hoShowCaret in FOptions then
  begin
    if ShiftPressed then
      AdjustSelectionA(GetOffset, GetOffsetByMove(-32))
    else
      CancelSelByUser(True);
    MoveCaret(-32);
    if ShiftPressed then DrawAllRow;
  end else
    DoCtrlUpKey(False);
end;

procedure TCustomHexEdit.DoDownKey(ShiftPressed: Boolean);
begin
  if hoShowCaret in FOptions then
  begin
    if ShiftPressed then
      AdjustSelectionB(GetOffset, GetOffsetByMove(32))
    else
      CancelSelByUser(True);
    MoveCaret(32);
    if ShiftPressed then DrawAllRow;
  end else
    DoCtrlDownKey(False);
end;

procedure TCustomHexEdit.DoLeftKey(ShiftPressed: Boolean);
begin
  if not (hoShowCaret in FOptions) then Exit;

  if FCurInHex then
  begin
    if ShiftPressed then
      AdjustSelectionA(GetOffset, GetOffsetByMove(-1))
    else
      CancelSelByUser(True);
    MoveCaret(-1);
  end else
  begin
    if ShiftPressed then
      AdjustSelectionA(GetOffset, GetOffsetByMove(-2))
    else
      CancelSelByUser(True);
    MoveCaret(-2);
  end;
  if ShiftPressed then DrawAllRow;
end;

procedure TCustomHexEdit.DoRightKey(ShiftPressed: Boolean);
begin
  if not (hoShowCaret in FOptions) then Exit;

  if FCurInHex then
  begin
    if ShiftPressed then
      AdjustSelectionB(GetOffset, GetOffsetByMove(1))
    else
      CancelSelByUser(True);
    MoveCaret(1);
  end else
  begin
    if ShiftPressed then
      AdjustSelectionB(GetOffset, GetOffsetByMove(2))
    else
      CancelSelByUser(True);
    MoveCaret(2);
  end;
  if ShiftPressed then DrawAllRow;
end;

procedure TCustomHexEdit.DoPageUpKey(ShiftPressed: Boolean);
var
  OffRow: Integer;
  Offset1, Offset2: Integer;
begin
  if FRowCount <= FVisRowCount then Exit;
  if (FTopRow = 0) and CheckCaretInWindow then Exit;

  Offset1 := GetOffset;

  if CheckCaretInWindow then
  begin
    OffRow := FCurRow - FTopRow;
    FTopRow := FTopRow - (FVisRowCount - 1);
    if FTopRow < 0 then FTopRow := 0;
    FCurRow := FTopRow + OffRow;
  end
  else if FCurRow > FTopRow then
  begin
    FCurRow := FCurRow - (FVisRowCount - 1);
    FTopRow := FCurRow - (FVisRowCount - 1);
    if FTopRow < 0 then FTopRow := 0;
    FCurRow := FTopRow + (FVisRowCount - 1);
  end
  else if FCurRow < FTopRow then
  begin
    FCurRow := FCurRow - (FVisRowCount - 1);
    if FCurRow < 0 then FCurRow := 0;
    FTopRow := FCurRow;
  end;

  Offset2 := GetOffset;
  if ShiftPressed then
    AdjustSelectionA(Offset1, Offset2)
  else
    CancelSelByUser(True);

  UpdateScrollPos(skVertical, FTopRow);
  DrawAllRow;
end;

procedure TCustomHexEdit.DoPageDownKey(ShiftPressed: Boolean);
var
  OffRow: Integer;
  Offset1, Offset2: Integer;
begin
  if FRowCount <= FVisRowCount then Exit;
  if (FTopRow+FVisRowCount-1 = FRowCount-1) and CheckCaretInWindow then Exit;

  Offset1 := GetOffset;

  if CheckCaretInWindow then
  begin
    OffRow := FCurRow - FTopRow;
    FTopRow := FTopRow + (FVisRowCount - 1);
    if FTopRow + FVisRowCount - 1 > FRowCount - 1 then
      FTopRow := FRowCount - FVisRowCount;
    FCurRow := FTopRow + OffRow;
    While GetOffset >= GetDataSize do
      Dec(FCurRow);
  end
  else if FCurRow > FTopRow then
  begin
    FCurRow := FCurRow + (FVisRowCount - 1);
    if FCurRow + FVisRowCount - 1 > FRowCount - 1 then
      FCurRow := FRowCount - FVisRowCount;
    FTopRow := FCurRow - (FVisRowCount - 1);
  end
  else if FCurRow < FTopRow then
  begin
    FCurRow := FCurRow + (FVisRowCount - 1);
    FTopRow := FCurRow;
    if FTopRow + FVisRowCount - 1 > FRowCount - 1 then
      FTopRow := FRowCount - FVisRowCount;
    FCurRow := FTopRow;
  end;

  Offset2 := GetOffset;
  if ShiftPressed then
    AdjustSelectionB(Offset1, Offset2)
  else
    CancelSelByUser(True);

  UpdateScrollPos(skVertical, FTopRow);
  DrawAllRow;
end;

procedure TCustomHexEdit.DoHomeKey(ShiftPressed: Boolean);
var
  Offset1, Offset2: Integer;
begin
  if hoShowCaret in FOptions then
  begin
    if (FCurCol > 0) or not FCurInHigh then
    begin
      Offset1 := GetOffset;
      FCurCol := 0;
      FCurInHigh := True;
      Offset2 := GetOffset;
      if ShiftPressed then
        AdjustSelectionA(Offset1, Offset2)
      else
        CancelSelByUser(False);
      DrawAllRow;
    end;
  end else
    DoCtrlPageUpKey(False);
end;

procedure TCustomHexEdit.DoEndKey(ShiftPressed: Boolean);
var
  Offset1, Offset2, CurDLen: Integer;
begin
  if hoShowCaret in FOptions then
  begin
    CurDLen := GetDLen;
    if (CurDlen mod 32 <> 0) and (CurDLen <> GetDataSize * 2) then
    begin
      Offset1 := GetOffset;
      if FCurRow = FRowCount - 1 then FCurCol := (GetDataSize-1) mod 16
      else FCurCol := 15;
      FCurInHigh := False;
      Offset2 := GetOffset;
      if ShiftPressed then
        AdjustSelectionB(Offset1, Offset2)
      else
        CancelSelByUser(False);
      DrawAllRow;
    end;
  end else
    DoCtrlPageDownKey(False);
end;

procedure TCustomHexEdit.DoTabKey;
begin
  DrawCurItem(False);
  FCurInHex := not FCurInHex;
  DrawCurItem(True);
end;

procedure TCustomHexEdit.DoCtrlJKey;
begin
  if DrawCharStyle = High(TDrawCharStyle) then
    DrawCharStyle := Low(TDrawCharStyle)
  else
    DrawCharStyle := Succ(FDrawCharStyle);
end;

procedure TCustomHexEdit.DoCtrlKKey(Key: Word);
begin
  if (Key >= Ord('0')) and (Key <= Ord('9')) then DoCtrlKNumKey(Key)
  else if (Key = Ord('B')) or (Key = Ord('b')) then DoCtrlKBKey(Key)
  else if (Key = Ord('K')) or (Key = Ord('k')) then DoCtrlKKKey(Key)
  else if (Key = Ord('H')) or (Key = Ord('h')) then DoCtrlKHKey(Key)
  else if (Key = Ord('W')) or (Key = Ord('w')) then DoCtrlKWKey(Key);
end;

procedure TCustomHexEdit.DoCtrlQKey(Key: Word);
begin
  if (Key >= Ord('0')) and (Key <= Ord('9')) then DoCtrlQNumKey(Key);
end;

procedure TCustomHexEdit.DoCtrlKNumKey(Key: Word);
var
  Idx: Integer;
begin
  Idx := Key - Ord('0');
  if Idx >= BookmarkCount then Exit;

  FBookmark[Idx].Active := True;
  FBookmark[Idx].DLen := GetDLen;
  FBookmark[Idx].CurInHex := FCurInHex;
end;

procedure TCustomHexEdit.DoCtrlKBKey(Key: Word);
begin
  if (hoAllowSelect in FOptions) and (hoShowCaret in FOptions) then
    SetSelectionStart(GetOffset, True);
end;

procedure TCustomHexEdit.DoCtrlKKKey(Key: Word);
begin
  if (hoAllowSelect in FOptions) and (hoShowCaret in FOptions) then
    SetSelectionEnd(GetOffset, True);
end;

procedure TCustomHexEdit.DoCtrlKHKey(Key: Word);
begin
  SetSelectionVisible(not FSelection.Active);
end;

procedure TCustomHexEdit.DoCtrlKWKey(Key: Word);
begin
  //{ TODO : DoCtrlKWKey }
end;

procedure TCustomHexEdit.DoCtrlQNumKey(Key: Word);
var
  Idx: Integer;
begin
  Idx := Key - Ord('0');
  if Idx >= BookmarkCount then Exit;
  if not FBookmark[Idx].Active then Exit;

  FCurInHex := FBookmark[Idx].CurInHex;
  MoveCaretTo(FBookmark[Idx].DLen);
end;

procedure TCustomHexEdit.DoCtrlUpKey(MoveCaret: Boolean);
begin
  if FTopRow <= 0 then Exit;
  Dec(FTopRow);
  if MoveCaret then
  begin
    if FCurRow < FTopRow then FCurRow := FTopRow;
    if FCurRow > FTopRow + FVisRowCount - 1 then
      FCurRow := FTopRow + FVisRowCount -1;
  end;

  UpdateScrollPos(skVertical, FTopRow);
  DrawAllRow;
end;

procedure TCustomHexEdit.DoCtrlDownKey(MoveCaret: Boolean);
begin
  if FTopRow >= FRowCount - FVisRowCount then Exit;
  Inc(FTopRow);
  if MoveCaret then
  begin
    if FCurRow < FTopRow then FCurRow

⌨️ 快捷键说明

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