source: oup/_old_/Tools/BinEdit.pas@ 173

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