{the following code is for Delphi 5, and the syntax for creating a registry key and reading must be slight modified to work on Delphi 3. note that the code below assumes that you want to add an icon extracted from the Windows registry to an ImageList, with the returned result of the function being the position of the icon inserted on the list, or '0' if the function failed at any point, in which case the default icon should be extracted (icon number 0 in Shell32.dll...Code is included below as a comment indicating how to locate the System folder and Shell32.dll on a computer, and the code to extract an icon (ExtractIconEx) is included in this sample (simply pass the Shell32.dll path and filename along with '0' for the icon pos to extract the default icon) ... You should extract icons from exe files from the exe file itself using the same method, and if no icon exists (the API extract function returns zero) then you can extract the generic 'com' icon for a program file from the registry (also found in the Shell32.dll file). You should extract icons from dll files and ico files from the files themselves, unless you are looking for the 'dll' icon itself, which you can extract from the registry (also located in Shell32.dll)... If you have a problem making the conversions of the Registry functions to Delphi 3 you can download the Delphi 3 version of the souce code under the heading Part Two, on this page http://www.awitness.org/delphi_pascal_tutorial/index.html you will need to add Registry to the uses clause of your unit. (Just a tip if you ever get stuck trying to figure out what file name to add to your uses clause when using API fucntions - get the find dialogue on the start menu, and type *.pas in the filename part, the function name in the containing text part and then navigate to the Delphi folder for the API Program Files\Borland\Delphi5\Source\Rtl\Win . The unit containing the API declaration will be the result of the find operation, you can also search the entire source folder but then you might also return results of sample code that uses that function, rather than just the name you need to include in the uses clause } uses Registry, ShellApi; {pass the file extension you want to look up in the Registry} function TForm1.RegistryIconExtraction(Extension : string):integer; var RegKey : TRegistry; IconPos : integer; AssocAppInfo : string; ExtractPath, FileName : string; IconHandle, PLargeIcon, PSmallIcon : HICON; AnIcon : TIcon; begin Result := 0; {default icon} IconHandle := 0; {init var} if Extension[1] <> '.' then Extension := '.' + Extension; If (Extension='.exe') then Extension := '.com'; try RegKey := TRegistry.Create; except Exit; end; { KEY_QUERY_VALUE grants permission to query subkey data. } RegKey.RootKey := HKEY_CLASSES_ROOT; {set folder for icon info lookup} if RegKey.OpenKey(Extension, false) then begin {extension key exists? false means do not create it if it doesn't exist} try AssocAppInfo := RegKey.ReadString(''); {read app key} RegKey.CloseKey; except RegKey.Free; Exit; end; end; if ((AssocAppInfo <> '') and {app key and icon info exists?} (RegKey.OpenKey(AssocAppInfo + '\DefaultIcon', false))) then begin try ExtractPath := RegKey.ReadString(''); {icon path} RegKey.CloseKey; except RegKey.Free; Exit; end; end; RegKey.Free; {free memory} {IconPos after comma in key ie: C:\Program Files\Winzip\Winzip.Exe,0} {did we get a key for icon, does IconPos exist after comma seperator?} If ((ExtractPath <> '') and (pos(',', ExtractPath) <> 0)) then begin {Filename in registry key is before the comma seperator} FileName := Copy(ExtractPath, 1, Pos(',', ExtractPath) - 1); {extract the icon Index from after the comma in the ExtractPath string} try IconPos := StrToInt(copy(ExtractPath, Pos(',', ExtractPath) + 1, Length(ExtractPath) - Pos(',', ExtractPath) + 1)); except Exit; end; {Filename : convert to Windows Api Pchar null terminated string IconPos : position icon in file - from registry key var Large and small HICON handles returned in PLarge/SmallIcon '1' = number of icons to retrieve} IconHandle := ExtractIconEx(PChar(FileName), IconPos, PLargeIcon, PSmallIcon, 1); { IconHandle = 0 no icons = 1 not exe dll or ico file-> default icon? note that according to the API Icon Handle is supposed to have these values when it does not succeed however I have found that it on rare occassions returns 4 billion or some other invalid number, the example that comes to mind on my computer being when it processes a file with the extension CNT ... therefore checking for a valid icon handler is safer and I have modified the code as follows, using in this example the value of the small icon handler as a check}} {otherwise IconHandle = handle to icon} If (PSmallIcon <>0) then begin AnIcon := TIcon.Create; AnIcon.Handle := PSmallIcon; Result := ImageList1.AddIcon(AnIcon); { FileExtensions.Append(Extension); } AnIcon.ReleaseHandle; AnIcon.Free; end; DeleteObject(PLargeIcon); DeleteObject(PSmallIcon); end; end; {If the function returns zero you will need to assign the 'default icon' to the file extension... note the following demos how to find the directory for the Windows System folder and the Shell32.dll ... not that the code only uses a Pchar transferred to a string because you cannot use the plus operator on a Pchar, but there are alternative ways to append to a PChar, although they don't seem to save many more steps than what you see below... The API function uses 'Windows' which is normally included in the header generated by Delphi var ShellDir : PChar; ShellLoc: String; begin ShellLoc := ''; ShellDir := AllocMem(MAX_PATH); GetSystemDirectory(ShellDir, MAX_PATH); ShellLoc := ShellDir; Finalize(ShellDir); ShellLoc := ShellLoc + '\' + 'SHELL32.DLL'; }