unit MetaEditor; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, VirtualTrees, _MetaManager, StdCtrls; type TForm_Meta = class(TForm) VST: TVirtualStringTree; Button1: TButton; Label3: TLabel; combo_connection: TComboBox; procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure FormCreate(Sender: TObject); procedure VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString); procedure Button1Click(Sender: TObject); procedure VSTInitChildren(Sender: TBaseVirtualTree; Node: PVirtualNode; var ChildCount: Cardinal); procedure VSTPaintText(Sender: TBaseVirtualTree; const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType); private public MetaManager: TMetaManager; end; var Form_Meta: TForm_Meta; implementation uses Data, _DataTypes, _FileTypes, ConnectionManager, TypeDefs, StrUtils; {$R *.dfm} type PNodeData = ^TNodeData; TNodeData = record Field: TObject; end; function AddVSTEntry(AVST: TCustomVirtualStringTree; ANode: PVirtualNode; ARecord: TNodeData): PVirtualNode; var Data: PNodeData; begin Result := AVST.AddChild(ANode); Data := AVST.GetNodeData(Result); AVST.ValidateNode(Result, False); Data^ := ARecord; end; procedure TForm_Meta.VSTInitChildren(Sender: TBaseVirtualTree; Node: PVirtualNode; var ChildCount: Cardinal); var data: PNodeData; newdata: TNodeData; newnode: PVirtualNode; i: Integer; id: Integer; begin data := VST.GetNodeData(node); for i := 0 to MetaManager.FileById[TFile(data.Field).FileID].ChildCount - 1 do begin id := MetaManager.FileById[TFile(data.Field).FileID].LinkByIndex[i].DestID; MetaManager.InitFile(id); newdata.Field := MetaManager.FileById[id]; newnode := AddVSTEntry(VST, Node, newdata); if MetaManager.FileById[id].ChildCount > 0 then VST.HasChildren[newnode] := True; end; ChildCount := MetaManager.FileById[TFile(data.Field).FileID].ChildCount; end; procedure TForm_Meta.Button1Click(Sender: TObject); var name: String; conid: Integer; a,b,c: Int64; i: Integer; data: TNodeData; node: PVirtualNode; begin if combo_connection.ItemIndex >= 0 then begin name := combo_connection.Items.Strings[combo_connection.ItemIndex]; conid := StrToInt(MidStr(name, Pos('[', name) + 1, Pos(']', name) - Pos('[', name) - 1)); QueryPerformanceFrequency(c); QueryPerformanceCounter(a); MetaManager := TMetaManager.Create(conid); QueryPerformanceCounter(b); ShowMessage('Loading Done - ' + FloatToStr((b-a)/c) + 's'); VST.Clear; VST.BeginUpdate; for i := 0 to MetaManager.FileCount - 1 do begin if Assigned(MetaManager.FileById[i]) then begin data.Field := MetaManager.FileById[i]; node := AddVSTEntry(VST, nil, data); if MetaManager.FileById[i].ChildCount > 0 then VST.HasChildren[node] := True; end; end; VST.EndUpdate; end; end; procedure TForm_Meta.FormClose(Sender: TObject; var Action: TCloseAction); begin MetaManager.Free; Action := caFree; end; procedure TForm_Meta.FormCreate(Sender: TObject); var i: Integer; fn, datatype, boxstring: String; level: Integer; begin combo_connection.ItemIndex := -1; combo_connection.Items.Clear; if ConManager.Count > 0 then begin for i := 0 to ConManager.Count - 1 do begin level := ConManager.ConnectionByIndex[i].LevelNumber; fn := ExtractFileName(ConManager.ConnectionByIndex[i].FileName); if ConManager.ConnectionByIndex[i].Backend = DB_ONI then datatype := 'ONI-.dat: ' else if ConManager.ConnectionByIndex[i].Backend = DB_ADB then datatype := 'OUP-DB: ' else datatype := 'Unknown: '; boxstring := datatype + fn + ' (Level: ' + IntToStr(level) + ') [' + IntToStr(ConManager.ConnectionByIndex[i].ConnectionID) + ']'; combo_connection.Items.Add(boxstring); end; if combo_connection.ItemIndex = -1 then begin combo_connection.ItemIndex := 0; end; end; VST.NodeDataSize := SizeOf(TNodeData); VST.Font.Charset := AppSettings.CharSet; VST.Clear; end; procedure TForm_Meta.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString); var Data: PNodeData; begin Data := Sender.GetNodeData(Node); CellText := ''; if TextType = ttNormal then begin case Column of 0: begin if Data.Field is TFile then begin CellText := TFile(Data.Field).FileName; if CellText = '' then CellText := 'Unnamed'; end; end; 1: begin if Data.Field is TFile then CellText := TFile(Data.Field).FileExt; end; 2: begin if Data.Field is TFile then CellText := IntToStr(TFile(Data.Field).FileID); end; end; end; end; procedure TForm_Meta.VSTPaintText(Sender: TBaseVirtualTree; const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType); var Data: PNodeData; begin Data := Sender.GetNodeData(Node); if TextType = ttNormal then begin case Column of 0: begin if Data.Field is TFile then begin if Length(TFile(Data.Field).FileName) = 0 then TargetCanvas.Font.Color := $C06060; if TFile(Data.Field).FileSize = 0 then TargetCanvas.Font.Color := $2020A0; end; end; end; end; end; { procedure WriteStructureInfos; var i, j: Integer; pdata: PNodeData; Data: TNodeData; node: PVirtualNode; begin VST.BeginUpdate; if VST.RootNodeCount = 0 then begin structs := LoadStructureDefinition(ConID, fileid); if structs.Data then begin if Length(structs.Global) > 0 then begin for i := 0 to High(structs.Global) do begin Data.Caption := structs.Global[i].Name; Data.Offset := structs.Global[i].offset; Data.DataType := structs.Global[i].datatype; Data.Value := GetValue(structs.Global[i].datatype, structs.Global[i].offset); Data.Description := structs.Global[i].description; AddVSTEntry(VST, nil, Data); end; end; if Length(structs.Subs) > 0 then begin for i := 0 to High(structs.Subs) do begin with structs.Subs[i] do begin if Length(Entries) > 0 then begin if Pos('#', SubName) > 0 then begin Data.Offset := StrToInt('$'+MidStr(SubName, Pos('#', SubName) + 1, 8)); Data.Value := '$' + MidStr(SubName, PosEx('#', SubName, Pos('#', SubName) + 1) + 1, 8); Data.Caption := MidStr(SubName, 1, Pos('#', SubName) - 1); Data.Description := SubDesc; end else begin Data.Caption := SubName; Data.Description := SubDesc; Data.Offset := 0; Data.Value := ''; end; Data.DataType := 0; node := AddVSTEntry(VST, nil, Data); Data.Description := ''; for j := 0 to High(Entries) do begin Data.Caption := Entries[j].Name; Data.Offset := Entries[j].offset; Data.DataType := Entries[j].datatype; Data.Value := GetValue(Entries[j].datatype, Entries[j].offset); Data.Description := Entries[j].description; AddVSTEntry(VST, node, Data); end; end; end; end; end; end; if VST.RootNodeCount > 0 then VST.FocusedNode := VST.GetFirst; end else begin Node := VST.GetFirst; while Assigned(Node) do begin pdata := VST.GetNodeData(Node); if pdata.DataType > 0 then pdata.Value := GetValue(pdata.Datatype, pdata.Offset); Node := VST.GetNext(Node); end; end; VST.EndUpdate; end; } end.