Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Create ico from bmps using c/c++

935 views
Skip to first unread message

Eltee

unread,
Dec 29, 2004, 12:58:13 PM12/29/04
to
Hi everybody,

Here's the layout: I have a series of bmp images (already in memory, stored in
mem buffers read directly, byte-after-byte, from disk). I'd like to know how to
put them all into an ico file programmatically, using C or C++ and win32 api
(I'd prefer a non-VisualC++ solution, MinGW if possible). Are there some
examples already doing that "out there"? Could somebody direct me to them or
give me some guidelines so that I can try writing them mysef, please? For
starters, I'd settle for one bmp per icon, too. Any help will be greatly
appreciated.

Thanks.

James Brown

unread,
Dec 29, 2004, 2:23:33 PM12/29/04
to
Look at the sourcecode download to:

www.catch22.net/tuts/sysimg.asp

The project includes C sourcecode to a "SaveIcon" routine,
which demonstrates how to store bitmaps into an .ico file..

James
---
www.catch22.net
Free win32 software, sourcecode and tutorials
-----
Please de-spam my email address before replying.
"Eltee" <el...@hotmail.com> wrote in message
news:33g9hjF...@individual.net...

Eltee

unread,
Dec 30, 2004, 4:15:45 AM12/30/04
to
James Brown wrote:
> Look at the sourcecode download to:
>
> www.catch22.net/tuts/sysimg.asp
>
> The project includes C sourcecode to a "SaveIcon" routine,
> which demonstrates how to store bitmaps into an .ico file..
>
> James

Thanks, James. I'm having a bit of a problem with your site, though. It's
unusually slow. The browser keeps receiving something (there's no timeout) but
nothing seems to come through. Ping works fine, though.

There's a workaround, however: I used Google's cached pages to view the contents
at the address you mentioned and I could download the zip file (sysimg.zip).

I think your http server is serving static content OK, but it has problems
contacting your application server (asp-specific, dynamically generated code).
Perhaps you're in the process of maintaining. If not, you should do something
about it, restart the whole thing maybe.

Had a first look at the SaveIcon.c. I'll have to convert my bmp buffers to
BITMAP's first. Do you happen to have that code, too? That'd be great.

One more thing: your code (t.i. your code convention) looks fantastic!

James Brown

unread,
Dec 30, 2004, 5:46:35 AM12/30/04
to
"Eltee" <el...@hotmail.com> wrote in message
news:33hv9vF...@individual.net...

OK thanks for the heads-up about the server, I use a webspace provider to
host the site so probably their servers were running a little slow..seems ok
to me
now but I'll keep my eye on it..

you shouldn't have to convert your bitmap buffers to the BITMAP structures -
these structures are just "information" structures which describe what the
bitmaps
look like, how many colours etc, the real bitmap data is obtained using the
GetBitmapBits API..

hope you find it useful..
Cheers,

Eltee

unread,
Jan 3, 2005, 8:36:17 AM1/3/05
to
James Brown wrote:
> hope you find it useful..

I can't seem to make it work. Whatever I do, there's just one image / icon
(available) in a saved ico file. The data for all the images is clearly written
in the file (filesize is considerable) but the system only recognizses the first
one. Here's what I've tried:

/*
Included stdio.h, windows.h and
all your functions from SaveIcon.c.
*/

int main() {
int i = 0;

int iconIndex = -1;
HICON hIcon = ExtractIcon(0, "shell32.dll", iconIndex);
int iconCount = (int)hIcon;
printf("Number of icons in shell32.dll: %d\n", iconCount);

HICON hIcons[iconCount];
for(i = 0; i < iconCount; i++)
hIcons[i] = ExtractIcon(0, "shell32.dll", i);

char* iconFilename = "many.ico";
BOOL ok = SaveIcon(iconFilename, hIcons, iconCount);
if(!ok)
printf("Saving failed\n");

iconIndex = -1;
hIcon = ExtractIcon(0, "many.ico", iconIndex);
iconCount = (int)hIcon;
printf("Number of icons in many.ico: %d\n", iconCount);

iconFilename = (char*)malloc(255);
for(i = 0; i < iconCount; i++) {
sprintf(iconFilename, "one_%d.ico\0", i);

HICON hIcons1[1];
hIcons1[0] = ExtractIcon(0, "many.ico", i);
ok = SaveIcon(iconFilename, hIcons1, 1);
if(!ok)
printf("Saving failed");
}
free(iconFilename);
}

When I compile and run this (assuming there's a shell32.dll in a current
directory), the output is:

Number of icons in shell32.dll: 238
Number of icons in many.ico: 1

The many.ico is 994 KB, and one_0.ico 4.18 KB.

What am I doing wrong?

Tim Robinson

unread,
Jan 4, 2005, 3:55:20 PM1/4/05
to
Eltee wrote:
[...]

> When I compile and run this (assuming there's a shell32.dll in a current
> directory), the output is:
>
> Number of icons in shell32.dll: 238
> Number of icons in many.ico: 1
>
> The many.ico is 994 KB, and one_0.ico 4.18 KB.
>
> What am I doing wrong?

Nothing -- the code is right. A .ICO file can only hold one icon,
although that icon can have an arbitrary number of images at different
resolutions and colour depths. A .DLL file can have any number of icons,
and again each one can contain multiple images.

ExtractIcon will pick the image closest to your display settings. To
load a particular image from your .ICO file, use LoadImage, though I
don't know what LoadImage will do given an icon containing more than one
image with the same resolution and colour depth.

--
Tim Robinson (MVP, Windows SDK)
http://mobius.sourceforge.net/

Edd

unread,
Jan 4, 2005, 8:47:02 PM1/4/05
to
Tim Robinson wrote:
> Eltee wrote:
> [...]
>
>> When I compile and run this (assuming there's a shell32.dll in a
>> current directory), the output is:
>>
>> Number of icons in shell32.dll: 238
>> Number of icons in many.ico: 1
>>
>> The many.ico is 994 KB, and one_0.ico 4.18 KB.
>>
>> What am I doing wrong?
>
>
> Nothing -- the code is right. A .ICO file can only hold one icon,
> although that icon can have an arbitrary number of images at different
> resolutions and colour depths. A .DLL file can have any number of icons,
> and again each one can contain multiple images.

Heh, I remember being told the exact same thing by you a few months back!

> ExtractIcon will pick the image closest to your display settings. To
> load a particular image from your .ICO file, use LoadImage, though I
> don't know what LoadImage will do given an icon containing more than one
> image with the same resolution and colour depth.
>

My experiments at the time also showed that if a given ICO file
contained more than 10 versions of the icon, Windows (2K pro) didn't
care to look at it i.e. the icon wouldn't display in Explorer. Can you
verify this, while we're on the subject?

Incidentally, if the OP is interested, I made a program a while back to
convert PPM images into ICO files with all kinds of crazy features.
Perhaps it might be useful in some way?
http://www.nunswithguns.net/ppm2ico.html
If you're interested in the source (ANSI/ISO C), drop me a line and I'll
gladly send it your way.

Edd

--
Edd Dawson www.nunswithguns.net | "Arthur! My moustache is
To email me, cut the crap. | touching my brain!"
e...@nunswithcrapguns.net | - The Tick

Eltee

unread,
Jan 5, 2005, 4:10:02 AM1/5/05
to
Tim Robinson wrote:
> Eltee wrote:
> [...]
>
>> When I compile and run this (assuming there's a shell32.dll in a
>> current directory), the output is:
>>
>> Number of icons in shell32.dll: 238
>> Number of icons in many.ico: 1
>>
>> The many.ico is 994 KB, and one_0.ico 4.18 KB.
>>
>> What am I doing wrong?
>
>
> Nothing -- the code is right. A .ICO file can only hold one icon,

Right. I meant images, bitmaps, bmps, whatever you want to call them. An ico
file can contain many of them. If it's structured properly. The one that
SaveIcon generates, either isn't or I don't know how to use it (the function)
properly.

> although that icon can have an arbitrary number of images at different
> resolutions and colour depths. A .DLL file can have any number of icons,
> and again each one can contain multiple images.
>
> ExtractIcon will pick the image closest to your display settings. To
> load a particular image from your .ICO file, use LoadImage, though I
> don't know what LoadImage will do given an icon containing more than one
> image with the same resolution and colour depth.

I'll look into that, thanks.

This whole icon / bitmap business is proving to be very complicated. If you look
at the .bmp (or .ico) format, Sheesh!, that's "innovation" for you. I mean,
those "conversions"
1. Given an .ico, extract (and save to disk) the contained .bmp(s).
2. Given a series of .bmp(s), put them into an .ico on disk.
should be trivial, right? Wrong. Does one really have to be a MS certified
something to do that?

Eltee

unread,
Jan 5, 2005, 4:49:05 AM1/5/05
to

Thanks for the offer, Edd. But I'm affraid that would present another problem: I
don't know anything about PPM format and I'd have to modify your code so that
it could be used with bmps. Bmps are a scary thing, I don't want to mess with
them more than I have to. I thought making conversions between header info
(BITMAPFILEHEADER, BITMAPINFOHEADER, ICOHEADER, ICODIR) would do the trick, but
I don't even seem to know how to do that. Messing with the bit data (quads,
masks, etc.) is even more tricky. Especially if you "allow" compressed stuff.

BTW: is there a BMP for dummies or ICO for dummies anywhere on the Internet? I
sure could use both of them.

Bob Hairgrove

unread,
Jan 5, 2005, 7:39:55 AM1/5/05
to
On Wed, 05 Jan 2005 10:49:05 +0100, Eltee <el...@hotmail.com> wrote:

[snip]

>BTW: is there a BMP for dummies or ICO for dummies anywhere on the Internet? I
>sure could use both of them.

That would interest me, too. Did you try looking at the docs under
http://www.wotsit.org ?? Lots of other formats are also described
there.

--
Bob Hairgrove
NoSpam...@Home.com

Eltee

unread,
Jan 5, 2005, 9:02:51 AM1/5/05
to

Good site. I found some useful (at first glance) docs for bmp and ico format(s).
I'll have to take a deeper look, though. Cheers!

Edd

unread,
Jan 5, 2005, 9:46:56 PM1/5/05
to

Thats fine. PPM is the lowest common denominator raster format. Looks
like this for e.g. a 1024*768 24 bit image:

P6 255 1024 768 [1024*768*3 RGB ordered triples of bytes]

Bmps are a scary thing, I
> don't want to mess with them more than I have to. I thought making
> conversions between header info (BITMAPFILEHEADER, BITMAPINFOHEADER,
> ICOHEADER, ICODIR) would do the trick, but I don't even seem to know how
> to do that. Messing with the bit data (quads, masks, etc.) is even more
> tricky. Especially if you "allow" compressed stuff.
>
> BTW: is there a BMP for dummies or ICO for dummies anywhere on the
> Internet? I sure could use both of them.

Funny you should say that! http://www.nunswithguns.net/format_spec_ico.html

Hope it helps.

The descriptions of the BMP file format on wotsit.org are pretty good
(though not 100% accurate). I seem to remember Daubnet (try google) has
a BMP description too, though again not 100% accurate. Using both of
them, though, you can figure out which bits are correct. Fun for all the
family :)

