# VBForums CodeBank > CodeBank - Visual Basic 6 and earlier >  [VB6] Icon Resource Organizer

## LaVolpe

*Edited: Retired.* An updated version, completely rewritten can be found here


Jump to bottom of this post for date/time of last update and the update.

Thought I'd share this code. The project allows you to create or modify an existing icon file.  Icons & cursors can be imported from file, including animated cursors, bitmaps, jpgs, pngs, gifs, wmf/emfs, tifs and binaries like exe, dll, and ocx.  Once loaded, the icons can be sorted or rearranged, individual ones can be deleted.  Regarding import of bitmaps/jpgs/gifs/tifs/wmfs/emfs... Auto palettizing is in play. If image can be reduced to 8, 4 or 1 bit bitmaps, it will be done. If the source bitmap file is already paletted, no change.  PNGs are not scrutinzed. Image sizes > 256 pixels in height or width will not be permitted.

Unicode is supported for file names and resource names. A lot of array manipulations and will run faster when compiled.

Many icon resources contain multiple images at varying sizes and bit depths.  VB can use 99% of the icon files out there as long as a 4 or 8 bit, non-PNG icon, exists at the front of the file.  So, simply by rearranging the icon order, you can use icon files that VB previously complained about not being a valid picture. Doesn't mean you can use those nice alpha-blended ones though. However, you can use them via APIs as sample code below shows.

The code is well commented and has a ton of icon handling routines that may be a good learning tool if you ever want to manage icons at such a low level.

Bonus material follows. Ever want to display a nice 32bit alphablended icon in your form's titlebar but VB won't allow it as the form's Icon property?  If so, do it with APIs.  Applies to XP and above.


```
Private Declare Function LoadImage Lib "user32.dll" Alias "LoadImageA" (ByVal hInst As Long, ByVal lpsz As String, ByVal un1 As Long, ByVal n1 As Long, ByVal n2 As Long, ByVal un2 As Long) As Long
Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByRef lParam As Any) As Long
Private Const WM_SETICON As Long = &H80
Private Const ICON_SMALL As Long = 0
Private Const IMAGE_ICON As Long = 1
Private Const LR_DEFAULTSIZE As Long = &H40
Private Const LR_LOADFROMFILE As Long = &H10

Private Sub Command1_Click()
    Dim hIcon As Long
    ' replace FileName below with a valid icon path/filename
    hIcon = LoadImage(0&, FileName, IMAGE_ICON, 0&, 0&, LR_DEFAULTSIZE Or LR_LOADFROMFILE)
    If hIcon Then
        SendMessage Me.hWnd, WM_SETICON, ICON_SMALL, ByVal hIcon
    End If
End Sub
```

Bouns #2. Well, what if you want to load that icon directly from memory without needing a file?  Add the icon to a resource file and extract the bytes. You will have to use Custom resource because we need the bytes, not an icon handle.


```
Private Declare Function CreateIconFromResourceEx Lib "user32.dll" (presbits As Any, dwResSize As Any, ByVal fIcon As Long, ByVal dwVer As Long, ByVal cxDesired As Long, ByVal cyDesired As Long, ByVal Flags As Long) As Long
Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByRef lParam As Any) As Long
Private Const WM_SETICON As Long = &H80
Private Const ICON_SMALL As Long = 0
Private Const ICRESVER As Long = &H30000
Private Const LR_DEFAULTSIZE As Long = &H40

Private Sub Command1_Click()
    Dim hIcon As Long, bData() As Byte
    Dim dwOffset As Long, dwSize As Long
    Dim Index As Long
    
    ' since an icon file can contain multiple icons...
    Index = 0 ' set index to which icon in the custom resource you want
    ' 0=1st icon, and if multiple icons: 1=2nd icon, 2=3rd icon, etc
    
    ' using VarPtr vs CopyMemory. Modified 1st 2 params of API to accept params "As Any"
    bData() = LoadResData(101, "Custom")        ' extract icon(s) from res file
    dwSize = VarPtr(bData(16& * Index + 14&))   ' get size of icon resource
    dwOffset = VarPtr(bData(bData(16& * Index + 18&))) ' get offset into the array
    ' create the icon & assign it to your form
    hIcon = CreateIconFromResourceEx(ByVal dwOffset, ByVal dwSize, 1, ICRESVER, 0&, 0&, LR_DEFAULTSIZE)
    If hIcon Then
        SendMessage Me.hWnd, WM_SETICON, ICON_SMALL, ByVal hIcon
    End If
End Sub
```

*TIP*: The above sample code will load PNGs embedded into icon files as a valid hIcon also if run on Vista and later only.

