source: oup/releases/0.34b/Tools/BinEdit.pas@ 957

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