home *** CD-ROM | disk | FTP | other *** search
/ PC Open 19 / pcopen19.iso / Zipped / CALMIR21.ZIP / SOURCE.ZIP / SRC / RESOURCE.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1998-02-20  |  12.7 KB  |  431 lines

  1. {**************************************************************************}
  2. {                                                                          }
  3. {    Calmira shell for Microsoft« Windows(TM) 3.1                          }
  4. {    Source Release 2.1                                                    }
  5. {    Copyright (C) 1997-1998 Li-Hsin Huang                                 }
  6. {                                                                          }
  7. {    This program is free software; you can redistribute it and/or modify  }
  8. {    it under the terms of the GNU General Public License as published by  }
  9. {    the Free Software Foundation; either version 2 of the License, or     }
  10. {    (at your option) any later version.                                   }
  11. {                                                                          }
  12. {    This program is distributed in the hope that it will be useful,       }
  13. {    but WITHOUT ANY WARRANTY; without even the implied warranty of        }
  14. {    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         }
  15. {    GNU General Public License for more details.                          }
  16. {                                                                          }
  17. {    You should have received a copy of the GNU General Public License     }
  18. {    along with this program; if not, write to the Free Software           }
  19. {    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.             }
  20. {                                                                          }
  21. {**************************************************************************}
  22.  
  23. unit Resource;
  24.  
  25. interface
  26.  
  27. uses Graphics, Classes, FileCtrl, ObjList, Strings;
  28.  
  29. type
  30.   { Icons, cursors and some bitmaps are handled by this module.
  31.  
  32.     TIconList manages a large number of icons extracted from
  33.     different files.  By keeping track of where each icon comes from,
  34.     it ensures that a particular icon is only loaded once, thus saving
  35.     memory and disk accesses.  Icons are loaded only when they are
  36.     required.
  37.  
  38.     The icon cache is only maintained for "document" files, because they
  39.     are likely to appear often.  Keeping icons for programs would just
  40.     waste memory because they are only used once or twice.
  41.  
  42.     The icon list is a string list, with each string associated with an
  43.     icon object, which may be nil. For example,
  44.  
  45.     bmp   [an icon ]
  46.     txt   [  nil   ]
  47.     bat   [  nil   ]
  48.  
  49.     ExtensionMap holds a list of file extensions and where the
  50.     representative icon is stored.  For example
  51.  
  52.     bmp=c:\windows\pbrush.exe(0)
  53.     txt=c:\windows\notepad.exe
  54.     bat=c:\windows\notepad.exe
  55.  
  56.     FileMap holds a list of filenames, and the objects array holds
  57.     icon objects, which can also be nil.
  58.  
  59.     c:\windows\pbrush.exe(0)  [ an icon ]
  60.     c:\windows\notepad.exe(0) [   nil   ]
  61.  
  62.  
  63.     When Get() is called, the icon list searches itself for a matching
  64.     key.  If it finds a match plus an icon, the icon is returned, making
  65.     the access fast.  If it finds a match but a nil pointer, the search
  66.     extends to ExtensionMap.
  67.  
  68.     With the data above, Get('bat') will find NIL, so it looks at the
  69.     extensions and finds the reference to Notepad.  Looking through FileMap
  70.     shows that no icon is available for Notepad, so it must be extracted.
  71.     The two nils encountered are overwritten with the TIcon object.
  72.   }
  73.  
  74.  
  75.   TIconlist = class(TUniqueStrings)
  76.   private
  77.     ExtensionMap, FileMap : TStringList;
  78.     Store : TObjectList;
  79.     function GetDriveIcon(dtype: TDriveType) : TIcon;
  80.   public
  81.     constructor Create;
  82.     destructor Destroy; override;
  83.     procedure AddIcon(const s: string; Icon: TIcon);
  84.     procedure DelayLoad(const key: string; filename: string);
  85.     function Get(const s: string): TIcon;
  86.     property Drive[dtype: TDriveType] : TIcon read GetDriveIcon;
  87.   end;
  88.  
  89.   TResBitmap = class(TBitmap)
  90.   private
  91.     ResID : PChar;
  92.     ExternalFile : string[12];
  93.   public
  94.     constructor Load(BitmapName : PChar);
  95.     constructor AlternateLoad(BitmapName : PChar; const Filename: string);
  96.     procedure Reload;
  97.   end;
  98.  
  99. const
  100.   crDropFile      = -20;
  101.   crDropCopy      = -21;
  102.   crDropMulti     = -22;
  103.   crDropMultiCopy = -23;
  104.   crFinger        = -24;
  105.   crFlutter       = -25;
  106.   crBusyPointer   = -26;
  107.   crTerminate     = -27;
  108.  
  109.  
  110. var
  111.   Icons: TIconList;
  112.   FolderIcon  : TIcon;
  113.   FileIcon    : TIcon;
  114.   LetterIcon  : TIcon;
  115.   WindowsIcon : TIcon;
  116.   DOSIcon     : TIcon;
  117.   TinyFile    : TIcon;
  118.   TinyFolder  : TIcon;
  119.   TinyProg    : TIcon;
  120.  
  121.   Sizebox    : TResBitmap;
  122.   ShortArrow : TResBitmap;
  123.   AliasArrow : TResBitmap;
  124.  
  125.  
  126. procedure LoadResources;
  127.  
  128. implementation
  129.  
  130. {$R ICONS.RES}
  131. {$R BITMAPS.RES}
  132. {$R CURSORS.RES}
  133.  
  134. uses SysUtils, WinProcs, ShellAPI, IniFiles, Forms, Controls,
  135.   Files, MiscUtil, Drives, WinTypes, Settings, Environs;
  136.  
  137. { TIconList }
  138.  
  139. constructor TIconList.Create;
  140. begin
  141.   inherited Create;
  142.   Store := TObjectList.Create;
  143.   ExtensionMap := TUniqueStrings.Create;
  144.   FileMap := TUniqueStrings.Create;
  145. end;
  146.  
  147.  
  148. destructor TIconList.Destroy;
  149. begin
  150.   Store.Free;
  151.   ExtensionMap.Free;
  152.   FileMap.Free;
  153.   inherited Destroy;
  154. end;
  155.  
  156.  
  157. procedure TIconList.AddIcon(const s: string; Icon: TIcon);
  158. begin
  159.   AddObject(s, Icon);
  160.   Store.Add(Icon);
  161. end;
  162.  
  163.  
  164. procedure TIconList.DelayLoad(const key: string; filename: string);
  165. begin
  166.   Add(key);
  167.   if ExtensionMap.Values[key] = '' then begin
  168.     filename := EnvironSubst(filename);
  169.     ExtensionMap.Add(Format('%s=%s', [key, filename]));
  170.     FileMap.Add(filename);
  171.   end;
  172. end;
  173.  
  174.  
  175. function TIconList.Get(const s: string): TIcon;
  176. var
  177.   i, j, index: Integer;
  178.   h : HIcon;
  179.   filename : TFilename;
  180. begin
  181.   i := IndexOf(s);
  182.  
  183.   if i <> -1 then begin
  184.     Result := TIcon(Objects[i]);
  185.  
  186.     if Result = nil then begin
  187.       { no icon in main list }
  188.       j := FileMap.IndexOf(ExtensionMap.Values[s]);
  189.  
  190.       if j = -1 then
  191.         { shouldn't really happen! }
  192.         j := FileMap.Add(ExtensionMap.Values[s]);
  193.  
  194.       if FileMap.Objects[j] = nil then begin
  195.         { try to extract icon }
  196.         filename := '';
  197.         index := 0;
  198.         Unformat(FileMap[j], '%s(%d', [@filename, 79, @index]);
  199.         h := ExtractIcon(HInstance, StringAsPChar(filename), index);
  200.  
  201.         if h > 1 then begin
  202.           { a new icon has been found }
  203.           Result := TIcon.Create;
  204.           Result.Handle := h;
  205.           Store.Add(Result);
  206.           FileMap.Objects[j] := Result;
  207.           Objects[i] := Result
  208.         end
  209.         else begin
  210.           { the file doesn't contain an icon so assign default }
  211.           Result := LetterIcon;
  212.           FileMap.Objects[j] := LetterIcon;
  213.           Objects[i] := LetterIcon;
  214.         end;
  215.       end
  216.       else begin
  217.         { Found an icon in FileMap }
  218.         Result := TIcon(FileMap.Objects[j]);
  219.         Objects[i] := Result;
  220.       end;
  221.     end
  222.   end
  223.   else Result := FileIcon;
  224. end;
  225.  
  226.  
  227. function TIconList.GetDriveIcon(dtype : TDriveType) : TIcon;
  228. const
  229.   DriveIdents : array[TDriveType] of string[15] =
  230.    ('HardDrive', 'HardDrive', 'FloppyDrive', 'HardDrive',
  231.     'NetworkDrive', 'CDROMDrive', 'RamDrive');
  232. begin
  233.   Result := Get(DriveIdents[dtype]);
  234. end;
  235.  
  236.  
  237. { TResBitmap }
  238.  
  239. constructor TResBitmap.Load(BitmapName : PChar);
  240. begin
  241.   inherited Create;
  242.   ResID := BitmapName;
  243.   ExternalFile := '';
  244.   Reload;
  245. end;
  246.  
  247. constructor TResBitmap.AlternateLoad(BitmapName : PChar; const Filename: string);
  248. begin
  249.   inherited Create;
  250.   ResID := BitmapName;
  251.   ExternalFile := Filename;
  252.   Reload;
  253. end;
  254.  
  255. procedure TResBitmap.ReLoad;
  256. var
  257.   bitmapfile : TFilename;
  258. begin
  259.   bitmapfile := ApplicationPath + ExternalFile;
  260.   if (ExternalFile > '') and FileExists(bitmapfile) then
  261.     LoadFromFile(bitmapfile)
  262.   else
  263.     Handle := LoadBitmap(HInstance, ResID);
  264. end;
  265.  
  266.  
  267. function LoadSystemIcon(const key, alt: string; ResID: PChar): TIcon;
  268. begin
  269.   Result := TIcon.Create;
  270.   with Icons do begin
  271.     if IndexOf(alt) > -1 then Result.Assign(Get(alt))
  272.     else Result.Handle := LoadIcon(HInstance, ResID);
  273.     AddIcon(key, Result);
  274.   end;
  275. end;
  276.  
  277.  
  278. function LoadProgmanIcon(const key, alt: string; index: Integer): TIcon;
  279. var buf: array[0..79] of Char;
  280. begin
  281.   Result := TIcon.Create;
  282.   with Icons do begin
  283.     if IndexOf(alt) > -1 then Result.Assign(Get(alt))
  284.     else Result.Handle := ExtractIcon(HInstance,
  285.         StrPCopy(buf, WinPath + 'progman.exe'), index);
  286.     AddIcon(key, Result);
  287.   end;
  288. end;
  289.  
  290.  
  291. procedure LoadSystemIcons;
  292. begin
  293.   FolderIcon  := LoadSystemIcon('Folder', '_folder', 'FOLDERICON');
  294.   FileIcon    := LoadSystemIcon('File', '_file', 'FILEICON');
  295.   LetterIcon  := LoadSystemIcon('Letter', '_doc', 'LETTERICON');
  296.   TinyFile    := LoadSystemIcon('TinyFile', '_tfile', 'TINYFILEICON');
  297.   TinyProg    := LoadSystemIcon('TinyProg', '_tprog', 'TINYPROGICON');
  298.   TinyFolder  := LoadSystemIcon('TinyFolder', '_tfolder', 'TINYFOLDERICON');
  299.  
  300.   DOSIcon     := LoadProgmanIcon('MSDOS', '_msdos', 1);
  301.   WindowsIcon := LoadProgmanIcon('Windows', '_windows', 8);
  302.  
  303.   LoadSystemIcon('MultiFile', '_multi', 'MULTIFILEICON');
  304.   LoadSystemIcon('HardDrive', '_hard', 'HARDICON');
  305.   LoadSystemIcon('FloppyDrive', '_floppy', 'FLOPPYICON');
  306.   LoadSystemIcon('CDROMDrive', '_cdrom', 'CDROMICON');
  307.   LoadSystemIcon('NetworkDrive', '_network', 'NETWORKICON');
  308.   LoadSystemIcon('RamDrive', '_ramdisk', 'RAMDISKICON');
  309.   LoadSystemIcon('EmptyBin', '_emptbin', 'BINICON');
  310.   LoadSystemIcon('FullBin', '_fullbin', 'FULLBINICON');
  311.   LoadSystemIcon('Computer', '_compute', 'COMPUTERICON');
  312.   LoadSystemIcon('Explorer', '_explore', 'EXPLORERICON');
  313.   LoadSystemIcon('FindDialog', '_finddlg', 'FINDDLGICON');
  314.   LoadSystemIcon('RunDialog', '_rundlg', 'RUNDLGICON');
  315.   LoadSystemIcon('Internet', '_internt', 'INTERNETICON');
  316.   LoadSystemIcon('ShutDownDialog', '_shutdn', 'SHUTDOWNICON');
  317. end;
  318.  
  319.  
  320. procedure LoadUserIcons;
  321. var
  322.   key : string[31];
  323.   temp : TStringList;
  324.   i : Integer;
  325.   path, filename : TFilename;
  326. begin
  327.   temp := TStringList.Create;
  328.   try
  329.     { Find all *.ICO files in the home directory (or directory specified in
  330.       the UserIcons value).  Discard their file extensions and add the
  331.       filenames to the internal lists }
  332.  
  333.     path := ini.ReadString('File System', 'UserIcons', ApplicationPath);
  334.     if path = '' then path := ApplicationPath;
  335.     path := MakePath(path);
  336.  
  337.     FindFiles(path + '*.ico', faArchive or faReadOnly, temp);
  338.  
  339.     for i := 0 to temp.Count-1 do begin
  340.       Unformat(Lowercase(temp[i]), '%s.', [@key, 31]);
  341.       Icons.DelayLoad(key, Format('%s%s(0)', [path, temp[i]]));
  342.     end;
  343.  
  344.     { Add all entries from the [Icons] section }
  345.     temp.Clear;
  346.     ini.ReadSectionValues('Icons', temp);
  347.     for i := 0 to temp.Count-1 do begin
  348.       Unformat(Lowercase(temp[i]), '%s=%s', [@key, 31, @filename, 79]);
  349.       Icons.DelayLoad(key, filename);
  350.     end;
  351.   finally
  352.     temp.Free;
  353.   end;
  354. end;
  355.  
  356.  
  357. procedure LoadRegisteredIcons;
  358. var
  359.   ext : string[15];
  360.   win : TIniFile;
  361.   progname : TFilename;
  362.   i : Integer;
  363.   temp : TStringList;
  364. begin
  365.   { Read [Extensions] section from WIN.INI }
  366.  
  367.   temp := TStringList.Create;
  368.   try
  369.     temp.Clear;
  370.     win := TIniFile.Create('WIN.INI');
  371.     win.ReadSectionValues('Extensions', temp);
  372.     win.Free;
  373.  
  374.     for i := 0 to temp.Count-1 do begin
  375.       Unformat(Lowercase(temp[i]), '%s=%s ', [@ext, 15, @progname, 79]);
  376.       if ExtractFilePath(progname) = '' then progname := WinPath + progname;
  377.       Icons.DelayLoad(ext, progname + '(0)');
  378.     end;
  379.   finally
  380.     temp.Free;
  381.   end;
  382. end;
  383.  
  384.  
  385. procedure LoadCursors;
  386. begin
  387.   with Screen do begin
  388.     Cursors[crDropFile]      := LoadCursor(HInstance, 'DROPFILE');
  389.     Cursors[crDropMulti]     := LoadCursor(HInstance, 'DROPMULTIFILE');
  390.     Cursors[crDropCopy]      := LoadCursor(HInstance, 'DROPFILECOPY');
  391.     Cursors[crDropMultiCopy] := LoadCursor(HInstance, 'DROPMULTIFILECOPY');
  392.     Cursors[crFinger]        := LoadCursor(HInstance, 'FINGERPRESS');
  393.     Cursors[crFlutter]       := LoadCursor(HInstance, 'FILEFLUTTER');
  394.     Cursors[crNoDrop]        := LoadCursor(HInstance, 'DRAGFILE');
  395.     Cursors[crBusyPointer]   := LoadCursor(HInstance, 'BUSYPOINTER');
  396.     Cursors[crTerminate]     := LoadCursor(HInstance, 'TERMINATEAPP');
  397.   end;
  398. end;
  399.  
  400.  
  401. procedure LoadResources;
  402. begin
  403.   LoadUserIcons;
  404.   LoadSystemIcons;
  405.   LoadRegisteredIcons;
  406.   LoadCursors;
  407. end;
  408.  
  409.  
  410. procedure InitResources;
  411. begin
  412.   Icons := TIconList.Create;
  413.   SizeBox := TResBitmap.AlternateLoad('SIZEBOX', 'sizebox.bmp');
  414.   ShortArrow := TResBitmap.AlternateLoad('SHORTARROW', 'arrow.bmp');
  415.   AliasArrow := TResBitmap.AlternateLoad('SHORTARROW', 'arrow.bmp');
  416. end;
  417.  
  418. procedure DoneResources; far;
  419. begin
  420.   Icons.Free;
  421.   Sizebox.Free;
  422.   ShortArrow.Free;
  423.   AliasArrow.Free;
  424. end;
  425.  
  426.  
  427. initialization
  428.   InitResources;
  429.   AddExitProc(DoneResources);
  430. end.
  431.