3825 lines
121 KiB
Plaintext
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.
|