source: oup/current/Tools/BinEdit.pas@ 801

Last change on this file since 801 was 248, checked in by alloc, 17 years ago
File size: 28.1 KB
RevLine 
[104]1unit BinEdit;
[218]2
[104]3interface
[218]4
[104]5uses
6 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
[218]7 Dialogs, VirtualTrees, Grids, Wrapgrid, MPHexEditor,
8 StdCtrls, Menus, ExtCtrls, Buttons,
[225]9 Data, TypeDefs, ConnectionManager,
[221]10 _TemplateFileList, VTHeaderPopup, ComCtrls;
[104]11
12type
[218]13 TForm_BinEdit = class(TForm_TemplateFileList)
14 panel_imexport: TPanel;
15 btn_export: TButton;
16 btn_import: TButton;
[104]17 hex: TMPHexEditor;
18 Splitter2: TSplitter;
19 value_viewer: TWrapGrid;
[218]20 Splitter3: TSplitter;
[104]21 VST: TVirtualStringTree;
[218]22 VTHPopup: TVTHeaderPopupMenu;
[104]23 value_viewer_context: TPopupMenu;
24 value_viewer_context_copy: TMenuItem;
25 value_viewer_context_copyasdec: TMenuItem;
26 value_viewer_context_copyasfloat: TMenuItem;
27 value_viewer_context_copyasbitset: TMenuItem;
28 value_viewer_context_copyasstring: TMenuItem;
29 value_viewer_context_copyashex: TMenuItem;
30 procedure NewFile(fileinfo: TFileInfo);
31
32 function Save: Boolean;
[111]33 function GetValue(datatype: Word; offset: Integer): String;
34 procedure SetNewValue(datatype: Word; offset: Integer; Value: String);
[104]35
36 procedure WriteStructureInfos;
37 procedure ClearStructViewer;
38
39 procedure ClearValues;
40 procedure WriteValues;
[218]41
42 procedure FormCreate(Sender: TObject);
43 procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
44 procedure hexChange(Sender: TObject);
45 procedure hexKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
46 procedure hexSelectionChanged(Sender: TObject);
[104]47 procedure value_viewerDblClick(Sender: TObject);
[218]48 procedure FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
49 procedure value_viewer_contextPopup(Sender: TObject);
[104]50 procedure value_viewerMouseDown(Sender: TObject; Button: TMouseButton;
51 Shift: TShiftState; X, Y: Integer);
[218]52 procedure value_viewer_context_copyClick(Sender: TObject);
53 procedure VSTDblClick(Sender: TObject);
54 procedure VSTFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode;
55 Column: TColumnIndex);
56 procedure VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
57 Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
58 procedure VSTHeaderDragged(Sender: TVTHeader; Column: TColumnIndex;
59 OldPosition: Integer);
60 procedure VTHPopupColumnChange(const Sender: TBaseVirtualTree;
61 const Column: TColumnIndex; Visible: Boolean);
[104]62 private
63 fileid: Integer;
64 ConID: Integer;
[177]65 rawlist: TRawDataList;
[104]66 public
67 end;
68
69implementation
70{$R *.dfm}
[218]71uses ValueEdit, Main, Functions, DatStructureLoader, RawEdit, RawList,
[225]72 StrUtils, Clipbrd, _TemplateFile;
[104]73
[218]74
[104]75type
76 PNodeData = ^TNodeData;
77
78 TNodeData = record
79 Caption: String;
80 Offset: LongInt;
81 DataType: Word;
82 Value: String;
83 Description: String;
84 end;
85
86
87
88procedure TForm_BinEdit.FormCreate(Sender: TObject);
89begin
90 inherited;
91 Self.OnNewFileSelected := NewFile;
92
93 Self.Caption := '';
94 fileid := 0;
95 VST.NodeDataSize := SizeOf(TNodeData);
96 value_viewer.ColCount := 2;
97 value_viewer.RowCount := 8;
98 value_viewer.FixedRows := 1;
99 value_viewer.FixedCols := 1;
100 value_viewer.Cells[0, 0] := 'Type';
101 value_viewer.Cells[1, 0] := 'Value';
102 value_viewer.Cells[0, 1] := '1 byte, unsigned';
103 value_viewer.Cells[0, 2] := '2 bytes, unsigned';
104 value_viewer.Cells[0, 3] := '4 bytes, unsigned';
105 value_viewer.Cells[0, 4] := 'Bitset';
106 value_viewer.Cells[0, 5] := 'Float';
107 value_viewer.Cells[0, 6] := 'String';
108 value_viewer.Cells[0, 7] := 'Selected length';
109 value_viewer.ColWidths[0] := 120;
110 value_viewer.ColWidths[1] := 1000;
111// hex.Height := content.Height - 215;
112 //
113 value_viewer.Font.Charset := AppSettings.CharSet;
114 VST.Font.Charset := AppSettings.CharSet;
115 hex.Translation := tkAsIs;
116 hex.Font.Charset := AppSettings.CharSet;
117 //
118end;
119
[218]120
[104]121procedure TForm_BinEdit.NewFile(fileinfo: TFileInfo);
122var
123 mem: TMemoryStream;
124begin
125 if ConID <> -1 then
126 begin
127 if hex.Modified then
128 begin
129 if not Save then
130 begin
131 Self.SelectFileID(ConnectionID, FileID);
132 Exit;
133 end;
134 end;
135 end;
[231]136 if fileinfo.ID >= 0 then
[104]137 begin
[231]138 fileid := fileinfo.ID;
[104]139 ConID := ConnectionID;
[231]140// if ConManager.Connection[ConID].ExtractFileIDOfName(filelist.Items.Strings[filelist.ItemIndex]) <> fileid then
141// Self.SelectFileID(ConnectionID, fileid);
[104]142 Self.ClearStructViewer;
[248]143 ClearValues;
[104]144 mem := nil;
[248]145 hex.DataSize := 0;
146 if fileinfo.Size > 0 then
147 begin
148 ConManager.Connection[ConID].LoadDatFile(fileid, TStream(mem));
149 rawlist := ConManager.Connection[ConID].GetRawList(fileid);
150 hex.LoadFromStream(mem);
151 mem.Free;
152 WriteStructureInfos;
153 end;
[104]154 end
155 else
156 begin
[231]157 fileid := -1;
[104]158 ConID := -1;
159 Self.ClearStructViewer;
160 ClearValues;
161 hex.DataSize := 0;
[177]162 SetLength(rawlist, 0);
[104]163 end;
164end;
165
166
167
[231]168
169function AddVSTEntry(AVST: TCustomVirtualStringTree; ANode: PVirtualNode;
170 ARecord: TNodeData): PVirtualNode;
171var
172 Data: PNodeData;
173begin
174 Result := AVST.AddChild(ANode);
175 Data := AVST.GetNodeData(Result);
176 AVST.ValidateNode(Result, False);
177 Data^ := ARecord;
178end;
179
180
181
182
183
[111]184function TForm_BinEdit.GetValue(datatype: Word; offset: Integer): String;
[104]185var
186 Data: TByteData;
[177]187 i: Integer;
[104]188 floatformat: TFormatSettings;
189begin
190 floatformat.DecimalSeparator := '.';
191 case datatype of
192 1:
193 Result := IntToStr(hex.Data[offset]);
194 2:
195 Result := IntToStr(hex.Data[offset] + hex.Data[offset + 1] * 256);
196 3:
197 Result := IntToStr(hex.Data[offset] + hex.Data[offset + 1] * 256 + hex.Data[offset + 2] * 256 * 256);
198 4:
199 Result := IntToStr(hex.Data[offset] + hex.Data[offset + 1] * 256 + hex.Data[offset + 2] *
200 256 * 256 + hex.Data[offset + 3] * 256 * 256 * 256);
201 5:
202 Result := '0x' + IntToHex(hex.Data[offset], 2);
203 6:
204 Result := '0x' + IntToHex(hex.Data[offset] + hex.Data[offset + 1] * 256, 4);
205 7:
206 Result := '0x' + IntToHex(hex.Data[offset] + hex.Data[offset + 1] * 256 +
207 hex.Data[offset + 2] * 256 * 256, 6);
208 8:
209 Result := '0x' + IntToHex(hex.Data[offset] + hex.Data[offset + 1] * 256 +
210 hex.Data[offset + 2] * 256 * 256 + hex.Data[offset + 3] * 256 * 256 * 256, 8);
211 9:
212 begin
213 SetLength(Data, 4);
214 Data[0] := hex.Data[offset];
215 Data[1] := hex.Data[offset + 1];
216 Data[2] := hex.Data[offset + 2];
217 Data[3] := hex.Data[offset + 3];
218 Result := FloatToStr(Decode_Float(Data), floatformat);
219 end;
220 10:
221 Result := IntToBin(hex.Data[offset]);
222 11:
[113]223 begin
[177]224 if Length(rawlist) > 0 then
[198]225 begin
[177]226 for i := 0 to High(rawlist) do
227 if rawlist[i].SrcOffset = offset then
228 begin
229 if rawlist[i].RawAddr > 0 then
230 Result := '0x' + IntToHex(rawlist[i].RawAddr, 8)
231 else
232 Result := 'unused';
233 Break;
234 end;
[198]235 if i > High(rawlist) then
236 Result := 'unused';
237 end;
[113]238 end;
[104]239 12:
[113]240 if hex.Data[offset] = 1 then
241 Result := FormatNumber(hex.Data[offset + 1] + hex.Data[offset + 2] * 256 +
242 hex.Data[offset + 3] * 256 * 256, 5, '0')
243 else
244 Result := 'no link';
[104]245 13:
246 Result := IntToStr(hex.Data[offset]);
247 14:
248 Result := IntToStr(hex.Data[offset] + hex.Data[offset + 1] * 256);
249 15:
250 Result := IntToStr(hex.Data[offset] + hex.Data[offset + 1] * 256 + hex.Data[offset + 2] * 256 * 256);
251 16:
252 Result := IntToStr(hex.Data[offset] + hex.Data[offset + 1] * 256 + hex.Data[offset + 2] *
253 256 * 256 + hex.Data[offset + 3] * 256 * 256 * 256);
254 17:
255 Result := IntToStr((hex.Data[offset + 3]) div 2);
256 100..300:
257 begin
258 Result := '';
259 for i := 1 to datatype - 100 do
260 begin
261 if hex.Data[offset + i - 1] >= 32 then
262 Result := Result + Chr(hex.Data[offset + i - 1])
263 else
264 Break;
265 end;
266 end;
267 1000..9999:
268 begin
269 Result := '';
270 for i := 1 to datatype - 1000 do
271 begin
272 if hex.Data[offset + i - 1] >= 32 then
273 Result := Result + Chr(hex.Data[offset + i - 1])
274 else
275 Result := Result + '.';
276 end;
277 end;
278 10000..65535:
279 begin
280 Result := '';
281 for i := 1 to datatype - 10000 do
282 begin
283 if hex.Data[offset + i - 1] >= 32 then
284 Result := Result + Chr(hex.Data[offset + i - 1])
285 else
286 Result := Result + '.';
287 end;
288 end;
289 end;
290end;
291
292
293
294
295procedure TForm_BinEdit.WriteStructureInfos;
296var
[111]297 i, j: Integer;
[104]298 pdata: PNodeData;
299 Data: TNodeData;
300 node: PVirtualNode;
301 structs: TStructDef;
302begin
303 VST.BeginUpdate;
304 if VST.RootNodeCount = 0 then
305 begin
306 structs := LoadStructureDefinition(ConID, fileid);
307 if structs.Data then
308 begin
309 if Length(structs.Global) > 0 then
310 begin
311 for i := 0 to High(structs.Global) do
312 begin
313 Data.Caption := structs.Global[i].Name;
314 Data.Offset := structs.Global[i].offset;
315 Data.DataType := structs.Global[i].datatype;
316 Data.Value := GetValue(structs.Global[i].datatype, structs.Global[i].offset);
317 Data.Description := structs.Global[i].description;
318 AddVSTEntry(VST, nil, Data);
319 end;
320 end;
321 if Length(structs.Subs) > 0 then
322 begin
323 for i := 0 to High(structs.Subs) do
324 begin
325 with structs.Subs[i] do
326 begin
327 if Length(Entries) > 0 then
328 begin
329 if Pos('#', SubName) > 0 then
330 begin
[113]331 Data.Offset := StrToInt('$'+MidStr(SubName, Pos('#', SubName) + 1, 8));
332 Data.Value := '$' +
[104]333 MidStr(SubName, PosEx('#', SubName, Pos('#', SubName) + 1) + 1, 8);
334 Data.Caption := MidStr(SubName, 1, Pos('#', SubName) - 1);
335 Data.Description := SubDesc;
336 end
337 else
338 begin
339 Data.Caption := SubName;
340 Data.Description := SubDesc;
341 Data.Offset := 0;
342 Data.Value := '';
343 end;
344 Data.DataType := 0;
345 node := AddVSTEntry(VST, nil, Data);
346 Data.Description := '';
347 for j := 0 to High(Entries) do
348 begin
349 Data.Caption := Entries[j].Name;
350 Data.Offset := Entries[j].offset;
351 Data.DataType := Entries[j].datatype;
352 Data.Value := GetValue(Entries[j].datatype, Entries[j].offset);
353 Data.Description := Entries[j].description;
354 AddVSTEntry(VST, node, Data);
355 end;
356 end;
357 end;
358 end;
359 end;
360 end;
361 if VST.RootNodeCount > 0 then
362 VST.FocusedNode := VST.GetFirst;
363 end
364 else
365 begin
366 Node := VST.GetFirst;
367 while Assigned(Node) do
368 begin
369 pdata := VST.GetNodeData(Node);
370 if pdata.DataType > 0 then
371 pdata.Value := GetValue(pdata.Datatype, pdata.Offset);
372 Node := VST.GetNext(Node);
373 end;
374 end;
375 VST.EndUpdate;
376end;
377
378
379
380
381procedure TForm_BinEdit.ClearValues;
382var
383 i: Byte;
384begin
385 for i := 1 to value_viewer.RowCount - 1 do
386 begin
387 value_viewer.Cells[1, i] := '';
388 end;
389end;
390
391
392
393
394procedure TForm_BinEdit.WriteValues;
395var
396 i, j: Integer;
397 Data: TByteData;
398 str: String;
[111]399 Value: Integer;
[104]400 floatformat: TFormatSettings;
401begin
402 floatformat.DecimalSeparator := '.';
403 for i := 1 to value_viewer.RowCount - 1 do
404 begin
405 if value_viewer.Cells[0, i] = '1 byte, unsigned' then
406 begin
407 if ((hex.SelCount = 1) or (hex.SelCount = 0)) and not
408 ((hex.SelStart + 1) > hex.DataSize) then
409 begin
410 Value := hex.Data[hex.SelStart];
411 value_viewer.Cells[1, i] := IntToStr(Value) + ' / 0x' + IntToHex(Value, 2);
412 end
413 else
414 value_viewer.Cells[1, i] := '';
415 end;
416 if value_viewer.Cells[0, i] = '2 bytes, unsigned' then
417 begin
418 if ((hex.SelCount = 2) or (hex.SelCount = 0)) and not
419 ((hex.SelStart + 2) > hex.DataSize) then
420 begin
421 Value := hex.Data[hex.SelStart] + hex.Data[hex.SelStart + 1] * 256;
422 value_viewer.Cells[1, i] := IntToStr(Value) + ' / 0x' + IntToHex(Value, 4);
423 end
424 else
425 value_viewer.Cells[1, i] := '';
426 end;
427 if value_viewer.Cells[0, i] = '4 bytes, unsigned' then
428 begin
429 if ((hex.SelCount = 4) or (hex.SelCount = 0)) and not
430 ((hex.SelStart + 4) > hex.DataSize) then
431 begin
432 Value := hex.Data[hex.SelStart] + hex.Data[hex.SelStart + 1] * 256 +
433 hex.Data[hex.SelStart + 2] * 256 * 256 + hex.Data[hex.SelStart + 3] * 256 * 256 * 256;
434 value_viewer.Cells[1, i] := IntToStr(Value) + ' / 0x' + IntToHex(Value, 8);
435 end
436 else
437 value_viewer.Cells[1, i] := '';
438 end;
439 if value_viewer.Cells[0, i] = 'Bitset' then
440 begin
441 if (hex.SelCount <= 8) then
442 begin
443 if hex.SelCount = 0 then
444 begin
445 SetLength(Data, 1);
446 Data[0] := hex.Data[hex.SelStart];
447 end
448 else
449 begin
450 SetLength(Data, hex.SelCount);
451 for j := 0 to hex.SelCount - 1 do
452 Data[j] := hex.Data[hex.SelStart + j];
453 end;
454 value_viewer.Cells[1, i] := DataToBin(Data);
455 end
456 else
457 value_viewer.Cells[1, i] := '';
458 end;
459 if value_viewer.Cells[0, i] = 'Float' then
460 begin
461 if ((hex.SelCount = 4) or (hex.SelCount = 0)) and not
462 ((hex.SelStart + 4) > hex.DataSize) then
463 begin
464 SetLength(Data, 4);
465 for j := 0 to 3 do
466 Data[j] := hex.Data[hex.SelStart + j];
467 value_viewer.Cells[1, i] := FloatToStr(Decode_Float(Data), floatformat);
468 end
469 else
470 value_viewer.Cells[1, i] := '';
471 end;
472 if value_viewer.Cells[0, i] = 'Selected length' then
473 begin
474 value_viewer.Cells[1, i] := IntToStr(hex.SelCount) + ' bytes';
475 end;
476 if value_viewer.Cells[0, i] = 'String' then
477 begin
478 j := 0;
479 str := '';
480 if hex.SelCount = 0 then
481 begin
[174]482 while (hex.SelStart + j) < hex.DataSize do
[104]483 begin
[174]484 if hex.Data[hex.SelStart + j] = 0 then
485 Break;
[104]486 if hex.Data[hex.selstart + j] >= 32 then
487 str := str + Char(hex.Data[hex.SelStart + j])
488 else
489 str := str + '.';
490 Inc(j);
491 end;
492 end
493 else
494 begin
495 for j := 0 to hex.SelCount - 1 do
496 if hex.Data[hex.selstart + j] >= 32 then
497 str := str + Char(hex.Data[hex.SelStart + j])
498 else if hex.Data[hex.selstart + j] > 0 then
499 str := str + '.'
500 else
501 Break;
502 end;
503 value_viewer.Cells[1, i] := str;
504 end;
505 end;
506end;
507
508
509
510
511function TForm_BinEdit.Save: Boolean;
512var
513 mem: TMemoryStream;
[111]514 i: Integer;
[104]515begin
516 case MessageBox(Self.Handle, PChar('Save changes to file ' +
517 ConManager.Connection[ConID].GetFileInfo(fileid).Name + '?'), PChar('Data changed...'),
518 MB_YESNOCANCEL + MB_ICONQUESTION) of
519 idYes:
520 begin
521 mem := TMemoryStream.Create;
522 hex.SaveToStream(mem);
523 mem.Seek(0, soFromBeginning);
524 ConManager.Connection[ConID].UpdateDatFile(fileid, mem);
525 mem.Free;
526 hex.Modified := False;
527 for i := 0 to hex.Datasize - 1 do
528 hex.ByteChanged[i] := False;
529 Result := True;
530 end;
531 idNo:
532 Result := True;
533 idCancel:
534 begin
535 Result := False;
536 end;
537 end;
538end;
539
540
541
542
543procedure TForm_BinEdit.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
544begin
545 if hex.Modified then
546 begin
547 if not Save then
548 CanClose := False;
549 end;
550end;
551
552
553
554
555procedure TForm_BinEdit.ClearStructViewer;
556begin
557 VST.Clear;
558end;
559
560
561
562
563
564
565procedure TForm_BinEdit.hexChange(Sender: TObject);
566begin
567 ClearValues;
568 if hex.DataSize > 0 then
569 begin
570 WriteStructureInfos;
571 WriteValues;
572 end;
573end;
574
575
576
577
578procedure TForm_BinEdit.hexKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
579//var
580// temps: String;
581begin
582 if (Shift = [ssCtrl]) and (Key = Ord('C')) then
583 begin
584 if hex.SelCount > 0 then
585 begin
586 if hex.InCharField then
587 Clipboard.AsText := hex.SelectionAsText
588 else
589 Clipboard.AsText := hex.SelectionAsHex;
590 end;
591 end;
592 if (Shift = [ssCtrl]) and (Key = Ord('V')) then
593 begin
594{ temps:=Clipboard.AsText;
595 IF hex.SelStart+Length(temps)>hex.DataSize THEN
596 SetLength(temps, hex.DataSize-hex.SelStart);
597 hex.Sel
598 hex.SelCount:=Length(temps);
599 hex.ReplaceSelection(temps,Length(temps));
600} end;
601end;
602
603
604
605
606procedure TForm_BinEdit.hexSelectionChanged(Sender: TObject);
607var
608 selstart: Integer;
609 node: PVirtualNode;
610 pdata: PNodeData;
611begin
612 if hex.DataSize > 0 then
613 begin
614 WriteValues;
615 selstart := hex.SelStart;
616 if VST.RootNodeCount > 0 then
617 begin
618 Node := VST.GetFirst;
619 while Assigned(Node) do
620 begin
621 pdata := VST.GetNodeData(Node);
622 if pdata.DataType > 0 then
623 begin
624 if ((selstart - pdata.Offset) < GetDataTypeLength(pdata.DataType)) and
625 ((selstart - pdata.Offset) >= 0) then
626 begin
627 VST.FocusedNode := Node;
628 VST.Selected[Node] := True;
629 Break;
630 end;
631 end;
632 Node := VST.GetNext(Node);
633 end;
634 end;
635 end;
636end;
637
638
639
640
641procedure TForm_BinEdit.value_viewer_contextPopup(Sender: TObject);
642var
643 i: Byte;
644begin
645 for i := 0 to value_viewer_context.Items.Count - 1 do
646 value_viewer_context.Items.Items[i].Visible := False;
647 with value_viewer do
648 begin
649 if (Col = 1) and (Row > 0) and (Length(Cells[Col, Row]) > 0) then
650 begin
651 if Pos(' byte', Cells[0, Row]) = 2 then
652 begin
653 value_viewer_context.Items.Find('Copy to &clipboard').Visible := True;
654 value_viewer_context.Items.Find('Copy to clipboard (as &dec)').Visible := True;
655 value_viewer_context.Items.Find('Copy to clipboard (as &hex)').Visible := True;
656 end;
657 if Pos('Float', Cells[0, Row]) = 1 then
658 value_viewer_context.Items.Find('Copy to clipboard (as &float)').Visible := True;
659 if Pos('Bitset', Cells[0, Row]) = 1 then
660 value_viewer_context.Items.Find(
661 'Copy to clipboard (as &bitset)').Visible := True;
662 if Pos('String', Cells[0, Row]) = 1 then
663 value_viewer_context.Items.Find(
664 'Copy to clipboard (as &string)').Visible := True;
665 if Pos('Selected length', Cells[0, Row]) = 1 then
666 value_viewer_context.Items.Find('Copy to &clipboard').Visible := True;
667 end;
668 end;
669end;
670
671
672
673
674procedure TForm_BinEdit.value_viewerMouseDown(Sender: TObject; Button: TMouseButton;
675 Shift: TShiftState; X, Y: Integer);
676var
677 ACol, ARow: Integer;
678begin
679 if Button = mbRight then
680 begin
681 value_viewer.MouseToCell(x, y, ACol, ARow);
682 if ARow > 0 then
683 begin
684 value_viewer.Col := ACol;
685 value_viewer.Row := ARow;
686 end;
687 end;
688end;
689
690
691
692
693procedure TForm_BinEdit.value_viewer_context_copyClick(Sender: TObject);
694var
695 Name: String;
[111]696 Value: Integer;
[104]697begin
698 Name := TMenuItem(Sender).Name;
699 if Pos('asstring', Name) > 0 then
700 begin
701 Clipboard.AsText := value_viewer.Cells[value_viewer.Col, value_viewer.Row];
702 end
703 else if Pos('asfloat', Name) > 0 then
704 begin
705 Clipboard.AsText := value_viewer.Cells[value_viewer.Col, value_viewer.Row];
706 end
707 else if Pos('asbitset', Name) > 0 then
708 begin
709 Clipboard.AsText := value_viewer.Cells[value_viewer.Col, value_viewer.Row];
710 end
711 else if (Pos('ashex', Name) > 0) or (Pos('asdec', Name) > 0) then
712 begin
713 if value_viewer.Cells[0, value_viewer.Row] = '1 byte, unsigned' then
714 begin
715 if ((hex.SelCount = 1) or (hex.SelCount = 0)) and not
716 ((hex.SelStart + 1) > hex.DataSize) then
717 Value := hex.Data[hex.SelStart];
718 end;
719 if value_viewer.Cells[0, value_viewer.Row] = '2 bytes, unsigned' then
720 begin
721 if ((hex.SelCount = 2) or (hex.SelCount = 0)) and not
722 ((hex.SelStart + 2) > hex.DataSize) then
723 Value := hex.Data[hex.SelStart] + hex.Data[hex.SelStart + 1] * 256;
724 end;
725 if value_viewer.Cells[0, value_viewer.Row] = '4 bytes, unsigned' then
726 begin
727 if ((hex.SelCount = 4) or (hex.SelCount = 0)) and not
728 ((hex.SelStart + 4) > hex.DataSize) then
729 Value := hex.Data[hex.SelStart] + hex.Data[hex.SelStart + 1] * 256 +
730 hex.Data[hex.SelStart + 2] * 256 * 256 + hex.Data[hex.SelStart + 3] * 256 * 256 * 256;
731 end;
732 if Pos('asdec', Name) > 0 then
733 begin
734 Clipboard.AsText := IntToStr(Value);
735 end
736 else
737 begin
738 if value_viewer.Cells[0, value_viewer.Row] = '1 byte, unsigned' then
739 Clipboard.AsText := '0x' + IntToHex(Value, 2);
740 if value_viewer.Cells[0, value_viewer.Row] = '2 bytes, unsigned' then
741 Clipboard.AsText := '0x' + IntToHex(Value, 4);
742 if value_viewer.Cells[0, value_viewer.Row] = '4 bytes, unsigned' then
743 Clipboard.AsText := '0x' + IntToHex(Value, 8);
744 end;
745 end
746 else
747 begin
748 Clipboard.AsText := value_viewer.Cells[value_viewer.Col, value_viewer.Row];
749 end;
750end;
751
752
753
754
755procedure TForm_BinEdit.VSTDblClick(Sender: TObject);
756var
757 node: PVirtualNode;
758 nodedata: PNodeData;
[177]759 rawinfo: TRawDataInfo;
[217]760 form: TForm_TemplateFileList;
[104]761begin
762 if VST.FocusedColumn = 3 then
763 begin
764 node := VST.FocusedNode;
765 nodedata := VST.GetNodeData(node);
766
767 if not (nodedata.datatype in [11, 12]) and
768 ((nodedata.DataType < 100) or (nodedata.DataType > 300)) then
769 begin
770 Form_ValueEdit.MakeVarInput(nodedata.Caption, nodedata.offset,
771 nodedata.datatype, nodedata.Value, Self);
772 end
773 else
774 begin
[113]775 if (nodedata.DataType = 11) and (nodedata.Value <> 'unused') then
[104]776 begin
[177]777 rawinfo := ConManager.Connection[ConID].GetRawInfo(fileid, nodedata.offset);
778 if rawinfo.RawSize > 0 then
779 begin
780 form := nil;
[217]781 form := TForm_TemplateFileList(Form_Main.open_child('rawedit', ConID, fileid));
[177]782 if Assigned(form) then
783 TForm_RawEdit(form).LoadRaw(rawinfo);
784 end;
[104]785 end;
[113]786 if (nodedata.DataType = 12) and (nodedata.Value <> 'no link') then
[104]787 begin
788 if (StrToInt(nodedata.Value) < ConManager.Connection[ConID].GetFileCount) and
789 (StrToInt(nodedata.Value) > 0) and
790 (StrToInt(nodedata.Value) <> fileid) then
791 begin
792 if ConManager.Connection[ConID].GetFileInfo(StrToInt(nodedata.Value)).Size > 0 then
793 Form_Main.open_child('binedit', ConID, StrToInt(nodedata.Value))
794 else
795 ShowMessage('Linked filed is a zero-byte-file');
796 end;
797 end;
798 if (nodedata.DataType >= 100) and (nodedata.DataType <= 300) then
799 begin
[217]800 form := TForm_TemplateFileList(Form_Main.open_child('binedit', ConID));
[104]801 if Assigned(form) then
802 form.SetFileFilters(nodedata.Value, '', False);
803 end;
804 end;
805
806 end;
807end;
808
809
810
811
812procedure TForm_BinEdit.VSTFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode;
813 Column: TColumnIndex);
814var
815 Data: PNodeData;
816begin
817 Data := VST.GetNodeData(node);
818 if Data.DataType > 0 then
819 begin
820 hex.SelStart := Data.Offset;
821 hex.SelEnd := Data.Offset + GetDataTypeLength(Data.DataType) - 1;
822 end
823 else
824 begin
825 hex.SelStart := Data.Offset;
[113]826 hex.SelEnd := Data.Offset + StrToInt(Data.Value) - 1;
[104]827 end;
828end;
829
830
831
832
833procedure TForm_BinEdit.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
834 Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
835var
836 Data: PNodeData;
837begin
838 Data := Sender.GetNodeData(Node);
839 CellText := '';
840 if TextType = ttNormal then
841 begin
842 case Column of
843 0:
844 CellText := Data.Caption;
845 1:
846 if Data.DataType > 0 then
847 CellText := '0x' + IntToHex(Data.Offset, 8)
848 else if Data.Offset > 0 then
849 CellText := '0x' + IntToHex(Data.Offset, 8);
850 2:
851 if Data.DataType > 0 then
852 CellText := GetDataType(Data.DataType);
853 3:
854 if Data.DataType > 0 then
855 CellText := Data.Value //GetValue(data.DataType, data.Offset)
856 else if Length(Data.Value) > 0 then
[113]857 CellText := IntToStr(StrToInt(Data.Value)) + ' Bytes';
[104]858 4:
859 CellText := Data.Description;
860 end;
861 end;
862end;
863
864
865
866
867procedure TForm_BinEdit.VSTHeaderDragged(Sender: TVTHeader; Column: TColumnIndex;
868 OldPosition: Integer);
869begin
870 if Sender.Columns.Items[column].Position < 1 then
871 Sender.Columns.Items[column].Position := OldPosition;
872end;
873
874
875
876
877procedure TForm_BinEdit.VTHPopupColumnChange(const Sender: TBaseVirtualTree;
878 const Column: TColumnIndex; Visible: Boolean);
879begin
880 if column = 0 then
881 TVirtualStringTree(Sender).Header.Columns.Items[column].Options :=
882 TVirtualStringTree(Sender).Header.Columns.Items[column].Options + [coVisible];
883end;
884
885
886
887
[111]888procedure TForm_BinEdit.SetNewValue(datatype: Word; offset: Integer; Value: String);
[104]889var
890 Data: TByteData;
891 value_int: LongWord;
892 value_float: Single;
893 i: Word;
894begin
895 case datatype of
896 1..4:
897 begin
898 value_int := StrToInt(Value);
899 SetLength(Data, datatype);
900 for i := 0 to datatype - 1 do
901 begin
902 Data[i] := value_int mod 256;
903 value_int := value_int div 256;
904 end;
905 end;
906 5..8:
907 begin
908 value_int := StrToInt('$' + Value);
909 SetLength(Data, datatype - 4);
910 for i := 0 to datatype - 5 do
911 begin
912 Data[i] := value_int mod 256;
913 value_int := value_int div 256;
914 end;
915 end;
916 9:
917 begin
918 value_float := StrToFloat(Value);
919 Data := Encode_Float(value_float);
920 end;
921 10:
922 begin
923 value_int := BinToInt(Value);
924 SetLength(Data, 1);
925 Data[0] := value_int;
926 end;
927 10000..65535:
928 begin
929 SetLength(Data, datatype - 10000);
930 for i := 1 to datatype - 10000 do
931 begin
932 if i <= Length(Value) then
933 Data[i - 1] := Ord(Value[i])
934 else
935 Data[i - 1] := 0;
936 end;
937 end;
938 end;
939 for i := 0 to High(Data) do
940 begin
941 if hex.Data[offset + i] <> Data[i] then
942 hex.ByteChanged[offset + i] := True;
943 hex.Data[offset + i] := Data[i];
944 end;
945 hex.Modified := True;
946 hexChange(Self);
947 hex.Repaint;
948end;
949
950
951
952
953procedure TForm_BinEdit.value_viewerDblClick(Sender: TObject);
954var
[111]955 offset: Integer;
[104]956 datatype: Word;
957 objectname: String;
958 Value: String;
959begin
960 if (value_viewer.Col = 1) and (Length(value_viewer.Cells[1, value_viewer.Row]) > 0) then
961 begin
962 offset := hex.SelStart;
963 if value_viewer.Cells[0, value_viewer.Row] = '1 byte, unsigned' then
964 datatype := 1;
965 if value_viewer.Cells[0, value_viewer.Row] = '2 bytes, unsigned' then
966 datatype := 2;
967 if value_viewer.Cells[0, value_viewer.Row] = '4 bytes, unsigned' then
968 datatype := 4;
969 if value_viewer.Cells[0, value_viewer.Row] = 'Bitset' then
970 datatype := 10;
971 if value_viewer.Cells[0, value_viewer.Row] = 'Float' then
972 datatype := 9;
973 if value_viewer.Cells[0, value_viewer.Row] = 'Selected length' then
974 Exit;
975 if value_viewer.Cells[0, value_viewer.Row] = 'String' then
976 begin
977 if hex.SelCount > 0 then
978 datatype := 10000 + hex.SelCount
979 else
980 datatype := 10000 + Length(value_viewer.Cells[1, value_viewer.Row]);
981 end;
982 objectname := '';
983 Value := GetValue(datatype, offset);
984 Form_ValueEdit.MakeVarInput(objectname, offset, datatype, Value, Self);
985 end;
986end;
987
988
989
990procedure TForm_BinEdit.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
991begin
992 if (Shift = [ssCtrl]) and (Key = 83) then
993 if hex.Modified then
994 if not Save then
995 Exit;
996end;
997
998
999begin
1000 AddToolListEntry('binedit', 'Binary .dat-Editor', '');
1001end.
Note: See TracBrowser for help on using the repository browser.