ExtractIconExW

This is the forum for miscellaneous technical/programming questions.

Moderator: 2ffat

Post Reply
theLizard
BCBJ Master
BCBJ Master
Posts: 457
Joined: Wed Mar 18, 2009 2:14 pm

ExtractIconExW

Post by theLizard »

What am I doing wrong!

I am using the following code ( for working out how to go about it ) to extract icons from files (exe / dll) and getting Access violation errors.

I have had success but the successes were random, by this I mean that if I opened the same file more than once it would work the first time then hang the second attempt to open with a TFileOpen dialog window.

On the second attempt, TFileOpen->Execute() did not produce a file open window.

I have searched and searched for sample code that was more than what I have but no luck.

I have no trouble using ExtractAssociatedIcon and adding to ListView.

I have tried all types of variations without luck,

Code: Select all

	UINT ico_count;
	UINT nIcons;
	UnicodeString lpszFile;
	int nIconIndex = -1;
	HICON * phiconLarge;
	HICON * phiconSmall;
	HICON icon;
	TIcon *ico;

	TListItem *item;

	lpszFile = fileName;
	ico_count = ExtractIconExW(lpszFile.w_str(), nIconIndex, phiconLarge, phiconSmall, nIcons);
	ico = new TIcon();
	ico->Height = 32;
	ico->Width = 32;

 if(phiconSmall > 0)
	{
	for(int i = 0; i < ico_count; i++)
		{
		icon = phiconSmall[i];
		ico->Handle = icon;
		ImageList->AddIcon(ico);
		item = lv->Items->Add();
		item->ImageIndex = ImageList->Count -1;
		}
	}

	for(int j = 0; j < ico_count; j++)
		DestroyIcon(phiconSmall[j]);

	delete ico;

TIA..
HsiaLin
BCBJ Master
BCBJ Master
Posts: 343
Joined: Sun Jul 08, 2007 6:29 pm

Re: ExtractIconExW

Post by HsiaLin »

This is the way i used it a while ago, im typing this from memory so it may
need tweaking:

Code: Select all

   HICON I;
   long Index = 0;
   long Limit = 0;

   if(OpenDialog1->Execute())
   {
      Limit = (long)ExtractIcon(HInstance, OpenDialog1->FileName.c_str(), -1);
      if(Limit < 1)
      {
         ShowMessage("No icons!");
         return 0;
      }

      I = ExtractIcon(HInstance, OpenDialog1->FileName.c_str(), Index);
      if((int)I > 1)
      {
         Image1->Picture->Icon->Handle = I;
      }
   }
}
User avatar
minas
BCBJ Guru
BCBJ Guru
Posts: 199
Joined: Sat Jul 10, 2004 6:09 am
Location: Greece

Re: ExtractIconExW

Post by minas »

ico_count = ExtractIconExW(lpszFile.w_str(), nIconIndex, phiconLarge, phiconSmall, nIcons);
to get the number of icons call ExtractIconExW with
nIconIndex=-1
phiconLarge=NULL
phiconSmall= NULL

Code: Select all

ico_count = ExtractIconExW(lpszFile.w_str(), -1,NULL,NULL, nIcons);
then allocate memory for the icons' handles array

Code: Select all

if (ico_count>0){
      phiconSmall= new HICON[ico_count];
      // in one shot you get in phiconSmall the small Icons Handles
      // num is the number of successfully extracted 
      int num = ExtractIconExW(lpszFile.w_str(),0, NULL, phiconSmall, ico_count);
      for(int i = 0; i < num; i++)
      {
          icon = phiconSmall[i];
          ico->Handle = icon;
          ImageList->AddIcon(ico);
          item = lv->Items->Add();
          item->ImageIndex =i;
         }
         
         for(int j = 0; j < num; j++)
                 DestroyIcon(phiconSmall[j]);

          if (phiconSmall!=NULL)
            delete[] phiconSmall;
      }
       delete ico;      
}
Last edited by minas on Mon Apr 18, 2016 1:08 pm, edited 1 time in total.
theLizard
BCBJ Master
BCBJ Master
Posts: 457
Joined: Wed Mar 18, 2009 2:14 pm

Re: ExtractIconExW

Post by theLizard »

Thanks minas and HsiaLin very much appreciated.

Appears that the only thing I did not try in my earlier attempts was to allocate memory for the handles, which, of course now makes sense that it needed to be done.

Cheers.
rlebeau
BCBJ Author
BCBJ Author
Posts: 1759
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA
Contact:

Re: ExtractIconExW

Post by rlebeau »

minas wrote: to get the number of icons call ExtractIconExW with
nIconIndex=-1
phiconLarge=NULL
phiconSmall= NULL
FWIW, this is documented behavior on MSDN:

ExtractIconEx function
nIconIndex [in]
Type: int

The zero-based index of the first icon to extract. For example, if this value is zero, the function extracts the first icon in the specified file.

If this value is –1 and phiconLarge and phiconSmall are both NULL, the function returns the total number of icons in the specified file. If the file is an executable file or DLL, the return value is the number of RT_GROUP_ICON resources. If the file is an .ico file, the return value is 1.

If this value is a negative number and either phiconLarge or phiconSmall is not NULL, the function begins by extracting the icon whose resource identifier is equal to the absolute value of nIconIndex. For example, use -3 to extract the icon whose resource identifier is 3.
When something is not working right for you, try reading the documentation :wink:
Remy Lebeau (TeamB)
Lebeau Software
theLizard
BCBJ Master
BCBJ Master
Posts: 457
Joined: Wed Mar 18, 2009 2:14 pm

Re: ExtractIconExW

Post by theLizard »

rlebeau wrote:When something is not working right for you, try reading the documentation :wink:
Prior to posting, I read the article in the link you posted and a number of others I found and only after spending some time getting random results using various approaches did I post for some assistance.

minas pointed out that memory needed to be allocated, the one thing I did not try (not seeing the forest for the trees, so to speak) once memory was allocated, I got the result I was after so, all is well now.

But while you are here, is there an easy way to get all the sizes of icons contained in a file, dll, exe etc... so that I can load any size image into a TListView

Cheers
rlebeau
BCBJ Author
BCBJ Author
Posts: 1759
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA
Contact:

Re: ExtractIconExW

Post by rlebeau »

theLizard wrote: But while you are here, is there an easy way to get all the sizes of icons contained in a file, dll, exe etc... so that I can load any size image into a TListView
There is no single Win32 API function for that particular purpose. You would have to enumerate an executable's resources to discover its available icon resources, and then manually parse the raw resource data to get the particular icon details, like size dimensions.

Find out number of icons in an icon resource using Win32 API
Remy Lebeau (TeamB)
Lebeau Software
HsiaLin
BCBJ Master
BCBJ Master
Posts: 343
Joined: Sun Jul 08, 2007 6:29 pm

Re: ExtractIconExW

Post by HsiaLin »

This simple demo shows how to scroll thru all the icons in a dll/exe file.
Attachments
IconBandit.zip
Icon Extractor
(10.83 KiB) Downloaded 1276 times
Post Reply