*Edited*: 13 Oct 10 12:50 AM GMT/Zulu
:: Would not parse multi-sets of animated cursors contained in single cursor file (Win7). Fixed. See posts 15 & 17 below
:: Done modifying this project for enhancements. Will update due to bugs only
3 Mar 10
Bug fixes and one enhancement (as long as I found a bug)
:: Save routine did not release mapped file handle; caused some issues when saving and then adding more images afterwards, in same session. Fixed
:: BitmapToIcon routine could corrupt image data in some cases. Fixed
:: Enhancement: Imported PNGs are now loaded in both PNG & 32bpp icon format.
1 Jan 10
Included more image formats and minor corrections
:: Can now accept animated gifs and transparent gifs. GDI+ required
:: Can now accept TIFFs. GDI+ required
:: Can now accept WMF/EMFs. GDI+ required
:: Can now accept animated cursors
:: Vista/Win7 PNG-to-icon display used vs GDI+ for those operating systems
:: Binary resource extraction was ignoring PNGs again; fixed.
30 Dec 09
:: By-selection deletion was not using sorted index which led to deletion of wrong images in some cases
:: When appending images in some cases, the previously loaded images would be cleared from the cache.
:: LavaSoft's adaware.exe has some unknown/custom resources as RT_CURSORS which caused app to abort loading. Reworked the DLL/binary extraction routine to firm up recognition of properly formatted resources.
:: Added option to extract icons/cursors, icons only, cursors only from binarires.
28 Dec 09
:: Added ability to select multiple files, per request
:: Reworked project to use disk file vs memory for caching images
:: Added option to create transparent cursors along with transparent icons
24 Dec 09
:: Didn't like the way I controlled the vertical scrollbar in multiview. Better implementation now
:: For some reason, GetWindowTextLengthW could return zero when it shouldn't. Used a simpler method instead.
23 Dec 09 
:: Fixed obstacle noted in reply #2 below
:: Added some additional right click functionality for the mulitview
22 Dec 09
:: In some scenarios it was possible that icons were being forced to be saved with .cur extensions
:: CreateWindowExW was being called for non-unicode O/S. Copy/paste oversight on my part - fixed
:: Oops, broke the multiview selection when I last updated. Fixed again.
21 Dec 09
:: Updated zip to fix minor logic error that can occur when reading cursors/icons from executables.
:: Hmmm, found a 256x256 32bit non-PNG icon in exe file & parser didn't like; now it does.
:: Included a secondary graphical view of the icon resources.

----------


## LaVolpe

A note about extracting icons from executables. Most, if not all, exe and ocx files can be used for icon/cursor extraction, assuming they have something to extract.  DLLs may be iffy in some cases.  Let's say you are using WinXP and you want to load the shell32.dll icons from Win2000.  The routines use LoadLibrary API to map the DLL into memory and then perform resource search/extraction.  Well, odds are you already have XP's Shell32 loaded in your process space and trying to load an earlier version of the same DLL will fail.

I will experiment with the use of LoadLibraryEx and some of its optional flags.  If it works, I will update the project appropriately.  Will post the result either way after some testing.

*Edited*: By using the LOAD_LIBRARY_AS_DATAFILE with LoadLibraryEx, I was able to get around the obstacle noted above. The zip in post #1 has been modified.

----------


## edhanz

this is what i'm looking for..
all my custom icon (from bitmap) have watermark in it because i use commercial demo sofware..  :Big Grin: 

thank you, and will tell you if i find problem..

----------


## VBClassicRocks

Excellent tool.  Two thoughts:
1) Allow multiple file selection.
2) Don't raise an error when the user cancels the fileopen dialog.

----------


## LaVolpe

> Excellent tool.  Two thoughts:
> 1) Allow multiple file selection.
> 2) Don't raise an error when the user cancels the fileopen dialog.


Thank you.  Replies to your comments:

1) I thought about it and should incorporate that.  What I want to prevent is allowing multiple selections that would cause an extemely large amount of icons/cursors to be cached.  As is, Vista's Shell32 has 2000 icons, XP's has 1400 icons.  If someone tried to multiselect, I don't know, maybe 200 resources, the number of icons cached could potentially reach 10k+.  I haven't coded the project for such abuse.  Maybe I'll add that functionality with a limit of how many files can be multi-selected, let's say 20 for example.

Edited: A better solution would be to store the cached icons to a temporary file vs in memory.  This should allow such abuse to be handled, but would cause a small performance hit when displaying icons and retrieving icon properties from the file.  Thinking...

Update: Reworked to use temporary cache file vs memory. Source files are actually processed much faster because need to resize large arrays is no longer an issue.  Any performance hit in retrieving data is not noticeable.

2) The issue with the error raising you may be receiving is due to your VB settings.  If you have error trapping option to "Break in Class Modules", change it to "Break on Unhandled Errors".  That error is required in order to mimic common dialog's CancelError property.  VB stopping on that error applies only to IDE not if project is compiled.

----------


## LaVolpe

> ... Allow multiple file selection.


Done. Zip in first post has been updated.

*Edited*: Included more image formats for importing:
- Animated cursors
- Animated/Transparent GIFs and single/multi-page TIFFs if GDI+ exists on the system

----------


## Smadav

Excellent Code, Many Thanks !!  :Thumb: 

I'm planning to use it in Smadav to do a heuristic icon detector for viruses that use social-engineering icon (e.g. Fake Folder Icon, Fake Word Icon, etc.).  :Wink:

----------


## coolcurrent4u

Thanks for the code

