unit BinEdit; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Template, StdCtrls, ExtCtrls, VirtualTrees, Grids, Wrapgrid, MPHexEditor, VTHeaderPopup, Menus, StrUtils, Clipbrd, Data, OniDataClass, Functions, DataStructures, Exporters, Buttons; type TForm_BinEdit = class(TForm_ToolTemplate) hex: TMPHexEditor; Splitter2: TSplitter; value_viewer: TWrapGrid; VST: TVirtualStringTree; Splitter3: TSplitter; value_viewer_context: TPopupMenu; value_viewer_context_copy: TMenuItem; value_viewer_context_copyasdec: TMenuItem; value_viewer_context_copyasfloat: TMenuItem; value_viewer_context_copyasbitset: TMenuItem; value_viewer_context_copyasstring: TMenuItem; value_viewer_context_copyashex: TMenuItem; VTHPopup: TVTHeaderPopupMenu; procedure FormCreate(Sender: TObject); procedure NewFile(fileinfo: TFileInfo); procedure FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); procedure hexKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); procedure hexSelectionChanged(Sender: TObject); procedure hexChange(Sender: TObject); procedure LoadDat(_fileid: LongWord); function Save: Boolean; function GetValue(datatype: Word; offset: LongWord): String; procedure SetNewValue(datatype: Word; offset: LongWord; Value: String); procedure WriteStructureInfos; procedure ClearStructViewer; procedure VSTDblClick(Sender: TObject); procedure VSTFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex); procedure VTHPopupColumnChange(const Sender: TBaseVirtualTree; const Column: TColumnIndex; Visible: Boolean); procedure VSTHeaderDragged(Sender: TVTHeader; Column: TColumnIndex; OldPosition: Integer); procedure VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString); procedure ClearValues; procedure WriteValues; procedure value_viewerDblClick(Sender: TObject); procedure value_viewer_context_copyClick(Sender: TObject); procedure value_viewerMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure value_viewer_contextPopup(Sender: TObject); private fileid: LongWord; public end; var Form_BinEdit: TForm_BinEdit; implementation uses Helper_ValueEdit, Main, RawEdit; {$R *.dfm} type PNodeData = ^TNodeData; TNodeData = record Caption: String; Offset: LongInt; DataType: Word; Value: String; Description: String; end; procedure TForm_BinEdit.FormCreate(Sender: TObject); begin inherited; Self.OnNewFileSelected := NewFile; Self.Caption := ''; fileid := 0; VST.NodeDataSize := SizeOf(TNodeData); value_viewer.ColCount := 2; value_viewer.RowCount := 8; value_viewer.FixedRows := 1; value_viewer.Cells[0, 0] := 'Type'; value_viewer.Cells[1, 0] := 'Value'; value_viewer.Cells[0, 1] := '1 byte, unsigned'; value_viewer.Cells[0, 2] := '2 bytes, unsigned'; value_viewer.Cells[0, 3] := '4 bytes, unsigned'; value_viewer.Cells[0, 4] := 'Bitset'; value_viewer.Cells[0, 5] := 'Float'; value_viewer.Cells[0, 6] := 'String'; value_viewer.Cells[0, 7] := 'Selected length'; // value_viewer.ColWidths[0] := 100; // value_viewer.ColWidths[1] := value_viewer.Width - 150; // hex.Height := content.Height - 215; // value_viewer.Font.Charset := AppSettings.CharSet; VST.Font.Charset := AppSettings.CharSet; hex.Translation := tkAsIs; hex.Font.Charset := AppSettings.CharSet; // end; procedure TForm_BinEdit.NewFile(fileinfo: TFileInfo); begin LoadDat(fileinfo.ID); end; function AddVSTEntry(AVST: TCustomVirtualStringTree; ANode: PVirtualNode; ARecord: TNodeData): PVirtualNode; var Data: PNodeData; begin Result := AVST.AddChild(ANode); Data := AVST.GetNodeData(Result); AVST.ValidateNode(Result, False); Data^ := ARecord; end; procedure TForm_BinEdit.LoadDat(_fileid: LongWord); var mem: TMemoryStream; Data: Tdata; begin if hex.Modified then begin if not Save then begin Self.SelectFileID(fileid); Exit; end; end; fileid := _fileid; if OniDataConnection.ExtractFileID( filelist.Items.Strings[filelist.ItemIndex]) <> fileid then Self.SelectFileID(fileid); Self.ClearStructViewer; Data := OniDataConnection.LoadDatFile(fileid); if Length(Data) > 0 then begin mem := TMemoryStream.Create; mem.Write(Data[0], Length(Data)); mem.Seek(0, soFromBeginning); hex.LoadFromStream(mem); mem.Free; WriteStructureInfos; end else begin ClearValues; hex.DataSize := 0; end; end; function IntToBin(Value: Byte): String; var i: Byte; begin Result := ''; for i := 7 downto 0 do begin Result := Result + IntToStr((Value shr i) and $01); end; end; function TForm_BinEdit.GetValue(datatype: Word; offset: LongWord): String; var Data: Tdata; i: Word; floatformat: TFormatSettings; begin floatformat.DecimalSeparator := '.'; case datatype of 1: Result := IntToStr(hex.Data[offset]); 2: Result := IntToStr(hex.Data[offset] + hex.Data[offset + 1] * 256); 3: Result := IntToStr(hex.Data[offset] + hex.Data[offset + 1] * 256 + hex.Data[offset + 2] * 256 * 256); 4: Result := IntToStr(hex.Data[offset] + hex.Data[offset + 1] * 256 + hex.Data[offset + 2] * 256 * 256 + hex.Data[offset + 3] * 256 * 256 * 256); 5: Result := '0x' + IntToHex(hex.Data[offset], 2); 6: Result := '0x' + IntToHex(hex.Data[offset] + hex.Data[offset + 1] * 256, 4); 7: Result := '0x' + IntToHex(hex.Data[offset] + hex.Data[offset + 1] * 256 + hex.Data[offset + 2] * 256 * 256, 6); 8: Result := '0x' + IntToHex(hex.Data[offset] + hex.Data[offset + 1] * 256 + hex.Data[offset + 2] * 256 * 256 + hex.Data[offset + 3] * 256 * 256 * 256, 8); 9: begin SetLength(Data, 4); Data[0] := hex.Data[offset]; Data[1] := hex.Data[offset + 1]; Data[2] := hex.Data[offset + 2]; Data[3] := hex.Data[offset + 3]; Result := FloatToStr(Decode_Float(Data), floatformat); end; 10: Result := IntToBin(hex.Data[offset]); 11: Result := '0x' + IntToHex(OniDataConnection.GetRawInfo(fileid, offset).raw_addr, 8); 12: Result := FormatNumber(hex.Data[offset + 1] + hex.Data[offset + 2] * 256 + hex.Data[offset + 3] * 256 * 256, 5, '0'); 13: Result := IntToStr(hex.Data[offset]); 14: Result := IntToStr(hex.Data[offset] + hex.Data[offset + 1] * 256); 15: Result := IntToStr(hex.Data[offset] + hex.Data[offset + 1] * 256 + hex.Data[offset + 2] * 256 * 256); 16: Result := IntToStr(hex.Data[offset] + hex.Data[offset + 1] * 256 + hex.Data[offset + 2] * 256 * 256 + hex.Data[offset + 3] * 256 * 256 * 256); 17: Result := IntToStr((hex.Data[offset + 3]) div 2); 100..300: begin Result := ''; for i := 1 to datatype - 100 do begin if hex.Data[offset + i - 1] >= 32 then Result := Result + Chr(hex.Data[offset + i - 1]) else Break; end; end; 1000..9999: begin Result := ''; for i := 1 to datatype - 1000 do begin if hex.Data[offset + i - 1] >= 32 then Result := Result + Chr(hex.Data[offset + i - 1]) else Result := Result + '.'; end; end; 10000..65535: begin Result := ''; for i := 1 to datatype - 10000 do begin if hex.Data[offset + i - 1] >= 32 then Result := Result + Chr(hex.Data[offset + i - 1]) else Result := Result + '.'; end; end; end; end; procedure TForm_BinEdit.WriteStructureInfos; var i, j: LongWord; pdata: PNodeData; Data: TNodeData; node: PVirtualNode; structs: TStructDef; begin VST.BeginUpdate; if VST.RootNodeCount = 0 then begin structs := LoadStructureDefinition(fileid); if structs.Data then begin if Length(structs.Global) > 0 then begin for i := 0 to High(structs.Global) do begin Data.Caption := structs.Global[i].Name; Data.Offset := structs.Global[i].offset; Data.DataType := structs.Global[i].datatype; Data.Value := GetValue(structs.Global[i].datatype, structs.Global[i].offset); Data.Description := structs.Global[i].description; AddVSTEntry(VST, nil, Data); end; end; if Length(structs.Subs) > 0 then begin for i := 0 to High(structs.Subs) do begin with structs.Subs[i] do begin if Length(Entries) > 0 then begin if Pos('#', SubName) > 0 then begin Data.Offset := HexToLong(MidStr(SubName, Pos('#', SubName) + 1, 8)); Data.Value := MidStr(SubName, PosEx('#', SubName, Pos('#', SubName) + 1) + 1, 8); Data.Caption := MidStr(SubName, 1, Pos('#', SubName) - 1); Data.Description := SubDesc; end else begin Data.Caption := SubName; Data.Description := SubDesc; Data.Offset := 0; Data.Value := ''; end; Data.DataType := 0; node := AddVSTEntry(VST, nil, Data); Data.Description := ''; for j := 0 to High(Entries) do begin Data.Caption := Entries[j].Name; Data.Offset := Entries[j].offset; Data.DataType := Entries[j].datatype; Data.Value := GetValue(Entries[j].datatype, Entries[j].offset); Data.Description := Entries[j].description; AddVSTEntry(VST, node, Data); end; end; end; end; end; end; if VST.RootNodeCount > 0 then VST.FocusedNode := VST.GetFirst; end else begin Node := VST.GetFirst; while Assigned(Node) do begin pdata := VST.GetNodeData(Node); if pdata.DataType > 0 then pdata.Value := GetValue(pdata.Datatype, pdata.Offset); Node := VST.GetNext(Node); end; end; VST.EndUpdate; end; procedure TForm_BinEdit.ClearValues; var i: Byte; begin for i := 1 to value_viewer.RowCount - 1 do begin value_viewer.Cells[1, i] := ''; end; end; procedure TForm_BinEdit.WriteValues; var i, j: Byte; Data: Tdata; str: String; Value: LongWord; floatformat: TFormatSettings; begin floatformat.DecimalSeparator := '.'; for i := 1 to value_viewer.RowCount - 1 do begin if value_viewer.Cells[0, i] = '1 byte, unsigned' then begin if ((hex.SelCount = 1) or (hex.SelCount = 0)) and not ((hex.SelStart + 1) > hex.DataSize) then begin Value := hex.Data[hex.SelStart]; value_viewer.Cells[1, i] := IntToStr(Value) + ' / 0x' + IntToHex(Value, 2); end else value_viewer.Cells[1, i] := ''; end; if value_viewer.Cells[0, i] = '2 bytes, unsigned' then begin if ((hex.SelCount = 2) or (hex.SelCount = 0)) and not ((hex.SelStart + 2) > hex.DataSize) then begin Value := hex.Data[hex.SelStart] + hex.Data[hex.SelStart + 1] * 256; value_viewer.Cells[1, i] := IntToStr(Value) + ' / 0x' + IntToHex(Value, 4); end else value_viewer.Cells[1, i] := ''; end; if value_viewer.Cells[0, i] = '4 bytes, unsigned' then begin if ((hex.SelCount = 4) or (hex.SelCount = 0)) and not ((hex.SelStart + 4) > hex.DataSize) then begin Value := hex.Data[hex.SelStart] + hex.Data[hex.SelStart + 1] * 256 + hex.Data[hex.SelStart + 2] * 256 * 256 + hex.Data[hex.SelStart + 3] * 256 * 256 * 256; value_viewer.Cells[1, i] := IntToStr(Value) + ' / 0x' + IntToHex(Value, 8); end else value_viewer.Cells[1, i] := ''; end; if value_viewer.Cells[0, i] = 'Bitset' then begin if (hex.SelCount <= 8) then begin if hex.SelCount = 0 then begin SetLength(Data, 1); Data[0] := hex.Data[hex.SelStart]; end else begin SetLength(Data, hex.SelCount); for j := 0 to hex.SelCount - 1 do Data[j] := hex.Data[hex.SelStart + j]; end; value_viewer.Cells[1, i] := DataToBin(Data); end else value_viewer.Cells[1, i] := ''; end; if value_viewer.Cells[0, i] = 'Float' then begin if ((hex.SelCount = 4) or (hex.SelCount = 0)) and not ((hex.SelStart + 4) > hex.DataSize) then begin SetLength(Data, 4); for j := 0 to 3 do Data[j] := hex.Data[hex.SelStart + j]; value_viewer.Cells[1, i] := FloatToStr(Decode_Float(Data), floatformat); end else value_viewer.Cells[1, i] := ''; end; if value_viewer.Cells[0, i] = 'Selected length' then begin value_viewer.Cells[1, i] := IntToStr(hex.SelCount) + ' bytes'; end; if value_viewer.Cells[0, i] = 'String' then begin j := 0; str := ''; if hex.SelCount = 0 then begin while (hex.Data[hex.SelStart + j] > 0) and ((hex.SelStart + j) < hex.DataSize) do begin if hex.Data[hex.selstart + j] >= 32 then str := str + Char(hex.Data[hex.SelStart + j]) else str := str + '.'; Inc(j); end; end else begin for j := 0 to hex.SelCount - 1 do if hex.Data[hex.selstart + j] >= 32 then str := str + Char(hex.Data[hex.SelStart + j]) else if hex.Data[hex.selstart + j] > 0 then str := str + '.' else Break; end; value_viewer.Cells[1, i] := str; end; end; end; function TForm_BinEdit.Save: Boolean; var mem: TMemoryStream; Data: Tdata; i: LongWord; begin case MessageBox(Self.Handle, PChar('Save changes to file ' + OniDataConnection.GetFileInfo(fileid).FileName + '?'), PChar('Data changed...'), MB_YESNOCANCEL) of idYes: begin mem := TMemoryStream.Create; hex.SaveToStream(mem); mem.Seek(0, soFromBeginning); SetLength(Data, mem.Size); mem.Read(Data[0], mem.Size); mem.Free; OniDataConnection.UpdateDatFile(fileid, Data); hex.Modified := False; for i := 0 to hex.Datasize - 1 do hex.ByteChanged[i] := False; Result := True; end; idNo: Result := True; idCancel: begin Result := False; end; end; end; procedure TForm_BinEdit.FormCloseQuery(Sender: TObject; var CanClose: Boolean); begin if hex.Modified then begin if not Save then CanClose := False; end; end; procedure TForm_BinEdit.ClearStructViewer; begin VST.Clear; end; procedure TForm_BinEdit.hexChange(Sender: TObject); begin ClearValues; if hex.DataSize > 0 then begin WriteStructureInfos; WriteValues; end; end; procedure TForm_BinEdit.hexKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); //var // temps: String; begin if (Shift = [ssCtrl]) and (Key = Ord('C')) then begin if hex.SelCount > 0 then begin if hex.InCharField then Clipboard.AsText := hex.SelectionAsText else Clipboard.AsText := hex.SelectionAsHex; end; end; if (Shift = [ssCtrl]) and (Key = Ord('V')) then begin { temps:=Clipboard.AsText; IF hex.SelStart+Length(temps)>hex.DataSize THEN SetLength(temps, hex.DataSize-hex.SelStart); hex.Sel hex.SelCount:=Length(temps); hex.ReplaceSelection(temps,Length(temps)); } end; end; procedure TForm_BinEdit.hexSelectionChanged(Sender: TObject); var selstart: Integer; node: PVirtualNode; pdata: PNodeData; begin if hex.DataSize > 0 then begin WriteValues; selstart := hex.SelStart; if VST.RootNodeCount > 0 then begin Node := VST.GetFirst; while Assigned(Node) do begin pdata := VST.GetNodeData(Node); if pdata.DataType > 0 then begin if ((selstart - pdata.Offset) < GetTypeDataLength(pdata.DataType)) and ((selstart - pdata.Offset) >= 0) then begin VST.FocusedNode := Node; VST.Selected[Node] := True; Break; end; end; Node := VST.GetNext(Node); end; end; end; end; procedure TForm_BinEdit.value_viewer_contextPopup(Sender: TObject); var i: Byte; begin for i := 0 to value_viewer_context.Items.Count - 1 do value_viewer_context.Items.Items[i].Visible := False; with value_viewer do begin if (Col = 1) and (Row > 0) and (Length(Cells[Col, Row]) > 0) then begin if Pos(' byte', Cells[0, Row]) = 2 then begin value_viewer_context.Items.Find('Copy to &clipboard').Visible := True; value_viewer_context.Items.Find('Copy to clipboard (as &dec)').Visible := True; value_viewer_context.Items.Find('Copy to clipboard (as &hex)').Visible := True; end; if Pos('Float', Cells[0, Row]) = 1 then value_viewer_context.Items.Find('Copy to clipboard (as &float)').Visible := True; if Pos('Bitset', Cells[0, Row]) = 1 then value_viewer_context.Items.Find( 'Copy to clipboard (as &bitset)').Visible := True; if Pos('String', Cells[0, Row]) = 1 then value_viewer_context.Items.Find( 'Copy to clipboard (as &string)').Visible := True; if Pos('Selected length', Cells[0, Row]) = 1 then value_viewer_context.Items.Find('Copy to &clipboard').Visible := True; end; end; end; procedure TForm_BinEdit.value_viewerMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var ACol, ARow: Integer; begin if Button = mbRight then begin value_viewer.MouseToCell(x, y, ACol, ARow); if ARow > 0 then begin value_viewer.Col := ACol; value_viewer.Row := ARow; end; end; end; procedure TForm_BinEdit.value_viewer_context_copyClick(Sender: TObject); var Name: String; Value: LongWord; begin Name := TMenuItem(Sender).Name; if Pos('asstring', Name) > 0 then begin Clipboard.AsText := value_viewer.Cells[value_viewer.Col, value_viewer.Row]; end else if Pos('asfloat', Name) > 0 then begin Clipboard.AsText := value_viewer.Cells[value_viewer.Col, value_viewer.Row]; end else if Pos('asbitset', Name) > 0 then begin Clipboard.AsText := value_viewer.Cells[value_viewer.Col, value_viewer.Row]; end else if (Pos('ashex', Name) > 0) or (Pos('asdec', Name) > 0) then begin if value_viewer.Cells[0, value_viewer.Row] = '1 byte, unsigned' then begin if ((hex.SelCount = 1) or (hex.SelCount = 0)) and not ((hex.SelStart + 1) > hex.DataSize) then Value := hex.Data[hex.SelStart]; end; if value_viewer.Cells[0, value_viewer.Row] = '2 bytes, unsigned' then begin if ((hex.SelCount = 2) or (hex.SelCount = 0)) and not ((hex.SelStart + 2) > hex.DataSize) then Value := hex.Data[hex.SelStart] + hex.Data[hex.SelStart + 1] * 256; end; if value_viewer.Cells[0, value_viewer.Row] = '4 bytes, unsigned' then begin if ((hex.SelCount = 4) or (hex.SelCount = 0)) and not ((hex.SelStart + 4) > hex.DataSize) then Value := hex.Data[hex.SelStart] + hex.Data[hex.SelStart + 1] * 256 + hex.Data[hex.SelStart + 2] * 256 * 256 + hex.Data[hex.SelStart + 3] * 256 * 256 * 256; end; if Pos('asdec', Name) > 0 then begin Clipboard.AsText := IntToStr(Value); end else begin if value_viewer.Cells[0, value_viewer.Row] = '1 byte, unsigned' then Clipboard.AsText := '0x' + IntToHex(Value, 2); if value_viewer.Cells[0, value_viewer.Row] = '2 bytes, unsigned' then Clipboard.AsText := '0x' + IntToHex(Value, 4); if value_viewer.Cells[0, value_viewer.Row] = '4 bytes, unsigned' then Clipboard.AsText := '0x' + IntToHex(Value, 8); end; end else begin Clipboard.AsText := value_viewer.Cells[value_viewer.Col, value_viewer.Row]; end; end; procedure TForm_BinEdit.VSTDblClick(Sender: TObject); var node: PVirtualNode; nodedata: PNodeData; form: TForm_ToolTemplate; begin if VST.FocusedColumn = 3 then begin node := VST.FocusedNode; nodedata := VST.GetNodeData(node); if not (nodedata.datatype in [11, 12]) and ((nodedata.DataType < 100) or (nodedata.DataType > 300)) then begin Form_ValueEdit.MakeVarInput(nodedata.Caption, nodedata.offset, nodedata.datatype, nodedata.Value, Self); end else begin if nodedata.DataType = 11 then begin if OniDataConnection.GetRawInfo(fileid, nodedata.offset).raw_size > 0 then Form_Main.open_child('rawedit', fileid); end; if nodedata.DataType = 12 then begin if (StrToInt(nodedata.Value) < OniDataConnection.GetFilesCount) and (StrToInt(nodedata.Value) > 0) and (StrToInt(nodedata.Value) <> fileid) then begin if OniDataConnection.GetFileInfo(StrToInt(nodedata.Value)).Size > 0 then Form_Main.open_child('binedit', StrToInt(nodedata.Value)) else ShowMessage('Linked filed is a zero-byte-file'); end; end; if (nodedata.DataType >= 100) and (nodedata.DataType <= 300) then begin form := Form_Main.open_child('binedit', -1); if Assigned(form) then form.SetFileFilters(nodedata.Value, '', False); end; end; end; end; procedure TForm_BinEdit.VSTFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex); var Data: PNodeData; begin Data := VST.GetNodeData(node); if Data.DataType > 0 then begin hex.SelStart := Data.Offset; hex.SelEnd := Data.Offset + GetTypeDataLength(Data.DataType) - 1; end else begin hex.SelStart := Data.Offset; hex.SelEnd := Data.Offset + HexToLong(Data.Value) - 1; end; end; procedure TForm_BinEdit.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString); var Data: PNodeData; begin Data := Sender.GetNodeData(Node); CellText := ''; if TextType = ttNormal then begin case Column of 0: CellText := Data.Caption; 1: if Data.DataType > 0 then CellText := '0x' + IntToHex(Data.Offset, 8) else if Data.Offset > 0 then CellText := '0x' + IntToHex(Data.Offset, 8); 2: if Data.DataType > 0 then CellText := GetDataType(Data.DataType); 3: if Data.DataType > 0 then CellText := Data.Value //GetValue(data.DataType, data.Offset) else if Length(Data.Value) > 0 then CellText := IntToStr(HexToLong(Data.Value)) + ' Bytes'; 4: CellText := Data.Description; end; end; end; procedure TForm_BinEdit.VSTHeaderDragged(Sender: TVTHeader; Column: TColumnIndex; OldPosition: Integer); begin if Sender.Columns.Items[column].Position < 1 then Sender.Columns.Items[column].Position := OldPosition; end; procedure TForm_BinEdit.VTHPopupColumnChange(const Sender: TBaseVirtualTree; const Column: TColumnIndex; Visible: Boolean); begin if column = 0 then TVirtualStringTree(Sender).Header.Columns.Items[column].Options := TVirtualStringTree(Sender).Header.Columns.Items[column].Options + [coVisible]; end; procedure TForm_BinEdit.SetNewValue(datatype: Word; offset: LongWord; Value: String); var Data: Tdata; value_int: LongWord; value_float: Single; i: Word; begin case datatype of 1..4: begin value_int := StrToInt(Value); SetLength(Data, datatype); for i := 0 to datatype - 1 do begin Data[i] := value_int mod 256; value_int := value_int div 256; end; end; 5..8: begin value_int := StrToInt('$' + Value); SetLength(Data, datatype - 4); for i := 0 to datatype - 5 do begin Data[i] := value_int mod 256; value_int := value_int div 256; end; end; 9: begin value_float := StrToFloat(Value); Data := Encode_Float(value_float); end; 10: begin value_int := BinToInt(Value); SetLength(Data, 1); Data[0] := value_int; end; 10000..65535: begin SetLength(Data, datatype - 10000); for i := 1 to datatype - 10000 do begin if i <= Length(Value) then Data[i - 1] := Ord(Value[i]) else Data[i - 1] := 0; end; end; end; for i := 0 to High(Data) do begin if hex.Data[offset + i] <> Data[i] then hex.ByteChanged[offset + i] := True; hex.Data[offset + i] := Data[i]; end; hex.Modified := True; hexChange(Self); hex.Repaint; end; procedure TForm_BinEdit.value_viewerDblClick(Sender: TObject); var offset: LongWord; datatype: Word; objectname: String; Value: String; begin if (value_viewer.Col = 1) and (Length(value_viewer.Cells[1, value_viewer.Row]) > 0) then begin offset := hex.SelStart; if value_viewer.Cells[0, value_viewer.Row] = '1 byte, unsigned' then datatype := 1; if value_viewer.Cells[0, value_viewer.Row] = '2 bytes, unsigned' then datatype := 2; if value_viewer.Cells[0, value_viewer.Row] = '4 bytes, unsigned' then datatype := 4; if value_viewer.Cells[0, value_viewer.Row] = 'Bitset' then datatype := 10; if value_viewer.Cells[0, value_viewer.Row] = 'Float' then datatype := 9; if value_viewer.Cells[0, value_viewer.Row] = 'Selected length' then Exit; if value_viewer.Cells[0, value_viewer.Row] = 'String' then begin if hex.SelCount > 0 then datatype := 10000 + hex.SelCount else datatype := 10000 + Length(value_viewer.Cells[1, value_viewer.Row]); end; objectname := ''; Value := GetValue(datatype, offset); Form_ValueEdit.MakeVarInput(objectname, offset, datatype, Value, Self); end; end; procedure TForm_BinEdit.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); begin if (Shift = [ssCtrl]) and (Key = 83) then if hex.Modified then if not Save then Exit; end; begin AddToolListEntry('binedit', 'Binary .dat-Editor', ''); end.