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

Last change on this file since 220 was 218, 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,
[217]9 Data, TypeDefs, ConnectionManager, Template,
[218]10 _TemplateFileList, VTHeaderPopup;
[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 procedure LoadDat(_fileid: Integer);
33 function Save: Boolean;
[111]34 function GetValue(datatype: Word; offset: Integer): String;
35 procedure SetNewValue(datatype: Word; offset: Integer; Value: String);
[104]36
37 procedure WriteStructureInfos;
38 procedure ClearStructViewer;
39
40 procedure ClearValues;
41 procedure WriteValues;
[218]42
43 procedure FormCreate(Sender: TObject);
44 procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
45 procedure hexChange(Sender: TObject);
46 procedure hexKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
47 procedure hexSelectionChanged(Sender: TObject);
[104]48 procedure value_viewerDblClick(Sender: TObject);
[218]49 procedure FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
50 procedure value_viewer_contextPopup(Sender: TObject);
[104]51 procedure value_viewerMouseDown(Sender: TObject; Button: TMouseButton;
52 Shift: TShiftState; X, Y: Integer);
[218]53 procedure value_viewer_context_copyClick(Sender: TObject);
54 procedure VSTDblClick(Sender: TObject);
55 procedure VSTFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode;
56 Column: TColumnIndex);
57 procedure VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
58 Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
59 procedure VSTHeaderDragged(Sender: TVTHeader; Column: TColumnIndex;
60 OldPosition: Integer);
61 procedure VTHPopupColumnChange(const Sender: TBaseVirtualTree;
62 const Column: TColumnIndex; Visible: Boolean);
[104]63 private
64 fileid: Integer;
65 ConID: Integer;
[177]66 rawlist: TRawDataList;
[104]67 public
68 end;
69
70implementation
71{$R *.dfm}
[218]72uses ValueEdit, Main, Functions, DatStructureLoader, RawEdit, RawList,
73 StrUtils, Clipbrd;
[104]74
[218]75
[104]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
[218]121
[104]122procedure TForm_BinEdit.NewFile(fileinfo: TFileInfo);
123begin
124 LoadDat(fileinfo.ID);
125end;
126
127
128
129
130function AddVSTEntry(AVST: TCustomVirtualStringTree; ANode: PVirtualNode;
131 ARecord: TNodeData): PVirtualNode;
132var
133 Data: PNodeData;
134begin
135 Result := AVST.AddChild(ANode);
136 Data := AVST.GetNodeData(Result);
137 AVST.ValidateNode(Result, False);
138 Data^ := ARecord;
139end;
140
141
142
143
144procedure TForm_BinEdit.LoadDat(_fileid: Integer);
145var
146 mem: TMemoryStream;
147begin
148 if ConID <> -1 then
149 begin
150 if hex.Modified then
151 begin
152 if not Save then
153 begin
154 Self.SelectFileID(ConnectionID, FileID);
155 Exit;
156 end;
157 end;
158 end;
159 if _fileid >= 0 then
160 begin
161 fileid := _fileid;
162 ConID := ConnectionID;
163 if ConManager.Connection[ConID].ExtractFileIDOfName(filelist.Items.Strings[filelist.ItemIndex]) <> fileid then
164 Self.SelectFileID(ConnectionID, fileid);
165 Self.ClearStructViewer;
166 mem := nil;
167 ConManager.Connection[ConID].LoadDatFile(fileid, TStream(mem));
[177]168 rawlist := ConManager.Connection[ConID].GetRawList(fileid);
[104]169 hex.LoadFromStream(mem);
170 mem.Free;
171 ClearValues;
172 WriteStructureInfos;
173 end
174 else
175 begin
176 fileid := _fileid;
177 ConID := -1;
178 Self.ClearStructViewer;
179 ClearValues;
180 hex.DataSize := 0;
[177]181 SetLength(rawlist, 0);
[104]182 end;
183end;
184
185
186
[111]187function TForm_BinEdit.GetValue(datatype: Word; offset: Integer): String;
[104]188var
189 Data: TByteData;
[177]190 i: Integer;
[104]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:
[113]226 begin
[177]227 if Length(rawlist) > 0 then
[198]228 begin
[177]229 for i := 0 to High(rawlist) do
230 if rawlist[i].SrcOffset = offset then
231 begin
232 if rawlist[i].RawAddr > 0 then
233 Result := '0x' + IntToHex(rawlist[i].RawAddr, 8)
234 else
235 Result := 'unused';
236 Break;
237 end;
[198]238 if i > High(rawlist) then
239 Result := 'unused';
240 end;
[113]241 end;
[104]242 12:
[113]243 if hex.Data[offset] = 1 then
244 Result := FormatNumber(hex.Data[offset + 1] + hex.Data[offset + 2] * 256 +
245 hex.Data[offset + 3] * 256 * 256, 5, '0')
246 else
247 Result := 'no link';
[104]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
[111]300 i, j: Integer;
[104]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(ConID, 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
[113]334 Data.Offset := StrToInt('$'+MidStr(SubName, Pos('#', SubName) + 1, 8));
335 Data.Value := '$' +
[104]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: TByteData;
401 str: String;
[111]402 Value: Integer;
[104]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
[174]485 while (hex.SelStart + j) < hex.DataSize do
[104]486 begin
[174]487 if hex.Data[hex.SelStart + j] = 0 then
488 Break;
[104]489 if hex.Data[hex.selstart + j] >= 32 then
490 str := str + Char(hex.Data[hex.SelStart + j])
491 else
492 str := str + '.';
493 Inc(j);
494 end;
495 end
496 else
497 begin
498 for j := 0 to hex.SelCount - 1 do
499 if hex.Data[hex.selstart + j] >= 32 then
500 str := str + Char(hex.Data[hex.SelStart + j])
501 else if hex.Data[hex.selstart + j] > 0 then
502 str := str + '.'
503 else
504 Break;
505 end;
506 value_viewer.Cells[1, i] := str;
507 end;
508 end;
509end;
510
511
512
513
514function TForm_BinEdit.Save: Boolean;
515var
516 mem: TMemoryStream;
[111]517 i: Integer;
[104]518begin
519 case MessageBox(Self.Handle, PChar('Save changes to file ' +
520 ConManager.Connection[ConID].GetFileInfo(fileid).Name + '?'), PChar('Data changed...'),
521 MB_YESNOCANCEL + MB_ICONQUESTION) of
522 idYes:
523 begin
524 mem := TMemoryStream.Create;
525 hex.SaveToStream(mem);
526 mem.Seek(0, soFromBeginning);
527 ConManager.Connection[ConID].UpdateDatFile(fileid, mem);
528 mem.Free;
529 hex.Modified := False;
530 for i := 0 to hex.Datasize - 1 do
531 hex.ByteChanged[i] := False;
532 Result := True;
533 end;
534 idNo:
535 Result := True;
536 idCancel:
537 begin
538 Result := False;
539 end;
540 end;
541end;
542
543
544
545
546procedure TForm_BinEdit.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
547begin
548 if hex.Modified then
549 begin
550 if not Save then
551 CanClose := False;
552 end;
553end;
554
555
556
557
558procedure TForm_BinEdit.ClearStructViewer;
559begin
560 VST.Clear;
561end;
562
563
564
565
566
567
568procedure TForm_BinEdit.hexChange(Sender: TObject);
569begin
570 ClearValues;
571 if hex.DataSize > 0 then
572 begin
573 WriteStructureInfos;
574 WriteValues;
575 end;
576end;
577
578
579
580
581procedure TForm_BinEdit.hexKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
582//var
583// temps: String;
584begin
585 if (Shift = [ssCtrl]) and (Key = Ord('C')) then
586 begin
587 if hex.SelCount > 0 then
588 begin
589 if hex.InCharField then
590 Clipboard.AsText := hex.SelectionAsText
591 else
592 Clipboard.AsText := hex.SelectionAsHex;
593 end;
594 end;
595 if (Shift = [ssCtrl]) and (Key = Ord('V')) then
596 begin
597{ temps:=Clipboard.AsText;
598 IF hex.SelStart+Length(temps)>hex.DataSize THEN
599 SetLength(temps, hex.DataSize-hex.SelStart);
600 hex.Sel
601 hex.SelCount:=Length(temps);
602 hex.ReplaceSelection(temps,Length(temps));
603} end;
604end;
605
606
607
608
609procedure TForm_BinEdit.hexSelectionChanged(Sender: TObject);
610var
611 selstart: Integer;
612 node: PVirtualNode;
613 pdata: PNodeData;
614begin
615 if hex.DataSize > 0 then
616 begin
617 WriteValues;
618 selstart := hex.SelStart;
619 if VST.RootNodeCount > 0 then
620 begin
621 Node := VST.GetFirst;
622 while Assigned(Node) do
623 begin
624 pdata := VST.GetNodeData(Node);
625 if pdata.DataType > 0 then
626 begin
627 if ((selstart - pdata.Offset) < GetDataTypeLength(pdata.DataType)) and
628 ((selstart - pdata.Offset) >= 0) then
629 begin
630 VST.FocusedNode := Node;
631 VST.Selected[Node] := True;
632 Break;
633 end;
634 end;
635 Node := VST.GetNext(Node);
636 end;
637 end;
638 end;
639end;
640
641
642
643
644procedure TForm_BinEdit.value_viewer_contextPopup(Sender: TObject);
645var
646 i: Byte;
647begin
648 for i := 0 to value_viewer_context.Items.Count - 1 do
649 value_viewer_context.Items.Items[i].Visible := False;
650 with value_viewer do
651 begin
652 if (Col = 1) and (Row > 0) and (Length(Cells[Col, Row]) > 0) then
653 begin
654 if Pos(' byte', Cells[0, Row]) = 2 then
655 begin
656 value_viewer_context.Items.Find('Copy to &clipboard').Visible := True;
657 value_viewer_context.Items.Find('Copy to clipboard (as &dec)').Visible := True;
658 value_viewer_context.Items.Find('Copy to clipboard (as &hex)').Visible := True;
659 end;
660 if Pos('Float', Cells[0, Row]) = 1 then
661 value_viewer_context.Items.Find('Copy to clipboard (as &float)').Visible := True;
662 if Pos('Bitset', Cells[0, Row]) = 1 then
663 value_viewer_context.Items.Find(
664 'Copy to clipboard (as &bitset)').Visible := True;
665 if Pos('String', Cells[0, Row]) = 1 then
666 value_viewer_context.Items.Find(
667 'Copy to clipboard (as &string)').Visible := True;
668 if Pos('Selected length', Cells[0, Row]) = 1 then
669 value_viewer_context.Items.Find('Copy to &clipboard').Visible := True;
670 end;
671 end;
672end;
673
674
675
676
677procedure TForm_BinEdit.value_viewerMouseDown(Sender: TObject; Button: TMouseButton;
678 Shift: TShiftState; X, Y: Integer);
679var
680 ACol, ARow: Integer;
681begin
682 if Button = mbRight then
683 begin
684 value_viewer.MouseToCell(x, y, ACol, ARow);
685 if ARow > 0 then
686 begin
687 value_viewer.Col := ACol;
688 value_viewer.Row := ARow;
689 end;
690 end;
691end;
692
693
694
695
696procedure TForm_BinEdit.value_viewer_context_copyClick(Sender: TObject);
697var
698 Name: String;
[111]699 Value: Integer;
[104]700begin
701 Name := TMenuItem(Sender).Name;
702 if Pos('asstring', Name) > 0 then
703 begin
704 Clipboard.AsText := value_viewer.Cells[value_viewer.Col, value_viewer.Row];
705 end
706 else if Pos('asfloat', Name) > 0 then
707 begin
708 Clipboard.AsText := value_viewer.Cells[value_viewer.Col, value_viewer.Row];
709 end
710 else if Pos('asbitset', Name) > 0 then
711 begin
712 Clipboard.AsText := value_viewer.Cells[value_viewer.Col, value_viewer.Row];
713 end
714 else if (Pos('ashex', Name) > 0) or (Pos('asdec', Name) > 0) then
715 begin
716 if value_viewer.Cells[0, value_viewer.Row] = '1 byte, unsigned' then
717 begin
718 if ((hex.SelCount = 1) or (hex.SelCount = 0)) and not
719 ((hex.SelStart + 1) > hex.DataSize) then
720 Value := hex.Data[hex.SelStart];
721 end;
722 if value_viewer.Cells[0, value_viewer.Row] = '2 bytes, unsigned' then
723 begin
724 if ((hex.SelCount = 2) or (hex.SelCount = 0)) and not
725 ((hex.SelStart + 2) > hex.DataSize) then
726 Value := hex.Data[hex.SelStart] + hex.Data[hex.SelStart + 1] * 256;
727 end;
728 if value_viewer.Cells[0, value_viewer.Row] = '4 bytes, unsigned' then
729 begin
730 if ((hex.SelCount = 4) or (hex.SelCount = 0)) and not
731 ((hex.SelStart + 4) > hex.DataSize) then
732 Value := hex.Data[hex.SelStart] + hex.Data[hex.SelStart + 1] * 256 +
733 hex.Data[hex.SelStart + 2] * 256 * 256 + hex.Data[hex.SelStart + 3] * 256 * 256 * 256;
734 end;
735 if Pos('asdec', Name) > 0 then
736 begin
737 Clipboard.AsText := IntToStr(Value);
738 end
739 else
740 begin
741 if value_viewer.Cells[0, value_viewer.Row] = '1 byte, unsigned' then
742 Clipboard.AsText := '0x' + IntToHex(Value, 2);
743 if value_viewer.Cells[0, value_viewer.Row] = '2 bytes, unsigned' then
744 Clipboard.AsText := '0x' + IntToHex(Value, 4);
745 if value_viewer.Cells[0, value_viewer.Row] = '4 bytes, unsigned' then
746 Clipboard.AsText := '0x' + IntToHex(Value, 8);
747 end;
748 end
749 else
750 begin
751 Clipboard.AsText := value_viewer.Cells[value_viewer.Col, value_viewer.Row];
752 end;
753end;
754
755
756
757
758procedure TForm_BinEdit.VSTDblClick(Sender: TObject);
759var
760 node: PVirtualNode;
761 nodedata: PNodeData;
[177]762 rawinfo: TRawDataInfo;
[217]763 form: TForm_TemplateFileList;
[104]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
[113]778 if (nodedata.DataType = 11) and (nodedata.Value <> 'unused') then
[104]779 begin
[177]780 rawinfo := ConManager.Connection[ConID].GetRawInfo(fileid, nodedata.offset);
781 if rawinfo.RawSize > 0 then
782 begin
783 form := nil;
[217]784 form := TForm_TemplateFileList(Form_Main.open_child('rawedit', ConID, fileid));
[177]785 if Assigned(form) then
786 TForm_RawEdit(form).LoadRaw(rawinfo);
787 end;
[104]788 end;
[113]789 if (nodedata.DataType = 12) and (nodedata.Value <> 'no link') then
[104]790 begin
791 if (StrToInt(nodedata.Value) < ConManager.Connection[ConID].GetFileCount) and
792 (StrToInt(nodedata.Value) > 0) and
793 (StrToInt(nodedata.Value) <> fileid) then
794 begin
795 if ConManager.Connection[ConID].GetFileInfo(StrToInt(nodedata.Value)).Size > 0 then
796 Form_Main.open_child('binedit', ConID, StrToInt(nodedata.Value))
797 else
798 ShowMessage('Linked filed is a zero-byte-file');
799 end;
800 end;
801 if (nodedata.DataType >= 100) and (nodedata.DataType <= 300) then
802 begin
[217]803 form := TForm_TemplateFileList(Form_Main.open_child('binedit', ConID));
[104]804 if Assigned(form) then
805 form.SetFileFilters(nodedata.Value, '', False);
806 end;
807 end;
808
809 end;
810end;
811
812
813
814
815procedure TForm_BinEdit.VSTFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode;
816 Column: TColumnIndex);
817var
818 Data: PNodeData;
819begin
820 Data := VST.GetNodeData(node);
821 if Data.DataType > 0 then
822 begin
823 hex.SelStart := Data.Offset;
824 hex.SelEnd := Data.Offset + GetDataTypeLength(Data.DataType) - 1;
825 end
826 else
827 begin
828 hex.SelStart := Data.Offset;
[113]829 hex.SelEnd := Data.Offset + StrToInt(Data.Value) - 1;
[104]830 end;
831end;
832
833
834
835
836procedure TForm_BinEdit.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
837 Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
838var
839 Data: PNodeData;
840begin
841 Data := Sender.GetNodeData(Node);
842 CellText := '';
843 if TextType = ttNormal then
844 begin
845 case Column of
846 0:
847 CellText := Data.Caption;
848 1:
849 if Data.DataType > 0 then
850 CellText := '0x' + IntToHex(Data.Offset, 8)
851 else if Data.Offset > 0 then
852 CellText := '0x' + IntToHex(Data.Offset, 8);
853 2:
854 if Data.DataType > 0 then
855 CellText := GetDataType(Data.DataType);
856 3:
857 if Data.DataType > 0 then
858 CellText := Data.Value //GetValue(data.DataType, data.Offset)
859 else if Length(Data.Value) > 0 then
[113]860 CellText := IntToStr(StrToInt(Data.Value)) + ' Bytes';
[104]861 4:
862 CellText := Data.Description;
863 end;
864 end;
865end;
866
867
868
869
870procedure TForm_BinEdit.VSTHeaderDragged(Sender: TVTHeader; Column: TColumnIndex;
871 OldPosition: Integer);
872begin
873 if Sender.Columns.Items[column].Position < 1 then
874 Sender.Columns.Items[column].Position := OldPosition;
875end;
876
877
878
879
880procedure TForm_BinEdit.VTHPopupColumnChange(const Sender: TBaseVirtualTree;
881 const Column: TColumnIndex; Visible: Boolean);
882begin
883 if column = 0 then
884 TVirtualStringTree(Sender).Header.Columns.Items[column].Options :=
885 TVirtualStringTree(Sender).Header.Columns.Items[column].Options + [coVisible];
886end;
887
888
889
890
[111]891procedure TForm_BinEdit.SetNewValue(datatype: Word; offset: Integer; Value: String);
[104]892var
893 Data: TByteData;
894 value_int: LongWord;
895 value_float: Single;
896 i: Word;
897begin
898 case datatype of
899 1..4:
900 begin
901 value_int := StrToInt(Value);
902 SetLength(Data, datatype);
903 for i := 0 to datatype - 1 do
904 begin
905 Data[i] := value_int mod 256;
906 value_int := value_int div 256;
907 end;
908 end;
909 5..8:
910 begin
911 value_int := StrToInt('$' + Value);
912 SetLength(Data, datatype - 4);
913 for i := 0 to datatype - 5 do
914 begin
915 Data[i] := value_int mod 256;
916 value_int := value_int div 256;
917 end;
918 end;
919 9:
920 begin
921 value_float := StrToFloat(Value);
922 Data := Encode_Float(value_float);
923 end;
924 10:
925 begin
926 value_int := BinToInt(Value);
927 SetLength(Data, 1);
928 Data[0] := value_int;
929 end;
930 10000..65535:
931 begin
932 SetLength(Data, datatype - 10000);
933 for i := 1 to datatype - 10000 do
934 begin
935 if i <= Length(Value) then
936 Data[i - 1] := Ord(Value[i])
937 else
938 Data[i - 1] := 0;
939 end;
940 end;
941 end;
942 for i := 0 to High(Data) do
943 begin
944 if hex.Data[offset + i] <> Data[i] then
945 hex.ByteChanged[offset + i] := True;
946 hex.Data[offset + i] := Data[i];
947 end;
948 hex.Modified := True;
949 hexChange(Self);
950 hex.Repaint;
951end;
952
953
954
955
956procedure TForm_BinEdit.value_viewerDblClick(Sender: TObject);
957var
[111]958 offset: Integer;
[104]959 datatype: Word;
960 objectname: String;
961 Value: String;
962begin
963 if (value_viewer.Col = 1) and (Length(value_viewer.Cells[1, value_viewer.Row]) > 0) then
964 begin
965 offset := hex.SelStart;
966 if value_viewer.Cells[0, value_viewer.Row] = '1 byte, unsigned' then
967 datatype := 1;
968 if value_viewer.Cells[0, value_viewer.Row] = '2 bytes, unsigned' then
969 datatype := 2;
970 if value_viewer.Cells[0, value_viewer.Row] = '4 bytes, unsigned' then
971 datatype := 4;
972 if value_viewer.Cells[0, value_viewer.Row] = 'Bitset' then
973 datatype := 10;
974 if value_viewer.Cells[0, value_viewer.Row] = 'Float' then
975 datatype := 9;
976 if value_viewer.Cells[0, value_viewer.Row] = 'Selected length' then
977 Exit;
978 if value_viewer.Cells[0, value_viewer.Row] = 'String' then
979 begin
980 if hex.SelCount > 0 then
981 datatype := 10000 + hex.SelCount
982 else
983 datatype := 10000 + Length(value_viewer.Cells[1, value_viewer.Row]);
984 end;
985 objectname := '';
986 Value := GetValue(datatype, offset);
987 Form_ValueEdit.MakeVarInput(objectname, offset, datatype, Value, Self);
988 end;
989end;
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.