if i were to get the list of api available at least in xp, and their usage, and some examples, somthing like allapi.net api software (which is incomplete and lacks most functions and constants, it also does no allow u find constants values), where do i start?

----------


## LaVolpe

> Thanks for the code
> 
> if i were to get the list of api available at least in xp, and their usage, and some examples, somthing like allapi.net api software (which is incomplete and lacks most functions and constants, it also does no allow u find constants values), where do i start?


The API Viewer here is really good.  It is far more complete than allapi.net, but does not have examples.  On that site, you can also download GDI+ database of APIs, enumerations, constants.

----------


## LaVolpe

Enhanced for the following reason.  If one imported a PNG, the app would happily store it as a PNG inside an icon structure.  That is fine, but only Vista and above O/S will read the icon.  XP and below won't.  So, as long as GDI+ exists on the system, the PNG will be read and parsed into a 32bpp alphablended icon or bit reduced if possible so that it will be an icon that XP and below could read.  Note that XP and above are only O/S that support 32bpp alphablended icons.

Also two bugs were fixed. Bug description and update history at post #1, along with the updated zip file.

----------


## coolcurrent4u

Hello Lavolpe,

is it possible to extract the different images from an icon file in vb6, modify it (maybe using photoshop like me) and then combine them together again!

----------


## LaVolpe

Very possible. 

1) The project will let you save/extract individual icons, though it will be saved as an icon file/format. If photoshop will allow you to use icons, then you are good to go. 
2) Once you have the images tweaked from photoshop, the project above will allow you to select most image formats and will convert to icon. You can select multiple images and combine them

The project's "Icon File Append" menu is what to use to add multiple individual files. The project's "Save Selected" or "Save All" is what you'd use to save the loaded images to icon format.  Remember, max size of any single icon is 256x256

----------


## coolcurrent4u

Hello Lavolpe,

At what color depth does you tool package the icons, is it possible to alter the color depth?

----------


## LaVolpe

> Hello Lavolpe,
> 
> At what color depth does you tool package the icons, is it possible to alter the color depth?


If you are importing a non-icon/cursor, bit depth is automatically applied, if color count in image = 256 or less. Exception are PNGs. No color reduction is applied to those.  Other than that, you'll need to add your own color reduction routines.

----------


## petersen

Good code.

Just for info.  Code needs some modification if to allow a Windows 7 ANI file which contains more than one animated cursors, e.g. one for 32x32 and another 48x48.  Currently the code would fail to load any of them.

----------


## LaVolpe

> Good code.
> 
> Just for info.  Code needs some modification if to allow a Windows 7 ANI file which contains more than one animated cursors, e.g. one for 32x32 and another 48x48.  Currently the code would fail to load any of them.


Would you mind posting one that it fails to load? It may be a parsing issue in the ParseAnimatedCursor routine. I can take a look-see.

----------


## petersen

Sure, the zip contains 2 such ANI files, each with 32x32 and 48x48 ANI groups.  Instead of "1", .idCount entry of each "icon" is "2".  Thus it should be easy to loop through each BIH to extract individual cursors.  However, if one is to extract a group (making it a single-group ANI), one has to alter the values after "RIFF" and "LIST" as well.

----------


## LaVolpe

Thank you. Will take a look in a day or two. May need to update my AlphaImage control I just posted as it may not parse those ani cursors correctly.

----------


## LaVolpe

Easier fix than it appears. I do have a logic error and have never encountered an animated cursor saving more than one in a single ICON RIFF block. Troubleshooting also pointed me to a small bug in my alpha image control.  Now to kill 2 birds with one stone.  Thanx.  Will update this project later tonight.

----------


## petersen

I would also like to run a test of your AlphaImage as mentioned above, would you please point me to the link to fetch it (when ready)?

----------


## LaVolpe

> I would also like to run a test of your AlphaImage as mentioned above, would you please point me to the link to fetch it (when ready)?


Project in post #1 above now fixed to correctly parse Win7 ani-cursors.
The link to the alpha image control provided. Note that I did not make patch in it yet. Need to rework a couple things for these animated cursors. Project not really designed for animation sets within animation file.

Thanx for bringing this shortcoming to my attention.

Let me ask you a question for clarification. When I parse those cursor files, I see 18 cursors total. 9 sets of 2, each set having a 32x and 48x sized icon. The same ani-cursor for Vista has 18 same sized cursors. What is the animation like for Win7. Does the ring rotate and pulsate? If so, looks kind of odd to me when I animated it with a 500ms timer. Many ani-cursors will have a sequence RIFF block so one can see the order of the cursors, but those you provided do not.  Maybe you didn't give me the entire file? Maybe 1/2 weren't provided, expecting 36 cursors vs just 18?

*Edited*: Ignore the above question. So little documentation on animated cursor RIFF format. It appears what is the number of icons/cursors is not. It is the number of icon/cursor RIFF blocks. So when parser saw 18, it assumed 18 cursors. Really, it meant 18 blocks, each block containing 2 cursors. Now I think I know how Win7 animates it. It simply uses system settings and picks the best-fit cursor from each block. Therefore, it doesn't matter if a block contained 1 or 10 cursors, each with different bit depths and/or sizes. The best-fit will be picked from each block.

