source: oup/current/Tool_BinEdit.pas@ 44

Last change on this file since 44 was 43, checked in by alloc, 18 years ago

DevTree 0.33a.

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