home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 March / Chip_2002-03_cd1.bin / zkuste / delphi / kompon / d3456 / SYSIMAGE.ZIP / SysImg.pas < prev   
Encoding:
Pascal/Delphi Source File  |  2001-12-27  |  6.0 KB  |  195 lines

  1. {------------------------------------------------------------------------------}
  2. {                                                                              }
  3. {  TSysImageList v1.20                                                         }
  4. {  by Kambiz R. Khojasteh                                                      }
  5. {                                                                              }
  6. {  kambiz@delphiarea.com                                                       }
  7. {  http://www.delphiarea.com                                                   }
  8. {                                                                              }
  9. {------------------------------------------------------------------------------}
  10.  
  11. {$I DELPHIAREA.INC}
  12.  
  13. unit SysImg;
  14.  
  15. interface
  16.  
  17. uses
  18.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  19.   {$IFDEF DELPHI4_UP} ImgList {$ELSE} ComCtrls {$ENDIF};
  20.  
  21. type
  22.  
  23.   TIconSize = (isSmallIcons, isLargeIcons);
  24.  
  25.   {$IFDEF DELPHI4_UP}
  26.   TSysImageList = class(TCustomImageList)
  27.   {$ELSE}
  28.   TSysImageList = class(TImageList)
  29.   {$ENDIF}
  30.   private
  31.     fIconSize: TIconSize;
  32.     procedure SetIconSize(Value: TIconSize);
  33.     procedure UpdateHandle;
  34.   protected
  35.     procedure DefineProperties(Filer: TFiler); override;
  36.   public
  37.     constructor Create(AOwner: TComponent); override;
  38.     function ImageIndexOf(const Path: String; OpenIcon: Boolean
  39.       {$IFDEF DELPHI4_UP} = False {$ENDIF}): Integer;
  40.   published
  41.     Property BkColor;
  42.     Property BlendColor;
  43.     property DrawingStyle default dsTransparent;
  44.     property IconSize: TIconSize read fIconSize write SetIconSize default isSmallIcons;
  45.     property OnChange;
  46.   end;
  47.  
  48. procedure Register;
  49.  
  50. implementation
  51.  
  52. uses
  53.   ShellAPI, ShlObj, ActiveX;
  54.  
  55. type
  56.   TSpecialFolder = record
  57.     Name: String;
  58.     ID: Integer;
  59.   end;
  60.  
  61. const
  62.   IconSizeFlags: array[TIconSize] of Word =
  63.     (SHGFI_SMALLICON, SHGFI_LARGEICON);
  64.   OPenIconFlags: array[Boolean] of Word =
  65.     (0, SHGFI_OPENICON);
  66.   SpecialFolders: array[1..7] of TSpecialFolder = (
  67.     (Name: 'Desktop';              ID: CSIDL_DESKTOP),
  68.     (Name: 'Control Panel';        ID: CSIDL_CONTROLS),
  69.     (Name: 'Printers';             ID: CSIDL_PRINTERS),
  70.     (Name: 'My Documents';         ID: CSIDL_PERSONAL),
  71.     (Name: 'Recycle Bin';          ID: CSIDL_BITBUCKET),
  72.     (Name: 'My Computer';          ID: CSIDL_DRIVES),
  73.     (Name: 'Network Neighborhood'; ID: CSIDL_NETWORK));
  74.  
  75. constructor TSysImageList.Create(AOwner: TComponent);
  76. begin
  77.   inherited Create(AOwner);
  78.   fIconSize := isSmallIcons;
  79.   DrawingStyle := dsTransparent;
  80.   ShareImages := True;
  81.   UpdateHandle;
  82. end;
  83.  
  84. procedure TSysImageList.DefineProperties(Filer: TFiler);
  85. begin
  86.   Handle := 0;
  87.   inherited DefineProperties(Filer);
  88.   UpdateHandle;
  89. end;
  90.  
  91. procedure TSysImageList.UpdateHandle;
  92. var
  93.   FileInfo: TShFileInfo;
  94. begin
  95.   Handle := ShGetFileInfo('C:\', 0, FileInfo, SizeOf(FileInfo),
  96.     IconSizeFlags[fIconSize] or SHGFI_SYSICONINDEX);
  97. end;
  98.  
  99. function GetUniqueFileName: String;
  100. var
  101.   TempPath: array[0..255] of Char;
  102.   TempFile: array[0..255] of Char;
  103. begin
  104.   GetTempPath(SizeOf(TempPath), TempPath);
  105.   GetTempFileName(TempPath, 'TMP', Random(100), TempFile);
  106.   Result := TempFile;
  107. end;
  108.  
  109. function TSysImageList.ImageIndexOf(const Path: String; OpenIcon: Boolean): Integer;
  110.  
  111. var
  112.   FileInfo: TShFileInfo;
  113.   DesktopFolder: IShellFolder;
  114.   PIDL: PItemIDList;
  115.   Malloc: IMalloc;
  116.   NumChars, Flags: {$IFDEF DELPHI4_UP} Cardinal {$ELSE} LongInt {$ENDIF};
  117.   WidePath: PWideChar;
  118.   SpecialFolderID, Index: Integer;
  119.   FileExt, TempFileName: String;
  120.   TempFile: THandle;
  121. begin
  122.   Result := 0;
  123.   // Looks for special folders
  124.   SpecialFolderID := -1;
  125.   for Index := Low(SpecialFolders) to High(SpecialFolders) do
  126.     if CompareText(Path, SpecialFolders[Index].Name) = 0 then
  127.     begin
  128.       SpecialFolderID := SpecialFolders[Index].ID;
  129.       Break;
  130.     end;
  131.   if SpecialFolderID >= 0 then
  132.     SHGetSpecialFolderLocation(Application.Handle, SpecialFolderID, PIDL)
  133.   else // If the path is not a special folder, we get its PIDL by using desktop folder
  134.   begin
  135.     Flags := 0;
  136.     WidePath := StringToOleStr(Path);
  137.     NumChars := Length(WidePath);
  138.     SHGetDesktopFolder(DesktopFolder);
  139.     DesktopFolder.ParseDisplayName(0, nil, WidePath, NumChars, PIDL, Flags);
  140.   end;
  141.   // If PIDL is obtained, we use it for finding the image index. When path is not
  142.   // a URL or an existing file, PIDL could be null.
  143.   if PIDL <> nil then
  144.   begin
  145.     FillChar(FileInfo, SizeOf(FileInfo), 0);
  146.     ShGetFileInfo(PChar(PIDL), 0, FileInfo, SizeOf(FileInfo), SHGFI_PIDL or
  147.       SHGFI_SYSICONINDEX or IconSizeFlags[fIconSize] or OpenIconFlags[OpenIcon]);
  148.     if FileInfo.iIcon > 0 then Result := FileInfo.iIcon;
  149.     ShGetMalloc(Malloc);
  150.     Malloc.Free(PIDL);
  151.   end
  152.   else
  153.   begin
  154.     // If PIDL is null, we try to find the image index by using the file type
  155.     FileExt := ExtractFileExt(Path);
  156.     FillChar(FileInfo, SizeOf(FileInfo), 0);
  157.     ShGetFileInfo(PChar('*' + FileExt), 0, FileInfo, SizeOf(FileInfo),
  158.       SHGFI_SYSICONINDEX or IconSizeFlags[fIconSize] or OpenIconFlags[OpenIcon]);
  159.     if FileInfo.iIcon > 0 then
  160.       Result := FileInfo.iIcon
  161.     else if not FileExists(Path) then
  162.     begin
  163.       // If using file type failed and path does not point to an existing file,
  164.       // we create a temporary file as type of the file. If there is any icon
  165.       // associated to the type, we will have it.
  166.       TempFileName := GetUniqueFileName + FileExt;
  167.       TempFile := FileCreate(TempFileName);
  168.       if TempFile > 0 then
  169.         FileClose(TempFile);
  170.       if FileExists(TempFileName) then
  171.         try
  172.           Result := ImageIndexOf(TempFileName, OpenIcon);
  173.         finally
  174.           DeleteFile(TempFileName);
  175.         end;
  176.     end;
  177.   end;
  178. end;
  179.  
  180. procedure TSysImageList.SetIconSize(Value: TIconSize);
  181. begin
  182.   if fIconSize <> Value then
  183.   begin
  184.     fIconSize := Value;
  185.     UpdateHandle;
  186.   end;
  187. end;
  188.  
  189. procedure Register;
  190. begin
  191.   RegisterComponents('Delphi Area', [TSysImageList]);
  192. end;
  193.  
  194. end.
  195.