----------


## petersen

I am not sure you are in the middle of doing the code, so I make a quick reply fo clarify the key points first:

(1) The ANI files in zip are definitely complete ones.  They come with Win 7.  (A customer sent them to me a few months ago when he could not access the 2nd group in an ANI file with my older version of program.)

(2) Yes there is little proper documentation on ANI, but there are variations in actual ANI coding, e.g. these Win 7 are an example.

If you like, I can send you a gadget program of mine which would let you (a) split each of the ANI files in the ZIP into 2 (so that each stands alone as a aingle-group ANI, one for 32x32 and one for 48x48, consisting of 18 frames in each); and (2) save any frame of any group in a loaded ANI file  (all individual images are shown on screen).   We can discuss any technical questions you might have, either here or if you prefer, in e-mail (often quicker and easier to clarify certain technical points).

Edit:  I can confirm that each ANI file does have 18 32x32 cursors and 18 48x48 cursors.

----------


## petersen

Not related to the current thread topic, but related to AlphaImage mentioned above.  I've downloaded AlphaImage zip. Because I can't readily run it (as it is for OCX), so I take a quick look at the code block concerning WMF/EMF.  There is a small point I wish to raise (before you wind up your revision of AlphaImage).

Please set your Windows to Large Font, i.e. 120 DPI, test a WMF/EMF to see whether the size you obtain (reported by your OCX) is the same as you would in a normal 96 DPI screen.  If not, you may wish to adjust the width and height downward by a factor of "96 / 120" whereas 120 is the actual screen resolution you would obtain from a Windows API call.

I raise this point because most people omit to address it in their code dealing with stdPicture size for WMF/EMF.

----------


## LaVolpe

> Please set your Windows to Large Font, i.e. 120 DPI, test a WMF/EMF to see whether the size you obtain (reported by your OCX) is the same as you would in a normal 96 DPI screen.  If not, you may wish to adjust the width and height downward by a factor of "96 / 120" whereas 120 is the actual screen resolution you would obtain from a Windows API call.
> 
> I raise this point because most people omit to address it in their code dealing with stdPicture size for WMF/EMF.


I'll look at it later, but don't expect any issues. WMF/EMF are not being processed as such. I know how to scale the metafile from its contained resolution parameters for the current DPI. But WMF/EMF do not work well in GDI+ when wanting to manipulate the image, i.e., can't grayscale metafiles with GDI+. So, internally, WMF/EMF are saved to PNG for display. GDI+ when saving metafile to another format, calculates the size in relation to DPI during the process.

----------


## petersen

Re: Downward size adjustment for WMF/EMF if Large Font -- it is the same whether you process WMF/EMF via GDI+  or not.  To see my point easily, load the usually seen "MVP" WMF/EMFfile to your stdPicture Render Usage (Load From File) in normal screen, double click the image,  the size of 429x378 would be reported (one or two pixel diff may arise due to himetric conversion).   However, in a Large Font screen, it would be reported as 537x473 -- because the adjustment factor not being applied.  Just a note for your reference.

----------


## LaVolpe

Regarding Metafiles and DPI.... Doesn't apply to this project because icons created from them force the metafile to be rendered at specific/static sizes. I did implement your suggestion in my updated alpha image control.

----------


## petersen

Your Icon Resource Organizer is actually an excellent code.  As such, I tend to play a bit more with it than I would normally do.

Point one (as a suggestion):

You might consider adding "Bonus #3" at the top of your posting:

If a WMF file is a legacy one without a "placeable" header, VB6 LoadPicture wouldn't be able to handle it (runtime error), but your code can.  (Remarks: I myself don't use GDI+ to load WMF/EMF except when I've detected such a WMF file).


Point two (as a question):

