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

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