source: oup/current/Unit8_binedit.pas @ 10

Last change on this file since 10 was 10, checked in by alloc, 17 years ago
  • Property svn:executable set to *
File size: 30.6 KB
Line 
1UNIT Unit8_binedit;
2INTERFACE
3USES
4  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
5  Dialogs, Wrapgrid, StdCtrls, Grids, StrUtils, MPHexEditor, ExtCtrls, Clipbrd,
6  Unit3_data, Unit2_functions, Unit9_data_structures, Unit4_exporters, Unit15_Classes,
7  Menus, Math, VirtualTrees, VTHeaderPopup;
8
9TYPE
10  TForm8 = Class(TForm)
11    Splitter1: TSplitter;
12    panel_data: TPanel;
13    hex: TMPHexEditor;
14    Splitter2: TSplitter;
15    panel_files: TPanel;
16    list: TListBox;
17    panel_extension: TPanel;
18    lbl_filter: TLabel;
19    combo_extension: TComboBox;
20    Bevel1: TBevel;
21    panel_imexport: TPanel;
22    btn_export: TButton;
23    btn_import: TButton;
24    opend: TOpenDialog;
25    saved: TSaveDialog;
26    value_viewer: TWrapGrid;
27    Splitter3: TSplitter;
28    value_viewer_context: TPopupMenu;
29    value_viewer_context_copy: TMenuItem;
30    value_viewer_context_copyashex: TMenuItem;
31    value_viewer_context_copyasdec: TMenuItem;
32    value_viewer_context_copyasfloat: TMenuItem;
33    value_viewer_context_copyasbitset: TMenuItem;
34    value_viewer_context_copyasstring: TMenuItem;
35    check_zerobyte: TCheckBox;
36    edit_filtername: TEdit;
37    check_filtername: TCheckBox;
38    VST: TVirtualStringTree;
39    VTHPopup: TVTHeaderPopupMenu;
40    procedure VSTFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode;
41      Column: TColumnIndex);
42    procedure VSTDblClick(Sender: TObject);
43    procedure VTHPopupColumnChange(const Sender: TBaseVirtualTree;
44      const Column: TColumnIndex; Visible: Boolean);
45    procedure VSTHeaderDragged(Sender: TVTHeader; Column: TColumnIndex;
46      OldPosition: Integer);
47    procedure VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
48      Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
49    procedure hexKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
50    PROCEDURE LoadDat(_fileid:LongWord);
51    PROCEDURE LoadFileNames;
52    PROCEDURE check_filternameClick(Sender: TObject);
53    PROCEDURE check_zerobyteClick(Sender: TObject);
54    PROCEDURE combo_extensionClick(Sender: TObject);
55    PROCEDURE panel_extensionResize(Sender: TObject);
56    PROCEDURE listClick(Sender: TObject);
57    PROCEDURE Recreatelist;
58
59    PROCEDURE FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
60    PROCEDURE value_viewerDblClick(Sender: TObject);
61    PROCEDURE value_viewer_context_copyClick(Sender: TObject);
62    PROCEDURE value_viewerMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
63    PROCEDURE value_viewer_contextPopup(Sender: TObject);
64    PROCEDURE btn_importClick(Sender: TObject);
65    PROCEDURE btn_exportClick(Sender: TObject);
66    PROCEDURE panel_imexportResize(Sender: TObject);
67    FUNCTION Save:Boolean;
68    PROCEDURE FormClose(Sender: TObject; var Action: TCloseAction);
69    FUNCTION GetValue(datatype:Word; offset:LongWord):String;
70    PROCEDURE WriteStructureInfos; //(structinfoid:Integer);
71    PROCEDURE hexSelectionChanged(Sender: TObject);
72    PROCEDURE hexChange(Sender: TObject);
73    PROCEDURE FormResize(Sender: TObject);
74    PROCEDURE ClearStructViewer;
75    PROCEDURE FormCloseQuery(Sender: TObject; var CanClose: Boolean);
76    PROCEDURE FormCreate(Sender: TObject);
77    PROCEDURE ClearValues;
78    PROCEDURE WriteValues;
79    PROCEDURE SetNewValue(datatype:Word; offset:LongWord; value:String);
80  PRIVATE
81    fileid:LongWord;
82  PUBLIC
83  END;
84
85VAR
86  Form8: TForm8;
87
88IMPLEMENTATION
89{$R *.dfm}
90USES Unit1_main, Unit12_ValueEdit, Unit13_rawedit;
91
92TYPE
93  PNodeData = ^TNodeData;
94  TNodeData = record
95    Caption:String;
96    Offset:LongInt;
97    DataType:Word;
98    Value:String;
99    Description:String;
100  end;
101
102
103function AddVSTEntry(AVST:TCustomVirtualStringTree; ANode:PVirtualNode; ARecord:TNodeData):PVirtualNode;
104  var
105    data:PNodeData;
106  begin
107    Result:=AVST.AddChild(ANode);
108    data:=AVST.GetNodeData(Result);
109    AVST.ValidateNode(Result,False);
110    data^:=ARecord;
111  end;
112
113
114
115PROCEDURE TForm8.LoadDat(_fileid:LongWord);
116  VAR
117    i:LongWord;
118    mem:TMemoryStream;
119    data:Tdata;
120  BEGIN
121    IF hex.Modified THEN BEGIN
122      IF NOT Save THEN BEGIN
123        FOR i:=0 TO list.Count-1 DO BEGIN
124          IF OniDataConnection.ExtractFileID(list.Items.Strings[i])=fileid THEN BEGIN
125            list.ItemIndex:=i;
126            Exit;
127          END;
128        END;
129      END;
130    END;
131    fileid:=_fileid;
132    FOR i:=0 TO list.Count-1 DO
133      IF OniDataConnection.ExtractFileID(list.Items.Strings[i])=fileid THEN BEGIN
134        list.ItemIndex:=i;
135        Break;
136      END;
137    Self.ClearStructViewer;
138    data:=OniDataConnection.LoadDatFile(fileid);
139    IF Length(data)>0 THEN BEGIN
140      mem:=TMemoryStream.Create;
141      mem.Write(data[0],Length(data));
142      mem.Seek(0,soFromBeginning);
143      hex.LoadFromStream(mem);
144      mem.Free;
145      WriteStructureInfos; 
146    END ELSE BEGIN
147      ClearValues;
148      hex.DataSize:=0;
149    END;
150  END;
151
152PROCEDURE TForm8.Recreatelist;
153  VAR
154    i:LongWord;
155    exts:TStringArray;
156  BEGIN
157    combo_extension.Items.Clear;
158    combo_extension.Items.Add('_All files_ ('+IntToStr(OniDataConnection.GetFilesCount)+')');
159    exts:=OniDataConnection.GetExtensionsList;
160    FOR i:=0 TO High(exts) DO
161      combo_extension.Items.Add(exts[i]);
162    combo_extension.ItemIndex:=0;
163    combo_extensionClick(Self);
164  END;
165
166PROCEDURE TForm8.LoadFileNames;
167  VAR
168    Extension:String[4];
169    no_zero_bytes:Boolean;
170    pattern:String;
171    files:TStringArray;
172    i:LongWord;
173  BEGIN
174    Extension:=MidStr(combo_extension.Items.Strings[combo_extension.ItemIndex],1,4);
175    no_zero_bytes:=NOT check_zerobyte.Checked;
176    pattern:='';
177    IF check_filtername.Checked THEN pattern:=edit_filtername.Text;
178    IF Extension='_All' THEN Extension:='';
179
180    files:=OniDataConnection.GetFilesList(extension,pattern,no_zero_bytes);
181    list.Items.Clear;
182    IF Length(files)>0 THEN
183      FOR i:=0 TO High(files) DO
184        list.Items.Add(files[i]);
185  END;
186
187PROCEDURE TForm8.panel_extensionResize(Sender: TObject);
188  BEGIN
189    combo_extension.Width:=panel_extension.Width-5;
190    edit_filtername.Width:=panel_extension.Width-5;
191  END;
192
193PROCEDURE TForm8.combo_extensionClick(Sender: TObject);
194  BEGIN
195    LoadFileNames;
196  END;
197
198PROCEDURE TForm8.check_zerobyteClick(Sender: TObject);
199  BEGIN
200    LoadFileNames;
201  END;
202
203PROCEDURE TForm8.check_filternameClick(Sender: TObject);
204  BEGIN
205    edit_filtername.Enabled:=NOT check_filtername.Checked;
206    LoadFileNames;
207  END;
208
209PROCEDURE TForm8.listClick(Sender: TObject);
210  BEGIN
211    LoadDat(OniDataConnection.ExtractFileID(list.Items.Strings[list.ItemIndex]));
212  END;
213
214
215
216
217FUNCTION IntToBin(value:Byte):String;
218  VAR i:Byte;
219  BEGIN
220    Result:='';
221    FOR i:=7 DOWNTO 0 DO BEGIN
222      Result:=Result+IntToStr((value SHR i) AND $01);
223    END;
224  END;
225
226FUNCTION TForm8.GetValue(datatype:Word; offset:LongWord):String;
227  VAR
228    data:Tdata;
229    i:Word;
230  BEGIN
231    CASE datatype OF
232      1: Result:=IntToStr(hex.data[offset]);
233      2: Result:=IntToStr(hex.data[offset]+hex.data[offset+1]*256);
234      3: Result:=IntToStr(hex.data[offset]+hex.data[offset+1]*256+hex.data[offset+2]*256*256);
235      4: Result:=IntToStr(hex.data[offset]+hex.data[offset+1]*256+hex.data[offset+2]*256*256+hex.data[offset+3]*256*256*256);
236      5: Result:='0x'+IntToHex(hex.data[offset],2);
237      6: Result:='0x'+IntToHex(hex.data[offset]+hex.data[offset+1]*256,4);
238      7: Result:='0x'+IntToHex(hex.data[offset]+hex.data[offset+1]*256+hex.data[offset+2]*256*256,6);
239      8: Result:='0x'+IntToHex(hex.data[offset]+hex.data[offset+1]*256+hex.data[offset+2]*256*256+hex.data[offset+3]*256*256*256,8);
240      9: BEGIN
241          SetLength(data,4);
242          data[0]:=hex.data[offset];
243          data[1]:=hex.data[offset+1];
244          data[2]:=hex.data[offset+2];
245          data[3]:=hex.data[offset+3];
246          Result:=FloatToStr(Decode_Float(data));
247        END;
248      10: Result:=IntToBin(hex.data[offset]);
249      11: Result:='0x'+IntToHex(OniDataConnection.GetRawInfo(fileid,offset).raw_addr,8);
250      12: Result:=FormatNumber(hex.data[offset+1]+hex.data[offset+2]*256+hex.data[offset+3]*256*256,5,'0');
251      13: Result:=IntToStr(hex.data[offset]);
252      14: Result:=IntToStr(hex.data[offset]+hex.data[offset+1]*256);
253      15: Result:=IntToStr(hex.data[offset]+hex.data[offset+1]*256+hex.data[offset+2]*256*256);
254      16: Result:=IntToStr(hex.data[offset]+hex.data[offset+1]*256+hex.data[offset+2]*256*256+hex.data[offset+3]*256*256*256);
255      17: Result:=IntToStr((hex.data[offset+3]) DIV 2);
256      100..300: BEGIN
257          Result:='';
258          FOR i:=1 TO datatype-100 DO BEGIN
259            IF hex.Data[offset+i-1]>=32 THEN
260              Result:=Result+Chr(hex.Data[offset+i-1])
261            ELSE
262              Break;
263          END;
264        END;
265      1000..9999: BEGIN
266          Result:='';
267          FOR i:=1 TO datatype-1000 DO 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: BEGIN
275          Result:='';
276          FOR i:=1 TO datatype-10000 DO BEGIN
277            IF hex.Data[offset+i-1]>=32 THEN
278              Result:=Result+Chr(hex.Data[offset+i-1])
279            ELSE
280              Result:=Result+'.';
281          END;
282        END;
283    END;
284  END;
285
286PROCEDURE TForm8.WriteStructureInfos;
287  VAR
288    i,j:LongWord;
289    pdata: PNodeData;
290    data: TNodeData;
291    node: PVirtualNode;
292    structs: TStructDef;
293  BEGIN
294    VST.BeginUpdate;
295    IF VST.RootNodeCount=0 THEN BEGIN
296      structs:=LoadStructureDefinition(fileid);
297      IF structs.data THEN BEGIN
298        IF Length(structs.Global)>0 THEN BEGIN
299          FOR i:=0 TO High(structs.Global) DO BEGIN
300            data.Caption:=structs.Global[i].name;
301            data.Offset:=structs.Global[i].offset;
302            data.DataType:=structs.Global[i].datatype;
303            data.Value:=GetValue(structs.Global[i].datatype, structs.Global[i].offset);
304            data.Description:=structs.Global[i].description;
305            AddVSTEntry(VST, nil, data);
306          END;
307        END;
308        IF Length(structs.Subs)>0 THEN BEGIN
309          FOR i:=0 TO High(structs.Subs) DO BEGIN
310            WITH structs.Subs[i] DO BEGIN
311              IF Length(Entries)>0 THEN BEGIN
312                IF Pos('#',SubName)>0 THEN BEGIN
313                  data.Offset:=HexToLong(MidStr(SubName, Pos('#',SubName)+1, 8));
314                  data.Value:=MidStr(SubName, PosEx('#',SubName,Pos('#',SubName)+1)+1, 8);
315                  data.Caption:=MidStr(SubName, 1, Pos('#',SubName)-1);
316                  data.Description:=SubDesc;
317                END ELSE BEGIN
318                  data.Caption:=SubName;
319                  data.Description:=SubDesc;
320                  data.Offset:=0;
321                  data.Value:='';
322                END;
323                data.DataType:=0;
324                node:=AddVSTEntry(VST, nil, data);
325                data.Description:='';
326                FOR j:=0 TO High(Entries) DO BEGIN
327                  data.Caption:=Entries[j].name;
328                  data.Offset:=Entries[j].offset;
329                  data.DataType:=Entries[j].datatype;
330                  data.Value:=GetValue(Entries[j].datatype, Entries[j].offset);
331                  data.Description:=Entries[j].description;
332                  AddVSTEntry(VST, node, data);
333                END;
334              END;
335            END;
336          END;
337        END;
338      END;
339      IF VST.RootNodeCount>0 THEN
340        VST.FocusedNode:=VST.GetFirst;
341    END ELSE BEGIN
342      Node:=VST.GetFirst;
343      WHILE Assigned(Node) DO BEGIN
344        pdata:=VST.GetNodeData(Node);
345        IF pdata.DataType>0 THEN
346          pdata.Value:=GetValue(pdata.Datatype, pdata.Offset);
347        Node:=VST.GetNext(Node);
348      END;
349    END;
350    VST.EndUpdate;
351  END;
352
353PROCEDURE TForm8.ClearValues;
354  VAR
355    i:Byte;
356  BEGIN
357    FOR i:=1 TO value_viewer.RowCount-1 DO BEGIN
358      value_viewer.Cells[1,i]:='';
359    END;
360  END;
361
362PROCEDURE TForm8.WriteValues;
363  VAR
364    i,j:Byte;
365    data:Tdata;
366    str:String;
367    value:LongWord;
368  BEGIN
369    FOR i:=1 TO value_viewer.RowCount-1 DO BEGIN
370      IF value_viewer.Cells[0,i]='1 byte, unsigned' THEN BEGIN
371        IF ((hex.SelCount=1) OR (hex.SelCount=0)) AND NOT ((hex.SelStart+1)>hex.DataSize) THEN BEGIN
372          value:=hex.Data[hex.SelStart];
373          value_viewer.Cells[1,i]:=IntToStr( value )+' / 0x'+IntToHex( value , 2 );
374        END ELSE
375          value_viewer.Cells[1,i]:='';
376      END;
377      IF value_viewer.Cells[0,i]='2 bytes, unsigned' THEN BEGIN
378        IF ((hex.SelCount=2) OR (hex.SelCount=0)) AND NOT ((hex.SelStart+2)>hex.DataSize) THEN BEGIN
379          value:=hex.Data[hex.SelStart] + hex.Data[hex.SelStart+1]*256;
380          value_viewer.Cells[1,i]:=IntToStr( value )+' / 0x'+IntToHex( value , 4 );
381        END ELSE
382          value_viewer.Cells[1,i]:='';
383      END;
384      IF value_viewer.Cells[0,i]='4 bytes, unsigned' THEN BEGIN
385        IF ((hex.SelCount=4) OR (hex.SelCount=0)) AND NOT ((hex.SelStart+4)>hex.DataSize) THEN BEGIN
386          value:=hex.Data[hex.SelStart]+hex.Data[hex.SelStart+1]*256+hex.Data[hex.SelStart+2]*256*256+hex.Data[hex.SelStart+3]*256*256*256;
387          value_viewer.Cells[1,i]:=IntToStr( value )+' / 0x'+IntToHex( value , 8 );
388        END ELSE
389          value_viewer.Cells[1,i]:='';
390      END;
391      IF value_viewer.Cells[0,i]='Bitset' THEN BEGIN
392        IF (hex.SelCount<=8) THEN BEGIN
393          IF hex.SelCount=0 THEN BEGIN
394            SetLength(data,1);
395            data[0]:=hex.Data[hex.SelStart];
396          END ELSE BEGIN
397            SetLength(data,hex.SelCount);
398            FOR j:=0 TO hex.SelCount-1 DO
399              data[j]:=hex.Data[hex.SelStart+j];
400          END;
401          value_viewer.Cells[1,i]:=DataToBin(data);
402        END ELSE
403          value_viewer.Cells[1,i]:='';
404      END;
405      IF value_viewer.Cells[0,i]='Float' THEN BEGIN
406        IF ((hex.SelCount=4) OR (hex.SelCount=0)) AND NOT ((hex.SelStart+4)>hex.DataSize) THEN BEGIN
407          SetLength(data,4);
408          FOR j:=0 TO 3 DO
409            data[j]:=hex.Data[hex.SelStart+j];
410          value_viewer.Cells[1,i]:=FloatToStr(Decode_Float(data));
411        END ELSE
412          value_viewer.Cells[1,i]:='';
413      END;
414      IF value_viewer.Cells[0,i]='Selected length' THEN BEGIN
415        value_viewer.Cells[1,i]:=IntToStr(hex.SelCount)+' bytes';
416      END;
417      IF value_viewer.Cells[0,i]='String' THEN BEGIN
418        j:=0;
419        str:='';
420        IF hex.SelCount=0 THEN BEGIN
421          WHILE (hex.Data[hex.SelStart+j]>0) AND ((hex.SelStart+j)<hex.DataSize) DO BEGIN
422            IF hex.Data[hex.selstart+j]>=32 THEN
423              str:=str+Char(hex.Data[hex.SelStart+j])
424            ELSE
425              str:=str+'.';
426            Inc(j);
427          END;
428        END ELSE BEGIN
429          FOR j:=0 TO hex.SelCount-1 DO
430            IF hex.Data[hex.selstart+j]>=32 THEN
431              str:=str+Char(hex.Data[hex.SelStart+j])
432            ELSE
433              IF hex.Data[hex.selstart+j]>0 THEN
434                str:=str+'.'
435              ELSE
436                Break;
437        END;
438        value_viewer.Cells[1,i]:=str;
439      END;
440    END;
441  END;
442
443PROCEDURE TForm8.FormCreate(Sender: TObject);
444  BEGIN
445    Self.Caption:='';
446    fileid:=0;
447    VST.NodeDataSize:=SizeOf(TNodeData);
448    value_viewer.ColCount:=2;
449    value_viewer.RowCount:=8;
450    value_viewer.FixedRows:=1;
451    value_viewer.Cells[0,0]:='Type';
452    value_viewer.Cells[1,0]:='Value';
453    value_viewer.Cells[0,1]:='1 byte, unsigned';
454    value_viewer.Cells[0,2]:='2 bytes, unsigned';
455    value_viewer.Cells[0,3]:='4 bytes, unsigned';
456    value_viewer.Cells[0,4]:='Bitset';
457    value_viewer.Cells[0,5]:='Float';
458    value_viewer.Cells[0,6]:='String';
459    value_viewer.Cells[0,7]:='Selected length';
460    value_viewer.ColWidths[0]:=100;
461    value_viewer.ColWidths[1]:=value_viewer.Width-150;
462    hex.Height:=panel_data.Height-215;
463//
464    value_viewer.Font.Charset:=AppSettings.CharSet;
465    VST.Font.Charset:=AppSettings.CharSet;
466    hex.Translation:=tkAsIs;
467    hex.Font.Charset:=AppSettings.CharSet;
468//
469  END;
470
471FUNCTION TForm8.Save:Boolean;
472  VAR
473    mem:TMemoryStream;
474    data:Tdata;
475    i:LongWord;
476  BEGIN
477    CASE MessageBox(Self.Handle,PChar('Save changes to file '+OniDataConnection.GetFileInfo(fileid).FileName+'?'),PChar('Data changed...'),MB_YESNOCANCEL) OF
478      IDYES: BEGIN
479          mem:=TMemoryStream.Create;
480          hex.SaveToStream(mem);
481          mem.Seek(0,soFromBeginning);
482          SetLength(data,mem.Size);
483          mem.Read(data[0],mem.Size);
484          mem.Free;
485          OniDataConnection.UpdateDatFile(fileid,data);
486          hex.Modified:=False;
487          FOR i:=0 TO hex.Datasize-1 DO hex.ByteChanged[i]:=False;
488          Result:=True;
489        END;
490      IDNO: Result:=True;
491      IDCANCEL: BEGIN
492          Result:=False;
493        END;
494    END;
495  END;
496
497PROCEDURE TForm8.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
498  BEGIN
499    IF hex.Modified THEN BEGIN
500      IF NOT Save THEN CanClose:=False;
501    END;
502  END;
503
504PROCEDURE TForm8.ClearStructViewer;
505  BEGIN
506    VST.Clear;
507  END;
508
509PROCEDURE TForm8.FormResize(Sender: TObject);
510  BEGIN
511    IF Self.Width>=650 THEN BEGIN
512    END ELSE Self.Width:=650;
513    IF Self.Height>=450 THEN BEGIN
514    END ELSE Self.Height:=450;
515  END;
516
517PROCEDURE TForm8.hexChange(Sender: TObject);
518  BEGIN
519    ClearValues;
520    IF hex.DataSize>0 THEN BEGIN
521      WriteStructureInfos;
522      WriteValues;
523    END;
524  END;
525
526PROCEDURE TForm8.hexKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
527  VAR
528    temps: String;
529  BEGIN
530    IF (Shift=[ssCtrl]) AND (Key=Ord('C')) THEN BEGIN
531      IF hex.SelCount>0 THEN BEGIN
532        IF hex.InCharField THEN
533          Clipboard.AsText:=hex.SelectionAsText
534        ELSE
535          Clipboard.AsText:=hex.SelectionAsHex;
536      END;
537    END;
538    IF (Shift=[ssCtrl]) AND (Key=Ord('V')) THEN BEGIN
539{      temps:=Clipboard.AsText;
540      IF hex.SelStart+Length(temps)>hex.DataSize THEN
541        SetLength(temps, hex.DataSize-hex.SelStart);
542      hex.Sel
543      hex.SelCount:=Length(temps);
544      hex.ReplaceSelection(temps,Length(temps));
545}    END;
546  END;
547
548PROCEDURE TForm8.hexSelectionChanged(Sender: TObject);
549  VAR
550    selstart:Integer;
551    node:PVirtualNode;
552    pdata:PNodeData;
553  BEGIN
554    IF hex.DataSize>0 THEN BEGIN
555      WriteValues;
556      selstart:=hex.SelStart;
557      IF VST.RootNodeCount>0 THEN BEGIN
558        Node:=VST.GetFirst;
559        WHILE Assigned(Node) DO BEGIN
560          pdata:=VST.GetNodeData(Node);
561          IF pdata.DataType>0 THEN BEGIN
562            IF ((selstart-pdata.Offset)<GetTypeDataLength(pdata.DataType)) AND ((selstart-pdata.Offset)>=0) THEN BEGIN
563              VST.FocusedNode:=Node;
564              VST.Selected[Node]:=True;
565              Break;
566            END;
567          END;
568          Node:=VST.GetNext(Node);
569        END;
570      END;
571    END;
572  END;
573
574PROCEDURE TForm8.FormClose(Sender: TObject; var Action: TCloseAction);
575  BEGIN
576    Action:=caFree;
577  END;
578
579PROCEDURE TForm8.panel_imexportResize(Sender: TObject);
580  BEGIN
581    btn_import.Width:=panel_imexport.Width-8;
582    btn_export.Width:=panel_imexport.Width-8;
583  END;
584
585PROCEDURE TForm8.btn_exportClick(Sender: TObject);
586  BEGIN
587    saved.Filter:='Files of matching extension (*.'+OniDataConnection.GetFileInfo(fileid).Extension+')|*.'+OniDataConnection.GetFileInfo(fileid).Extension+'|All files|*.*';
588    saved.DefaultExt:=OniDataConnection.GetFileInfo(fileid).Extension;
589    IF saved.Execute THEN BEGIN
590      ExportDatFile(fileid,saved.FileName);
591    END;
592  END;
593
594PROCEDURE TForm8.btn_importClick(Sender: TObject);
595  VAR
596    fs:TFileStream;
597  BEGIN
598    opend.Filter:='Files of matching extension (*.'+OniDataConnection.GetFileInfo(fileid).Extension+')|*.'+OniDataConnection.GetFileInfo(fileid).Extension+'|All files|*.*';
599    IF opend.Execute THEN BEGIN
600      fs:=TFileStream.Create(opend.FileName,fmOpenRead);
601      IF fs.Size<>hex.DataSize THEN BEGIN
602        ShowMessage('Can''t import '+ExtractFilename(opend.FileName)+
603                    ', file has to have same size as file in .dat.'+CrLf+
604                    'Size of file in .dat: '+FormatFileSize(hex.datasize)+CrLf+
605                    'Size of chosen file: '+FormatFileSize(fs.Size));
606      END ELSE BEGIN
607        hex.LoadFromStream(fs);
608        hex.Modified:=True;
609      END;
610      fs.Free;
611    END;
612  END;
613
614PROCEDURE TForm8.value_viewer_contextPopup(Sender: TObject);
615  VAR
616    i:Byte;
617  BEGIN
618    FOR i:=0 TO value_viewer_context.Items.Count-1 DO
619      value_viewer_context.Items.Items[i].Visible:=False;
620    WITH value_viewer DO BEGIN
621      IF (Col=1) AND (Row>0) AND (Length(Cells[Col,Row])>0) THEN BEGIN
622        IF Pos(' byte',Cells[0,Row])=2 THEN BEGIN
623          value_viewer_context.Items.Find('Copy to &clipboard').Visible:=True;
624          value_viewer_context.Items.Find('Copy to clipboard (as &dec)').Visible:=True;
625          value_viewer_context.Items.Find('Copy to clipboard (as &hex)').Visible:=True;
626        END;
627        IF Pos('Float',Cells[0,Row])=1 THEN
628          value_viewer_context.Items.Find('Copy to clipboard (as &float)').Visible:=True;
629        IF Pos('Bitset',Cells[0,Row])=1 THEN
630          value_viewer_context.Items.Find('Copy to clipboard (as &bitset)').Visible:=True;
631        IF Pos('String',Cells[0,Row])=1 THEN
632          value_viewer_context.Items.Find('Copy to clipboard (as &string)').Visible:=True;
633        IF Pos('Selected length',Cells[0,Row])=1 THEN
634          value_viewer_context.Items.Find('Copy to &clipboard').Visible:=True;
635      END;
636    END;
637  END;
638
639PROCEDURE TForm8.value_viewerMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
640  VAR
641    ACol,ARow:Integer;
642  BEGIN
643    IF Button=mbRight THEN BEGIN
644      value_viewer.MouseToCell(x,y,ACol,ARow);
645      IF ARow>0 THEN BEGIN
646        value_viewer.Col:=ACol;
647        value_viewer.Row:=ARow;
648      END;
649    END;
650  END;
651
652PROCEDURE TForm8.value_viewer_context_copyClick(Sender: TObject);
653  VAR
654    name:String;
655    value:LongWord;
656  BEGIN
657    name:=TMenuItem(Sender).Name;
658    IF Pos('asstring',name)>0 THEN BEGIN
659      Clipboard.AsText:=value_viewer.Cells[value_viewer.Col,value_viewer.Row];
660    END ELSE
661    IF Pos('asfloat',name)>0 THEN BEGIN
662      Clipboard.AsText:=value_viewer.Cells[value_viewer.Col,value_viewer.Row];
663    END ELSE
664    IF Pos('asbitset',name)>0 THEN BEGIN
665      Clipboard.AsText:=value_viewer.Cells[value_viewer.Col,value_viewer.Row];
666    END ELSE
667    IF (Pos('ashex',name)>0) OR (Pos('asdec',name)>0) THEN BEGIN
668      IF value_viewer.Cells[0,value_viewer.Row]='1 byte, unsigned' THEN BEGIN
669        IF ((hex.SelCount=1) OR (hex.SelCount=0)) AND NOT ((hex.SelStart+1)>hex.DataSize) THEN
670          value:=hex.Data[hex.SelStart];
671      END;
672      IF value_viewer.Cells[0,value_viewer.Row]='2 bytes, unsigned' THEN BEGIN
673        IF ((hex.SelCount=2) OR (hex.SelCount=0)) AND NOT ((hex.SelStart+2)>hex.DataSize) THEN
674          value:=hex.Data[hex.SelStart] + hex.Data[hex.SelStart+1]*256;
675      END;
676      IF value_viewer.Cells[0,value_viewer.Row]='4 bytes, unsigned' THEN BEGIN
677        IF ((hex.SelCount=4) OR (hex.SelCount=0)) AND NOT ((hex.SelStart+4)>hex.DataSize) THEN
678          value:=hex.Data[hex.SelStart]+hex.Data[hex.SelStart+1]*256+hex.Data[hex.SelStart+2]*256*256+hex.Data[hex.SelStart+3]*256*256*256;
679      END;
680      IF Pos('asdec',name)>0 THEN BEGIN
681        Clipboard.AsText:=IntToStr(value);
682      END ELSE BEGIN
683        IF value_viewer.Cells[0,value_viewer.Row]='1 byte, unsigned' THEN
684          Clipboard.AsText:='0x'+IntToHex(value,2);
685        IF value_viewer.Cells[0,value_viewer.Row]='2 bytes, unsigned' THEN
686          Clipboard.AsText:='0x'+IntToHex(value,4);
687        IF value_viewer.Cells[0,value_viewer.Row]='4 bytes, unsigned' THEN
688          Clipboard.AsText:='0x'+IntToHex(value,8);
689      END;
690    END ELSE BEGIN
691      Clipboard.AsText:=value_viewer.Cells[value_viewer.Col,value_viewer.Row];
692    END;
693  END;
694
695procedure TForm8.VSTDblClick(Sender: TObject);
696  var
697    node:PVirtualNode;
698    nodedata:PNodeData;
699    id:Integer;
700  begin
701    if VST.FocusedColumn=3 then begin
702      node:=VST.FocusedNode;
703      nodedata:=VST.GetNodeData(node);
704
705      if not (nodedata.datatype in [11,12]) and ((nodedata.DataType<100) or (nodedata.DataType>300)) then begin
706        Form12.MakeVarInput(nodedata.Caption,nodedata.offset,nodedata.datatype,nodedata.value,Self);
707      end else begin
708        if nodedata.DataType=11 then begin
709          if OniDataConnection.GetRawInfo(fileid,nodedata.offset).raw_size>0 then begin
710            if Form1.open_child('rawedit') then begin
711              TForm13(Form1.ActiveMDIChild).LoadRaw(OniDataConnection.GetRawInfo(fileid,nodedata.offset));
712            end;
713          end;
714        end;
715        if nodedata.DataType=12 then begin
716          if (StrToInt(nodedata.Value)<OniDataConnection.GetFilesCount) and
717              (StrToInt(nodedata.Value)>0) and
718              (StrToInt(nodedata.Value)<>fileid) then begin
719            if OniDataConnection.GetFileInfo(StrToInt(nodedata.Value)).Size>0 then begin
720              if Form1.open_child('binedit') then begin
721                TForm8(Form1.ActiveMDIChild).LoadDat(StrToInt(nodedata.Value));
722              end;
723            end else begin
724              ShowMessage('Linked filed is a zero-byte-file');
725            end;
726          end;
727        end;
728        if (nodedata.DataType>=100) and (nodedata.DataType<=300) then begin
729          if Form1.open_child('binedit') then begin
730            TForm8(Form1.ActiveMDIChild).edit_filtername.Text:=nodedata.Value;
731            TForm8(Form1.ActiveMDIChild).check_filtername.Checked:=True;
732            TForm8(Form1.ActiveMDIChild).check_filternameClick(Self);
733          end;
734        end;
735      end;
736
737    end;
738  end;
739
740procedure TForm8.VSTFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode;
741  Column: TColumnIndex);
742  var
743    data:PNodeData;
744  begin
745    data:=VST.GetNodeData(node);
746    IF data.DataType>0 THEN BEGIN
747      hex.SelStart:=data.Offset;
748      hex.SelEnd:=data.Offset+GetTypeDataLength(data.DataType)-1;
749    END ELSE BEGIN
750      hex.SelStart:=data.Offset;
751      hex.SelEnd:=data.Offset+HexToLong(data.Value)-1;
752    END;
753  end;
754
755procedure TForm8.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
756  Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
757  var
758    data:PNodeData;
759  begin
760    data := Sender.GetNodeData(Node);
761    CellText := '';
762    if TextType = ttNormal then begin
763      case Column of
764        0: CellText := data.Caption;
765        1:
766          if data.DataType>0 then
767            CellText := '0x'+IntToHex(data.Offset,8)
768          else
769            if data.Offset>0 then
770              CellText := '0x'+IntToHex(data.Offset,8);
771        2:
772          if data.DataType>0 then
773            CellText := GetDataType(data.DataType);
774        3:
775          if data.DataType>0 then
776            CellText := data.Value //GetValue(data.DataType, data.Offset)
777          else
778            if Length(data.Value)>0 then
779              CellText := IntToStr(HexToLong(data.Value))+' Bytes';
780        4:
781          CellText := data.Description;
782      end;
783    end;
784  end;
785
786procedure TForm8.VSTHeaderDragged(Sender: TVTHeader; Column: TColumnIndex;
787  OldPosition: Integer);
788  begin
789    if Sender.Columns.Items[column].Position<1 then
790      Sender.Columns.Items[column].Position:=OldPosition;
791  end;
792
793procedure TForm8.VTHPopupColumnChange(const Sender: TBaseVirtualTree;
794  const Column: TColumnIndex; Visible: Boolean);
795  begin
796    if column=0 then
797      TVirtualStringTree(Sender).Header.Columns.Items[column].Options:=TVirtualStringTree(Sender).Header.Columns.Items[column].Options+[coVisible];
798  end;
799
800PROCEDURE TForm8.SetNewValue(datatype:Word; offset:LongWord; value:String);
801  VAR
802    data:Tdata;
803    value_int:LongWord;
804    value_float:Single;
805    i:Word;
806  BEGIN
807    CASE datatype OF
808      1..4: BEGIN
809              value_int:=StrToInt(value);
810              SetLength(data,datatype);
811              FOR i:=0 TO datatype-1 DO BEGIN
812                data[i]:=value_int MOD 256;
813                value_int:=value_int DIV 256;
814              END;
815            END;
816      5..8: BEGIN
817              value_int:=StrToInt('$'+value);
818              SetLength(data,datatype-4);
819              FOR i:=0 TO datatype-5 DO BEGIN
820                data[i]:=value_int MOD 256;
821                value_int:=value_int DIV 256;
822              END;
823            END;
824      9:    BEGIN
825              value_float:=StrToFloat(value);
826              data:=Encode_Float(value_float);
827            END;
828      10:   BEGIN
829              value_int:=BinToInt(value);
830              SetLength(data,1);
831              data[0]:=value_int;
832            END;
833      10000..65535: BEGIN
834              SetLength(data,datatype-10000);
835              FOR i:=1 TO datatype-10000 DO BEGIN
836                IF i<=Length(value) THEN
837                  data[i-1]:=Ord(value[i])
838                ELSE
839                  data[i-1]:=0;
840              END;
841            END;
842    END;
843    FOR i:=0 TO High(data) DO BEGIN
844      IF hex.Data[offset+i]<>data[i] THEN hex.ByteChanged[offset+i]:=True;
845      hex.Data[offset+i]:=data[i];
846    END;
847    hex.Modified:=True;
848    hexChange(Self);
849    hex.Repaint;
850  END;
851
852PROCEDURE TForm8.value_viewerDblClick(Sender: TObject);
853  VAR
854    offset:LongWord;
855    datatype:Word;
856    objectname:String;
857    value:String;
858  BEGIN
859    IF (value_viewer.Col=1) AND (Length(value_viewer.Cells[1,value_viewer.Row])>0) THEN BEGIN
860      offset:=hex.SelStart;
861      IF value_viewer.Cells[0,value_viewer.Row]='1 byte, unsigned' THEN
862        datatype:=1;
863      IF value_viewer.Cells[0,value_viewer.Row]='2 bytes, unsigned' THEN
864        datatype:=2;
865      IF value_viewer.Cells[0,value_viewer.Row]='4 bytes, unsigned' THEN
866        datatype:=4;
867      IF value_viewer.Cells[0,value_viewer.Row]='Bitset' THEN
868        datatype:=10;
869      IF value_viewer.Cells[0,value_viewer.Row]='Float' THEN
870        datatype:=9;
871      IF value_viewer.Cells[0,value_viewer.Row]='Selected length' THEN
872        Exit;
873      IF value_viewer.Cells[0,value_viewer.Row]='String' THEN BEGIN
874        IF hex.SelCount>0 THEN
875          datatype:=10000+hex.SelCount
876        ELSE
877          datatype:=10000+Length(value_viewer.Cells[1,value_viewer.Row]);
878      END;
879      objectname:='';
880      value:=GetValue(datatype,offset);
881      Form12.MakeVarInput(objectname,offset,datatype,value,Self);
882    END;
883  END;
884
885PROCEDURE TForm8.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
886  BEGIN
887    IF (Shift=[ssCtrl]) AND (Key=83) THEN
888      IF hex.Modified THEN
889        IF NOT Save THEN
890          Exit;
891  END;
892
893
894END.
Note: See TracBrowser for help on using the repository browser.