I believe you are well aware of it, and have no problem dealing with it, but why do you just leave 32-BMP out?  I mean the code would save a 32-BPP BMP as 24-BPP without honoring the alpha bytes in file.  I know GDI+ would just ignore values of the 4th bytes of BMP (despite bitmap is MS's baby), but we can manually process such a BMP file ourselves (thus able to save it as a 32-BPP icon).  Of course probably 32-BPP BMP is something only played about by VB6 guys.

----------


## LaVolpe

> ... I believe you are well aware of it, and have no problem dealing with it, but why do you just leave 32-BMP out?


Refresh my memory. What exactly are you referring to? Until you brought up those Win7 ani-cursors, I haven't looked at that code for about 6 months.

----------


## petersen

I should have made it clearer.  What I meant is that, I believe you are aware of possible existence of 32-BPP BMP files (among VB6 guys at least) and you have no problem of dealing it, but why do you just save a 32-BPP BMP to a 24-BPP icon (instead of a 32-BPP icon)?

----------


## LaVolpe

Oh, I gotcha.  Really, just a bit lazy 'cause they're not used that often. In other projects I wrote, I did include functionality for 32bpp bitmaps.  In this case, I just felt it just wasn't important enough. Bad on me.  There are some issues with 32bpp, some people are aware of & some not.  Here they are.

1. 32bpp comes in 3 flavors: RGB (alpha channel not used), RGBA, RGBpA (premultiplied against alpha)
2. I have routines that are good at scanning a 32bpp bmp and deciding which of the 3 above applies
3. It is not fool-proof. 
- A completely black bmp can be either 100&#37; opaque black RGB or 100% transparent RGBA/RGBpA
- If all RGB components are less-than or equal to the alpha component, toss up... Is it RGBA or RGBpA? (visual difference is noticable)
- And here's the worse one. When a DIB is created, it is not guaranteed to be clean. In other words, the memory allocated is not guaranteed to be zeroed out. From experience, I now use FillMemory when creating DIBs because of that. So when a dirty 32bpp RGB is passed, any processing routine checking the alpha channel will see they are used (some or most); even though the alpha is suppose to be ignored. VB does this to. Doing a screen capture and then Set myPic = Clipboard.GetData() can return a dirty 32bpp RGB bitmap within the stdPicture. 

With the above in mind and the rarity of these, I decided not to support them. However, the alpha image control does. But it makes some assumptions which are not truly fair in all cases:
1) 32bpp stdPicture objects are always considered RGB (no alpha)
2) All other 32bpp objects will be processed for RGB, RGBA or RGBpA
3) Should someone want 32bpp stdPicture processed with alpha channel, then they need to pass it by handle vs stdPicture object.
Though the above greatly reduces logic from picking the wrong format, it is still not fool-proof. And adding in a bunch of extra code so a user can do trial and error wasn't worth it IMO.

Long answer for such a short question, huh?   :Smilie:

----------


## petersen

To cut down the text, I summarize some points from my own view:

-- I use DIB on a daily basis for many years (starting from WinME time in order to be able to edit monster-size pic) in 1, 4, 8, 24 and 32 BPP.  I have never had any irregular experience about DIB (such as that you mentioned).  If you like to pursue what I say,  get a small project which would produce the "bad" DIB you have encountered, let me see whether I can address it for good.

-- Regarding detection of a genuine 32-BPP, I basically see if there is any 4th byte which value is > 0 and < 255.  If yes, it is deemed a genuine 32-BPP.  However, in the case of PNG, I would further see what ColorType it is, so that a "simple transparency" PNG wouldn't be taken as genuine 32-BPP.  That is basically all.

-- As GDI+ always produces image bytes in premultiplied form, therefore I have to have a subroutine of "UndoPremultiply" to restore those bytes to their original "raw" values [so that I can, e.g. save a GDI+ loaded 32 BPP (say) PNG to a 32-BPP (say) TIFF, avoiding a double "premultiply" situation.)

I can understand that sometimes for a "not so serousl" project, one tends to be a bit lax or lazy about it.  I myself often have that (and that often comes back to haunt me later on).

----------


## LaVolpe

Let me address a couple of your points.

1. Dirty DIBs. I have seen them, I have created them (or really Windows did), simply by calling CreateDIBSection. It happens, take my word for it.  For an example of a screenshot that produced a dirty DIB (contained in stdPicture), look at this post, replies 39-48.

2. GDI+ doesn't always "produce" RGBpA images, but it always draws them. One can get the original, un-molested bytes from the loaded PNG via the GdipBitmapLockBits function & requesting RGBA pixel format.  Actually that function should work for any RGBA loaded image. In fact, even if the image was loaded from a RGBpA DIB via GdipCreateBitmapFromScan0, you can still have GDI+ return RGBA pixels and let it do the un-multiply for you. Just FYI.

----------


## petersen

I will certainly follow up your two points: For "1", to satisfy curiosity and for "2" to acquire somethng new to me (although I have to call my subroutine "UndoPremultiply" still, because it is the "raw" image that I have to use, plus the alpha bytes kept, when I save to a 32-BPP file of other format).

Whist we are here, I have a question arising from a situation I encountered a little whiel ago.  I passed hDC of a DIB to a function wherein a stdPicture is obtained there .  I wanted to "Render" the image from the stdPicture to the DIB (per its hDC passed to the function), I failed to get the image from "Render" call.  (I tried to use Render just for the sake of trying, I used other means to get the work done).   Do you know whether the above-said failure is normal?

If I passed a PictureBox, then I got the image on it alright (by using the same Render).

----------


## LaVolpe

By Render, do you mean the .Render method of the stdPicture object? If so, I have never had it fail as long as the method's parameters were correctly formatted. See the "stdPicture Render Usage" linked in my signature. But P.S., I have seen it draw into the alpha channel & that I reproduced time and time again... getting back to dirty DIBs.

Now, I have experienced where an image is selected into some other DC. When I then tried to select it into my DC and BitBlt, failure. MSDN does mention quite often with its rendering functions that an image should not be selected into multiple DCs.

If none of the above apply, you may want to post it in the main forum so others can learn from the experience also. I'd be happy to respond. In the nearly 20 years of messing with DIBs, DDBs, DCs, etc., I've seen or heard a wealth of things.

----------


## petersen

For good order sake, I clear the following outstanding items on my part, again from my own view only:

--  Since I don't intend to use Render method of stdPicture, I would just drop this point.

