home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 September / Chip_2001-09_cd1.bin / zkuste / delphi / kolekce / d6 / RX275D6.ZIP / Units / ICOLIST.PAS < prev    next >
Pascal/Delphi Source File  |  1999-10-12  |  9KB  |  379 lines

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