Displaying icon in picturebox control

Error when trying to show a file from a dll (ex: shell32.dll)

Page 1 of 1

8 Replies - 16088 Views - Last Post: 24 August 2008 - 03:53 AM Rate Topic: -----

#1 Iouri  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 11
  • Joined: 09-August 08

Displaying icon in picturebox control

Post icon  Posted 09 August 2008 - 05:09 PM

Hello everybody!

I've started to program in C# not so long time ago, and I'm currently just learning the language by creating small applications.
So far I could find my answers on the net, but I really need help with this one. :)


The program I'm writing is called Icon Changer, it goes into the needed extension key in the registry and modifies "DefaultIcon" to the needed icon.

I'm stuck at the point where I have 3 pictureboxes, a 16x16 one, a 32x32 one, and a 48x48 one, earlier today I found a code which I use to display the "Current Extension Icon" in the 2 small pictureboxes (the icon gets bad quality in 48x48, any help with that too?).

But! When I get to DefaultIcon values like "C:/Windows/System32/shell32.dll, 44", my application crashes.
I've searched around the net and found something about ExtractIcon but I couldn't really understand it well.

Screenshots:
Posted Image
Posted Image






		private const int SHGFI_ICON = 0x100;
		private const int SHGFI_SMALLICON = 0x1;
		private const int SHGFI_LARGEICON = 0x0;
		public struct SHFILEINFO
		{
			public IntPtr hIcon;
			public int iIcon;
			public uint dwAttributes;
			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
			public string szDisplayName;
			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
			public string szTypeName;
		};
		[DllImport("Shell32.dll")]
		public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, int cbFileInfo, uint uFlags);

 

			IntPtr hImgSmall;
			IntPtr hImgLarge;
			IntPtr hImgHuge;
			SHFILEINFO shinfo = new SHFILEINFO();
			string FileName = txtbifp.Text;
			System.Drawing.Icon xIcon;
			hImgSmall = SHGetFileInfo(FileName, 0, ref shinfo, Marshal.SizeOf(shinfo), SHGFI_ICON | SHGFI_SMALLICON);
			xIcon = System.Drawing.Icon.FromHandle(shinfo.hIcon);
			pbCurrentIcon16x16.Image = xIcon.ToBitmap();
			hImgLarge = SHGetFileInfo(FileName, 0, ref shinfo, Marshal.SizeOf(shinfo), SHGFI_ICON | SHGFI_LARGEICON);
			xIcon = System.Drawing.Icon.FromHandle(shinfo.hIcon);
			pbCurrentIcon32x32.Image = xIcon.ToBitmap();
			//hImgHuge = SHGetFileInfo(FileName, 0, ref shinfo, Marshal.SizeOf(shinfo), SHGFI_ICON | SHGFI_LARGEICON);
			//xIcon = System.Drawing.Icon.FromHandle(shinfo.hIcon);
			//pbCurrentIcon48x48.Image = xIcon.ToBitmap();

This post has been edited by Iouri: 09 August 2008 - 05:46 PM


Is This A Good Question/Topic? 0
  • +

Replies To: Displaying icon in picturebox control

#2 Martyr2  Icon User is offline

  • Programming Theoretician
  • member icon

Reputation: 4361
  • View blog
  • Posts: 12,180
  • Joined: 18-April 07

Re: Displaying icon in picturebox control

Posted 09 August 2008 - 07:50 PM

So to get this straight, it works on all values up to 44 and then when it gets to 44 of shell32.dll it crashes? If that is the case, it is probably because you are ending up with a null pointer because it can't find a shell32 icon with that index. I have applied a program called Reshacker to shell32.dll and see that once you get around 44 it goes into some not so default looking icons. Perhaps that is the problem.

Because if your code extracts up to 44 just fine, I see no reason why it shouldn't extract above 44 if they exist. Your error is also suggesting that the value retrieved in your SHFILEINFO structure for hIcon is turning out to be a null pointer and thus causing the exception.