--  I've looked at the posting(s) on "dirty DIB", I am not convinced.   As there are variations in the approach to creating a DIB, unless a clean example is obtained, I cannot just accept it on the face value. In my case, I often create 1 and 8-BPP ones, and for 24 and 32-BPP ones I always apply a brush of the wanted color to the background, I am not sure whether it is because of this that I have never had any irregularity in all cases and in all these years.

-- (For clarification) The reason I have to obtain the "raw" image (i.e. the 32-BPP image without "premultiply") is that I have to allow users to edit both (a) the image which must be before alpha effects; and (b) the alpha values, on two screens.  Users can of course inspect the image with alpha effects any time on a separate screen.  The "edit" includes applying new paints, brighten, add text, rotate and or resize, etc.  (Users can then save the edited/resized image and alpha values back to a 32-BPP file of their chosen format allowable).  

Please consider there is no any outstanding item from me at this point.

----------


## Chris001

Is it possible to automatically create an icon with different formats from one image?

What I mean is, is it possible to load a 350 x 350 image and convert it to a single icon with the following formats:

256x256 XP
256x256 True Color
128x128 XP
128x128 True Color
64x64 XP
64x64 True Color
48x48 XP
48x48 True Color
32x32 XP
32x32 True Color
24x24 XP
24x24 True Color
16x16 XP
16x16 True Color

(or just the XP icons is fine too)

----------


## LaVolpe

Yes, but you have to modify as needed.  I have no desire to modify it. You might want to search for a freebie out there called IconFX I believe. Many posts by RhinoBull and others reference it. It may do what you need.

Here's some notes:
1) Depending on your source size, scaling to 16 or 256 could result in poor quality
2) Adding 256x256 XP (alphablended 32bpp) and 24bpp (True Color) icons will create a very large icon file.
Here's the size required for just those 2 sized images (nearly 1/2 mb):
-- 32bpp 256x256: 270,336 bytes for data + 56 bytes for icon directory entry & bitmap headers
-- 24bpp 256x256: 204,800 bytes for data + 56 bytes for icon directory entry & bitmap headers
-- Ideally, you should also provide 16 color (4bpp) for compatibility with older operating systems. This is recommended by Microsoft

Tip: 256x256 icons are almost always in PNG format. Vista+ can load these, XP and below cannot.

----------


## si_the_geek

Very close, it is actually IcoFx:  http://icofx.ro/

..and it is extremely easy to use it to create multiple icon sizes etc from an initial 'large' picture, and edit them if needed (because automatic resizing is never perfect).  To make resizing more accurate I recommend starting with a file at the largest size you want (or at least the X and Y sizes each a power of 2).

----------


## petersen

I try to give you an answer from the technical angle, with a brief explanation.

First of all, there is a confusion in what you have given, e.g. you listed "256x256 XP" and "256x256 True Color". The listing should be "256x256 32-BPP" and "256x256 24-BPP", and so on. (".....XP" can be 32 BPP or 24 BPP, and both 32 BPP and 24 BPP can be termed as "True Color").

Technically speaking, the answer lies in what kind of image you supply. 

(1) If the source image is 24-BPP or below, and without a designated transparent color, the answer is no. Although Icon Resource Organizer can save them in ".ico" file format, with "image" and "mask" parts in the file, I am afraid this kind of ".ico" files does not give you any advantage (the "mask" is all black). Try to load a 32x32 24-BMP and save it to ".ico", then place the saved ".ico" to your desk, you wouldn't see any transparency (why do you want the new file format then).

(2) If the source image is 24-BPP or below, and with a designated transparent color, the answer should be yes (ideally some "alpha effects" should be created along the edges for the 32-BPP ones, the creation can be automated fairly easily).

What sizes and/or BPP to save is just a matter of resizing/optimizing  colors of the original source, hence wouldn't really matter (whether currently Icon Resource Organizer actually does it or not is not an issue here).

(3) If the source image is of genuine 32-BPP, it is suitable to save to a 32-BPP ".ico", of various sizes desired. One could also duly convert it to 24-BPP or below, but the resultant quality tends to be unacceptable, hence not advisable.

----------


## LaVolpe

Though Petersen's thoughts are right on.  A bit more: When both 32bpp and lower color depth icons are provided in the same icon file, you will find they are not the same images (at least with professional icons). This is because, as stated above, 32bpp varieties generally have alpha-blending (i.e., shadows, soft edges). You can't transfer that to 24bpp or lower without it looking shabby because 24bpp only supports 2 alpha values: on or off, via the mask: 32bpp offers 256 values within the data; though a mask is provided, it isn't used by XP & above except maybe at low monitor resolutions.

----------


## petersen

Re "3" of my earlier posting.  Even if it is a "straight" 32-BPP image, once converted to 24-BPP (or below), the original parts with "alpha effects" of which mostly along the edges of the image (so called "edge smoothing"),  which was originally intended to be blended in to whatever the background colors,  have now become fixed, i.e. bound to a color or colors present when one does the conversion.  Later on, when one places the resultant image against a background of different color(s), the said parts (edges) would appear "out of place".  Do one and try to use a Fill tool to fill the transparent parts with a different color in turn, one will see the ugly edges clearly then.