Edd

unread,
Jan 5, 2005, 9:57:31 PM1/5/05
to
Eltee wrote:
> Tim Robinson wrote:
>
>> Eltee wrote:
>> [...]
>>
>>> When I compile and run this (assuming there's a shell32.dll in a
>>> current directory), the output is:
>>>
>>> Number of icons in shell32.dll: 238
>>> Number of icons in many.ico: 1
>>>
>>> The many.ico is 994 KB, and one_0.ico 4.18 KB.
>>>
>>> What am I doing wrong?
>>
>>
>>
>> Nothing -- the code is right. A .ICO file can only hold one icon,
>
>
> Right. I meant images, bitmaps, bmps, whatever you want to call them. An
> ico file can contain many of them. If it's structured properly. The one
> that SaveIcon generates, either isn't or I don't know how to use it (the
> function) properly.

To clarify what Tim said: An ICO file can hold many rasters, but each on
is supposed to be a different representation of the _SAME_ image.
Usually each raster in an ICO file has a different size colour-depth or
colour depth. Windows picks the most appropriate one automatically. Even
if you try to 'browse' your ico file, only one icon will show up.

You can test this by making an icon containing two completely different
rasters, but one with 256 colours and the other with 16. If you then
change your windows display settings between the two colour depths,
you'll be able to see both icons, but not simultaneously.

