BSOne.SFC/EM.Lib/ImageEn_SRC/Demos/FullApps/ResourceExtractor/uResourceExtractor.pas

3825 lines
121 KiB
Plaintext

(* ------------------------------------------------------------------------------
ResourceExtractor : 1.0
Copyright © 1986-2012 : Copyright Adirondack Software & Graphics
Last Modification : 04-05-2012
Source File : uResourceExtractor.pas
Compiler : Delphi 2010
Operating System : Windows 7
This file is copyright (C) W W Miller, 1986-2012.
It may be used without restriction. This code distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
------------------------------------------------------------------------------ *)
// NOTE: TShellTreeView is an optional component in Delphi, e.g. in XE8 you can install it from:
// C:\Users\Public\Documents\Embarcadero\Studio\14.0\Samples\Object Pascal\VCL\ShellControls
unit uResourceExtractor;
//
{$WARN SYMBOL_PLATFORM OFF}
{$WARN UNIT_PLATFORM OFF}
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, Menus, ImgList, ExtCtrls, ExtDlgs, ShellCtrls,
IEView, IEMView, ImageENView, ImageENIO, HyIEUtils, Gauges, uSplash, iexBitmaps,
hyiedefs, iesettings, iexLayers, iexRulers;
type
TFormResExtractor = class( TForm )
OpenDialog1: TOpenDialog;
ImageList1: TImageList;
Panel1: TPanel;
SavePictureDialog1: TSavePictureDialog;
PopupMenu1: TPopupMenu;
Splitter1: TSplitter;
Splitter2: TSplitter;
TreeView1: TTreeView;
Splitter3: TSplitter;
ShellTreeView1: TShellTreeView;
MainMenu1: TMainMenu;
MenuItem1: TMenuItem;
MenuItem2: TMenuItem;
SaveImageAs1: TMenuItem;
N1: TMenuItem;
MenuItem4: TMenuItem;
Panel2: TPanel;
Zoom1: TComboBox;
ImageEnView1: TImageEnView;
StatusBar1: TStatusBar;
SaveAs1: TButton;
ExtractAll1: TButton;
TaskDialog1: TTaskDialog;
Options1: TMenuItem;
DefaultDestinationFolder1: TMenuItem;
Close1: TButton;
SaveGroupIcons1: TButton;
SaveAllImages1: TMenuItem;
SaveSelectedGroupIcon2: TMenuItem;
N2: TMenuItem;
SaveSelectedGroupIconToMultiFrameIcon1: TMenuItem;
SaveSelectedGroupIcon1: TButton;
SaveAllGroupIconsToMultiframeIconfile1: TMenuItem;
SaveAllImagesToAFolder1: TMenuItem;
SaveSelectedIimage1: TMenuItem;
ReturnToTheSystem32Folder1: TMenuItem;
SaveAllGroupIcons1: TMenuItem;
NoImages1: TLabel;
NoBitmaps1: TLabel;
NoPNG1: TLabel;
NoGroupIcons1: TLabel;
NoIcons1: TLabel;
NoGroupCursors1: TLabel;
NoCursors1: TLabel;
NoResources1: TLabel;
Label1: TLabel;
SaveAllIcons1: TButton;
View1: TMenuItem;
ViewIcons1: TMenuItem;
Dimensions1: TLabel;
Colors1: TLabel;
Frames1: TLabel;
ViewIcons2: TButton;
SaveAllIcons2: TMenuItem;
DestinationFolderComboBox1: TComboBox;
BrowseForFolder1: TButton;
Label2: TLabel;
Label3: TLabel;
PopupMenuShellListView1: TPopupMenu;
Icon1: TMenuItem;
SmallIcon1: TMenuItem;
List1: TMenuItem;
Report1: TMenuItem;
ShellListView1: TShellListView;
PopupMenuDestCombobox1: TPopupMenu;
Delete1: TMenuItem;
Clear1: TMenuItem;
Gauge1: TGauge;
Help1: TMenuItem;
About1: TMenuItem;
Filename1: TLabel;
FileSize1: TLabel;
procedure FormCreate( Sender: TObject );
procedure FormDestroy( Sender: TObject );
procedure Exit1Click( Sender: TObject );
procedure Open1Click( Sender: TObject );
procedure TreeView1Change( Sender: TObject; Node: TTreeNode );
procedure TreeView1GetImageIndex( Sender: TObject; Node: TTreeNode );
procedure Saveimageas1Click( Sender: TObject );
procedure DestinationFolder1Click( Sender: TObject );
procedure SaveAs1Click( Sender: TObject );
procedure SavePictureDialog1TypeChange( Sender: TObject );
procedure Zoom1Change( Sender: TObject );
procedure ShellListView1Change( Sender: TObject; Item: TListItem; Change: TItemChange );
procedure ShellTreeView1Change( Sender: TObject; Node: TTreeNode );
procedure DefaultDestinationFolder1Click( Sender: TObject );
procedure FormShow( Sender: TObject );
procedure ShellListView1KeyDown( Sender: TObject; var Key: Word; Shift: TShiftState );
procedure ShellListView1MouseDown( Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: integer );
procedure ExtractAll1Click( Sender: TObject );
procedure ShellListView1ColumnClick( Sender: TObject; Column: TListColumn );
procedure SaveGroupIcons1Click( Sender: TObject );
procedure SaveSelectedGroupIcon1Click( Sender: TObject );
procedure ReturnToTheSystem32Folder1Click( Sender: TObject );
procedure PopupMenu1Popup( Sender: TObject );
procedure SaveAllIcons1Click( Sender: TObject );
procedure ViewIcons1Click( Sender: TObject );
procedure ImageEnView1Progress( Sender: TObject; per: integer );
procedure ImageEnView1FinishWork( Sender: TObject );
procedure BrowseForFolder1Click( Sender: TObject );
procedure Icon1Click( Sender: TObject );
procedure SmallIcon1Click( Sender: TObject );
procedure List1Click( Sender: TObject );
procedure Report1Click( Sender: TObject );
procedure Delete1Click( Sender: TObject );
procedure DestinationFolderComboBox1CloseUp( Sender: TObject );
procedure Clear1Click( Sender: TObject );
procedure About1Click( Sender: TObject );
private
{ Private declarations }
FIniFilename: string;
FState: integer;
FStartupFolder: string;
FFilePath: string;
FDestinationFolder: string;
procedure ReadIni( IniFilename: string );
procedure WriteIni( IniFilename: string );
public
{ Public declarations }
FResourceExtractor: TIEResourceExtractor;
end;
var
FormResExtractor: TFormResExtractor;
implementation
{$R *.dfm}
uses ShlObj, IniFiles, ShellAPI, ShLwApi, StrUtils, FileCtrl, uViewIcons, uAbout;
var
ShellListSortColumn: integer;
ShellListSortAscending: boolean;
function ShellCompare( Item1, Item2: Pointer ): integer;
// Compare shell columns
const
i: array [ boolean ] of Byte = ( 0, 1 );
begin
Result := 0;
if ( Item1 = nil ) or ( Item2 = nil ) then
Exit;
if ShellListSortAscending then
begin
Result := i[ TShellFolder( Item2 ).IsFolder ] - i[ TShellFolder( Item1 ).IsFolder ];
if Result = 0 then
if ( TShellFolder( Item1 ).ParentShellFolder <> nil ) then
Result := Smallint( TShellFolder( Item1 ).ParentShellFolder.CompareIDs( ShellListSortColumn, // sort_type,
TShellFolder( Item1 ).RelativeID, TShellFolder( Item2 ).RelativeID ) );
end
else
begin
Result := i[ TShellFolder( Item1 ).IsFolder ] - i[ TShellFolder( Item2 ).IsFolder ];
if Result = 0 then
if ( TShellFolder( Item2 ).ParentShellFolder <> nil ) then
Result := Smallint( TShellFolder( Item2 ).ParentShellFolder.CompareIDs( ShellListSortColumn, // sort_type,
TShellFolder( Item2 ).RelativeID, TShellFolder( Item1 ).RelativeID ) );
end;
end;
function GetSizeOfPIDL( PIDL: pItemIDList ): integer;
// Get the size of a pidl
var
iSize: integer;
begin
if ( PIDL <> nil ) then
begin
Result := SizeOf( PIDL^.mkid.cb );
while ( PIDL^.mkid.cb <> 0 ) do
begin
iSize := PIDL^.mkid.cb;
inc( Result, iSize );
inc( PByte( PIDL ), iSize );
end;
end
else
Result := 0;
end;
function PathToPIDL( APath: WideString ): pItemIDList;
// Takes the passed Path and attempts to convert it to the equavalent PIDL
var
iDesktop: IShellFolder;
iEaten, dwAttributes: ULONG;
begin
Result := nil;
SHGetDesktopFolder( iDesktop );
dwAttributes := 0;
if Assigned( iDesktop ) then
begin
if iDesktop.ParseDisplayName( 0, nil, PWideChar( APath ), iEaten, Result, dwAttributes ) <> NOERROR then
Result := nil
end;
end;
function PIDLToString( PIDL: pItemIDList ): string;
// Convert a pidl to a string
var
iPidlLength: integer;
begin
iPidlLength := GetSizeOfPIDL( PIDL );
SetLength( Result, iPidlLength );
Move( PIDL^, PChar( Result )^, iPidlLength );
end;
function CurrentDrive: Char;
// Returns the letter that identifies the current drive.
var
iDir: string; // current drive as string
begin
GetDir( 0, iDir );
Result := iDir[ 1 ];
end;
function LocalAppDataFolder: string;
// Find LocalAppData folder location
var
i: Bool;
iPath: array [ 0 .. MAX_PATH ] of Char;
begin
i := ShGetSpecialFolderPath( 0, iPath, CSIDL_LOCAL_APPDATA, False );
if not i then
raise Exception.Create( 'Could not find LocalAppData folder location.' );
Result := iPath;
end;
function AppDataFolder: string;
// Find AppData folder location
var
i: Bool;
iPath: array [ 0 .. MAX_PATH ] of Char;
begin
i := ShGetSpecialFolderPath( 0, iPath, CSIDL_APPDATA, False );
if not i then
raise Exception.Create( 'Could not find AppData folder location.' );
Result := iPath;
end;
function ProfileFolder: string;
// Find Profile folder location
var
i: Bool;
iPath: array [ 0 .. MAX_PATH ] of Char;
begin
i := ShGetSpecialFolderPath( 0, iPath, CSIDL_PROFILE, False );
if not i then
raise Exception.Create( 'Could not find Profile folder location.' );
Result := iPath;
end;
function WindowsFolder: string;
// Returns the Windows directory
begin
SetLength( Result, Windows.MAX_PATH );
SetLength( Result, Windows.GetWindowsDirectory( PChar( Result ), Windows.MAX_PATH ) );
end;
function System32Folder: string;
// Returns the Windows System32 directory
begin
Result := IncludeTrailingPathDelimiter( WindowsFolder ) + 'System32';
end;
function DocumentsFolder: string;
// Find Documents folder location
var
i: Bool;
iPath: array [ 0 .. MAX_PATH ] of Char;
begin
i := ShlObj.ShGetSpecialFolderPath( 0, iPath, CSIDL_PERSONAL, False );
if not i then
raise Exception.Create( 'Could not find Documents folder location.' );
Result := IncludeTrailingPathDelimiter( iPath );
end;
function DesktopFolder: string;
// Find Desktop folder location
var
i: Bool;
iPath: array [ 0 .. MAX_PATH ] of Char;
begin
i := ShlObj.ShGetSpecialFolderPath( 0, iPath, CSIDL_DESKTOP, False );
if not i then
raise Exception.Create( 'Could not find Documents folder location.' );
Result := IncludeTrailingPathDelimiter( iPath );
end;
function BrowseForFolder( AFolder: string ): string;
// BrowseForFolder
var
iFolder: string;
begin
if DirectoryExists( AFolder ) then
if FileCtrl.SelectDirectory( 'Select Folder', iFolder, AFolder, [ sdNewFolder, sdNewUI ], FormResExtractor ) then
Result := AFolder;
end;
function JustFilename( const APathName: string ): string;
// Return a filename from a string
var
iString: string;
i: integer;
// Turn
// Reverse characters in a string ABCD -> DCBA
function Turn( const AString: string ): string;
var
i: integer;
begin
Result := '';
if AString <> '' then
for i := 1 to Length( AString ) do
Result := AString[ i ] + Result;
end;
begin
iString := Turn( APathName );
i := Pos( '\', iString );
if i = 0 then
i := Pos( ':', iString );
if i = 0 then
Result := APathName
else
Result := Turn( Copy( iString, 1, i - 1 ) );
end;
function JustName( const APathName: string ): string;
// Return just the name from a file string
var
iString: string;
begin
iString := JustFilename( APathName );
if Pos( '.', iString ) <> 0 then
Result := Copy( iString, 1, Pos( '.', iString ) - 1 )
else
Result := iString;
end;
procedure SearchDirectory( List: TStrings; const Directory: string; const Mask: string = '*.*';
Recursive: boolean = True; Append: boolean = False );
// "Directory": will be searched for files and directories, the results will
// be added with the full path to "List". directories are written with a
// trailing "\" at the end.
// "Mask": can contain one or several masks, delimited with a semikolon. to
// ignore directory names, add an extension to the mask. for more detailed
// information see the delphi function "FindFirst".
// "Recursive": if true, subdirectories will be searched too.
// "Append": if true, existing entries remain in "List".
//
procedure _SearchDirectory( List: TStrings; const DelimitedDirectory: string; Masks: TStrings; Recursive: boolean );
var
iMaskIndex: integer;
iFoundFile: boolean;
iSearchRec: TSearchRec;
iFile, iDirectory: string;
begin
// list files and directories
for iMaskIndex := 0 to Masks.Count - 1 do
begin
iFoundFile := FindFirst( DelimitedDirectory + Masks[ iMaskIndex ], faAnyFile, iSearchRec ) = 0;
while ( iFoundFile ) do
begin
// skip "." and ".."
if ( iSearchRec.Name <> '.' ) and ( iSearchRec.Name <> '..' ) then
begin
iFile := DelimitedDirectory + iSearchRec.Name;
// add delimiter to directories
if ( ( iSearchRec.Attr and faDirectory ) <> 0 ) then
iFile := IncludeTrailingPathDelimiter( iFile );
// add to list
List.Add( iFile );
end;
// find next file
iFoundFile := FindNext( iSearchRec ) = 0;
end;
FindClose( iSearchRec );
end;
// recursive call for directories
if ( Recursive ) then
begin
iFoundFile := FindFirst( DelimitedDirectory + '*', faDirectory, iSearchRec ) = 0;
while ( iFoundFile ) do
begin
// skip "." and ".."
if ( iSearchRec.Name <> '.' ) and ( iSearchRec.Name <> '..' ) then
begin
iDirectory := IncludeTrailingPathDelimiter( DelimitedDirectory + iSearchRec.Name );
_SearchDirectory( List, iDirectory, Masks, Recursive );
end;
// find next directory
iFoundFile := FindNext( iSearchRec ) = 0;
end;
FindClose( iSearchRec );
end;
end;
var
islMasks: TStringList;
begin
// prepare list
if ( not Append ) then
List.Clear;
List.BeginUpdate;
islMasks := TStringList.Create;
try
// prepare masks
if ( Mask = '' ) then
islMasks.Add( '*' )
else
begin
islMasks.Delimiter := ';';
islMasks.DelimitedText := Mask;
end;
// start recursive loop
_SearchDirectory( List, IncludeTrailingPathDelimiter( Directory ), islMasks, Recursive );
finally
islMasks.Free;
List.EndUpdate;
end;
end;
// Remove duplicate strings from the string list
procedure RemoveDuplicates( const StringList: TStringList );
var
iBuffer: TStringList;
iCount: integer;
begin
StringList.Sort;
iBuffer := TStringList.Create;
try
iBuffer.Sorted := True;
iBuffer.Duplicates := dupIgnore;
iBuffer.BeginUpdate;
for iCount := 0 to StringList.Count - 1 do
iBuffer.Add( StringList[ iCount ] );
iBuffer.EndUpdate;
StringList.Assign( iBuffer );
finally
FreeandNil( iBuffer );
end;
end;
procedure NoDuplicates( AComboBox: TComboBox );
var
iStringList: TStringList;
begin
iStringList := TStringList.Create;
try
iStringList.Duplicates := dupIgnore;
iStringList.Sorted := True;
iStringList.Assign( AComboBox.Items );
AComboBox.Items.Assign( iStringList );
finally
iStringList.Free
end;
end;
function AddThousandSeparator( const S: string; const C: Char ): string;
// Adds a specified thousand separator in the correct location in a string
var
i: integer; // loops through separator position
begin
Result := S;
i := Length( S ) - 2;
while i > 1 do
begin
Insert( C, Result, i );
i := i - 3;
end;
end;
function AddDefThousandSeparator( const S: string ): string;
// Adds the thousands separator from the default locale in the correct location in a string
begin
// Note: FormatSettings.ThousandSeparator in XE8 or Newer
Result := AddThousandSeparator( S, SysUtils.ThousandSeparator );
end;
function IntegerToString( const Value: integer ): string;
// Convert value into a string with thousandsseperator
begin
Result := AddDefThousandSeparator( IntToStr( Value ) );
end;
function FileSize( FileName: WideString ): Int64;
// Returns file size in bytes or -1 if not found.
var
isr: TSearchRec;
begin
if FindFirst( FileName, faAnyFile, isr ) = 0 then
Result := Int64( isr.FindData.nFileSizeHigh ) shl Int64( 32 ) + Int64( isr.FindData.nFileSizeLow )
else
Result := -1;
FindClose( isr );
end;
function FormatByteSize( ABytes: cardinal ): string;
{ Converts a numeric value into a string that represents the number expressed as a size value in bytes, kilobytes, megabytes, or gigabytes, depending on the size. }
var
ArrSize: array [ 0 .. 255 ] of Char;
begin
{ statusbar style }
Result := '';
{ same formating used in statusbar of Explorer }
Result := ShLwApi.StrFormatByteSizeW( ABytes, ArrSize, Length( ArrSize ) - 1 );
end;
function FormatKBSize( ABytes: cardinal ): string;
{ Converts a numeric value into a string that represents the number expressed as a size value in kilobytes. }
var
ArrSize: array [ 0 .. 255 ] of Char;
begin
{ explorer style }
Result := '';
{ same formating used in the Size column of Explorer in detailed mode }
Result := ShLwApi.StrFormatKBSizeW( ABytes, ArrSize, Length( ArrSize ) - 1 );
end;
function FormatMBSize( ABytes: Int64 ): string;
{ Converts a numeric value into a string that represents the number expressed as a size value in megabytes. }
const
B = 1; { byte }
KB = 1024 * B; { kilobyte }
MB = 1024 * KB; { megabyte }
GB = 1024 * MB; { gigabyte }
begin
Result := FormatFloat( '###,# MB', ABytes / MB );
end;
function IEFileTypeToExtension( AIEFileType: TIOFileType ): string;
// Convert TIOFileType to a file extension
begin
// Result := ExtractFileExt( IEFileFormatGetInfo( AIEFileType ).FullName );
case AIEFileType of
ioTIFF:
Result := '.tif';
ioGIF:
Result := '.gif';
ioJPEG:
Result := '.jpg';
ioPCX:
Result := '.pcx';
ioBMP:
Result := '.bmp';
ioICO:
Result := '.ico';
ioCUR:
Result := '.cur';
ioPNG:
Result := '.png';
ioWMF:
Result := '.wmf';
ioEMF:
Result := '.emf';
ioTGA:
Result := '.tga';
ioPXM:
Result := '.ppm';
ioJP2:
Result := '.jp2';
ioJ2K:
Result := '.j2k';
ioAVI:
Result := '.avi';
ioWBMP:
Result := '.wbmp';
ioPS:
Result := '.ps';
ioPDF:
Result := '.pdf';
ioDCX:
Result := '.dcx';
ioRAW:
Result := '.raw';
ioBMPRAW:
Result := '.braw';
ioWMV:
Result := '.wmv';
ioMPEG:
Result := '.mpeg';
ioPSD:
Result := '.psd';
ioIEV:
Result := '.iev';
ioHDP:
Result := '.wdp';
ioLYR:
Result := '.lyr';
ioALL:
Result := '.all';
ioDICOM:
Result := '.dcm';
end; // case
end;
function IEFileTypeToString( AIEFileType: TIOFileType ): string;
// Convert TIOFileType to a string
begin
Result := IEFileFormatGetInfo( AIEFileType ).FullName;
end;
function BitDepthToString( const ASamplesPerPixel: integer; const ABitsPerSample: integer ): string;
// Convert a bitdepth to a string.
begin
if ( ASamplesPerPixel = 4 ) and ( ABitsPerSample = 8 ) then
Result := 'RGBA 32-Bit'
else if ( ASamplesPerPixel = 3 ) and ( ABitsPerSample = 8 ) then
Result := 'RGB 24-Bit'
else if ( ASamplesPerPixel = 1 ) and ( ABitsPerSample = 8 ) then
Result := 'RGB 8-Bit'
else if ( ASamplesPerPixel = 1 ) and ( ABitsPerSample = 4 ) then
Result := 'RGB 4-Bit'
else if ( ASamplesPerPixel = 1 ) and ( ABitsPerSample = 2 ) then
Result := 'RGB 2-Bit'
else
Result := 'Unknown';
end;
function Instr( str: string; substr: string ): integer;
begin
Instr := Pos( substr, str );
end;
function StringStripAll( instring, charac: string ): string;
var
idone: boolean;
ipos: integer;
begin
repeat
ipos := Instr( instring, charac );
if ipos > 0 then
begin
idone := False;
delete( instring, ipos, 1 );
end
else
idone := True;
until idone;
StringStripAll := instring;
end;
function RemoveDotFromExtension( AExt: string ): string;
// Remove the dot '.' from the extension
begin
// Delete removes a substring of Count characters from string S starting with S[Index].
delete( AExt, 1, 1 );
Result := AExt;
end;
function RemoveColonFromString( AString: string ): string;
// Remove the dot ':' from the extension
begin
Result := StringStripAll( AString, ':' );
end;
function IEFileTypeToShortExtension( AIEFileType: TIOFileType ): string;
// Convert AIEFileType to a short string- no dot
var
iExtension: string;
begin
iExtension := IEFileFormatGetInfo( AIEFileType ).Extensions;
Result := RemoveDotFromExtension( iExtension );
end;
function GetFileCount( AFolder, AWildCard: string ): integer;
// Get the file count in AFolder with a wildcard
var
iIntFound: integer;
iSearchRec: TSearchRec;
begin
Screen.Cursor := crHourGlass;
try
Result := 0;
if ( AFolder <> '' ) and ( AFolder[ Length( AFolder ) ] <> '\' ) then
AFolder := AFolder + '\';
iIntFound := FindFirst( AFolder + AWildCard, faAnyFile, iSearchRec );
while ( iIntFound = 0 ) do
begin
if not( iSearchRec.Attr and faDirectory = faDirectory ) then
inc( Result );
iIntFound := FindNext( iSearchRec );
end;
FindClose( iSearchRec );
finally
Screen.Cursor := crDefault;
end;
end;
function StringContainsText( ADest, ASource: string ): boolean;
// Return true if ASouce contains ADest
begin
// if 0 then equal
Result := Pos( ADest, ASource ) > 0;
end;
function IsWhiteSpace( const AChar: Char ): boolean;
{ Checks if a character is white space. }
begin
Result := SysUtils.CharInSet( AChar, [ ' ', #9, #10, #11, #12, #13 ] );
end;
function CapFirst( const AValue: string ): string;
// Convert all first letters to caps
var
i: integer;
iString: string;
begin
iString := UpperCase( AValue[ 1 ] );
for i := 2 to Length( AValue ) do
if SysUtils.CharInSet( AValue[ i - 1 ], [ ' ', ',', ':', ';', '.', '\' ] ) then
iString := iString + UpperCase( AValue[ i ] )
else
iString := iString + LowerCase( AValue[ i ] );
Result := iString;
end;
function TitleCase( const AString: string ): string;
// Converts a string to title case
var
idx: integer; // loops through each character in string
iWantCapital: boolean; // flag indicating whether captial letter required
begin
Result := SysUtils.LowerCase( AString );
iWantCapital := True;
for idx := 1 to Length( AString ) do
begin
if SysUtils.CharInSet( Result[ idx ], [ 'a' .. 'z', 'A' .. 'Z' ] ) then
begin
if iWantCapital then
Result[ idx ] := UpCase( Result[ idx ] ); // capital letter required
iWantCapital := False; // following chars lower case
end
else
iWantCapital := IsWhiteSpace( Result[ idx ] ); // space: next char is capital
end;
end;
function IsFileAResource( AFilename: string ): boolean;
// Is AFilename a resource file
var
iResFileExtension: string;
begin
iResFileExtension := LowerCase( ExtractFileExt( AFilename ) );
Result := ( iResFileExtension = '.exe' ) or ( iResFileExtension = '.dll' ) or ( iResFileExtension = '.icl' ) or
( iResFileExtension = '.bpl' ) or ( iResFileExtension = '.ocx' ) or ( iResFileExtension = '.scr' ) or
( iResFileExtension = '.cpl' );
end;
function NumberOfResourcesInRes( APath: string ): integer;
// Return the number of resources in the resource file
var
i: integer;
j: integer;
iTotalResources: integer;
iResourceExtractor: TIEResourceExtractor;
begin
Result := 0;
iTotalResources := 0;
iResourceExtractor := TIEResourceExtractor.Create( APath );
try
if iResourceExtractor.IsValid then
begin
for i := 0 to iResourceExtractor.TypesCount - 1 do
for j := 0 to iResourceExtractor.NamesCount[ i ] - 1 do
if iResourceExtractor.IsGroup[ i ] then
inc( iTotalResources, iResourceExtractor.GroupCountFrames[ i, j ] )
else
inc( iTotalResources );
Result := iTotalResources;
end;
finally
iResourceExtractor.Free;
end;
end;
function NumberOfImagesInRes( APath: string ): integer;
// Return the number of images in the resource file
var
i: integer;
j: integer;
iTotalImages: integer;
iResourceExtractor: TIEResourceExtractor;
begin
Result := 0;
iTotalImages := 0;
iResourceExtractor := TIEResourceExtractor.Create( APath );
try
if iResourceExtractor.IsValid then
begin
for i := 0 to iResourceExtractor.TypesCount - 1 do
for j := 0 to iResourceExtractor.NamesCount[ i ] - 1 do
if ( iResourceExtractor.IsGroup[ i ] ) and ( ( iResourceExtractor.FriendlyTypes[ i ] = 'GroupIcon' ) or
( iResourceExtractor.FriendlyTypes[ i ] = 'Image' ) or
( iResourceExtractor.FriendlyTypes[ i ] = 'Icon' ) or
( iResourceExtractor.FriendlyTypes[ i ] = 'GroupCursor' ) or
( iResourceExtractor.FriendlyTypes[ i ] = 'Cursor' ) or
( iResourceExtractor.FriendlyTypes[ i ] = 'Bitmap' ) or
( iResourceExtractor.FriendlyTypes[ i ] = 'PNG' ) ) then
inc( iTotalImages, iResourceExtractor.GroupCountFrames[ i, j ] )
else if ( iResourceExtractor.FriendlyTypes[ i ] = 'Image' ) or
( iResourceExtractor.FriendlyTypes[ i ] = 'Icon' ) or ( iResourceExtractor.FriendlyTypes[ i ] = 'Cursor' )
or ( iResourceExtractor.FriendlyTypes[ i ] = 'Bitmap' ) or
( iResourceExtractor.FriendlyTypes[ i ] = 'PNG' ) then
inc( iTotalImages );
Result := iTotalImages;
end;
finally
iResourceExtractor.Free;
end;
end;
function NumberOfGroupIconsInRes( APath: string ): integer;
// Return the number of groupicons in the resource file
var
i: integer;
j: integer;
iTotalImages: integer;
iResourceExtractor: TIEResourceExtractor;
begin
Result := 0;
iTotalImages := 0;
iResourceExtractor := TIEResourceExtractor.Create( APath );
try
if iResourceExtractor.IsValid then
begin
for i := 0 to iResourceExtractor.TypesCount - 1 do
for j := 0 to iResourceExtractor.NamesCount[ i ] - 1 do
if ( iResourceExtractor.IsGroup[ i ] ) and ( ( iResourceExtractor.FriendlyTypes[ i ] = 'GroupIcon' ) ) then
inc( iTotalImages );
Result := iTotalImages;
end;
finally
iResourceExtractor.Free;
end;
end;
function NumberOfGroupCursorsInRes( APath: string ): integer;
// Return the number of groupcursors in the resource file
var
i: integer;
j: integer;
iTotalImages: integer;
iResourceExtractor: TIEResourceExtractor;
begin
Result := 0;
iTotalImages := 0;
iResourceExtractor := TIEResourceExtractor.Create( APath );
try
if iResourceExtractor.IsValid then
begin
for i := 0 to iResourceExtractor.TypesCount - 1 do
for j := 0 to iResourceExtractor.NamesCount[ i ] - 1 do
if ( iResourceExtractor.IsGroup[ i ] ) and ( ( iResourceExtractor.FriendlyTypes[ i ] = 'GroupCursor' ) ) then
inc( iTotalImages, iResourceExtractor.GroupCountFrames[ i, j ] );
Result := iTotalImages;
end;
finally
iResourceExtractor.Free;
end;
end;
function NumberOfBMPInRes( APath: string ): integer;
// Return the number of bmp in the resource file
var
i: integer;
j: integer;
iTotalImages: integer;
iResourceExtractor: TIEResourceExtractor;
begin
Result := 0;
iTotalImages := 0;
iResourceExtractor := TIEResourceExtractor.Create( APath );
try
if iResourceExtractor.IsValid then
begin
for i := 0 to iResourceExtractor.TypesCount - 1 do
for j := 0 to iResourceExtractor.NamesCount[ i ] - 1 do
if iResourceExtractor.FriendlyTypes[ i ] = 'Bitmap' then
inc( iTotalImages );
Result := iTotalImages;
end;
finally
iResourceExtractor.Free;
end;
end;
function NumberOfIconsInRes( APath: string ): integer;
// Return the number of ico in the resource file
var
i: integer;
j: integer;
iTotalImages: integer;
iResourceExtractor: TIEResourceExtractor;
begin
Result := 0;
iTotalImages := 0;
iResourceExtractor := TIEResourceExtractor.Create( APath );
try
if iResourceExtractor.IsValid then
begin
for i := 0 to iResourceExtractor.TypesCount - 1 do
for j := 0 to iResourceExtractor.NamesCount[ i ] - 1 do
if iResourceExtractor.FriendlyTypes[ i ] = 'Icon' then
inc( iTotalImages );
Result := iTotalImages;
end;
finally
iResourceExtractor.Free;
end;
end;
function NumberOfCursorsInRes( APath: string ): integer;
// Return the number of cur in the resource file
var
i: integer;
j: integer;
iTotalImages: integer;
iResourceExtractor: TIEResourceExtractor;
begin
Result := 0;
iTotalImages := 0;
iResourceExtractor := TIEResourceExtractor.Create( APath );
try
if iResourceExtractor.IsValid then
begin
for i := 0 to iResourceExtractor.TypesCount - 1 do
for j := 0 to iResourceExtractor.NamesCount[ i ] - 1 do
if iResourceExtractor.FriendlyTypes[ i ] = 'Cursor' then
inc( iTotalImages );
Result := iTotalImages;
end;
finally
iResourceExtractor.Free;
end;
end;
function NumberOfBitmapsInRes( APath: string ): integer;
// Return the number of bmp in the resource file
var
i: integer;
j: integer;
iTotalImages: integer;
iResourceExtractor: TIEResourceExtractor;
begin
Result := 0;
iTotalImages := 0;
iResourceExtractor := TIEResourceExtractor.Create( APath );
try
if iResourceExtractor.IsValid then
begin
for i := 0 to iResourceExtractor.TypesCount - 1 do
for j := 0 to iResourceExtractor.NamesCount[ i ] - 1 do
if iResourceExtractor.FriendlyTypes[ i ] = 'Bitmap' then
inc( iTotalImages );
Result := iTotalImages;
end;
finally
iResourceExtractor.Free;
end;
end;
function NumberOfPNGInRes( APath: string ): integer;
// Return the number of png in the resource file
var
i: integer;
j: integer;
iTotalImages: integer;
iResourceExtractor: TIEResourceExtractor;
begin
Result := -1;
iTotalImages := 0;
iResourceExtractor := TIEResourceExtractor.Create( APath );
try
if iResourceExtractor.IsValid then
begin
for i := 0 to iResourceExtractor.TypesCount - 1 do
for j := 0 to iResourceExtractor.NamesCount[ i ] - 1 do
if iResourceExtractor.FriendlyTypes[ i ] = 'PNG' then
inc( iTotalImages );
Result := iTotalImages;
end;
finally
iResourceExtractor.Free;
end;
end;
function NumberOfExtractableImagesInRes( APath: string ): integer;
// Return the number of extractable images ( bmp, png, groupicons and icons,) in the resource file
var
iNumberOfExtractableImagesInRes: integer;
iNumberOfBitmaps: integer;
iNumberOfPNG: integer;
iNumberOfGroupIcons: integer;
iNumberOfIcons: integer;
begin
iNumberOfBitmaps := NumberOfBitmapsInRes( APath );
iNumberOfPNG := NumberOfPNGInRes( APath );
iNumberOfGroupIcons := NumberOfGroupIconsInRes( APath );
iNumberOfIcons := NumberOfIconsInRes( APath );
iNumberOfExtractableImagesInRes := iNumberOfBitmaps + iNumberOfPNG + iNumberOfGroupIcons + iNumberOfIcons;
Result := iNumberOfExtractableImagesInRes;
end;
function NodeChildCount( SelNode: TTreeNode ): integer;
// Return the number of child nodes in the selected node
var
iNode: TTreeNode;
begin
Result := 0;
if SelNode = nil then
Exit;
iNode := SelNode.GetNext;
while ( iNode <> nil ) and ( iNode.Parent = SelNode ) do
begin
inc( Result );
iNode := iNode.GetNext;
end;
end;
function CountChildNodes( ATreeView: TTreeView ): integer;
// Return the number of child nodes - level 1 in the selected node
var
i: integer;
begin
Result := 0;
if ATreeView.Selected = nil then
begin
for i := 0 to ATreeView.Items.Count - 1 do
if ATreeView.Items[ i ].Level = 0 then
inc( Result );
end
else
Result := ATreeView.Selected.Count;
end;
function ResourceHasBMP( APath: string ): boolean;
// Return true if the resource has bitmaps, false if not
begin
Result := NumberOfBMPInRes( APath ) > 0;
end;
function ResourceHasPNG( APath: string ): boolean;
// Return true if the resource has png, false if not
begin
Result := NumberOfPNGInRes( APath ) > 0;
end;
function ResourceHasIcons( APath: string ): boolean;
// Return true if the resource has ico, false if not
begin
Result := NumberOfIconsInRes( APath ) > 0;
end;
function ResourceHasGroupIcons( APath: string ): boolean;
// Return true if the resource has groupicons, false if not
begin
Result := NumberOfGroupIconsInRes( APath ) > 0;
end;
function ResourceHasImages( APath: string ): boolean;
// Return true if the resource has images, false if not
begin
Result := NumberOfImagesInRes( APath ) > 0;
end;
function DoesResourceContainGroupIcon( APath: string ): boolean;
// Returns True if the resource file contains a GroupIcon, or false of not
var
i: integer;
iFriendlyType: string;
iResourceExtractor: TIEResourceExtractor;
begin
Result := False;
iResourceExtractor := TIEResourceExtractor.Create( APath );
try
if iResourceExtractor.IsValid then
begin
for i := 0 to iResourceExtractor.TypesCount - 1 do
begin
iFriendlyType := string( iResourceExtractor.FriendlyTypes[ i ] );
Result := iFriendlyType = 'GroupIcon';
if Result then
Break;
end;
end;
finally
iResourceExtractor.Free;
end;
end;
function DoesResourceContainIcon( APath: string ): boolean;
// Returns True if the resource file contains a Icon, or false of not
var
i: integer;
iFriendlyType: string;
iResourceExtractor: TIEResourceExtractor;
begin
Result := False;
iResourceExtractor := TIEResourceExtractor.Create( APath );
try
if iResourceExtractor.IsValid then
begin
for i := 0 to iResourceExtractor.TypesCount - 1 do
begin
iFriendlyType := string( iResourceExtractor.FriendlyTypes[ i ] );
Result := iFriendlyType = 'Icon';
if Result then
Break;
end;
end;
finally
iResourceExtractor.Free;
end;
end;
function DoesResourceContainCursor( APath: string ): boolean;
// Returns True if the resource file contains a Cursor, or false of not
var
i: integer;
iFriendlyType: string;
iResourceExtractor: TIEResourceExtractor;
begin
Result := False;
iResourceExtractor := TIEResourceExtractor.Create( APath );
try
if iResourceExtractor.IsValid then
begin
for i := 0 to iResourceExtractor.TypesCount - 1 do
begin
iFriendlyType := string( iResourceExtractor.FriendlyTypes[ i ] );
Result := iFriendlyType = 'Cursor';
if Result then
Break;
end;
end;
finally
iResourceExtractor.Free;
end;
end;
function DoesResourceContainGroupCursor( APath: string ): boolean;
// Returns True if the resource file contains a Cursor, or false of not
var
i: integer;
iFriendlyType: string;
iResourceExtractor: TIEResourceExtractor;
begin
Result := False;
iResourceExtractor := TIEResourceExtractor.Create( APath );
try
if iResourceExtractor.IsValid then
begin
for i := 0 to iResourceExtractor.TypesCount - 1 do
begin
iFriendlyType := string( iResourceExtractor.FriendlyTypes[ i ] );
Result := iFriendlyType = 'GroupCursor';
if Result then
Break;
end;
end;
finally
iResourceExtractor.Free;
end;
end;
function DoesResourceContainBitmap( APath: string ): boolean;
// Returns True if the resource file contains a Bitmap, or false of not
var
i: integer;
iFriendlyType: string;
iResourceExtractor: TIEResourceExtractor;
begin
Result := False;
iResourceExtractor := TIEResourceExtractor.Create( APath );
try
if iResourceExtractor.IsValid then
begin
for i := 0 to iResourceExtractor.TypesCount - 1 do
begin
iFriendlyType := string( iResourceExtractor.FriendlyTypes[ i ] );
Result := iFriendlyType = 'Bitmap';
if Result then
Break;
end;
end;
finally
iResourceExtractor.Free;
end;
end;
function DoesResourceContainPNG( APath: string ): boolean;
// Returns True if the resource file contains a PNG, or false of not
var
i: integer;
iFriendlyType: string;
iResourceExtractor: TIEResourceExtractor;
begin
Result := False;
iResourceExtractor := TIEResourceExtractor.Create( APath );
try
if iResourceExtractor.IsValid then
begin
for i := 0 to iResourceExtractor.TypesCount - 1 do
begin
iFriendlyType := string( iResourceExtractor.FriendlyTypes[ i ] );
Result := iFriendlyType = 'PNG';
if Result then
Break;
end;
end;
finally
iResourceExtractor.Free;
end;
end;
function IsResourceGroupIcon( APath: string; AIndex: integer ): boolean;
// Returns True if AIndex is a GroupIcon resource, or false of not
var
iIndex: integer;
iResourceExtractor: TIEResourceExtractor;
iFriendlyType: string;
iIsGroup: boolean;
iIsGrouped: boolean;
begin
Result := False;
iResourceExtractor := TIEResourceExtractor.Create( APath );
try
if iResourceExtractor.IsValid then
begin
// search for GroupIcon
iIndex := AIndex;
iFriendlyType := string( iResourceExtractor.FriendlyTypes[ iIndex ] );
iIsGroup := iResourceExtractor.IsGroup[ iIndex ];
iIsGrouped := iResourceExtractor.IsGrouped[ iIndex ];
if ( iFriendlyType = 'GroupIcon' ) or ( iIsGroup ) or ( iIsGrouped ) then
Result := True
else
Result := False;
end;
finally
iResourceExtractor.Free( );
end;
end;
function IsResourceIcon( APath: string; ASelection: string; AIndex: integer ): boolean;
// Returns True if ASelection is a Icon resource, or false of not
var
i: integer;
j: integer;
iFriendlyType: string;
iResourceExtractor: TIEResourceExtractor;
iResourceExtractorName: string;
begin
Result := False;
iResourceExtractor := TIEResourceExtractor.Create( APath );
try
if iResourceExtractor.IsValid then
begin
for i := 0 to iResourceExtractor.TypesCount - 1 do
begin
iFriendlyType := string( iResourceExtractor.FriendlyTypes[ AIndex ] );
if i <> 0 then
if iFriendlyType = string( iResourceExtractor.FriendlyTypes[ i ] ) then
Break;
for j := 0 to iResourceExtractor.NamesCount[ i ] - 1 do
begin
// Use the selection to select the resource
iResourceExtractorName := string( iResourceExtractor.Names[ i, j ] );
if iResourceExtractorName = ASelection then
begin
iFriendlyType := string( iResourceExtractor.FriendlyTypes[ i ] );
Break;
end;
end;
end;
Result := iFriendlyType = 'Icon';
end;
finally
iResourceExtractor.Free;
end;
end;
function IsResourceGroupCursor( APath: string; AIndex: integer ): boolean;
// Returns True if ASelection is a GroupCursor resource, or false of not
var
iResourceExtractor: TIEResourceExtractor;
begin
Result := False;
iResourceExtractor := TIEResourceExtractor.Create( APath );
try
if iResourceExtractor.IsValid then
begin
// search for GroupCursor
if iResourceExtractor.FriendlyTypes[ AIndex ] = 'GroupCursor' then
Result := True
else
Result := False;
end;
finally
iResourceExtractor.Free( );
end;
end;
function IsResourceCursor( APath: string; ASelection: string ): boolean;
// Returns True if ASelection is a Cursor resource, or false of not
var
i: integer;
j: integer;
iFriendlyType: string;
iResourceExtractor: TIEResourceExtractor;
iResourceExtractorName: string;
begin
Result := False;
iResourceExtractor := TIEResourceExtractor.Create( APath );
try
if iResourceExtractor.IsValid then
begin
for i := 0 to iResourceExtractor.TypesCount - 1 do
begin
if i <> 0 then
if iFriendlyType = string( iResourceExtractor.FriendlyTypes[ i - 1 ] ) then
Break;
for j := 0 to iResourceExtractor.NamesCount[ i ] - 1 do
begin
// Use the selection to select the resource
iResourceExtractorName := string( iResourceExtractor.Names[ i, j ] );
if iResourceExtractorName = ASelection then
begin
iFriendlyType := string( iResourceExtractor.FriendlyTypes[ i ] );
Break;
end;
end;
end;
Result := iFriendlyType = 'Cursor';
end;
finally
iResourceExtractor.Free;
end;
end;
function IsResourceBitmap( APath: string; ASelection: string ): boolean;
// Returns True if ASelection is a Bitmap resource, or false of not
var
i: integer;
j: integer;
iFriendlyType: string;
iResourceExtractor: TIEResourceExtractor;
iResourceExtractorName: string;
begin
Result := False;
iResourceExtractor := TIEResourceExtractor.Create( APath );
try
if iResourceExtractor.IsValid then
begin
for i := 0 to iResourceExtractor.TypesCount - 1 do
begin
if i <> 0 then
if iFriendlyType = string( iResourceExtractor.FriendlyTypes[ i - 1 ] ) then
Break;
for j := 0 to iResourceExtractor.NamesCount[ i ] - 1 do
begin
// Use the selection to select the resource
iResourceExtractorName := string( iResourceExtractor.Names[ i, j ] );
if iResourceExtractorName = ASelection then
begin
iFriendlyType := string( iResourceExtractor.FriendlyTypes[ i ] );
Break;
end;
end;
end;
Result := iFriendlyType = 'Bitmap';
end;
finally
iResourceExtractor.Free;
end;
end;
function IsResourcePNG( APath: string; ASelection: string ): boolean;
// Returns True if ASelection is a PNG resource, or false of not
var
i: integer;
j: integer;
iFriendlyType: string;
iResourceExtractor: TIEResourceExtractor;
iResourceExtractorName: string;
begin
Result := False;
iResourceExtractor := TIEResourceExtractor.Create( APath );
try
if iResourceExtractor.IsValid then
begin
for i := 0 to iResourceExtractor.TypesCount - 1 do
begin
if i <> 0 then
if iFriendlyType = string( iResourceExtractor.FriendlyTypes[ i - 1 ] ) then
Break;
for j := 0 to iResourceExtractor.NamesCount[ i ] - 1 do
begin
// Use the selection to select the resource
iResourceExtractorName := string( iResourceExtractor.Names[ i, j ] );
if iResourceExtractorName = ASelection then
begin
iFriendlyType := string( iResourceExtractor.FriendlyTypes[ i ] );
Break;
end;
end;
end;
Result := iFriendlyType = 'PNG';
end;
finally
iResourceExtractor.Free;
end;
end;
procedure TFormResExtractor.ReadIni( IniFilename: string );
// Initialize variables from ini file
var
i: integer;
iIniFile: TIniFile;
iFolder: string;
iDestinationFolder: string;
iDestinationFolderCount: integer;
begin
iIniFile := TIniFile.Create( IniFilename );
try
with iIniFile do
begin
Left := ReadInteger( 'Form Main', 'Left', 0 );
Top := ReadInteger( 'Form Main', 'Top', 0 );
Width := ReadInteger( 'Form Main', 'Width', 1079 );
Height := ReadInteger( 'Form Main', 'Height', 654 );
FState := ReadInteger( 'Form Main', 'State', 0 );
WindowState := TWindowState( FState );
// If no window coordinates then set position to poDesktopCenter else poDesigned
if ( Left = 0 ) and ( Top = 0 ) then
Position := poDesktopCenter
else
Position := poDesigned;
// Position - OwnerFormCenter does not work here so center the splash form on its parent
FormSplash.Left := Left + ( Width div 2 ) - ( FormSplash.Width div 2 );
FormSplash.Top := Top + ( Height div 2 ) - ( FormSplash.Height div 2 );
FormSplash.Show;
FormSplash.Refresh;
FormSplash.Update;
FStartupFolder := ReadString( 'Form Main', 'StartupFolder', System32Folder );
iDestinationFolderCount := ReadInteger( 'Form Main', 'DestinationFolderCount', 0 );
iDestinationFolder := IncludeTrailingPathDelimiter( CurrentDrive + ':\Images\Extracted Images' );
FDestinationFolder := ReadString( 'Form Main', 'DestinationFolder', iDestinationFolder );
if not DirectoryExists( iDestinationFolder ) then
ForceDirectories( iDestinationFolder );
if not DirectoryExists( FDestinationFolder ) then
if DirectoryExists( iDestinationFolder ) then
FDestinationFolder := iDestinationFolder;
// Fill the DestinationFolderComboBox1 with folders
for i := 0 to iDestinationFolderCount - 1 do
begin
iFolder := ReadString( 'DestinationFolders', Format( '%s%d', [ '', i ] ), '' );
if DirectoryExists( iFolder ) then
begin
if DestinationFolderComboBox1.Items.IndexOf( iFolder ) = -1 then // if not in the list add it
DestinationFolderComboBox1.Items.Append( iFolder );
end;
end;
if iDestinationFolderCount = 0 then
begin
if DestinationFolderComboBox1.Items.IndexOf( iDestinationFolder ) = -1 then // if not in the list add it
DestinationFolderComboBox1.Items.Append( iDestinationFolder );
DestinationFolderComboBox1.ItemIndex := 0;
end;
end;
finally
iIniFile.Free;
end;
end;
procedure TFormResExtractor.WriteIni( IniFilename: string );
// Save parameters to ini file
var
i: integer;
iIniFile: TIniFile;
iFolder: string;
begin
iIniFile := TIniFile.Create( IniFilename );
try
with iIniFile do
begin
WriteInteger( 'Form Main', 'Left', Left );
WriteInteger( 'Form Main', 'Top', Top );
WriteInteger( 'Form Main', 'Width', Width );
WriteInteger( 'Form Main', 'Height', Height );
WriteInteger( 'Form Main', 'State', FState );
WriteString( 'Form Main', 'StartupFolder', FStartupFolder );
WriteInteger( 'Form Main', 'DestinationFolderCount', DestinationFolderComboBox1.Items.Count );
FDestinationFolder := DestinationFolderComboBox1.Items[ DestinationFolderComboBox1.ItemIndex ];
WriteString( 'Form Main', 'DestinationFolder', FDestinationFolder );
EraseSection( 'DestinationFolders' );
// Save the DestinationFolderComboBox1 folders
for i := 0 to DestinationFolderComboBox1.Items.Count - 1 do
begin
iFolder := DestinationFolderComboBox1.Items[ i ];
WriteString( 'DestinationFolders', Format( '%s%d', [ '', i ] ), iFolder );
end;
end;
finally
iIniFile.Free;
end;
end;
procedure TFormResExtractor.Report1Click( Sender: TObject );
// Set the ShellListView ViewStyle to Report
begin
ShellListView1.ViewStyle := vsReport;
end;
procedure TFormResExtractor.FormCreate( Sender: TObject );
begin
FResourceExtractor := nil;
FIniFilename := IncludeTrailingBackslash( LocalAppDataFolder ) + 'ASG\ResourceExtractor\' + 'ResourceExtractor.ini';
ForceDirectories( IncludeTrailingBackslash( LocalAppDataFolder ) + 'ASG\ResourceExtractor' );
ReadIni( FIniFilename );
ImageEnView1.Clear;
// View 32-bit bitmaps with alphachannel
ImageEnView1.IO.Params.BMP_HandleTransparency := True;
ShellTreeView1.HideSelection := False;
ShellListView1.HideSelection := False;
TreeView1.HideSelection := False;
Label3.Hint := 'The root destination folder is the parent folder for all extracted images.' + #10#13 + #10#13 +
'Images will be saved to the following folders: ' + #10#13 +
'Group Icons: ' + IncludeTrailingPathDelimiter( FDestinationFolder ) + 'GROUPICONS' + #10#13 +
'Icons: ' + IncludeTrailingPathDelimiter( FDestinationFolder ) + 'ICONS' + #10#13 +
'Bitmaps: ' + IncludeTrailingPathDelimiter( FDestinationFolder ) + 'BMP' + #10#13 +
'PNG Images: ' + IncludeTrailingPathDelimiter( FDestinationFolder ) + 'PNG';
end;
procedure TFormResExtractor.FormDestroy( Sender: TObject );
// Free any created objects
begin
WriteIni( FIniFilename );
FResourceExtractor.Free;
end;
procedure TFormResExtractor.FormShow( Sender: TObject );
// Setup the Shell and GUI
var
iNode: TTreeNode;
begin
// Many dll's with image resources are found in the System32 folder
ShellTreeView1.Path := FStartupFolder; // Default- 'C:\Windows\System32';
iNode := ShellTreeView1.Selected;
iNode.MakeVisible;
ShellTreeView1.TopItem := iNode;
// Sort the ShellListView descending by size
ShellListSortAscending := False;
ShellListSortColumn := 1; // Size Column
// Sorting capability was added to ShellCtrls.pas which is located in the project folder
ShellListView1.FolderList.Sort( ShellCompare );
ShellListView1.Invalidate;
DestinationFolderComboBox1.ItemIndex := DestinationFolderComboBox1.Items.IndexOf( FDestinationFolder );
DestinationFolderComboBox1.Hint := FDestinationFolder;
StatusBar1.Panels[ 10 ].Text := FileCtrl.MinimizeName( FDestinationFolder, Canvas, 250 );
end;
procedure TFormResExtractor.Icon1Click( Sender: TObject );
// Set the ShellListView ViewStyle to Icon
begin
ShellListView1.ViewStyle := vsIcon;
end;
procedure TFormResExtractor.ImageEnView1FinishWork( Sender: TObject );
begin
Gauge1.Progress := 0;
end;
procedure TFormResExtractor.ImageEnView1Progress( Sender: TObject; per: integer );
begin
Gauge1.MaxValue := 100;
Gauge1.Progress := per;
end;
procedure TFormResExtractor.List1Click( Sender: TObject );
// Set the ShellListView ViewStyle to List
begin
ShellListView1.ViewStyle := vsList;
end;
procedure TFormResExtractor.SaveSelectedGroupIcon1Click( Sender: TObject );
// Save the selected group icon to a multi-frame icon
var
i: integer;
j: integer;
k: integer;
iCurrentDrive: string;
iBaseFolder: string;
iResFileName: string;
iResFileExtension: string;
iResourceExtractor: TIEResourceExtractor;
iResourceName: string;
iFrames: array of TObject;
iBuffer: Pointer;
iBufferLen: integer;
iFileToSave: string;
iGroupFrameWidth: integer;
iGroupFrameHeight: integer;
begin
// Create a folder to save the icons to
iCurrentDrive := CurrentDrive;
iResFileName := ShellListView1.SelectedFolder.PathName;
iBaseFolder := IncludeTrailingPathDelimiter( iCurrentDrive + ':\Images\Extracted Images' + JustName( iResFileName )
+ '\' );
if DirectoryExists( iBaseFolder ) then
SavePictureDialog1.InitialDir := iBaseFolder;
SavePictureDialog1.DefaultExt := GraphicExtension( TIcon );
SavePictureDialog1.Filter := GraphicFilter( TIcon );
if SavePictureDialog1.Execute then
begin
FDestinationFolder := ExcludeTrailingPathDelimiter( ExtractFileDir( SavePictureDialog1.fileName ) );
iResFileExtension := LowerCase( ExtractFileExt( iResFileName ) );
// Is the selected file a resource file
if IsFileAResource( iResFileName ) then
begin
Screen.Cursor := crHourGlass;
try
iResourceExtractor := TIEResourceExtractor.Create( iResFileName );
try
if iResourceExtractor.IsValid then
begin
// search for GroupIcon, loop among Types
for i := 0 to iResourceExtractor.TypesCount - 1 do
if iResourceExtractor.FriendlyTypes[ i ] = 'GroupIcon' then
begin
// GroupIcon found, loop among Names
for j := 0 to iResourceExtractor.NamesCount[ i ] - 1 do
begin
iResourceName := string( iResourceExtractor.Names[ i, j ] );
if Assigned( TreeView1.Selected ) then
begin
// Use selected group icon
if iResourceName = 'INTRESOURCE:' + IntToStr( TreeView1.Selected.Index ) then
begin
// Allocate array of TImageEnView objects and load frames
SetLength( iFrames, iResourceExtractor.GroupCountFrames[ i, j ] );
for k := 0 to Length( iFrames ) - 1 do
begin
iBuffer := iResourceExtractor.GetFrameBuffer( i, j, k, iBufferLen );
iFrames[ k ] := TImageEnView.Create( nil );
iGroupFrameWidth := iResourceExtractor.GroupFrameWidth[ i, j, k ];
iGroupFrameHeight := iResourceExtractor.GroupFrameHeight[ i, j, k ];
( iFrames[ k ] as TImageEnView )
.IO.Params.IsResource := True; ( iFrames[ k ] as TImageEnView )
.IO.LoadFromBuffer( iBuffer, iBufferLen, ioICO ); ( iFrames[ k ] as TImageEnView )
.IO.Params.ICO_Sizes[ k ].cx := iGroupFrameWidth; ( iFrames[ k ] as TImageEnView )
.IO.Params.ICO_Sizes[ k ].cY := iGroupFrameHeight; ( iFrames[ k ] as TImageEnView )
.IO.Params.ICO_BitCount[ k ] := ( iFrames[ k ] as TImageEnView ).IO.Params.SamplesPerPixel *
( iFrames[ k ] as TImageEnView ).IO.Params.BitsPerSample;
end;
// Create Multiframe ICO
StatusBar1.Panels[ 10 ].Text := FileCtrl.MinimizeName( FDestinationFolder, Canvas, 250 );
iFileToSave := SavePictureDialog1.fileName;
IEWriteICOImages( iFileToSave, iFrames );
// Cleanup Frames
for k := 0 to Length( iFrames ) - 1 do
iFrames[ k ].Free( );
end;
end;
end;
end;
end;
finally
iResourceExtractor.Free;
end;
finally
Screen.Cursor := crDefault;
end;
end;
end;
end;
procedure TFormResExtractor.SaveGroupIcons1Click( Sender: TObject );
// Save all group icons to multi-frame group icons
var
i: integer;
j: integer;
k: integer;
iResourceExtractor: TIEResourceExtractor;
iResFileName: string;
iResFileExtension: string;
iFrames: array of TObject;
iBuffer: Pointer;
iBufferLen: integer;
iFilePath: string;
iResFilePath: string;
iBaseFolder: string;
iGroupIconFolder: string;
iCurrentDrive: string;
iResourceName: string;
iNumberOfGroupIcons: integer;
iPosition: integer;
begin
iCurrentDrive := CurrentDrive;
iFilePath := ShellListView1.SelectedFolder.PathName;
if DirectoryExists( FDestinationFolder ) then
iBaseFolder := IncludeTrailingPathDelimiter( FDestinationFolder )
else
iBaseFolder := IncludeTrailingPathDelimiter( iCurrentDrive + ':\Images\Extracted Images' );
if not DirectoryExists( iBaseFolder ) then
if FileCtrl.ForceDirectories( iBaseFolder ) then
begin
FDestinationFolder := iBaseFolder;
StatusBar1.Panels[ 10 ].Text := FileCtrl.MinimizeName( FDestinationFolder, Canvas, 250 );
end
else
begin
// Get the folder to save images to
iBaseFolder := BrowseForFolder( DesktopFolder );
if DirectoryExists( iBaseFolder ) then
begin
FDestinationFolder := iBaseFolder;
StatusBar1.Panels[ 10 ].Text := FileCtrl.MinimizeName( FDestinationFolder, Canvas, 250 );
end
else
Exit;
end;
if Assigned( ShellListView1.Selected ) then
begin
iResFilePath := ShellListView1.SelectedFolder.PathName;
iResFileName := ExtractFilename( iResFilePath );
iResFileExtension := LowerCase( ExtractFileExt( iResFileName ) );
// Is the selected file a resource file
if IsFileAResource( iResFileName ) then
begin
Screen.Cursor := crHourGlass;
try
// Create the GROUPICON folders
if ResourceHasGroupIcons( iResFilePath ) then
begin
iGroupIconFolder := IncludeTrailingPathDelimiter( iBaseFolder ) + 'GROUPICONS\' + JustName( iFilePath ) + '\';
if not DirectoryExists( iGroupIconFolder ) then
FileCtrl.ForceDirectories( iGroupIconFolder );
end;
iResourceExtractor := TIEResourceExtractor.Create( iResFileName );
try
if iResourceExtractor.IsValid then
begin
iNumberOfGroupIcons := NumberOfGroupIconsInRes( iResFilePath );
Gauge1.MaxValue := iNumberOfGroupIcons;
iPosition := 0;
Gauge1.Progress := iPosition;
// Search for ResType, loop among Types
for i := 0 to iResourceExtractor.TypesCount - 1 do
begin
if iResourceExtractor.FriendlyTypes[ i ] = 'GroupIcon' then
begin
// GroupIcon found, loop among Names
for j := 0 to iResourceExtractor.NamesCount[ i ] - 1 do
begin
// Allocate array of TImageEnView objects and load frames
SetLength( iFrames, iResourceExtractor.GroupCountFrames[ i, j ] );
for k := 0 to Length( iFrames ) - 1 do
begin
iBuffer := iResourceExtractor.GetFrameBuffer( i, j, k, iBufferLen );
iFrames[ k ] := TImageEnView.Create( nil ); ( iFrames[ k ] as TImageEnView )
.IO.Params.IsResource := True; ( iFrames[ k ] as TImageEnView )
.IO.LoadFromBuffer( iBuffer, iBufferLen, ioICO );
end;
iResourceName := iGroupIconFolder + CapFirst( JustName( iFilePath ) ) + '_GroupIcon_' + IntToStr
( j + 1 ) + '.ico';
// Save Multiframe ICO
IEWriteICOImages( iResourceName, iFrames );
StatusBar1.Panels[ 10 ].Text := FileCtrl.MinimizeName( iGroupIconFolder, Canvas, 250 );
inc( iPosition );
Gauge1.Progress := iPosition;
if iNumberOfGroupIcons < 20 then
Sleep( 50 );
Application.ProcessMessages;
// Cleanup Frames
for k := 0 to Length( iFrames ) - 1 do
iFrames[ k ].Free( );
end;
end;
end;
Gauge1.Progress := 0;
end;
finally
iResourceExtractor.Free;
end;
finally
Screen.Cursor := crDefault;
StatusBar1.Panels[ 10 ].Text := '';
ShellListView1.SetFocus;
end;
end;
end;
end;
procedure TFormResExtractor.Exit1Click( Sender: TObject );
begin
Close;
end;
procedure TFormResExtractor.SaveAs1Click( Sender: TObject );
// Extract the selected resource to a file
var
iJustResExtension: string;
iExtension: string;
iFriendlyType: string;
iFilePath: string;
iResFileName: string;
iResExtension: string;
iFolder: string;
iFileType: integer;
iResFilePath: string;
begin
if Assigned( TreeView1.Selected ) then
begin
iFolder := IncludeTrailingPathDelimiter( FDestinationFolder );
if Assigned( ShellListView1.Selected ) then
begin
iResFilePath := ShellListView1.SelectedFolder.PathName;
iResFileName := UpperCase( JustName( iResFilePath ) );
iExtension := IEFileTypeToExtension( ImageEnView1.IO.Params.FileType );
iResExtension := ExtractFileExt( iResFilePath );
iJustResExtension := UpperCase( RemoveDotFromExtension( iResExtension ) );
iFileType := ImageEnView1.IO.Params.FileType;
if iFileType = ioCUR then
begin
// Show cursor warning- ImageEN can not save cursors}
TaskDialog1.Title := 'Warning';
TaskDialog1.Caption := 'Extracting A Cursor Is Not Supported';
TaskDialog1.Text := 'Saving cursor files is not supported.';
TaskDialog1.CommonButtons := [ tcbOk ];
TaskDialog1.MainIcon := tdiWarning;
TaskDialog1.Flags := [ ];
TaskDialog1.Execute;
Exit;
end;
case iFileType of
ioICO:
iFriendlyType := 'Icon ' + IntToStr( TreeView1.Selected.Index + 1 );
ioBMP:
iFriendlyType := 'Bitmap ' + IntToStr( TreeView1.Selected.Index + 1 );
ioPNG:
iFriendlyType := 'PNG ' + IntToStr( TreeView1.Selected.Index + 1 );
end;
if ( TreeView1.Selected.Parent.Text = 'Icon' ) or ( TreeView1.Selected.Parent.Text = 'Bitmap' ) or
( TreeView1.Selected.Parent.Text = 'PNG' ) then
iFilePath := iFolder + TreeView1.Selected.Text + iExtension
else // Selection is a GroupIcon
iFilePath := iFolder + TreeView1.Selected.Parent.Text + ' ' + TreeView1.Selected.Text + iExtension;
SavePictureDialog1.InitialDir := iFolder;
SavePictureDialog1.fileName := ExtractFilename( iFilePath );
if SavePictureDialog1.Execute then
begin
Screen.Cursor := crHourGlass;
try
iExtension := LowerCase( ExtractFileExt( SavePictureDialog1.fileName ) );
// Save the icon
if iExtension = '.ico' then
begin
ImageEnView1.IO.Params.ICO_Sizes[ 0 ].cx := ImageEnView1.IEBitmap.Width;
ImageEnView1.IO.Params.ICO_Sizes[ 0 ].cY := ImageEnView1.IEBitmap.Height;
ImageEnView1.IO.Params.ICO_BitCount[ 0 ] := ImageEnView1.IO.Params.BitsPerSample *
ImageEnView1.IO.Params.SamplesPerPixel;
ImageEnView1.IO.SaveToFile( SavePictureDialog1.fileName, ioICO );
end
else if iExtension = '.cur' then
begin
TaskDialog1.Title := 'Warning';
TaskDialog1.Caption := 'Extracting A Cursor Is Not Supported';
TaskDialog1.Text := 'Saving cursor files is not supported.';
TaskDialog1.CommonButtons := [ tcbOk ];
TaskDialog1.MainIcon := tdiWarning;
TaskDialog1.Flags := [ ];
TaskDialog1.Execute;
end
else
// if not icon then do IOPreviews
begin
ImageEnView1.IO.PreviewsParams := [ ioppDefaultLockPreview ];
if ImageEnView1.IO.DoPreviews( [ ppAUTO ] ) then
ImageEnView1.IO.SaveToFile( SavePictureDialog1.fileName );
end;
finally
Screen.Cursor := crDefault;
end;
end;
ShellListView1.SetFocus;
end;
end;
end;
procedure TFormResExtractor.ExtractAll1Click( Sender: TObject );
// Save all images in the resource including group icons
var
i: integer;
j: integer;
k: integer;
iResourceExtractor: TIEResourceExtractor;
iImageEnView: TImageEnView;
iResFileName: string;
iResFileExtension: string;
iFrames: array of TObject;
iBuffer: Pointer;
iBufferLen: integer;
iFilePath: string;
iResFilePath: string;
iBitmapFolder: string;
iPNGFolder: string;
iBaseFolder: string;
iIconFolder: string;
iGroupIconFolder: string;
iCurrentDrive: string;
iResourceName: string;
iWidth: integer;
iHeight: integer;
iIconPath: string;
iNumberOfImagesInRes: integer;
iNumberOfBitmaps: integer;
iNumberOfPNG: integer;
iNumberOfGroupIcons: integer;
iNumberOfIcons: integer;
begin
iCurrentDrive := CurrentDrive;
iFilePath := ShellListView1.SelectedFolder.PathName;
if DirectoryExists( FDestinationFolder ) then
iBaseFolder := IncludeTrailingPathDelimiter( FDestinationFolder )
else
iBaseFolder := IncludeTrailingPathDelimiter( iCurrentDrive + ':\Images\Extracted Images' );
if not DirectoryExists( iBaseFolder ) then
if FileCtrl.ForceDirectories( iBaseFolder ) then
begin
FDestinationFolder := IncludeTrailingPathDelimiter( iBaseFolder );
StatusBar1.Panels[ 10 ].Text := FileCtrl.MinimizeName( FDestinationFolder, Canvas, 250 );
end
else
begin
// Get the folder to save images to
iBaseFolder := IncludeTrailingPathDelimiter( BrowseForFolder( DesktopFolder ) );
if DirectoryExists( iBaseFolder ) then
begin
FDestinationFolder := IncludeTrailingPathDelimiter( iBaseFolder );
StatusBar1.Panels[ 10 ].Text := FileCtrl.MinimizeName( FDestinationFolder, Canvas, 250 );
end
else
Exit;
end;
if Assigned( ShellListView1.Selected ) then
begin
iResFilePath := ShellListView1.SelectedFolder.PathName;
iResFileName := ExtractFilename( iResFilePath );
iResFileExtension := LowerCase( ExtractFileExt( iResFileName ) );
// Is the selected file a resource file
if IsFileAResource( iResFileName ) then
begin
Screen.Cursor := crHourGlass;
try
// Create the BMP, PNG, ICON and GROUPICON folders
if ResourceHasBMP( iResFilePath ) then
begin
iBitmapFolder := IncludeTrailingPathDelimiter( iBaseFolder ) + 'BMP\' + JustName( iFilePath ) + '\';
if not DirectoryExists( iBitmapFolder ) then
FileCtrl.ForceDirectories( iBitmapFolder );
end;
if ResourceHasPNG( iResFilePath ) then
begin
iPNGFolder := IncludeTrailingPathDelimiter( iBaseFolder ) + 'PNG\' + JustName( iFilePath ) + '\';
if not DirectoryExists( iPNGFolder ) then
FileCtrl.ForceDirectories( iPNGFolder );
end;
if ResourceHasIcons( iResFilePath ) then
begin
iIconFolder := IncludeTrailingPathDelimiter( iBaseFolder ) + 'ICONS\' + JustName( iFilePath ) + '\';
if not DirectoryExists( iIconFolder ) then
FileCtrl.ForceDirectories( iIconFolder );
end;
if ResourceHasGroupIcons( iResFilePath ) then
begin
iGroupIconFolder := IncludeTrailingPathDelimiter( iBaseFolder ) + 'GROUPICONS\' + JustName( iFilePath ) + '\';
if not DirectoryExists( iGroupIconFolder ) then
FileCtrl.ForceDirectories( iGroupIconFolder );
end;
iResourceExtractor := TIEResourceExtractor.Create( iResFileName );
try
if iResourceExtractor.IsValid then
begin
iNumberOfBitmaps := NumberOfBitmapsInRes( iResFilePath );
iNumberOfPNG := NumberOfPNGInRes( iResFilePath );
iNumberOfGroupIcons := NumberOfGroupIconsInRes( iResFilePath );
iNumberOfIcons := NumberOfIconsInRes( iResFilePath );
iNumberOfImagesInRes := iNumberOfBitmaps + iNumberOfPNG + iNumberOfGroupIcons + iNumberOfIcons;
Gauge1.MaxValue := iNumberOfImagesInRes;
Gauge1.Progress := 0;
try
// Search for ResType, loop among Types
for i := 0 to iResourceExtractor.TypesCount - 1 do
begin
if iResourceExtractor.FriendlyTypes[ i ] = 'Bitmap' then
// Bitmap found
begin
for j := 0 to iResourceExtractor.NamesCount[ i ] - 1 do
begin
iImageEnView := TImageEnView.Create( nil );
try
// Get the image buffer
iBuffer := iResourceExtractor.GetBuffer( i, j, iBufferLen );
iImageEnView.IO.Params.IsResource := True;
iImageEnView.IO.LoadFromBuffer( iBuffer, iBufferLen, ioBMP );
// Save bitmap
iWidth := iImageEnView.IEBitmap.Width;
iHeight := iImageEnView.IEBitmap.Height;
iResourceName := Format( '%s.bmp',
[ IncludeTrailingPathDelimiter( iBitmapFolder ) + CapFirst( JustName( iFilePath ) )
+ '_' + IntToStr( iWidth ) + 'x' + IntToStr( iHeight ) + '_' + BitDepthToString
( iImageEnView.IO.Params.SamplesPerPixel,
iImageEnView.IO.Params.BitsPerSample ) + '_' + IntToStr( j + 1 ) ] );
iImageEnView.IO.SaveToFile( iResourceName );
StatusBar1.Panels[ 10 ].Text := FileCtrl.MinimizeName( iBitmapFolder, Canvas, 250 );
Gauge1.Progress := Gauge1.Progress + 1;
Application.ProcessMessages;
Sleep( 1 );
finally
iImageEnView.Free;
end;
end;
end;
// PNG found
if iResourceExtractor.FriendlyTypes[ i ] = 'PNG' then
begin
iImageEnView := TImageEnView.Create( nil );
try
for j := 0 to iResourceExtractor.NamesCount[ i ] - 1 do
begin
iBuffer := iResourceExtractor.GetBuffer( i, j, iBufferLen );
iImageEnView.IO.Params.IsResource := True;
iImageEnView.IO.LoadFromBuffer( iBuffer, iBufferLen, ioPNG );
// Save PNG
iWidth := iImageEnView.IEBitmap.Width;
iHeight := iImageEnView.IEBitmap.Height;
iResourceName := Format( '%s.png',
[ IncludeTrailingPathDelimiter( iPNGFolder ) + CapFirst( JustName( iFilePath ) )
+ '_' + IntToStr( iWidth ) + 'x' + IntToStr( iHeight ) + '_' + BitDepthToString
( iImageEnView.IO.Params.SamplesPerPixel,
iImageEnView.IO.Params.BitsPerSample ) + '_' + IntToStr( j + 1 ) ] );
iImageEnView.IO.SaveToFile( iResourceName );
StatusBar1.Panels[ 10 ].Text := FileCtrl.MinimizeName( iPNGFolder, Canvas, 250 );
Gauge1.Progress := Gauge1.Progress + 1;
Application.ProcessMessages;
Sleep( 1 );
end;
finally
iImageEnView.Free;
end;
end;
if iResourceExtractor.FriendlyTypes[ i ] = 'Icon' then
// Icon found
begin
iImageEnView := TImageEnView.Create( nil );
try
for j := 0 to iResourceExtractor.NamesCount[ i ] - 1 do
begin
iBuffer := iResourceExtractor.GetBuffer( i, j, iBufferLen );
iImageEnView.IO.Params.IsResource := True;
iImageEnView.IO.LoadFromBuffer( iBuffer, iBufferLen, ioICO );
iWidth := iImageEnView.IEBitmap.Width;
iHeight := iImageEnView.IEBitmap.Height;
iIconFolder := IncludeTrailingPathDelimiter( iBaseFolder )
+ 'ICONS\' + IncludeTrailingPathDelimiter( JustName( iFilePath ) ) + IntToStr( iWidth )
+ 'x' + IntToStr( iHeight );
if not DirectoryExists( iIconFolder ) then
FileCtrl.ForceDirectories( iIconFolder );
iIconPath := Format( '%s.ico',
[ IncludeTrailingPathDelimiter( iIconFolder ) + CapFirst( JustName( iFilePath ) )
+ '_' + IntToStr( iWidth ) + 'x' + IntToStr( iHeight ) + '_' + BitDepthToString
( iImageEnView.IO.Params.SamplesPerPixel,
iImageEnView.IO.Params.BitsPerSample ) + '_' + IntToStr( j + 1 ) ] );
iImageEnView.IO.Params.ICO_Sizes[ 0 ].cx := iWidth;
iImageEnView.IO.Params.ICO_Sizes[ 0 ].cY := iHeight;
iImageEnView.IO.Params.ICO_BitCount[ 0 ] := iImageEnView.IO.Params.SamplesPerPixel *
iImageEnView.IO.Params.BitsPerSample;
// Save ICO
iImageEnView.IO.SaveToFile( iIconPath );
StatusBar1.Panels[ 10 ].Text := FileCtrl.MinimizeName( iIconFolder, Canvas, 250 );
Gauge1.Progress := Gauge1.Progress + 1;
Application.ProcessMessages;
Sleep( 1 );
end;
finally
iImageEnView.Free;
end;
end;
if iResourceExtractor.FriendlyTypes[ i ] = 'GroupIcon' then
begin
// GroupIcon found, loop among Names
for j := 0 to iResourceExtractor.NamesCount[ i ] - 1 do
begin
// Allocate array of TImageEnView objects and load frames
SetLength( iFrames, iResourceExtractor.GroupCountFrames[ i, j ] );
for k := 0 to Length( iFrames ) - 1 do
begin
iBuffer := iResourceExtractor.GetFrameBuffer( i, j, k, iBufferLen );
iFrames[ k ] := TImageEnView.Create( nil ); ( iFrames[ k ] as TImageEnView )
.IO.Params.IsResource := True; ( iFrames[ k ] as TImageEnView )
.IO.LoadFromBuffer( iBuffer, iBufferLen, ioICO );
end;
iResourceName := iGroupIconFolder + CapFirst( JustName( iFilePath ) ) + '_GroupIcon_' + IntToStr
( j + 1 ) + '.ico';
// Save Multiframe ICO
IEWriteICOImages( iResourceName, iFrames );
StatusBar1.Panels[ 10 ].Text := FileCtrl.MinimizeName( iGroupIconFolder, Canvas, 250 );
Gauge1.Progress := Gauge1.Progress + 1;
Application.ProcessMessages;
if iNumberOfGroupIcons < 20 then
Sleep( 50 )
else
Sleep( 1 );
// Cleanup Frames
for k := 0 to Length( iFrames ) - 1 do
iFrames[ k ].Free( );
end;
end;
Gauge1.Progress := Gauge1.Progress + 1;
Application.ProcessMessages;
end;
finally
Gauge1.Progress := 0;
end;
end;
finally
iResourceExtractor.Free;
end;
finally
Screen.Cursor := crDefault;
StatusBar1.Panels[ 10 ].Text := '';
ShellListView1.SetFocus;
end;
end;
end;
end;
procedure TFormResExtractor.Open1Click( Sender: TObject );
// Open a resource file
var
i, j, k: integer;
ip1, ip2, ip3: TTreeNode;
iResBookmark: TIEResourceBookmark;
iResFilePath: string;
iResFileName: string;
iResFileExtension: string;
iFolder: string;
iFilePath: string;
iFileName: string;
iFileExtension: string;
iExtension: string;
iTotalRes: integer;
iNumImages: integer;
iNumberOfBitmaps: integer;
iNumberOfPNG: integer;
iNumberOfGroupIcons: integer;
iNumberOfIcons: integer;
iNumberOfGroupCursors: integer;
iNumberOfCursors: integer;
iFileType: TIOFileType;
iResIsImage: boolean;
iFriendlyType: string;
iResourceHasImages: boolean;
iResourceHasIcons: boolean;
iHasExtractableImages: boolean;
begin
if OpenDialog1.Execute and FileExists( OpenDialog1.fileName ) then
begin
iResFilePath := OpenDialog1.fileName;
iResFileName := ExtractFilename( iResFilePath );
iResFileExtension := LowerCase( ExtractFileExt( iResFileName ) );
if Assigned( FResourceExtractor ) then
FResourceExtractor.Free;
TreeView1.Items.Clear;
// Is the selected file a resource file
if IsFileAResource( iResFilePath ) then
begin
Screen.Cursor := crHourGlass;
try
TreeView1.Items.BeginUpdate;
try
TreeView1.Items.Clear;
ImageEnView1.Clear;
Caption := 'Resource Extractor- ' + iResFilePath;
StatusBar1.Panels[ 0 ].Text := FileCtrl.MinimizeName( ExtractFileDir( iResFilePath ), Canvas, 150 );
StatusBar1.Panels[ 1 ].Text := ExtractFilename( iResFilePath );
ImageEnView1.LockPaint;
try
if FileExists( iResFilePath ) then
begin
FFilePath := iFileName;
iFolder := FDestinationFolder;
iFileExtension := ExtractFileExt( FFilePath );
iTotalRes := NumberOfResourcesInRes( iResFilePath );
iNumImages := NumberOfImagesInRes( iResFilePath );
iNumberOfBitmaps := NumberOfBitmapsInRes( iResFilePath );
iNumberOfPNG := NumberOfPNGInRes( iResFilePath );
iNumberOfGroupIcons := NumberOfGroupIconsInRes( iResFilePath );
iNumberOfIcons := NumberOfIconsInRes( iResFilePath );
iNumberOfGroupCursors := NumberOfGroupCursorsInRes( iResFilePath );
iNumberOfCursors := NumberOfCursorsInRes( iResFilePath );
NoResources1.Caption := 'Resources: ' + IntegerToString( iTotalRes );
NoImages1.Caption := 'Images: ' + IntegerToString( iNumImages );
NoBitmaps1.Caption := 'Bitmaps: ' + IntegerToString( iNumberOfBitmaps );
NoPNG1.Caption := 'PNG: ' + IntegerToString( iNumberOfPNG );
NoGroupIcons1.Caption := 'Group Icons: ' + IntegerToString( iNumberOfGroupIcons );
NoIcons1.Caption := 'Icons: ' + IntegerToString( iNumberOfIcons );
NoGroupCursors1.Caption := 'Group Cursors: ' + IntegerToString( iNumberOfGroupCursors );
NoCursors1.Caption := 'Cursors: ' + IntegerToString( iNumberOfCursors );
StatusBar1.Panels[ 2 ].Text := 'Resources: ' + IntegerToString( iTotalRes );
StatusBar1.Panels[ 3 ].Text := 'Images: ' + IntegerToString( iNumImages );
StatusBar1.Panels[ 4 ].Text := 'GroupIcons: ' + IntegerToString( iNumberOfGroupIcons );
StatusBar1.Panels[ 5 ].Text := 'Icons: ' + IntegerToString( iNumberOfIcons );
iResourceHasImages := ResourceHasImages( iResFilePath );
iHasExtractableImages := NumberOfExtractableImagesInRes( iResFilePath ) > 0;
SaveImageAs1.Enabled := iResourceHasImages;
SaveAllImages1.Enabled := iHasExtractableImages;
SaveAs1.Enabled := iResourceHasImages;
ExtractAll1.Enabled := iHasExtractableImages;
SaveGroupIcons1.Enabled := iNumberOfGroupIcons > 0;
SaveAllGroupIcons1.Enabled := iNumberOfGroupIcons > 0;
iResourceHasIcons := ResourceHasIcons( iResFilePath );
SaveAllIcons1.Enabled := iResourceHasIcons;
SaveAllIcons2.Enabled := iResourceHasIcons;
if Assigned( FResourceExtractor ) then
FResourceExtractor.Free;
FResourceExtractor := TIEResourceExtractor.Create( iResFilePath );
if FResourceExtractor.IsValid then
for i := 0 to FResourceExtractor.TypesCount - 1 do
begin
ip1 := TreeView1.Items.Add( nil, string( FResourceExtractor.FriendlyTypes[ i ] ) );
for j := 0 to FResourceExtractor.NamesCount[ i ] - 1 do
if FResourceExtractor.IsGroup[ i ] then
begin
iFriendlyType := string( FResourceExtractor.FriendlyTypes[ i ] );
ip2 := TreeView1.Items.AddChild( ip1,
iResFileName + ' ' + string( FResourceExtractor.FriendlyTypes[ i ] ) + ' ' + IntToStr( j + 1 )
{ string ( m_ResourceExtractor.Names [ i, j ] ) } );
for k := 0 to FResourceExtractor.GroupCountFrames[ i, j ] - 1 do
begin
ip3 := TreeView1.Items.AddChildObject( ip2,
IntToStr( FResourceExtractor.GroupFrameWidth[ i, j, k ] ) + ' x ' + IntToStr
( FResourceExtractor.GroupFrameHeight[ i, j, k ] ) + ' ' + IntToStr
( FResourceExtractor.GroupFrameDepth[ i, j, k ] ) + '-bit',
FResourceExtractor.GetResourceBookmark( i, j, k ) );
iResBookmark := TIEResourceBookmark( ip3.Data );
iFileType := ioUnknown;
if ( FResourceExtractor.FriendlyTypes[ iResBookmark.TypeIndex ] = 'GroupIcon' ) or
( FResourceExtractor.FriendlyTypes[ iResBookmark.TypeIndex ] = 'Icon' ) then
iFileType := ioICO
else if ( FResourceExtractor.FriendlyTypes[ iResBookmark.TypeIndex ] = 'GroupCursor' ) or
( FResourceExtractor.FriendlyTypes[ iResBookmark.TypeIndex ] = 'Cursor' ) then
iFileType := ioCUR
else if ( FResourceExtractor.FriendlyTypes[ iResBookmark.TypeIndex ] = 'Bitmap' ) then
iFileType := ioBMP
else if ( FResourceExtractor.FriendlyTypes[ iResBookmark.TypeIndex ] = 'PNG' ) then
iFileType := ioPNG
else if ( FResourceExtractor.FriendlyTypes[ iResBookmark.TypeIndex ] = 'IMAGE' ) then
iFileType := ioBMP;
iResIsImage := ( iFileType = ioICO ) or ( iFileType = ioCUR ) or ( iFileType = ioBMP ) or
( iFileType = ioPNG );
if iResIsImage then
begin
iExtension := IEFileTypeToExtension( iFileType );
iFilePath := IncludeTrailingPathDelimiter( iFolder ) + JustName( FFilePath )
+ '_' + RemoveDotFromExtension( iFileExtension ) + '_' + IntToStr( i ) + iExtension;
end
else
ImageEnView1.Clear;
ImageEnView1.Update;
end;
end
else
begin
iFileType := ioUnknown;
if ( FResourceExtractor.FriendlyTypes[ i ] = 'GroupIcon' ) or
( FResourceExtractor.FriendlyTypes[ i ] = 'Icon' ) then
iFileType := ioICO
else if ( FResourceExtractor.FriendlyTypes[ i ] = 'GroupCursor' ) or
( FResourceExtractor.FriendlyTypes[ i ] = 'Cursor' ) then
iFileType := ioCUR
else if ( FResourceExtractor.FriendlyTypes[ i ] = 'Bitmap' ) then
iFileType := ioBMP
else if ( FResourceExtractor.FriendlyTypes[ i ] = 'PNG' ) then
iFileType := ioPNG
else if ( FResourceExtractor.FriendlyTypes[ i ] = 'Image' ) then
iFileType := ioBMP;
iResIsImage := ( iFileType = ioICO ) or ( iFileType = ioCUR ) or ( iFileType = ioBMP ) or
( iFileType = ioPNG );
if iResIsImage then
begin
TreeView1.Items.AddChildObject( ip1,
iResFileName + ' ' + string( FResourceExtractor.FriendlyTypes[ i ] ) + ' ' + IntToStr
( j + 1 ), FResourceExtractor.GetResourceBookmark( i, j ) );
end;
end;
end;
end;
finally
ImageEnView1.UnLockPaint;
end;
finally
Screen.Cursor := crDefault;
end;
finally
TreeView1.Items.EndUpdate;
end;
end;
end;
end;
procedure TFormResExtractor.PopupMenu1Popup( Sender: TObject );
// Resource Tree Popupmenu
var
iFileName: string;
iResourceHasImages: boolean;
iResourceHasGroups: boolean;
iHasExtractableImages: boolean;
begin
if Assigned( ShellListView1.Selected ) then
begin
iFileName := ShellListView1.SelectedFolder.PathName;
iResourceHasImages := ResourceHasImages( iFileName );
iResourceHasGroups := DoesResourceContainGroupIcon( iFileName ) or DoesResourceContainGroupCursor( iFileName );
iHasExtractableImages := NumberOfExtractableImagesInRes( iFileName ) > 0;
SaveImageAs1.Enabled := iResourceHasImages;
SaveAllImages1.Enabled := iHasExtractableImages;
SaveAs1.Enabled := iResourceHasImages;
ExtractAll1.Enabled := iHasExtractableImages;
SaveSelectedIimage1.Enabled := iResourceHasImages;
SaveAllImagesToAFolder1.Enabled := iHasExtractableImages;
SaveAllGroupIconsToMultiframeIconfile1.Enabled := iResourceHasGroups;
SaveSelectedGroupIconToMultiFrameIcon1.Enabled := ( iResourceHasGroups ) and ( Assigned( TreeView1.Selected ) ) and
( IsResourceGroupIcon( iFileName, TreeView1.Selected.Index ) );
end;
end;
procedure TFormResExtractor.ReturnToTheSystem32Folder1Click( Sender: TObject );
// Set the ShellTreeView path to system32 folder
begin
ShellTreeView1.Path := System32Folder;
// Sort the ShellListView descending by size
ShellListSortAscending := False;
ShellListSortColumn := 1; // Size Column
// Sorting capability was added to ShellCtrls.pas which is located in the project folder
ShellListView1.FolderList.Sort( ShellCompare );
ShellListView1.Invalidate;
end;
procedure TFormResExtractor.SaveAllIcons1Click( Sender: TObject );
// Save all icons in resource file ( Does not save any group icons )
var
i: integer;
j: integer;
iResourceExtractor: TIEResourceExtractor;
iImageEnView: TImageEnView;
iResFileName: string;
iResFileExtension: string;
iBuffer: Pointer;
iBufferLen: integer;
iFilePath: string;
iPath: string;
iBaseFolder: string;
iIconFolder: string;
iCurrentDrive: string;
iWidth: integer;
iHeight: integer;
iIconPath: string;
begin
iCurrentDrive := CurrentDrive;
iFilePath := ShellListView1.SelectedFolder.PathName;
if DirectoryExists( FDestinationFolder ) then
iBaseFolder := IncludeTrailingPathDelimiter( FDestinationFolder )
else
iBaseFolder := IncludeTrailingPathDelimiter( iCurrentDrive + ':\Images\Extracted Images\ICONS' ) + CapFirst
( JustName( iFilePath ) );
if not DirectoryExists( iBaseFolder ) then
if FileCtrl.ForceDirectories( iBaseFolder ) then
begin
FDestinationFolder := iBaseFolder;
StatusBar1.Panels[ 10 ].Text := FileCtrl.MinimizeName( FDestinationFolder, Canvas, 250 );
end
else
begin
// Get the folder to save images to
iBaseFolder := IncludeTrailingPathDelimiter( BrowseForFolder( DesktopFolder ) );
if DirectoryExists( iBaseFolder ) then
begin
FDestinationFolder := iBaseFolder;
StatusBar1.Panels[ 10 ].Text := FileCtrl.MinimizeName( FDestinationFolder, Canvas, 250 );
end
else
Exit;
end;
if Assigned( ShellListView1.Selected ) then
begin
iPath := ShellListView1.SelectedFolder.PathName;
iResFileName := ExtractFilename( iPath );
iResFileExtension := LowerCase( ExtractFileExt( iResFileName ) );
// Is the selected file a resource file
if IsFileAResource( iResFileName ) then
begin
Screen.Cursor := crHourGlass;
try
iResourceExtractor := TIEResourceExtractor.Create( iResFileName );
try
if iResourceExtractor.IsValid then
begin
Gauge1.MaxValue := NumberOfIconsInRes( iResFileName );
Gauge1.Progress := 0;
try
// Search for ResType, loop among Types
for i := 0 to iResourceExtractor.TypesCount - 1 do
begin
if iResourceExtractor.FriendlyTypes[ i ] = 'Icon' then
// Icon found
begin
iImageEnView := TImageEnView.Create( nil );
try
for j := 0 to iResourceExtractor.NamesCount[ i ] - 1 do
begin
iBuffer := iResourceExtractor.GetBuffer( i, j, iBufferLen );
iImageEnView.IO.Params.IsResource := True;
iImageEnView.IO.LoadFromBuffer( iBuffer, iBufferLen, ioICO );
iWidth := iImageEnView.IEBitmap.Width;
iHeight := iImageEnView.IEBitmap.Height;
iIconFolder := IncludeTrailingPathDelimiter( iBaseFolder )
+ 'ICONS\' + IncludeTrailingPathDelimiter( JustName( iFilePath ) ) + IntToStr( iWidth )
+ 'x' + IntToStr( iHeight );
if not DirectoryExists( iIconFolder ) then
FileCtrl.ForceDirectories( iIconFolder );
iIconPath := Format( '%s.ico',
[ IncludeTrailingPathDelimiter( iIconFolder ) + CapFirst( JustName( iFilePath ) )
+ '_' + IntToStr( iWidth ) + 'x' + IntToStr( iHeight ) + '_' + BitDepthToString
( iImageEnView.IO.Params.SamplesPerPixel,
iImageEnView.IO.Params.BitsPerSample ) + '_' + IntToStr( j + 1 ) ] );
iImageEnView.IO.Params.ICO_Sizes[ 0 ].cx := iWidth;
iImageEnView.IO.Params.ICO_Sizes[ 0 ].cY := iHeight;
iImageEnView.IO.Params.ICO_BitCount[ 0 ] := iImageEnView.IO.Params.SamplesPerPixel *
iImageEnView.IO.Params.BitsPerSample;
// Save ICO
iImageEnView.IO.SaveToFile( iIconPath );
Gauge1.Progress := Gauge1.Progress + 1;
Application.ProcessMessages;
Sleep( 1 );
end;
finally
iImageEnView.Free;
end;
end;
end;
finally
Gauge1.Progress := 0;
end;
end;
ShellListView1.SetFocus;
finally
iResourceExtractor.Free;
end;
finally
Screen.Cursor := crDefault;
end;
end;
end;
end;
procedure TFormResExtractor.About1Click( Sender: TObject );
begin
FormAbout := TFormAbout.Create( self );
try
FormAbout.ShowModal;
finally
FormAbout.Free;
end;
end;
procedure TFormResExtractor.BrowseForFolder1Click( Sender: TObject );
// Set the default destination folder with BrowseForFolder
var
iPath: string;
begin
if DirectoryExists( FDestinationFolder ) then
iPath := BrowseForFolder( FDestinationFolder )
else
iPath := BrowseForFolder( DocumentsFolder );
if DirectoryExists( iPath ) then
begin
FDestinationFolder := iPath;
if DestinationFolderComboBox1.Items.IndexOf( iPath ) = -1 then // not in the list
begin
DestinationFolderComboBox1.Items.Add( FDestinationFolder );
DestinationFolderComboBox1.ItemIndex := DestinationFolderComboBox1.Items.Count - 1;
DestinationFolderComboBox1.Hint := FDestinationFolder;
end;
end;
StatusBar1.Panels[ 10 ].Text := FileCtrl.MinimizeName( FDestinationFolder, Canvas, 250 );
end;
procedure TFormResExtractor.Clear1Click( Sender: TObject );
// Clear all items in the destination combobox
begin
DestinationFolderComboBox1.Clear;
FDestinationFolder := '';
end;
procedure TFormResExtractor.DefaultDestinationFolder1Click( Sender: TObject );
// Set the default destination folder
var
iPath: string;
begin
if DirectoryExists( FDestinationFolder ) then
iPath := BrowseForFolder( FDestinationFolder )
else
iPath := BrowseForFolder( DocumentsFolder );
if DirectoryExists( iPath ) then
begin
FDestinationFolder := iPath;
if DestinationFolderComboBox1.Items.IndexOf( iPath ) = -1 then // not in the list
begin
DestinationFolderComboBox1.Items.Add( FDestinationFolder );
DestinationFolderComboBox1.ItemIndex := DestinationFolderComboBox1.Items.Count - 1;
DestinationFolderComboBox1.Hint := FDestinationFolder;
end;
end;
StatusBar1.Panels[ 10 ].Text := FileCtrl.MinimizeName( FDestinationFolder, Canvas, 250 );
end;
procedure TFormResExtractor.Delete1Click( Sender: TObject );
// Remove the selected destination folder from the combobox
begin
DestinationFolderComboBox1.Items.delete( DestinationFolderComboBox1.ItemIndex );
end;
procedure TFormResExtractor.DestinationFolder1Click( Sender: TObject );
// Set the destination folder
begin
FDestinationFolder := BrowseForFolder( FDestinationFolder );
StatusBar1.Panels[ 10 ].Text := FileCtrl.MinimizeName( FDestinationFolder, Canvas, 250 );
end;
procedure TFormResExtractor.DestinationFolderComboBox1CloseUp( Sender: TObject );
// Set the destination folder
begin
FDestinationFolder := DestinationFolderComboBox1.Items[ DestinationFolderComboBox1.ItemIndex ];
DestinationFolderComboBox1.Hint := FDestinationFolder;
StatusBar1.Panels[ 10 ].Text := FileCtrl.MinimizeName( FDestinationFolder, Canvas, 250 );
Label3.Hint := 'The root destination folder is the parent folder for all extracted images.' + #10#13 + #10#13 +
'Images will be saved to the following folders: ' + #10#13 +
'Group Icons: ' + IncludeTrailingPathDelimiter( FDestinationFolder ) + 'GROUPICONS' + #10#13 +
'Icons: ' + IncludeTrailingPathDelimiter( FDestinationFolder ) + 'ICONS' + #10#13 +
'Bitmaps: ' + IncludeTrailingPathDelimiter( FDestinationFolder ) + 'BMP' + #10#13 +
'PNG Images: ' + IncludeTrailingPathDelimiter( FDestinationFolder ) + 'PNG';
end;
procedure TFormResExtractor.Zoom1Change( Sender: TObject );
// Change ImageENView zoom
const
iZoomVal: array [ 0 .. 6 ] of double = ( 0, 25, 50, 100, 200, 400, 800 );
begin
if Zoom1.ItemIndex = 0 then
begin
ImageEnView1.AutoFit := True;
ImageEnView1.Update;
end
else
begin
ImageEnView1.AutoFit := False;
ImageEnView1.Zoom := iZoomVal[ Zoom1.ItemIndex ];
end;
end;
procedure TFormResExtractor.TreeView1Change( Sender: TObject; Node: TTreeNode );
// Respond to Treeview changes
var
iResBookmark: TIEResourceBookmark;
iBuffer: Pointer;
iBufferLen: integer;
iFileType: TIOFileType;
iDimensions: string;
iSmallDimensions: string;
iBitDepth: integer;
iColors: string;
iResIsImage: boolean;
iFriendlyType: string;
iResFileName: string;
iResourceHasImages: boolean;
iResourceHasGroups: boolean;
iResourceHasIcons: boolean;
iHasExtractableImages: boolean;
begin
if not Node.HasChildren and Assigned( Node.Data ) then
begin
iResBookmark := TIEResourceBookmark( Node.Data );
iBuffer := FResourceExtractor.GetBuffer( iResBookmark, iBufferLen );
if FResourceExtractor.FriendlyTypes[ iResBookmark.TypeIndex ] = 'GroupIcon' then
SaveSelectedGroupIcon1.Enabled := True;
// Set the file type
iFriendlyType := string( FResourceExtractor.FriendlyTypes[ iResBookmark.TypeIndex ] );
iFileType := ioUnknown;
if ( iFriendlyType = 'GroupIcon' ) or ( iFriendlyType = 'Icon' ) then
iFileType := ioICO
else if ( iFriendlyType = 'GroupCursor' ) or ( iFriendlyType = 'Cursor' ) then
iFileType := ioCUR
else if ( iFriendlyType = 'Bitmap' ) then
iFileType := ioBMP
else if ( iFriendlyType = 'PNG' ) then
iFileType := ioPNG;
if Assigned( ShellListView1.Selected ) then
begin
iResFileName := ShellListView1.SelectedFolder.PathName;
iResourceHasGroups := DoesResourceContainGroupIcon( iResFileName ) or DoesResourceContainGroupCursor
( iResFileName );
iHasExtractableImages := NumberOfExtractableImagesInRes( iResFileName ) > 0;
SaveAllImages1.Enabled := iHasExtractableImages;
ExtractAll1.Enabled := iHasExtractableImages;
if iFriendlyType = 'GroupIcon' then
begin
SaveGroupIcons1.Enabled := iResourceHasGroups;
SaveSelectedGroupIcon1.Enabled := True;
SaveAllGroupIcons1.Enabled := iResourceHasGroups;
SaveAllGroupIconsToMultiframeIconfile1.Enabled := iResourceHasGroups;
SaveSelectedGroupIcon2.Enabled := True;
SaveSelectedGroupIconToMultiFrameIcon1.Enabled := True;
end;
if iFileType = ioICO then
begin
SaveAs1.Enabled := True;
SaveImageAs1.Enabled := True;
SaveGroupIcons1.Enabled := iResourceHasGroups;
if TreeView1.Selected.Parent.Text = 'GroupIcon' then
SaveSelectedGroupIcon1.Enabled := True;
SaveAllGroupIcons1.Enabled := iResourceHasGroups;
SaveAllGroupIconsToMultiframeIconfile1.Enabled := iResourceHasGroups;
SaveSelectedGroupIcon2.Enabled := True;
SaveSelectedGroupIconToMultiFrameIcon1.Enabled := True;
StatusBar1.Panels[ 6 ].Text := 'Icon';
end
else if iFileType = ioCUR then
begin
SaveAs1.Enabled := False;
SaveImageAs1.Enabled := False;
SaveGroupIcons1.Enabled := iResourceHasGroups;
SaveSelectedGroupIcon1.Enabled := False;
SaveAllGroupIcons1.Enabled := iResourceHasGroups;
SaveAllGroupIconsToMultiframeIconfile1.Enabled := iResourceHasGroups;
SaveSelectedGroupIcon2.Enabled := False;
SaveSelectedGroupIconToMultiFrameIcon1.Enabled := False;
StatusBar1.Panels[ 6 ].Text := 'Cursor';
end
else if iFileType = ioBMP then
begin
SaveAs1.Enabled := True;
SaveImageAs1.Enabled := True;
SaveGroupIcons1.Enabled := iResourceHasGroups;
SaveSelectedGroupIcon1.Enabled := False;
SaveAllGroupIcons1.Enabled := iResourceHasGroups;
SaveAllGroupIconsToMultiframeIconfile1.Enabled := iResourceHasGroups;
SaveSelectedGroupIcon2.Enabled := False;
SaveSelectedGroupIconToMultiFrameIcon1.Enabled := False;
StatusBar1.Panels[ 6 ].Text := 'Bitmap';
end
else if iFileType = ioPNG then
begin
SaveAs1.Enabled := True;
SaveImageAs1.Enabled := True;
SaveGroupIcons1.Enabled := iResourceHasGroups;
SaveSelectedGroupIcon1.Enabled := False;
SaveAllGroupIcons1.Enabled := iResourceHasGroups;
SaveAllGroupIconsToMultiframeIconfile1.Enabled := iResourceHasGroups;
SaveSelectedGroupIcon2.Enabled := False;
SaveSelectedGroupIconToMultiFrameIcon1.Enabled := False;
StatusBar1.Panels[ 6 ].Text := 'PNG';
end
else
begin
SaveAs1.Enabled := False;
SaveImageAs1.Enabled := False;
SaveGroupIcons1.Enabled := iResourceHasGroups;
SaveSelectedGroupIcon1.Enabled := False;
SaveAllGroupIcons1.Enabled := iResourceHasGroups;
SaveAllGroupIconsToMultiframeIconfile1.Enabled := iResourceHasGroups;
SaveSelectedGroupIcon2.Enabled := False;
SaveSelectedGroupIconToMultiFrameIcon1.Enabled := False;
StatusBar1.Panels[ 6 ].Text := '';
end;
iResIsImage := ( iFileType = ioICO ) or ( iFileType = ioCUR ) or ( iFileType = ioBMP ) or ( iFileType = ioPNG );
if iResIsImage then
begin
ImageEnView1.IO.Params.IsResource := True;
ImageEnView1.IO.LoadFromBuffer( iBuffer, iBufferLen, iFileType );
ImageEnView1.IO.Params.FileType := iFileType;
end
else
ImageEnView1.Blank;
ImageEnView1.Update;
iDimensions := IntegerToString( ImageEnView1.IEBitmap.Width ) + ' pixels x ' + IntegerToString
( ImageEnView1.IEBitmap.Height ) + ' pixels';
iSmallDimensions := IntegerToString( ImageEnView1.IEBitmap.Width ) + ' x ' + IntegerToString
( ImageEnView1.IEBitmap.Height );
iBitDepth := ImageEnView1.IO.Params.BitsPerSample * ImageEnView1.IO.Params.SamplesPerPixel;
if iBitDepth = 32 then
begin
ImageEnView1.Background := clBtnFace;
ImageEnView1.BackgroundStyle := iebsChessboard;
ImageEnView1.SetChessboardStyle( 4 );
iColors := 'RGBA ' + IntToStr( iBitDepth ) + ' bit';
end
else
begin
ImageEnView1.Background := clWindow;
ImageEnView1.BackgroundStyle := iebsSolid;
iColors := 'RGB ' + IntToStr( iBitDepth ) + ' bit';
end;
if iFriendlyType = 'GroupIcon' then
Frames1.Caption := 'Frames: ' + IntegerToString( NodeChildCount( TreeView1.Selected.Parent ) )
else
Frames1.Caption := 'Frames: 1';
Dimensions1.Caption := 'Dimensions: ' + iSmallDimensions;
Colors1.Caption := 'Colors: ' + iColors;
StatusBar1.Panels[ 7 ].Text := 'Frames: ' + IntegerToString( NodeChildCount( TreeView1.Selected.Parent ) );
StatusBar1.Panels[ 8 ].Text := iDimensions;
StatusBar1.Panels[ 9 ].Text := iColors;
end;
end
else
begin
Node.Expand( False );
if Assigned( ShellListView1.Selected ) then
iResFileName := ShellListView1.SelectedFolder.PathName;
iResourceHasGroups := DoesResourceContainGroupIcon( iResFileName ) or DoesResourceContainGroupCursor
( iResFileName );
iResourceHasImages := ResourceHasImages( iResFileName );
iResourceHasIcons := ResourceHasIcons( iResFileName );
ImageEnView1.Blank;
SaveAs1.Enabled := ( TreeView1.Selected.Text <> 'GroupCursor' ) and ( TreeView1.Selected.Text <> 'Cursor' ) and
( TreeView1.Selected.Text <> 'Image' ) and ( TreeView1.Selected.Text <> 'GroupIcon' );
SaveImageAs1.Enabled := ( TreeView1.Selected.Text <> 'GroupCursor' ) and ( TreeView1.Selected.Text <> 'Cursor' )
and ( TreeView1.Selected.Text <> 'Image' ) and ( TreeView1.Selected.Text <> 'GroupIcon' );
ExtractAll1.Enabled := iResourceHasImages;
SaveAllIcons1.Enabled := iResourceHasIcons;
SaveAllIcons2.Enabled := iResourceHasIcons;
if ( TreeView1.Selected.Level = 1 ) and ( TreeView1.Selected.Parent.Text = 'GroupIcon' ) then
begin
StatusBar1.Panels[ 6 ].Text := 'GroupIcon';
SaveSelectedGroupIcon1.Enabled := True;
SaveSelectedGroupIcon2.Enabled := True;
end
else if ( TreeView1.Selected.Level = 1 ) and ( TreeView1.Selected.Parent.Text = 'GroupCursor' ) then
begin
SaveAs1.Enabled := False;
SaveImageAs1.Enabled := False;
StatusBar1.Panels[ 6 ].Text := 'GroupCursor';
end
else
begin
SaveAs1.Enabled := ( TreeView1.Selected.Text <> 'GroupIcon' ) and ( TreeView1.Selected.Text = 'Icon' ) and
( TreeView1.Selected.Text <> 'GroupCursor' ) and ( TreeView1.Selected.Text = 'Cursor' ) and
( TreeView1.Selected.Text = 'Bitmap' ) and ( TreeView1.Selected.Text = 'PNG' ) and
( TreeView1.Selected.Text <> 'Image' );
SaveImageAs1.Enabled := ( TreeView1.Selected.Text <> 'GroupIcon' ) and ( TreeView1.Selected.Text = 'Icon' ) and
( TreeView1.Selected.Text <> 'GroupCursor' ) and ( TreeView1.Selected.Text = 'Cursor' ) and
( TreeView1.Selected.Text = 'Bitmap' ) and ( TreeView1.Selected.Text = 'PNG' ) and
( TreeView1.Selected.Text <> 'Image' );
SaveGroupIcons1.Enabled := iResourceHasGroups;
SaveAllGroupIcons1.Enabled := iResourceHasGroups;
SaveSelectedGroupIcon1.Enabled := False;
SaveSelectedGroupIcon2.Enabled := False;
StatusBar1.Panels[ 6 ].Text := TreeView1.Selected.Text;
StatusBar1.Panels[ 7 ].Text := '';
StatusBar1.Panels[ 8 ].Text := '';
StatusBar1.Panels[ 9 ].Text := '';
end;
if TreeView1.Selected.Level = 0 then
begin
Frames1.Caption := 'Frames:';
StatusBar1.Panels[ 7 ].Text := '';
end;
if ( TreeView1.Selected.Level > 0 ) and ( TreeView1.Selected.Parent.Text = 'GroupIcon' ) then
begin
Frames1.Caption := 'Frames: ' + IntegerToString( CountChildNodes( TreeView1 ) );
Dimensions1.Caption := 'Dimensions:';
Colors1.Caption := 'Colors:';
StatusBar1.Panels[ 7 ].Text := 'Frames: ' + IntegerToString( CountChildNodes( TreeView1 ) );
end
else
begin
Frames1.Caption := 'Frames:';
Dimensions1.Caption := 'Dimensions:';
Colors1.Caption := 'Colors:';
StatusBar1.Panels[ 7 ].Text := '';
end;
end;
end;
procedure TFormResExtractor.TreeView1GetImageIndex( Sender: TObject; Node: TTreeNode );
// Get the image index of the selected node
begin
if Node.HasChildren then
begin
if Node.Expanded then
Node.ImageIndex := 0
else
Node.ImageIndex := 1;
Node.SelectedIndex := 1;
end
else
begin
Node.ImageIndex := 2;
Node.SelectedIndex := 2;
end;
end;
procedure TFormResExtractor.ViewIcons1Click( Sender: TObject );
// Icon viewer
var
iCurrentDrive: string;
iFilePath: string;
iBaseFolder: string;
iTreeNode: TTreeNode;
begin
FormViewIcons := TFormViewIcons.Create( self );
try
if Assigned( ShellListView1.Selected ) then
begin
iCurrentDrive := CurrentDrive;
iFilePath := ShellListView1.SelectedFolder.PathName;
iBaseFolder := IncludeTrailingPathDelimiter( iCurrentDrive + ':\Images\Extracted Images\GROUPICONS' ) + CapFirst
( JustName( iFilePath ) );
if DirectoryExists( iBaseFolder ) then
begin
// Set the icon viewer path to match the selected resource file
FormViewIcons.ShellTreeView1.Path := iBaseFolder;
iTreeNode := FormViewIcons.ShellTreeView1.Selected;
if Assigned( iTreeNode ) then
begin
// For some reason the listview does not change when the treeview path is set, so force a change by changing the treeview nodes
FormViewIcons.ShellTreeView1.Selected := FormViewIcons.ShellTreeView1.Items.Item
[ FormViewIcons.ShellTreeView1.Selected.Index + 1 ];
FormViewIcons.ShellTreeView1.Selected := iTreeNode;
// Make the node visible
iTreeNode.MakeVisible;
// Make the node the top node
FormViewIcons.ShellTreeView1.TopItem := iTreeNode;
end;
end;
end;
FormViewIcons.ShowModal;
finally
FormViewIcons.Free;
end;
end;
procedure TFormResExtractor.Saveimageas1Click( Sender: TObject );
// Save image as...
begin
if SavePictureDialog1.Execute then
ImageEnView1.IO.SaveToFile( SavePictureDialog1.fileName );
end;
procedure TFormResExtractor.SavePictureDialog1TypeChange( Sender: TObject );
// Change the SavePictureDialog file extension when the filter changes
var
FilePath: string;
fileName: string;
FileExt: string;
begin
FilePath := SavePictureDialog1.fileName;
FileExt := ExtractFileExt( FilePath );
fileName := ExtractFilename( FilePath );
end;
procedure TFormResExtractor.ShellListView1Change( Sender: TObject; Item: TListItem; Change: TItemChange );
// Respond to ShellListView changes
var
i, j, k: integer;
ip1, ip2, ip3: TTreeNode;
iResBookmark: TIEResourceBookmark;
iResFilePath: string;
iResFileName: string;
iResFileExtension: string;
iResFileShortExtension: string;
iFolder: string;
iFilePath: string;
iFileName: string;
iFileExtension: string;
iExtension: string;
iShortExtension: string;
iTotalRes: integer;
iNumImages: integer;
iNumberOfBitmaps: integer;
iNumberOfPNG: integer;
iNumberOfGroupIcons: integer;
iNumberOfIcons: integer;
iNumberOfGroupCursors: integer;
iNumberOfCursors: integer;
iFileType: TIOFileType;
iResIsImage: boolean;
iFriendlyType: string;
iResourceHasIcons: boolean;
iHasExtractableImages: boolean;
begin
if Assigned( ShellListView1.Selected ) then
begin
iResFilePath := ShellListView1.SelectedFolder.PathName;
iResFileName := JustName( iResFilePath );
iResFileExtension := LowerCase( ExtractFileExt( iResFileName ) );
iResFileShortExtension := RemoveDotFromExtension( UpperCase( ExtractFileExt( iResFilePath ) ) );
// Is the selected file a resource file
if IsFileAResource( iResFilePath ) then
begin
Screen.Cursor := crHourGlass;
try
TreeView1.Items.BeginUpdate;
try
TreeView1.Items.Clear;
ImageEnView1.Clear;
Caption := 'Resource Extractor- ' + iResFilePath;
StatusBar1.Panels[ 0 ].Text := FileCtrl.MinimizeName( ExtractFileDir( iResFilePath ), Canvas, 150 );
StatusBar1.Panels[ 1 ].Text := ExtractFilename( iResFilePath );
ImageEnView1.LockPaint;
try
if FileExists( iResFilePath ) then
begin
FFilePath := iFileName;
iFolder := FDestinationFolder;
iFileExtension := ExtractFileExt( FFilePath );
iTotalRes := NumberOfResourcesInRes( iResFilePath );
iNumImages := NumberOfImagesInRes( iResFilePath );
iNumberOfBitmaps := NumberOfBitmapsInRes( iResFilePath );
iNumberOfPNG := NumberOfPNGInRes( iResFilePath );
iNumberOfGroupIcons := NumberOfGroupIconsInRes( iResFilePath );
iNumberOfIcons := NumberOfIconsInRes( iResFilePath );
iNumberOfGroupCursors := NumberOfGroupCursorsInRes( iResFilePath );
iNumberOfCursors := NumberOfCursorsInRes( iResFilePath );
NoResources1.Caption := 'Resources: ' + IntegerToString( iTotalRes );
NoImages1.Caption := 'Images: ' + IntegerToString( iNumImages );
NoBitmaps1.Caption := 'Bitmaps: ' + IntegerToString( iNumberOfBitmaps );
NoPNG1.Caption := 'PNG: ' + IntegerToString( iNumberOfPNG );
NoGroupIcons1.Caption := 'Group Icons: ' + IntegerToString( iNumberOfGroupIcons );
NoIcons1.Caption := 'Icons: ' + IntegerToString( iNumberOfIcons );
NoGroupCursors1.Caption := 'Group Cursors: ' + IntegerToString( iNumberOfGroupCursors );
NoCursors1.Caption := 'Cursors: ' + IntegerToString( iNumberOfCursors );
StatusBar1.Panels[ 2 ].Text := FormatByteSize( FileSize( iResFilePath ) );
StatusBar1.Panels[ 3 ].Text := 'Resources: ' + IntegerToString( iTotalRes );
StatusBar1.Panels[ 4 ].Text := 'Images: ' + IntegerToString( iNumImages );
StatusBar1.Panels[ 5 ].Text := 'GroupIcons: ' + IntegerToString( iNumberOfGroupIcons );
StatusBar1.Panels[ 6 ].Text := 'Icons: ' + IntegerToString( iNumberOfIcons );
iHasExtractableImages := NumberOfExtractableImagesInRes( iResFilePath ) > 0;
SaveImageAs1.Enabled := iHasExtractableImages;
SaveAllImages1.Enabled := iHasExtractableImages;
SaveAs1.Enabled := iHasExtractableImages;
ExtractAll1.Enabled := iHasExtractableImages;
SaveGroupIcons1.Enabled := iNumberOfGroupIcons > 0;
SaveAllGroupIcons1.Enabled := iNumberOfGroupIcons > 0;
iResourceHasIcons := ResourceHasIcons( iResFilePath );
SaveAllIcons1.Enabled := iResourceHasIcons;
SaveAllIcons2.Enabled := iResourceHasIcons;
if Assigned( FResourceExtractor ) then
FResourceExtractor.Free;
FResourceExtractor := TIEResourceExtractor.Create( iResFilePath );
if FResourceExtractor.IsValid then
for i := 0 to FResourceExtractor.TypesCount - 1 do
begin
ip1 := TreeView1.Items.Add( nil, string( FResourceExtractor.FriendlyTypes[ i ] ) );
for j := 0 to FResourceExtractor.NamesCount[ i ] - 1 do
if FResourceExtractor.IsGroup[ i ] then
begin
iFriendlyType := string( FResourceExtractor.FriendlyTypes[ i ] );
if ( iFriendlyType = 'GroupIcon' ) or ( iFriendlyType = 'Icon' ) then
iShortExtension := 'Icon'
else if ( iFriendlyType = 'GroupCursor' ) or ( iFriendlyType = 'Cursor' ) then
iShortExtension := 'Cursor'
else if ( iFriendlyType = 'Bitmap' ) then
iShortExtension := 'Bitmap'
else if ( iFriendlyType = 'PNG' ) then
iShortExtension := 'Png'
else
iShortExtension := '';
iResFileName := JustName( iResFilePath );
ip2 := TreeView1.Items.AddChild( ip1,
CapFirst( iResFileName ) + iResFileShortExtension + ' ' + string
( FResourceExtractor.FriendlyTypes[ i ] ) + ' ' + iShortExtension + ' ' + IntToStr( j + 1 )
);
for k := 0 to FResourceExtractor.GroupCountFrames[ i, j ] - 1 do
begin
ip3 := TreeView1.Items.AddChildObject( ip2,
IntToStr( FResourceExtractor.GroupFrameWidth[ i, j, k ] ) + ' x ' + IntToStr
( FResourceExtractor.GroupFrameHeight[ i, j, k ] ) + ' ' + IntToStr
( FResourceExtractor.GroupFrameDepth[ i, j, k ] ) + '-bit',
FResourceExtractor.GetResourceBookmark( i, j, k ) );
iResBookmark := TIEResourceBookmark( ip3.Data );
iFileType := ioUnknown;
if ( FResourceExtractor.FriendlyTypes[ iResBookmark.TypeIndex ] = 'GroupIcon' ) or
( FResourceExtractor.FriendlyTypes[ iResBookmark.TypeIndex ] = 'Icon' ) then
iFileType := ioICO
else if ( FResourceExtractor.FriendlyTypes[ iResBookmark.TypeIndex ] = 'GroupCursor' ) or
( FResourceExtractor.FriendlyTypes[ iResBookmark.TypeIndex ] = 'Cursor' ) then
iFileType := ioCUR
else if ( FResourceExtractor.FriendlyTypes[ iResBookmark.TypeIndex ] = 'Bitmap' ) then
iFileType := ioBMP
else if ( FResourceExtractor.FriendlyTypes[ iResBookmark.TypeIndex ] = 'PNG' ) then
iFileType := ioPNG
else if ( FResourceExtractor.FriendlyTypes[ iResBookmark.TypeIndex ] = 'IMAGE' ) then
iFileType := ioBMP;
iResIsImage := ( iFileType = ioICO ) or ( iFileType = ioCUR ) or ( iFileType = ioBMP ) or
( iFileType = ioPNG );
if iResIsImage then
begin
iExtension := IEFileTypeToExtension( iFileType );
iFilePath := IncludeTrailingPathDelimiter( iFolder ) + JustName( FFilePath )
+ '_' + RemoveDotFromExtension( iFileExtension ) + '_' + IntToStr( i ) + iExtension;
end
else
ImageEnView1.Clear;
ImageEnView1.Update;
end;
end
else
begin
iFileType := ioUnknown;
if ( FResourceExtractor.FriendlyTypes[ i ] = 'GroupIcon' ) or
( FResourceExtractor.FriendlyTypes[ i ] = 'Icon' ) then
iFileType := ioICO
else if ( FResourceExtractor.FriendlyTypes[ i ] = 'GroupCursor' ) or
( FResourceExtractor.FriendlyTypes[ i ] = 'Cursor' ) then
iFileType := ioCUR
else if ( FResourceExtractor.FriendlyTypes[ i ] = 'Bitmap' ) then
iFileType := ioBMP
else if ( FResourceExtractor.FriendlyTypes[ i ] = 'PNG' ) then
iFileType := ioPNG
else if ( FResourceExtractor.FriendlyTypes[ i ] = 'Image' ) then
iFileType := ioBMP;
iResFileName := JustName( iResFilePath ) + iShortExtension;
iResIsImage := ( iFileType = ioICO ) or ( iFileType = ioCUR ) or ( iFileType = ioBMP ) or
( iFileType = ioPNG );
if iResIsImage then
begin
TreeView1.Items.AddChildObject( ip1,
CapFirst( iResFileName ) + iResFileShortExtension + ' ' + string
( FResourceExtractor.FriendlyTypes[ i ] ) + ' ' + IntToStr( j + 1 ),
FResourceExtractor.GetResourceBookmark( i, j ) );
end;
end;
end;
end;
finally
ImageEnView1.UnLockPaint;
end;
finally
Screen.Cursor := crDefault;
end;
finally
TreeView1.Items.EndUpdate;
end;
end
else
begin
StatusBar1.Panels[ 2 ].Text := '';
StatusBar1.Panels[ 3 ].Text := 'Resources: 0';
StatusBar1.Panels[ 4 ].Text := '';
StatusBar1.Panels[ 5 ].Text := '';
StatusBar1.Panels[ 6 ].Text := '';
end;
end;
end;
procedure TFormResExtractor.ShellListView1ColumnClick( Sender: TObject; Column: TListColumn );
// Respond to ShellListViewcolumn click - requires modified shellctrls.pas located in the application folder
begin
ShellListSortColumn := Column.Index;
ShellListSortAscending := not ShellListSortAscending;
ShellListView1.FolderList.Sort( ShellCompare );
ShellListView1.Invalidate;
end;
procedure TFormResExtractor.ShellListView1KeyDown( Sender: TObject; var Key: Word; Shift: TShiftState );
// Respond to Shelllistview keydown
var
iResFilePath: string;
iResFileName: string;
iResFileExtension: string;
iNumImages: integer;
iTotalRes: integer;
iNumberOfBitmaps: integer;
iNumberOfPNG: integer;
iNumberOfGroupIcons: integer;
iNumberOfIcons: integer;
iNumberOfGroupCursors: integer;
iNumberOfCursors: integer;
iHasExtractableImages: boolean;
begin
if Assigned( ShellListView1.Selected ) then
begin
iResFilePath := ShellListView1.SelectedFolder.PathName;
iResFileName := ExtractFilename( iResFilePath );
iResFileExtension := LowerCase( ExtractFileExt( iResFileName ) );
// Is the selected file a resource file
if IsFileAResource( iResFilePath ) then
begin
iTotalRes := NumberOfResourcesInRes( iResFilePath );
iNumImages := NumberOfImagesInRes( iResFilePath );
iNumberOfBitmaps := NumberOfBitmapsInRes( iResFilePath );
iNumberOfPNG := NumberOfPNGInRes( iResFilePath );
iNumberOfGroupIcons := NumberOfGroupIconsInRes( iResFilePath );
iNumberOfIcons := NumberOfIconsInRes( iResFilePath );
iNumberOfGroupCursors := NumberOfGroupCursorsInRes( iResFilePath );
iNumberOfCursors := NumberOfCursorsInRes( iResFilePath );
FileName1.Caption := 'Filename: ' + iResFilePath;
FileSize1.Caption := 'Filesize: ' + FormatByteSize( FileSize( iResFilePath ) );
NoResources1.Caption := 'Resources: ' + IntegerToString( iTotalRes );
NoImages1.Caption := 'Images: ' + IntegerToString( iNumImages );
NoBitmaps1.Caption := 'Bitmaps: ' + IntegerToString( iNumberOfBitmaps );
NoPNG1.Caption := 'PNG: ' + IntegerToString( iNumberOfPNG );
NoGroupIcons1.Caption := 'Group Icons: ' + IntegerToString( iNumberOfGroupIcons );
NoIcons1.Caption := 'Icons: ' + IntegerToString( iNumberOfIcons );
NoGroupCursors1.Caption := 'Group Cursors: ' + IntegerToString( iNumberOfGroupCursors );
NoCursors1.Caption := 'Cursors: ' + IntegerToString( iNumberOfCursors );
StatusBar1.Panels[ 2 ].Text := FormatByteSize( FileSize( iResFilePath ) );
StatusBar1.Panels[ 3 ].Text := 'Resources: ' + IntegerToString( iTotalRes );
StatusBar1.Panels[ 4 ].Text := 'Images: ' + IntegerToString( iNumImages );
StatusBar1.Panels[ 5 ].Text := 'GroupIcons: ' + IntegerToString( iNumberOfGroupIcons );
StatusBar1.Panels[ 6 ].Text := 'Icons: ' + IntegerToString( iNumberOfIcons );
iHasExtractableImages := NumberOfExtractableImagesInRes( iResFilePath ) > 0;
SaveImageAs1.Enabled := iHasExtractableImages;
SaveAllImages1.Enabled := iHasExtractableImages;
SaveAs1.Enabled := iHasExtractableImages;
ExtractAll1.Enabled := iHasExtractableImages;
SaveGroupIcons1.Enabled := iNumberOfGroupIcons > 0;
SaveAllGroupIcons1.Enabled := iNumberOfGroupIcons > 0;
end;
end;
end;
procedure TFormResExtractor.ShellListView1MouseDown( Sender: TObject; Button: TMouseButton; Shift: TShiftState;
X, Y: integer );
// Respond to shelllistview mousedown
var
iResFilePath: string;
iResFileName: string;
iResFileExtension: string;
iNumImages: integer;
iTotalRes: integer;
iNumberOfBitmaps: integer;
iNumberOfPNG: integer;
iNumberOfGroupIcons: integer;
iNumberOfIcons: integer;
iNumberOfGroupCursors: integer;
iNumberOfCursors: integer;
iHasExtractableImages: boolean;
begin
if Assigned( ShellListView1.Selected ) then
begin
iResFilePath := ShellListView1.SelectedFolder.PathName;
iResFileName := ExtractFilename( iResFilePath );
iResFileExtension := LowerCase( ExtractFileExt( iResFileName ) );
// Is the selected file a resource file
if IsFileAResource( iResFilePath ) then
begin
iTotalRes := NumberOfResourcesInRes( iResFilePath );
iNumImages := NumberOfImagesInRes( iResFilePath );
iNumberOfBitmaps := NumberOfBitmapsInRes( iResFilePath );
iNumberOfPNG := NumberOfPNGInRes( iResFilePath );
iNumberOfGroupIcons := NumberOfGroupIconsInRes( iResFilePath );
iNumberOfIcons := NumberOfIconsInRes( iResFilePath );
iNumberOfGroupCursors := NumberOfGroupCursorsInRes( iResFilePath );
iNumberOfCursors := NumberOfCursorsInRes( iResFilePath );
FileName1.Caption := 'Filename: ' + iResFilePath;
FileSize1.Caption := 'Filesize: ' + FormatByteSize( FileSize( iResFilePath ) );
NoResources1.Caption := 'Resources: ' + IntegerToString( iTotalRes );
NoImages1.Caption := 'Images: ' + IntegerToString( iNumImages );
NoBitmaps1.Caption := 'Bitmaps: ' + IntegerToString( iNumberOfBitmaps );
NoPNG1.Caption := 'PNG: ' + IntegerToString( iNumberOfPNG );
NoGroupIcons1.Caption := 'Group Icons: ' + IntegerToString( iNumberOfGroupIcons );
NoIcons1.Caption := 'Icons: ' + IntegerToString( iNumberOfIcons );
NoGroupCursors1.Caption := 'Group Cursors: ' + IntegerToString( iNumberOfGroupCursors );
NoCursors1.Caption := 'Cursors: ' + IntegerToString( iNumberOfCursors );
StatusBar1.Panels[ 2 ].Text := FormatByteSize( FileSize( iResFilePath ) );
StatusBar1.Panels[ 3 ].Text := 'Resources: ' + IntegerToString( iTotalRes );
StatusBar1.Panels[ 4 ].Text := 'Images: ' + IntegerToString( iNumImages );
StatusBar1.Panels[ 5 ].Text := 'GroupIcons: ' + IntegerToString( iNumberOfGroupIcons );
StatusBar1.Panels[ 6 ].Text := 'Icons: ' + IntegerToString( iNumberOfIcons );
iHasExtractableImages := NumberOfExtractableImagesInRes( iResFilePath ) > 0;
SaveImageAs1.Enabled := iHasExtractableImages;
SaveAllImages1.Enabled := iHasExtractableImages;
SaveAs1.Enabled := iHasExtractableImages;
ExtractAll1.Enabled := iHasExtractableImages;
SaveGroupIcons1.Enabled := iNumberOfGroupIcons > 0;
SaveAllGroupIcons1.Enabled := iNumberOfGroupIcons > 0;
end;
end;
end;
procedure TFormResExtractor.ShellTreeView1Change( Sender: TObject; Node: TTreeNode );
// Respond to shelltreeview change
var
iPath: string;
begin
if Assigned( ShellTreeView1.Selected ) then
begin
iPath := ShellTreeView1.SelectedFolder.PathName;
FStartupFolder := iPath;
Caption := 'Resource Extractor- ' + iPath;
StatusBar1.Panels[ 0 ].Text := FileCtrl.MinimizeName( iPath, Canvas, 150 );
end;
end;
procedure TFormResExtractor.SmallIcon1Click( Sender: TObject );
// Set the shelllistview viewstyle to smallicon
begin
ShellListView1.ViewStyle := vsSmallIcon;
end;
end.