----------


## Chris001

Thanks for the information. I don't have much knowledge about 24bbp and 32bbp. Normally I use convertico.com to convert PNG images to ICO and it does a pretty good job. Depending on the size of the PNG it creates a 32bpp 256x256, 128x128, 64x64, 48x48, 32x32, 16x16 icon. I was just wondering if it could be done with VB6.

----------


## petersen

(1)  I have tested convertico.com with a 256x256 32-BPP PNG, and obtained a multi-icon file containing  32-BPP icons of assorted sizes as you said.  Not bad.  However, professionally speaking, there is a great defect that you might not be aware of -- the masks are all entirely black (see image below).  The icons merely reply on the alpha values to show the images (just like any other 32-BPP non-icon files,.e.g. 32-BPP TGA or 32-BPP TIFF, thus killing the "icon" sense).   In this connection, Icon Resource Organizer does the job properly on the other hand -- if you feed the same PNG, you get a proper icon file from it (mask properly done, see image below also), and I have not the least doubt that La Volpe can properly save the image to 32-BPP icons of any size if he bothers to.

I upload a zip file which contains the said PNG file, together with the resulting ICO file, in case you or other readers would like to examine it.

(2)  Please be rest assured that VB6 is fully capable of creating a full-featured Icon Editor (without using any extrinsic control or any third party library).  If you want to be fully convinced in this respect, just drop me a email and I will let you try out a professional Icon Editor which is created purely with VB6 (good on all Windows platforms from Win95 to Windows 7, 32 or 64-bit, and currently there are registered users in over 30 countries).

----------


## Chris001

I believe you that it can be done with VB6. I'm not sure how you check if the mask has been done properly, but below is an icon I created with Icon Resource Organizer. I took your PNG file and resized it to 128x128, 64x64, 48x48, 32x32, 16x16 with GIMP (freeware image editor) and then used Icon Resource Organizer to create a single icon.

----------


## petersen

I've verified that all icons in your file are done properly, e.g. the masks and the entries in the header.

You should be able to see the mask image on the edit screen of a reasonably good icon editor.  Why is the mask image to be presented on screen, as and when the user edits the image?  To visually facilitate the edit (to distinguish painted areas from transparent areas, and vice versa, if it happens a paint color being applied is the same as the "screen color" used by the program).  Painted areas are seen as black on mask, transparent parts white.

----------


## Chris001

Thank you for your help.

----------


## petersen

Freeware IcoFX had been mentioned in a couple of postings in this thread, so I've now tried it as well. Indeed, it is technically a proficient program (and I am impressed).   However, there is a particular arrangement which I feel strongly against, for reasons which I would try to explain.

In the Toolbox, along with the paint tools, there is an Opacity tool which is meant to set alpha values. It is the points arising therefrom that I want to talk about, as most readers of this forum might not understand the implications of using the said toolbox.

Under the said arrangement, e.g. to arrive at a desired degree of "redness" of a "red" color, the user can (a) select the wanted color and paint it over and/or (b) paint a red color of an arbitrary "redness", then apply an alpha value to adjust it.  If we use a mathematical expression, it is like: 100 - 20 = 80 whereas "100" denotes the color without alpha effect, "20" the alpha value and "80" the result. In this case, the image presented on the edit screen is the "80".  As long as we get "80", it doesn't matter how "100" and "20" are being varied between them -- such a concept is fallacious.

To cut down the description of the said fallacy, imagine you have a picture of a Japanese flag with a perfect round shape in "red" (symbolizing the Sun) and you are to edit the edges of the painted areas, in order to make the picture look smoother. So you begin to dither the colors at some spots, sometimes you use a paint tool, at other times the Opacity tool, until you are satisfied.  However, later on you might find that:

-- On a machine which does not have the capability of showing alpha effects, the picture now looks much worse than before (no longer all of "100" values, in some adjacent spots, some "100", then "50", then "80" and then "20", and so on.)

-- On another machine which is capable of showing the alpha effects, the picture now looks not the same good as you originally determined. This is because, you were only visually satisfied with the combination of the painted color and the background color existing at the time you did the edit, given the "opacity" (alpha) values you set. But the background colors are different now!

-- In either machine,  some ghost spots may appear. This is caused by your applying some "opacity" paints in some transparent areas, unintentionally (but have thus been made non-transparent by the program). 

Conclusion comment: A proper approach should be to edit alpha values in a separate screen, specifically geared for that purpose (i.e. to change the alpha values only, not the paint values themselves). This means in the paint edit screen, the undiluted colors, i.e. the "100" ones, should be presented, not the "80" ones.  Of course the user should be able to inspect the picture with alpha effects any time he/she wants, e.g. by holding down a button or by invoking another screen.

----------


## Stidor

Question;

With Windows 7 the taskbar icons by default are larger than the titlebar icon. Not sure of exact size, 32x32 or 48x48? Anyway is it possible for a VB6 form to show 1 icon in the titlebar and another in the taskbar?

I have your example code working fine for me, I have an icon with 16x16, 24x24 and 32x32 icons in it. However in my taskbar all I get is a stretched version of the 16x16 icon.

