Click here to Skip to main content
12,693,891 members (32,814 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as

Stats

10.8K views
4 bookmarked
Posted

Extracting A Particular Icon From an .ICO Resource

, 26 Jan 2011 CPOL
Rate this:
Please Sign up or sign in to vote.
Extracting A Particular Icon From an .ICO Resource
I have a number of third party controls in my application. Some of them support 32bpp icons and some don't. So, wanting it to look as good as it is able to, I thought I'd used 32bpp icons where I could, but include lower bit depths in the icon file for use where they weren't supported. All I'd need is a way to extract a particular icon from my icon resource. Simple, eh?

Well, depleting my Google-fu quite considerably, told me no, it isn't simple. It is in fact, absurdly complicated. Nevertheless, after a few hours of trial-and-error, I came up with a function that gave me what I needed:

//------------------------------------------------------------------------------
HICON LoadResourceIcon(UINT nResID, BYTE nWidth, BYTE nHeight, SHORT nBitDepth)
//------------------------------------------------------------------------------
{
    HICON hIconRet = NULL;

    #pragma pack(2)
        struct IcoMemEntry          // This is what an icon resource looks like in memory
        {
            byte Width;             // Width, in pixels, of the image
            byte Height;            // Height, in pixels, of the image
            byte ColorCount;        // Number of colors in image(0 if >=8bpp)
            byte Reserved;          // Reserved (must be 0)
            short Planes;           // Color Planes
            short BitCount;         // Bits per pixel
            int BytesInRes;         // How many bytes in this resource?
            short ID;               // Where in the file is this image?
        };

        struct IcoHeader
        {
            short Reserved;         // Reserved (must be 0)
            short Type;             // 1 = Icon, 0 = Bitmap
            short Count;            // number of icons
            IcoMemEntry Entries;    // address place holder
        };
    #pragma pack()

    // Find the start of the icon resource in memory
    HMODULE hModule = AfxGetInstanceHandle();
    HRSRC hRes = ::FindResource(hModule, MAKEINTRESOURCE(nResID), RT_GROUP_ICON);
    HGLOBAL hGlobal = ::LoadResource(hModule, hRes);
    IcoHeader* pHead = (IcoHeader*)::LockResource(hGlobal);

    if (pHead->Count != 0)
    {
        // Get the hicon headers so we can examine them
        IcoMemEntry* pEntries = NULL;
        pEntries = new IcoMemEntry[pHead->Count];

        IcoMemEntry* pEntry = &(pHead->Entries);
        CopyMemory(pEntries, pEntry, sizeof(IcoMemEntry) * pHead->Count);

        for (int i = 0; i < pHead->Count; i++)
        {
            // If an icon matches our criteria, extract it
            if (pEntries[i].Width == nWidth && pEntries[i].Height == nHeight &&
                pEntries[i].BitCount == nBitDepth)
            {
                HRSRC hIconInfo = ::FindResource(hModule, MAKEINTRESOURCE(pEntry[i].ID),
                                                 MAKEINTRESOURCE(RT_ICON));
                HGLOBAL hIconRes = ::LoadResource(hModule, hIconInfo);
                BYTE* dibBits = (BYTE*)::LockResource(hIconRes);
                long szLength = ::SizeofResource(hModule, hIconInfo);

                hIconRet = CreateIconFromResourceEx((PBYTE) dibBits, szLength, TRUE, 0x00030000,
                                                    nWidth, nHeight, LR_DEFAULTCOLOR);
                ::DestroyIcon((HICON)dibBits);
                break;
            }
        }

        // Clean up
        if (pEntries != NULL)
        {
            delete[] pEntries;
        }
    }

    ::DestroyIcon((HICON)pHead);

    return hIconRet;
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Kyudos
Software Developer
New Zealand New Zealand
No Biography provided

You may also be interested in...

Pro

Comments and Discussions

 
QuestionA better of way to extract an icon from an executable file Pin
dc_200022hrs 51mins ago
memberdc_200022hrs 51mins ago 
GeneralUse Visual Studio to extract resources Pin
Harold Bamford16-Mar-10 13:00
memberHarold Bamford16-Mar-10 13:00 
GeneralRe: Use Visual Studio to extract resources Pin
codevisio15-Oct-10 4:24
membercodevisio15-Oct-10 4:24 
GeneralRe: Use Visual Studio to extract resources Pin
Harold Bamford18-Oct-10 6:43
memberHarold Bamford18-Oct-10 6:43 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170118.1 | Last Updated 26 Jan 2011
Article Copyright 2010 by Kyudos
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid