Author: Nik Ozniev
Down all controls for component in XMLDocument in simplest way?
Answer:
Simply it seems to pass under the component list and to create appropriate nodes of
the XML-document:
1 for k := 0 to MyComponent.ComponentCount - 1 do2 begin3 ifnot (MyComponent.Components[k] is TControl) then4 Continue;
5 // Here create node of the XML-document6 end;
However the problem is to satisfy parent - child relations during creation of nodes
of the XML-document.
The procedure given below carries out this task by conducting special list of those
controls for which are already created XML-document nodes.
Controls corresponding to created nodes are excluded from process of iteration.
7 8 // Writing all controls of given component to TXMLDocument according parent-child 9 relations
10 11 procedure Get_Component_as_XML(AXMLDoc: TXMLDocument; AComponent: TComponent);
12 var13 k: Integer;
14 Ctrl: TControl;
15 List: TList;
16 XMLNode: IXMLNode;
17 GrCtrl: TGraphicControl;
18 19 procedure Add_WinControlAttributes(AWCtrl: TWinControl; AXMLNode: IXMLNode);
20 begin21 with AXMLNode do22 begin23 Attributes['Name'] := AWCtrl.Name;
24 Attributes['Owner'] := AWCtrl.Owner.Name;
25 Attributes['Left'] := IntToStr(AWCtrl.Left);
26 Attributes['Top'] := IntToStr(AWCtrl.Top);
27 Attributes['Width'] := IntToStr(AWCtrl.Width);
28 Attributes['Height'] := IntToStr(AWCtrl.Height);
29 // ... add all needed properties30 end;
31 end;
32 33 procedure Add_GraphicsControlAttributes(AGCtrl: TGraphicControl; AXMLNode:
34 IXMLNode);
35 begin36 with AXMLNode do37 begin38 Attributes['Name'] := AGCtrl.Name;
39 Attributes['Owner'] := AGCtrl.Owner.Name;
40 Attributes['Left'] := AGCtrl.Left;
41 Attributes['Top'] := IntToStr(AGCtrl.Top);
42 Attributes['Width'] := IntToStr(AGCtrl.Width);
43 Attributes['Height'] := IntToStr(AGCtrl.Height);
44 // ... add all needed properties45 end;
46 end;
47 48 procedure Add_XML_Node(AWCtrl: TWinControl; AXMLNode: IXMLNode);
49 var50 i: Integer;
51 WinC: TWinControl;
52 SubIXMLNode,
53 NewStock: IXMLNode;
54 SubCtrl: TControl;
55 SubGrCtrl: TGraphicControl;
56 begin57 NewStock := AXMLNode.AddChild(AWCtrl.ClassName);
58 Add_WinControlAttributes(AWCtrl, NewStock);
59 60 if AWCtrl.ControlCount > 0 then61 for i := 0 to AWCtrl.ControlCount - 1 do62 begin63 SubCtrl := TControl(AWCtrl.Controls[i]);
64 if List.IndexOf(SubCtrl) >= 0 then65 Continue;
66 67 // take a special look at this list68 List.Add(Pointer(SubCtrl));
69 70 if SubCtrl is TGraphicControl then71 begin72 SubGrCtrl := TGraphicControl(SubCtrl);
73 SubIXMLNode := NewStock.AddChild(SubGrCtrl.ClassName);
74 Add_GraphicsControlAttributes(SubGrCtrl, SubIXMLNode);
75 end76 77 elseif SubCtrl is TWinControl then78 begin79 WinC := TWinControl(SubCtrl);
80 Add_XML_Node(WinC, NewStock);
81 end;
82 end;
83 end;
84 85 begin86 AXMLDoc.XML.Clear;
87 AXMLDoc.XML.Add(Format('<%s>', [AComponent.Name]));
88 AXMLDoc.XML.Add(Format('</%s>', [AComponent.Name]));
89 90 AXMLDoc.Active := True;
91 92 List := TList.Create; // special list to hold controls added to XML93 try94 for k := 0 to AComponent.ComponentCount - 1 do95 begin96 ifnot (AComponent.Components[k] is TControl) then97 Continue;
98 Ctrl := TControl(AComponent.Components[k]);
99 if List.IndexOf(Ctrl) >= 0 then100 Continue;
101 102 // take a special look at this list103 List.Add(Pointer(Ctrl));
104 105 if Ctrl is TGraphicControl then106 begin107 GrCtrl := TGraphicControl(Ctrl);
108 XMLNode := AXMLDoc.DocumentElement.AddChild(GrCtrl.ClassName);
109 Add_GraphicsControlAttributes(GrCtrl, XMLNode);
110 end111 112 elseif Ctrl is TWinControl then113 // Recursive process for child controls114 Add_XML_Node(TWinControl(Ctrl), AXMLDoc.DocumentElement);
115 end;
116 finally117 List.Clear;
118 List.Free;
119 end;
120 end;
I do not apply for exclusive novelty, but it seems, that this procedure may be useful to someone.