hxClasses.pas
上传用户:youjie821
上传日期:2013-01-27
资源大小:459k
文件大小:8k
源码类别:

PlugIns编程

开发平台:

Delphi

  1. unit hxClasses;
  2. interface
  3. uses
  4.   Classes, SysUtils;
  5. type
  6.   TNode = class;
  7.   TErrorObject = class(Exception);
  8.   TTree = class
  9.   private
  10.     FRemoveAll: boolean;
  11.     FIndex: Integer;
  12.     FRootNode: TNode;
  13.     FNodes: TList;
  14.     function GetItems(Index: Integer): TNode;
  15.     function GetCount: Integer;
  16.   protected
  17.     function CreateNode: TNode; virtual;
  18.   public
  19.     constructor Create;
  20.     destructor Destroy; override;
  21.     function AddNode(ParentNode: TNode; AText: string): TNode; virtual;
  22.     procedure RemoveNode(ANode: TNode);
  23.     procedure Clear; virtual;
  24.     procedure SaveToStream(Stream: TStream);
  25.     procedure LoadFromStream(Stream: TStream);
  26.     procedure Assign(ATree: TTree);
  27.     property Count: Integer read GetCount;
  28.     property RootNode: TNode read FRootNode;
  29.     property Items[Index: Integer]: TNode read GetItems;
  30.   end;
  31.   TNode = class
  32.   private
  33.     FTree: TTree;
  34.     FIndex: Integer;
  35.     FRelIndex: Integer;
  36.     FLevel: Integer;
  37.     FData: Pointer;
  38.     FChildren: TList;
  39.     FParent: TNode;
  40.     FText: string;
  41.     function GetNode(Index: Integer): TNode;
  42.     function GetCount: Integer;
  43.     function GetNextSibling: TNode;
  44.     function GetFirstSibling: TNode;
  45.   protected
  46.     procedure SaveMe(Stream: TStream);virtual;
  47.     procedure LoadMe(Stream: TStream);virtual;
  48.   public
  49.     constructor Create(ATree: TTree);
  50.     destructor Destroy; override;
  51.     procedure Clear;
  52.     procedure Save(Stream: TStream);//参数为文件或流
  53.     procedure Load(Stream: TStream);
  54.     property Tree: TTree read FTree;
  55.     property AbsoluteIndex: Integer read FIndex;
  56.     property RelativeIndex: Integer read FRelIndex;
  57.     property Level: Integer read FLevel;
  58.     property Count: Integer read GetCount;
  59.     property Text: string read FText write FText;
  60.     property Data: Pointer read FData write FData;
  61.     property Children[Index: Integer]: TNode read GetNode;
  62.     property NextSibling: TNode read GetNextSibling;
  63.     property FirstSibling: TNode read GetFirstSibling;
  64.     property Parent: TNode read FParent;
  65.   end;
  66.   procedure RaiseError(const msg: string);
  67.   procedure StreamWriteInteger(Stream: TStream; Value: Integer);
  68.   function StreamReadInteger(Stream: TStream): Integer;
  69.   procedure StreamWriteByte(Stream: TStream; Value: Byte);
  70.   function StreamReadByte(Stream: TStream): Byte;
  71.   procedure StreamWriteString(Stream: TStream; Value: string);
  72.   function StreamReadString(Stream: TStream): string;
  73. implementation
  74. procedure StreamWriteInteger(Stream: TStream; Value: Integer);
  75. begin
  76.   Stream.Write(Value, sizeof(Integer));
  77. end;
  78. function StreamReadInteger(Stream: TStream): Integer;
  79. begin
  80.   Stream.Read(Result, sizeof(Integer));
  81. end;
  82. procedure StreamWriteByte(Stream: TStream; Value: Byte);
  83. begin
  84.   Stream.Write(Value, sizeof(Byte));
  85. end;
  86. function StreamReadByte(Stream: TStream): Byte;
  87. begin
  88.   Stream.Read(Result, sizeof(Byte));
  89. end;
  90. procedure StreamWriteString(Stream: TStream; Value: string);
  91. begin
  92.   StreamWriteInteger(Stream, Length(Value));
  93.   Stream.Write(Value[1], Length(Value));
  94. end;
  95. function StreamReadString(Stream: TStream): string;
  96. var
  97.   C: Integer;
  98. begin
  99.   C:= StreamReadInteger(Stream);
  100.   SetLength(Result, C);
  101.   Stream.Read(Result[1], C);
  102. end;
  103. function TTree.GetCount: Integer;
  104. begin
  105.   Result := FNodes.Count;
  106. end;
  107. function TTree.GetItems(Index: Integer): TNode;
  108. begin
  109.   Result := nil;
  110.   if (Index >= 0) and (Index < FNodes.Count) then
  111.     Result := TNode(FNodes[Index])
  112. else
  113.   RaiseError('Range Out of Bounds');
  114. end;
  115. procedure TTree.Clear;
  116. var
  117.   I: Integer;
  118.   Node: TNode;
  119. begin
  120.   FRemoveAll := True;
  121.   FIndex := 1;
  122.   for I := 1 to FNodes.Count - 1 do
  123.   begin
  124.     Node := TNode(FNodes[I]);
  125.     FreeAndNil(Node);
  126.   end;
  127.   FNodes.clear;
  128.   FRootNode.FChildren.Clear;
  129.   FNodes.Add(FRootNode);
  130.   FRemoveAll := False;
  131. end;
  132. constructor TNode.Create(ATree: TTree);
  133. begin
  134.   FTree := ATree;
  135.   FIndex := FTree.FIndex;  // Absolute Index
  136.   Inc(FTree.FIndex);
  137.   FChildren := TList.Create;// Children Nodes
  138.   FData := nil;
  139. end;
  140. destructor TNode.Destroy;
  141. var
  142.   I: Integer;
  143.   Node: TNode;
  144. begin
  145.   if FTree.FRemoveAll = False then
  146.   begin
  147.     FTree.FNodes.Remove(Self);
  148.     for I := 0 to FChildren.Count - 1 do
  149.     begin
  150.       Node := TNode(FChildren[I]);
  151.       FreeAndNil(Node);
  152.     end;
  153.     FreeAndNil(FChildren);
  154.   end;
  155.   FTree := nil;
  156.   FParent := nil;
  157.   FData := nil;
  158.   inherited;
  159. end;
  160. function TNode.GetCount: Integer;
  161. begin
  162.   Assert(FChildren <> nil);
  163.   Result := FChildren.Count;
  164. end;
  165. function TNode.GetNode(Index: Integer): TNode;
  166. begin
  167.   Result := nil;
  168.   if (Index >= 0) and (Index < FChildren.Count) then
  169.      Result := FChildren[Index]
  170.   else
  171.     RaiseError('Range Out of Bounds');
  172. end;
  173. { 算法:从父节点的孩子中查找,自己的下一个就是兄弟 }
  174. function TNode.GetNextSibling: TNode;
  175. var
  176.   I: Integer;
  177. begin
  178.   Result := nil;
  179.   if FParent <> nil then
  180.   begin
  181.     for I := 0 to FParent.Count - 2 do
  182.       if FParent.Children[I] = Self then
  183.       begin
  184.         Result:= FParent.FChildren[I + 1];
  185.         Break;
  186.       end;
  187.   end;
  188. end;
  189. function TNode.GetFirstSibling: TNode;
  190. begin
  191.   if FParent <> nil then
  192.     Result := FParent.FChildren[0]
  193.   else
  194.     Result := Self;
  195. end;
  196. procedure TNode.Clear;
  197. var
  198.   I: Integer;
  199.   Node: TNode;
  200. begin
  201.   for I := 0 to FChildren.Count - 1 do
  202.   begin
  203.     Node := TNode(FChildren[I]);
  204.     FreeAndNil(Node);
  205.   end;
  206.   FChildren.Clear;
  207.   FRelIndex := 1;
  208. end;
  209. constructor TTree.Create;
  210. begin
  211.   FIndex := 0;
  212.   FRemoveAll := False;
  213.   FRootNode:= CreateNode;
  214.   FRootNode.FParent := nil;
  215.   FRootNode.FLevel := 0;
  216.   FNodes := TList.Create;
  217.   FNodes.Add(FRootNode);
  218. end;
  219. destructor TTree.destroy;
  220. begin
  221.   Clear;
  222.   FRemoveAll := True;
  223.   FreeAndNil(FRootNode);
  224.   FreeAndNil(FNodes);
  225.   inherited;
  226. end;
  227. function TTree.AddNode(ParentNode: TNode; AText: string): TNode;
  228. begin
  229.   if ParentNode = nil then
  230.     RaiseError('Invalid Parent Node');
  231.   Result := CreateNode;
  232.   Result.FParent := ParentNode;
  233.   ParentNode.FChildren.Add(Result);
  234.   Result.FRelIndex := ParentNode.FChildren.IndexOf(Result);
  235.   Result.FLevel := ParentNode.FLevel + 1;
  236.   Result.Text:= AText;
  237.   FNodes.Add(Result);
  238. end;
  239. procedure TTree.RemoveNode(ANode: TNode);
  240. var
  241.   I: Integer;
  242. begin
  243.   if ANode = FRootNode then
  244.     RaiseError('Cannot remove root node');
  245.   // 先删除所有子点
  246.   for I:= ANode.Count - 1 downto 0 do
  247.   begin
  248.     RemoveNode(ANode.Children[I]);
  249.   end;
  250.   // 再删除自己
  251.   ANode.FParent.FChildren.Remove(ANode);
  252.   FNodes.Remove(ANode);
  253.   FreeAndNil(ANode);
  254. end;
  255. procedure RaiseError(const msg: string);
  256. begin
  257.   raise TErrorObject.Create(msg);
  258. end;
  259. procedure TTree.LoadFromStream(Stream: TStream);
  260. var
  261.   I, C: Integer;
  262.   node:TNode;
  263. begin
  264.   Clear;
  265.   // 获取根结点文本(实际为根目录)
  266.   FRootNode.Text:= StreamReadString(Stream);
  267.   // 得到子节点的数目;
  268.   C:= StreamReadInteger(Stream);
  269.   for i:= 0 to C - 1 do
  270.   begin
  271.     Node:= AddNode(FRootNode, '');
  272.     Node.Load(Stream);  
  273.   end;
  274. end;
  275. procedure TTree.SaveToStream(Stream: TStream);
  276. var
  277.   I:integer;
  278. begin
  279.   // 保存根结点文本(实际为根目录
  280.   StreamWriteString(Stream, FRootNode.Text);
  281.   // 保存子节点的数量
  282.   StreamWriteInteger(Stream, FRootNode.Count);
  283.   for I:= 0 to FRootNode.Count - 1 do
  284.     FRootNode.Children[I].Save(Stream);
  285. end;
  286. procedure TNode.Load(Stream: TStream);
  287. var
  288.   I, C:integer;
  289.   node:TNode;
  290. begin
  291.   Loadme(Stream);//取数据
  292.   C:= StreamReadInteger(Stream); //得到了节点的数目
  293.   for I:= 0 to C - 1 do
  294.   begin
  295.     Node:= FTree.AddNode(Self, '');
  296.     Node.Load(Stream);
  297.   end;
  298. end;
  299. procedure TNode.Save(Stream: TStream);
  300. var
  301.   I:integer;
  302. begin
  303.   SaveMe(Stream);
  304.   StreamWriteInteger(Stream, Count); //保存子节点的数量
  305.   for I:= 0 to count - 1 do
  306.     Children[I].Save(Stream);
  307. end;
  308. procedure TNode.LoadMe(Stream: TStream);
  309. begin
  310.   // 加载节点数据
  311. end;
  312. procedure TNode.SaveMe(Stream: TStream);
  313. begin
  314.   // 保存节点数据
  315. end;
  316. function TTree.CreateNode: TNode;
  317. begin
  318.   FRootNode := TNode.Create(Self);
  319. end;
  320. procedure TTree.Assign(ATree: TTree);
  321. var
  322.   Stream: TStream;
  323. begin
  324.   Assert(ATree <> nil);
  325.   Stream:= TMemoryStream.Create;
  326.   try
  327.     ATree.SaveToStream(Stream);
  328.     SaveToStream(Stream);
  329.     Stream.Position:= 0;
  330.     Self.LoadFromStream(Stream);
  331.   finally
  332.     Stream.Free;
  333.   end;
  334. end;
  335. end.