Do you run into this crash with any other file that has icons in the low index number range? Like does it ever fail on a value in less than 15 on user32.dll? Then if it doesn't fail, try it on a value like 45 of user32.dll and see if it fails. If it then fails then that is what is happening is that you are running into a bad pointer.

:)
Was This Post Helpful? 0
  • +
  • -

#3 Iouri  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 11
  • Joined: 09-August 08

Re: Displaying icon in picturebox control

Posted 09 August 2008 - 08:01 PM

Hello! Thanks for your reply. :)

As I said, I'm only begging to program in C#, my application crashes when It load ANY files that has an Index. My question is how to display an icon from a dll into a picturebox. :) Even if I get the path C:/gg.exe,0 it crashes.
Was This Post Helpful? 0
  • +
  • -

#4 Martyr2  Icon User is offline

  • Programming Theoretician
  • member icon

Reputation: 4361
  • View blog
  • Posts: 12,180
  • Joined: 18-April 07

Re: Displaying icon in picturebox control

Posted 09 August 2008 - 10:41 PM

Oh ok, well then here you go...

    public partial class Form1 : Form
    {
        // Here is our hookup to the Shell32's ExtractIconEx function
        [DllImport("Shell32", CharSet = CharSet.Auto)]
        private static extern int ExtractIconEx(
            string lpszFile,
            int nIconIndex,
            IntPtr[] phIconLarge,
            IntPtr[] phIconSmall,
            int nIcons);

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // Check to see how many icons there are
            int m_nIcons = ExtractIconEx("C:\\WINDOWS\\system32\\SHELL32.dLL",-1,null,null,0);

            // If we have more than 0, lets extract
            if (m_nIcons >= 0)
            {
                // Array of pointers to large and small images
                IntPtr[] m_pIconsLarge = new IntPtr[m_nIcons];
                IntPtr[] m_pIconsSmall = new IntPtr[m_nIcons];

                // Lets extract image with index 1
                ExtractIconEx("C:\\WINDOWS\\system32\\SHELL32.dLL", 1, m_pIconsLarge, m_pIconsSmall, (int)m_nIcons);

                // Lets setup an icon object to the large version of the extracted icon
                // Then finally set that to the picturebox
                System.Drawing.Icon MyIcon = System.Drawing.Icon.FromHandle(m_pIconsLarge[0]);
                pictureBox1.Image = MyIcon.ToBitmap();
            }
        }



As you can see above we are putting in the signature for the winapi ExtractIconEx function, we then call it to see if there are any icons in shell32.dll, if there are, extract the first one and put it into the picturebox.

Remember to include System.Runtime.InteropServices at the top. Also where you see the path to the DLL, you can change it to any file path as long as it is exe, dll etc.

You can read more on it at the following address...

pinvoke.net ExtractIconEx (shell32.dll)

Enjoy!

"At DIC we be icon extracting code ninjas... we also extract the ladies from their homes when we lay down the kick ass code." :snap:
Was This Post Helpful? 1
  • +
  • -

#5 Iouri  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 11
  • Joined: 09-August 08

Re: Displaying icon in picturebox control

Posted 10 August 2008 - 06:32 AM

Wow! I cant believe I find what I've been searching for, thanks a million man! :)