DLLs and EXEs are different in that they can contain many icons, each
with a selection of rasters (afaik).

Anyway, I believe that's why your program says that your files only
contain a single icon; they do, but that icon has many representations
for different displays.

Hope that helps. For more information on the format, see the link I
posted else-thread.

Edd

Eltee

unread,
Jan 6, 2005, 3:14:53 AM1/6/05
to

Thanks, Edd. That looks promising. Thanks for clarifying the ico raster "thing"
in the other post, too.

Eltee

unread,
Jan 7, 2005, 3:34:31 AM1/7/05
to
Eltee wrote:
> Tim Robinson wrote:
>
>> Eltee wrote:
>> [...]
>>
>>> When I compile and run this (assuming there's a shell32.dll in a
>>> current directory), the output is:
>>>
>>> Number of icons in shell32.dll: 238
>>> Number of icons in many.ico: 1
>>>
>>> The many.ico is 994 KB, and one_0.ico 4.18 KB.
>>>
>>> What am I doing wrong?
>>
>>
>>
>> Nothing -- the code is right. A .ICO file can only hold one icon,
>
>
> Right. I meant images, bitmaps, bmps, whatever you want to call them. An
> ico file can contain many of them. If it's structured properly. The one
> that SaveIcon generates, either isn't or I don't know how to use it (the
> function) properly.

