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

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