My program works PERFECTLY now!

		void geticonv1(){
			bool ff = txtbifp.Text.Contains(",");
			if (ff == true)
			{
				string MainString = txtbifp.Text;
				string[] Split = MainString.Split(new Char[] { ',' });
				txtbifp.Text.Replace(@"\", @"\\");
				int m_nIcons = ExtractIconEx(Split[0], Convert.ToInt32(Split[1]), null, null, 0);
				if (m_nIcons >= 0)
				{
					IntPtr[] m_pIconsLarge = new IntPtr[m_nIcons];
					IntPtr[] m_pIconsSmall = new IntPtr[m_nIcons];
					ExtractIconEx(Split[0], Convert.ToInt32(Split[1]), m_pIconsLarge, m_pIconsSmall, (int)m_nIcons);
					System.Drawing.Icon MyIcon32x32 = System.Drawing.Icon.FromHandle(m_pIconsLarge[0]);
					pbCurrentIcon32x32.Image = MyIcon32x32.ToBitmap();
					System.Drawing.Icon MyIconx16x16 = System.Drawing.Icon.FromHandle(m_pIconsSmall[0]);
					pbCurrentIcon16x16.Image = MyIconx16x16.ToBitmap();
				}

			}
			else{
				IntPtr hImgSmall;
				IntPtr hImgLarge;
				SHFILEINFO shinfo = new SHFILEINFO();
				string FileName = txtbifp.Text;
				System.Drawing.Icon xIcon;
				hImgSmall = SHGetFileInfo(FileName, 0, ref shinfo, Marshal.SizeOf(shinfo), SHGFI_ICON | SHGFI_SMALLICON);
				xIcon = System.Drawing.Icon.FromHandle(shinfo.hIcon);
				pbCurrentIcon16x16.Image = xIcon.ToBitmap();
				hImgLarge = SHGetFileInfo(FileName, 0, ref shinfo, Marshal.SizeOf(shinfo), SHGFI_ICON | SHGFI_LARGEICON);
				xIcon = System.Drawing.Icon.FromHandle(shinfo.hIcon);
				pbCurrentIcon32x32.Image = xIcon.ToBitmap();}



Just one question, how do I get a high quality image in 48x48 size? :)


PS: Oh, just noticed that the application will give an error if the file path is like C:\Icons\Vista,Xp,winme\xxx.ico
It will split the Lines between VIsta, XP and then WinME...

This post has been edited by Iouri: 10 August 2008 - 06:34 AM

Was This Post Helpful? 0
  • +
  • -

#6 Iouri  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 11
  • Joined: 09-August 08

Re: Displaying icon in picturebox control

Posted 15 August 2008 - 07:19 AM

Anyone? :)
Was This Post Helpful? 0
  • +
  • -

#7 zakary  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 27
  • View blog
  • Posts: 427
  • Joined: 15-February 05

Re: Displaying icon in picturebox control

Posted 15 August 2008 - 08:04 AM

you are not splitting the string correctly

//if txtbifp.Text = C:\Icons\Vista,Xp,winme\xxx.ico
string MainString = txtbifp.Text;
string[] Split = MainString.Split(new Char[] { ',' });
txtbifp.Text.Replace(@"\", @"\\");
// Split[0] will = C:\Icons\Vista the winme\xxx.ico will be missing
int m_nIcons = ExtractIconEx(Split[0], Convert.ToInt32(Split[1]), null, null, 0);


Was This Post Helpful? 0
  • +
  • -

#8 Iouri  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 11
  • Joined: 09-August 08

Re: Displaying icon in picturebox control

Posted 15 August 2008 - 09:53 AM

Hello and thanks for your reply :)

But I've already fixed that bug:

					string IFP = txtbifp.Text;
					string[] Split = IFP.Split(new Char[] { ',' });
					txtbifp.Text.Replace(@"\", @"\\");
					int SA = Convert.ToInt32(Split.Length.ToString()); int SE = SA - 1; string SX;
					SX = txtbifp.Text.Replace("," + Split[SE], null);
					int m_nIcons = ExtractIconEx(SX, Convert.ToInt32(Split[SE]), null, null, 0);


Its just about the 48x48 HR icon :)
Was This Post Helpful? 0
  • +
  • -

#9 Iouri  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 11
  • Joined: 09-August 08

Re: Displaying icon in picturebox control

Posted 24 August 2008 - 03:53 AM

Well, to not to start another topic, I would like to ask another question...
How can I extract Strings from a .dll file? Example: There is a value in registry which points to "@%SystemRoot%\system32\shell32.dll,-22915", this is a string, but I don't know how to "extract" it from there, any ideas? :)

The 48x48 icon thingy - I haven't solved that one yet.. :)

Thanks
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1