One possibility is my windows icon cache may need clearing, but just wanted to check if it's actually possible to do.

----------


## LaVolpe

Edited: An idea. The icon used when Alt+Tab is pressed is generally 48x48 ish. Maybe that is the icon being used in the taskbar. If so, here is a way to set that icon, example is on PSC.

And if the above workaround fails, try this. Use that same code for the ALT+TAB window and apply to your form's hWnd.
And if that doesn't work then... subclassing the form may be the only way. When the icon is requested, a message is sent WM_GETICON and asks for the handle of the large or small icon. VB may not create a large icon; therefore, it stretches the small icon to large when large icon is asked for. That's a guess. But with subclassing, then that message can be intercepted and a proper icon can be provided.

I don't own Win7, so I can't play.

----------


## petersen

Two minor points, as a matter of interest:

(1)  I created 2 simple images for my own thumbnail testing on WinME, both with a thin rectangle in red color painted on white background.  One image is bigger than the targeted thumbnail size, the other is smaller.  My testing shows that there is no way for me to StretchBlt the bigger image (in DIB) onto the thumbnail (in PictureBox) without some missing parts of the painted rectangle, with HalfTone or ColorOnColor. (As a result, I have to resort to using GDIplus in order to maintain the original image intact in the thumbnail.)

It just occurred to me to take a look of your Icon Resource Organizer -- to see how it would perform on Vista for the above-said bigger image.  Since the program wouldn't allow it due to its size, I then tried the smaller size one anyway.

Because Icon Resource Organizer showed most parts of the originally red rectangle as black, I thought you might want to take a look of it. The image is contained in the attached ZIP.

(2)  I also did a test of the Save function of Icon Resource Organizer,  on a Windows Shell32.dll file.  After loading the file, I selected "Sort By Original Resource" menu option.  I intended to highlight all the items pertaining to an Icon Group and save them to a single ICO file.  However, I found that I had difficulties to arrive at what I intended, because not all the said items are in adjacent places, neither on the list nor on the thumbnail screen.

To explain what I've said above, I am attaching two screenshots.

The top one is from my own gadget -- it shows Group 311 is the one I intended to save, comprising 15 items as listed on the right hand side.

The next one is from Icon Resource Organizer.  As can be seen, only 6 items belonging to the said Group are shown adjacent to each other.

I know this is not the fault of Icon Resource Organizer itself; I just want to bring out the point in existence, in case you are not aware of it.
.

----------


## LaVolpe

Petersen, I have no idea what you are saying or suggesting. 

I don't have Win7 and therefore don't have the shell32 for that system. I'm not concerned about "groups". If the project shows all the images from the resource, them I'm comfortable with it; and it appears it does: 3,284 images. If you are talking about any issues regarding larger images not rendered resized with high quality, then by all means, add a call to GdipSetInterpolationMode before drawing. The project is designed to organize and extract.  Unless a bug is reported, I've already mentioned I am not enahncing this project. The project does not resize icons that are extracted anyway. Icons are extracted, not modified, as they exist in the resource (exception being with some non-icon/cursor images).

Attaching a full size screenshot of your app looks more like advertising it  :Wink: 
P.S. Organizing by RT_GROUP_ICON is a nice touch. You may want to post your project?

----------


## petersen

Re Point "1".  I just wanted to point out, with specific sample file supplied in ZIP, that there is a glitch in Icon Resource Organizer.  The originally painted rectangle per file attached is Red, but shown as Black on Icon Resource Organizer, per screenshot shown below.

Re Point "2".  I meant that when we retrieve icons from Icon Resource File such as Windows Shell32.dll, if we go by RT_GROUP_ICON (i.e. 14&) instead of RT_ICON (i.e. 3&), then icons pertaining to the same group are obtainable.  If we only go by RT_ICON, we are still able to obtain individual icons in total count, but items belonging to the same group are scattered in different places.  I use Win7 Shell32.dll here becuase it explains better, at least I thought so -- e.g. in this specific example I showed, among the 15 icons there are actually 3 "256x256" PNG items of the same image, but they do not appear in adjacent places in Icon Resource Organizer.  

Edited: The image shown in my previous posting is big because it is the actual size, i.e. 256x256.

.

----------


## LaVolpe

Point #1. No sample file in zip. A gif with a red rectangle. What use is that really? The actual icon might be of better use I'd think. Anyway, unless I can test it against the same icon you used, I can't determine if a bug exists. If I find a bug, I'd definitely want to fix it. The knowledge learned may apply to other projects I've written and/or apply to future projects.

Point #2. The project does not group. It retrieves icons/cursors as first come first served. I mentioned that I thought grouping was a nice touch, but am not interested in modifying this project. It was provided as-is.

----------


## petersen

Isn't there a menu in Icon Resource Organizer saying it "Append......GIF ....."?
.

----------


## LaVolpe

Were you talking about a gif or icon? If your source was a gif, then GDI+ loaded it. We already know there are issues with some GIFs and GDI+. This may be the situation?  If so, so be it. I'll take a look tomorrow. I've shut down my VB box for the night.

----------