It turns out, actually, that SaveIcon saves the icon perfectly (and I know how
to use it, too). It's just that ExtractIcon always returns 1 when called on an
ico file with -1 as an icon index, regardless of how many variants of an image
the ico contains. Hm. :-|

Tim Robinson

unread,
Jan 7, 2005, 2:42:07 PM1/7/05
to
Eltee wrote:
>>> Nothing -- the code is right. A .ICO file can only hold one icon,
>>
>>
>>
>> Right. I meant images, bitmaps, bmps, whatever you want to call them.
>> An ico file can contain many of them. If it's structured properly. The
>> one that SaveIcon generates, either isn't or I don't know how to use
>> it (the function) properly.
>
>
> It turns out, actually, that SaveIcon saves the icon perfectly (and I
> know how to use it, too). It's just that ExtractIcon always returns 1
> when called on an ico file with -1 as an icon index, regardless of how
> many variants of an image the ico contains. Hm. :-|

And that's the right behaviour. ExtractIcon returns the number of icons
the file contains, not the number of images. A .ICO file contains
exactly one icon, by definition. If you want to look at the different
image variants within the file, you'll need to load and parse the .ICO
file manually.

Eltee

unread,
Jan 10, 2005, 3:03:07 AM1/10/05
to
Tim Robinson wrote:
> Eltee wrote:
>
>>>> Nothing -- the code is right. A .ICO file can only hold one icon,
>>>
>>>
>>>
>>>
>>> Right. I meant images, bitmaps, bmps, whatever you want to call them.
>>> An ico file can contain many of them. If it's structured properly.
>>> The one that SaveIcon generates, either isn't or I don't know how to
>>> use it (the function) properly.
>>
>>
>>
>> It turns out, actually, that SaveIcon saves the icon perfectly (and I
>> know how to use it, too). It's just that ExtractIcon always returns 1
>> when called on an ico file with -1 as an icon index, regardless of how
>> many variants of an image the ico contains. Hm. :-|
>
>
> And that's the right behaviour.

Yes, I know. Now. ;-) It's just me doing the RTFM when another "idea" was
already anchored deep inside my mind.

0 new messages