Icolist.pas
上传用户:hylc_2004
上传日期:2014-01-23
资源大小:46800k
文件大小:8k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. {*******************************************************}
  2. {                                                       }
  3. {         Delphi VCL Extensions (RX)                    }
  4. {                                                       }
  5. {         Copyright (c) 1997 Master-Bank                }
  6. {                                                       }
  7. {*******************************************************}
  8. unit IcoList;
  9. interface
  10. {$I RX.INC}
  11. uses Messages, {$IFDEF WIN32} Windows, {$ELSE} WinTypes, WinProcs, {$ENDIF}
  12.   SysUtils, Classes, Graphics;
  13. type
  14. { TIconList class }
  15.   TIconList = class(TPersistent)
  16.   private
  17.     FList: TList;
  18.     FUpdateCount: Integer;
  19.     FOnChange: TNotifyEvent;
  20.     procedure ReadData(Stream: TStream);
  21.     procedure WriteData(Stream: TStream);
  22.     procedure SetUpdateState(Updating: Boolean);
  23.     procedure IconChanged(Sender: TObject);
  24.     function AddIcon(Icon: TIcon): Integer;
  25.   protected
  26.     procedure Changed; virtual;
  27.     procedure DefineProperties(Filer: TFiler); override;
  28.     function Get(Index: Integer): TIcon; virtual;
  29.     function GetCount: Integer; virtual;
  30.     procedure Put(Index: Integer; Icon: TIcon); virtual;
  31.   public
  32.     constructor Create;
  33.     destructor Destroy; override;
  34.     function Add(Icon: TIcon): Integer; virtual;
  35.     function AddResource(Instance: THandle; ResId: PChar): Integer; virtual;
  36.     procedure Assign(Source: TPersistent); override;
  37.     procedure BeginUpdate;
  38.     procedure EndUpdate;
  39.     procedure Clear; virtual;
  40.     procedure Delete(Index: Integer); virtual;
  41.     procedure Exchange(Index1, Index2: Integer); virtual;
  42.     function IndexOf(Icon: TIcon): Integer; virtual;
  43.     procedure Insert(Index: Integer; Icon: TIcon); virtual;
  44.     procedure InsertResource(Index: Integer; Instance: THandle;
  45.       ResId: PChar); virtual;
  46.     procedure LoadResource(Instance: THandle; const ResIds: array of PChar);
  47.     procedure LoadFromStream(Stream: TStream); virtual;
  48.     procedure Move(CurIndex, NewIndex: Integer); virtual;
  49.     procedure SaveToStream(Stream: TStream); virtual;
  50.     property Count: Integer read GetCount;
  51.     property Icons[Index: Integer]: TIcon read Get write Put; default;
  52.     property OnChange: TNotifyEvent read FOnChange write FOnChange;
  53.   end;
  54. implementation
  55. { TIconList }
  56. constructor TIconList.Create;
  57. begin
  58.   inherited Create;
  59.   FList := TList.Create;
  60. end;
  61. destructor TIconList.Destroy;
  62. begin
  63.   FOnChange := nil;
  64.   Clear;
  65.   FList.Free;
  66.   inherited Destroy;
  67. end;
  68. procedure TIconList.BeginUpdate;
  69. begin
  70.   if FUpdateCount = 0 then SetUpdateState(True);
  71.   Inc(FUpdateCount);
  72. end;
  73. procedure TIconList.Changed;
  74. begin
  75.   if (FUpdateCount = 0) and Assigned(FOnChange) then FOnChange(Self);
  76. end;
  77. procedure TIconList.EndUpdate;
  78. begin
  79.   Dec(FUpdateCount);
  80.   if FUpdateCount = 0 then SetUpdateState(False);
  81. end;
  82. procedure TIconList.ReadData(Stream: TStream);
  83. var
  84.   Len, Cnt: Longint;
  85.   I: Integer;
  86.   Icon: TIcon;
  87.   Mem: TMemoryStream;
  88. begin
  89.   BeginUpdate;
  90.   try
  91.     Clear;
  92.     Mem := TMemoryStream.Create;
  93.     try
  94.       Stream.Read(Cnt, SizeOf(Longint));
  95.       for I := 0 to Cnt - 1 do begin
  96.         Stream.Read(Len, SizeOf(Longint));
  97.         if Len > 0 then begin
  98.           Icon := TIcon.Create;
  99.           try
  100.             Mem.SetSize(Len);
  101.             Stream.Read(Mem.Memory^, Len);
  102.             Mem.Position := 0;
  103.             Icon.LoadFromStream(Mem);
  104.             AddIcon(Icon);
  105.           except
  106.             Icon.Free;
  107.             raise;
  108.           end;
  109.         end
  110.         else AddIcon(nil);
  111.       end;
  112.     finally
  113.       Mem.Free;
  114.     end;
  115.   finally
  116.     EndUpdate;
  117.   end;
  118. end;
  119. procedure TIconList.WriteData(Stream: TStream);
  120. var
  121.   I: Integer;
  122.   Len: Longint;
  123.   Mem: TMemoryStream;
  124. begin
  125.   Mem := TMemoryStream.Create;
  126.   try
  127.     Len := FList.Count;
  128.     Stream.Write(Len, SizeOf(Longint));
  129.     for I := 0 to FList.Count - 1 do begin
  130.       Mem.Clear;
  131.       if (Icons[I] <> nil) and not Icons[I].Empty then begin
  132.         Icons[I].SaveToStream(Mem);
  133.         Len := Mem.Size;
  134.       end
  135.       else Len := 0;
  136.       Stream.Write(Len, SizeOf(Longint));
  137.       if Len > 0 then Stream.Write(Mem.Memory^, Mem.Size);
  138.     end;
  139.   finally
  140.     Mem.Free;
  141.   end;
  142. end;
  143. procedure TIconList.DefineProperties(Filer: TFiler);
  144. {$IFDEF WIN32}
  145.   function DoWrite: Boolean;
  146.   var
  147.     I: Integer;
  148.     Ancestor: TIconList;
  149.   begin
  150.     Ancestor := TIconList(Filer.Ancestor);
  151.     if (Ancestor <> nil) and (Ancestor.Count = Count) and (Count > 0) then
  152.     begin
  153.       Result := False;
  154.       for I := 0 to Count - 1 do begin
  155.         Result := Icons[I] <> Ancestor.Icons[I];
  156.         if Result then Break;
  157.       end
  158.     end
  159.     else Result := Count > 0;
  160.   end;
  161. {$ENDIF}
  162. begin
  163.   Filer.DefineBinaryProperty('Icons', ReadData, WriteData,
  164.     {$IFDEF WIN32} DoWrite {$ELSE} Count > 0 {$ENDIF});
  165. end;
  166. function TIconList.Get(Index: Integer): TIcon;
  167. begin
  168.   Result := TObject(FList[Index]) as TIcon;
  169. end;
  170. function TIconList.GetCount: Integer;
  171. begin
  172.   Result := FList.Count;
  173. end;
  174. procedure TIconList.IconChanged(Sender: TObject);
  175. begin
  176.   Changed;
  177. end;
  178. procedure TIconList.Put(Index: Integer; Icon: TIcon);
  179. begin
  180.   BeginUpdate;
  181.   try
  182.     if Index = Count then Add(nil);
  183.     if Icons[Index] = nil then FList[Index] := TIcon.Create;
  184.     Icons[Index].OnChange := IconChanged;
  185.     Icons[Index].Assign(Icon);
  186.   finally
  187.     EndUpdate;
  188.   end;
  189. end;
  190. function TIconList.AddIcon(Icon: TIcon): Integer;
  191. begin
  192.   Result := FList.Add(Icon);
  193.   if Icon <> nil then Icon.OnChange := IconChanged;
  194.   Changed;
  195. end;
  196. function TIconList.Add(Icon: TIcon): Integer;
  197. var
  198.   Ico: TIcon;
  199. begin
  200.   Ico := TIcon.Create;
  201.   try
  202.     Ico.Assign(Icon);
  203.     Result := AddIcon(Ico);
  204.   except
  205.     Ico.Free;
  206.     raise;
  207.   end;
  208. end;
  209. function TIconList.AddResource(Instance: THandle; ResId: PChar): Integer;
  210. var
  211.   Ico: TIcon;
  212. begin
  213.   Ico := TIcon.Create;
  214.   try
  215.     Ico.Handle := LoadIcon(Instance, ResId);
  216.     Result := AddIcon(Ico);
  217.   except
  218.     Ico.Free;
  219.     raise;
  220.   end;
  221. end;
  222. procedure TIconList.Assign(Source: TPersistent);
  223. var
  224.   I: Integer;
  225. begin
  226.   if Source = nil then Clear
  227.   else if Source is TIconList then begin
  228.     BeginUpdate;
  229.     try
  230.       Clear;
  231.       for I := 0 to TIconList(Source).Count - 1 do
  232.         Add(TIconList(Source)[I]);
  233.     finally
  234.       EndUpdate;
  235.     end;
  236.   end
  237.   else if Source is TIcon then begin
  238.     BeginUpdate;
  239.     try
  240.       Clear;
  241.       Add(TIcon(Source));
  242.     finally
  243.       EndUpdate;
  244.     end;
  245.   end
  246.   else inherited Assign(Source);
  247. end;
  248. procedure TIconList.Clear;
  249. var
  250.   I: Integer;
  251. begin
  252.   BeginUpdate;
  253.   try
  254.     for I := FList.Count - 1 downto 0 do Delete(I);
  255.   finally
  256.     EndUpdate;
  257.   end;
  258. end;
  259. procedure TIconList.Delete(Index: Integer);
  260. var
  261.   Icon: TIcon;
  262. begin
  263.   Icon := Icons[Index];
  264.   if Icon <> nil then begin
  265.     Icon.OnChange := nil;
  266.     Icon.Free;
  267.   end;
  268.   FList.Delete(Index);
  269.   Changed;
  270. end;
  271. procedure TIconList.Exchange(Index1, Index2: Integer);
  272. begin
  273.   FList.Exchange(Index1, Index2);
  274.   Changed;
  275. end;
  276. function TIconList.IndexOf(Icon: TIcon): Integer;
  277. begin
  278.   Result := FList.IndexOf(Icon);
  279. end;
  280. procedure TIconList.InsertResource(Index: Integer; Instance: THandle;
  281.   ResId: PChar);
  282. var
  283.   Ico: TIcon;
  284. begin
  285.   Ico := TIcon.Create;
  286.   try
  287.     Ico.Handle := LoadIcon(Instance, ResId);
  288.     FList.Insert(Index, Ico);
  289.     Ico.OnChange := IconChanged;
  290.   except
  291.     Ico.Free;
  292.     raise;
  293.   end;
  294.   Changed;
  295. end;
  296. procedure TIconList.Insert(Index: Integer; Icon: TIcon);
  297. var
  298.   Ico: TIcon;
  299. begin
  300.   Ico := TIcon.Create;
  301.   try
  302.     Ico.Assign(Icon);
  303.     FList.Insert(Index, Ico);
  304.     Ico.OnChange := IconChanged;
  305.   except
  306.     Ico.Free;
  307.     raise;
  308.   end;
  309.   Changed;
  310. end;
  311. procedure TIconList.LoadResource(Instance: THandle; const ResIds: array of PChar);
  312. var
  313.   I: Integer;
  314. begin
  315.   BeginUpdate;
  316.   try
  317.     for I := Low(ResIds) to High(ResIds) do
  318.       AddResource(Instance, ResIds[I]);
  319.   finally
  320.     EndUpdate;
  321.   end;
  322. end;
  323. procedure TIconList.Move(CurIndex, NewIndex: Integer);
  324. begin
  325.   FList.Move(CurIndex, NewIndex);
  326.   Changed;
  327. end;
  328. procedure TIconList.SetUpdateState(Updating: Boolean);
  329. begin
  330.   if not Updating then Changed;
  331. end;
  332. procedure TIconList.LoadFromStream(Stream: TStream);
  333. begin
  334.   ReadData(Stream);
  335. end;
  336. procedure TIconList.SaveToStream(Stream: TStream);
  337. begin
  338.   WriteData(Stream);
  339. end;
  340. end.