Welcome to Dream.In.Code
Getting C# Help is Easy!

Join 136,451 C# Programmers for FREE! Get instant access to thousands of C# experts, tutorials, code snippets, and more! There are 2,038 people online right now. Registration is fast and FREE... Join Now!




Displaying icon in picturebox control

 
Reply to this topicStart new topic

Displaying icon in picturebox control, Error when trying to show a file from a dll (ex: shell32.dll)

Iouri
9 Aug, 2008 - 04:09 PM
Post #1

New D.I.C Head
*

Joined: 9 Aug, 2008
Posts: 10


My Contributions
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. smile.gif


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:
IPB Image
IPB Image






CODE
        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);

CODE


            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: 9 Aug, 2008 - 04:46 PM
User is offlineProfile CardPM
+Quote Post

Martyr2
RE: Displaying Icon In Picturebox Control
9 Aug, 2008 - 06:50 PM
Post #2

Programming Theoretician
Group Icon

Joined: 18 Apr, 2007
Posts: 5,209



Thanked: 214 times
Expert In: C/C++, Java, VB, VB.NET, C#, PHP, Web Development, HTML & CSS, Javascript

My Contributions
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.

smile.gif
User is online!Profile CardPM
+Quote Post

Iouri
RE: Displaying Icon In Picturebox Control
9 Aug, 2008 - 07:01 PM
Post #3

New D.I.C Head
*

Joined: 9 Aug, 2008
Posts: 10


My Contributions
Hello! Thanks for your reply. smile.gif

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. smile.gif Even if I get the path C:/gg.exe,0 it crashes.
User is offlineProfile CardPM
+Quote Post

Martyr2
RE: Displaying Icon In Picturebox Control
9 Aug, 2008 - 09:41 PM
Post #4

Programming Theoretician
Group Icon

Joined: 18 Apr, 2007
Posts: 5,209



Thanked: 214 times
Expert In: C/C++, Java, VB, VB.NET, C#, PHP, Web Development, HTML & CSS, Javascript

My Contributions
Oh ok, well then here you go...

csharp

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." decap.gif
User is online!Profile CardPM
+Quote Post

Iouri
RE: Displaying Icon In Picturebox Control
10 Aug, 2008 - 05:32 AM
Post #5

New D.I.C Head
*

Joined: 9 Aug, 2008
Posts: 10


My Contributions
Wow! I cant believe I find what I've been searching for, thanks a million man! smile.gif

My program works PERFECTLY now!

CODE
        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? smile.gif


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 Aug, 2008 - 05:34 AM
User is offlineProfile CardPM
+Quote Post

Iouri
RE: Displaying Icon In Picturebox Control
15 Aug, 2008 - 06:19 AM
Post #6

New D.I.C Head
*

Joined: 9 Aug, 2008
Posts: 10


My Contributions
Anyone? smile.gif
User is offlineProfile CardPM
+Quote Post

zakary
RE: Displaying Icon In Picturebox Control
15 Aug, 2008 - 07:04 AM
Post #7

D.I.C Regular
Group Icon

Joined: 15 Feb, 2005
Posts: 405



Thanked: 6 times
Dream Kudos: 175
My Contributions
you are not splitting the string correctly

csharp

//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);




User is offlineProfile CardPM
+Quote Post

Iouri
RE: Displaying Icon In Picturebox Control
15 Aug, 2008 - 08:53 AM
Post #8

New D.I.C Head
*

Joined: 9 Aug, 2008
Posts: 10


My Contributions
Hello and thanks for your reply smile.gif

But I've already fixed that bug:

CODE
                    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 smile.gif
User is offlineProfile CardPM
+Quote Post

Iouri
RE: Displaying Icon In Picturebox Control
24 Aug, 2008 - 02:53 AM
Post #9

New D.I.C Head
*

Joined: 9 Aug, 2008
Posts: 10


My Contributions
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? smile.gif

The 48x48 icon thingy - I haven't solved that one yet.. smile.gif

Thanks
User is offlineProfile CardPM
+Quote Post

Fast ReplyReply to this topicStart new topic
Time is now: 12/2/08 03:06PM

Live C# Help!

C# Tutorials

Reference Sheets

C# Snippets

DIC Chatroom

Bye Bye Ads

Monthly Drawing

Thumb Drive

Top Contributors

Top 10 Kudos This Month