Click here to Skip to main content
15,895,656 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
I have copied the following code from stack-overflow for generating .ico file from HICON instance. This code works fine except that generated .ico file is blank and white even though original image being pointed by HICON has colors.

C++
#include "stdafx.h" 
#include "windows.h"
#include "olectl.h"
#pragma comment(lib, "oleaut32.lib") 
 
HRESULT SaveIcon(HICON hIcon, const wchar_t* path) { 
    // Create the IPicture intrface 
    PICTDESC desc = { sizeof(PICTDESC) }; 
    desc.picType = PICTYPE_ICON; 
    desc.icon.hicon = hIcon; 
    IPicture* pPicture = 0; 
    HRESULT hr = OleCreatePictureIndirect(&desc, IID_IPicture, FALSE,(void**)&pPicture);
    if (FAILED(hr)) return hr;
 
    // Create a stream and save the image 
    IStream* pStream = 0; 
    CreateStreamOnHGlobal(0, TRUE, &pStream); 
    LONG cbSize = 0; 
    hr = pPicture->SaveAsFile(pStream, TRUE, &cbSize); 
 
    // Write the stream content to the file 
    if (!FAILED(hr)) { 
        HGLOBAL hBuf = 0; 
        GetHGlobalFromStream(pStream, &hBuf); 
        void* buffer = GlobalLock(hBuf); 
        HANDLE hFile = CreateFile(path, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0); 
        if (!hFile) hr = HRESULT_FROM_WIN32(GetLastError()); 
        else { 
            DWORD written = 0; 
            WriteFile(hFile, buffer, cbSize, &written, 0); 
            CloseHandle(hFile); 
        } 
        GlobalUnlock(buffer); 
    } 
    // Cleanup 
    pStream->Release(); 
    pPicture->Release(); 
    return hr; 
 }


What can be problem with this code?
Posted
Updated 22-Feb-11 1:03am
v2

I found this on code project:
http://www.codeproject.com/Messages/2287455/HICON-ico.aspx[^]
PICTDESC pictDesc;
pictDesc.cbSizeofstruct = sizeof(PICTDESC);
pictDesc.icon.hicon = hICon;
pictDesc.picType = PICTYPE_ICON;
IPicture *pPicture = NULL;
IStorage *pStg = NULL;
IStream *pStream = NULL;
LONG lSize = 0;
HRESULT hr = OleCreatePictureIndirect(&pictDesc,IID_IPicture,TRUE,(void**)&pPicture);
hr = StgCreateDocfile(L"c:\\My.ico",STGM_CREATE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE,0,&pStg);
hr = pStg->CreateStream(L"icoStream",STGM_CREATE |
STGM_WRITE |
STGM_DIRECT |
STGM_SHARE_EXCLUSIVE ,0,0,&pStream);
hr = pPicture->SaveAsFile(pStream,TRUE,&lSize); 


But I didn't try it...
 
Share this answer
 
Comments
Rajesh G Manwani from Mumbai 23-Feb-11 3:37am    
with this code, .ico file is not at all getting generated.
try this one:
ICONINFO		ii;
if(GetIconInfo(hicon,&ii))
{
  __IcoSave24(store,ii.hbmMask,ii.hbmColor);
  if(ii.hbmColor) DeleteObject(ii.hbmColor);
  if(ii.hbmMask ) DeleteObject(ii.hbmMask );
}


static void __IcoSave24(vStore& store,HBITMAP hbmMask,HBITMAP hbmColor)
{
  BITMAP  bmiMask;
  BITMAP  bmiColor;
  if(
      GetObject(hbmColor,sizeof(bmiColor),&bmiColor) &&
      GetObject(hbmMask,sizeof(bmiMask),&bmiMask) &&
      (bmiColor.bmWidth==bmiMask.bmWidth) &&
      (bmiColor.bmHeight==bmiMask.bmHeight)
    )
  {
    ICONDIR            icodir;
    ICONDIRENTRY      icoent;
    BITMAPINFOHEADER  icobmi = {0};
    tArr<char>        bits;
    unsigned int      size;

    icodir.idReserved = 0;
    icodir.idType     = 1;
    icodir.idCount    = 1;

    icoent.bWidth        = (unsigned char)bmiColor.bmWidth;
    icoent.bHeight       = (unsigned char)bmiColor.bmHeight;
    icoent.bColorCount   = 8<=bmiColor.bmBitsPixel?0:1<<bmiColor.bmBitsPixel;
    icoent.bReserved     = 0;
    icoent.wPlanes       = bmiColor.bmPlanes;
    icoent.wBitCount     = bmiColor.bmBitsPixel;
    icoent.dwBytesInRes  = sizeof(BITMAPINFOHEADER) + (__bmp_bpl(bmiColor.bmBitsPixel,bmiColor.bmWidth)*bmiColor.bmHeight) + (__bmp_bpl(bmiMask.bmBitsPixel,bmiMask.bmWidth)*bmiMask.bmHeight);
    icoent.dwImageOffset = sizeof(icodir) + sizeof(icoent);

    store.Write(&icodir,sizeof(icodir));
    store.Write(&icoent,sizeof(icoent));

    if(0>bmiMask.bmHeight) Beep(3000,1000);

    icobmi.biSize      = sizeof(icobmi);
    icobmi.biWidth     = bmiColor.bmWidth;
    icobmi.biHeight    = bmiColor.bmHeight + bmiMask.bmHeight;
    icobmi.biPlanes    = 1;
    icobmi.biBitCount  = bmiColor.bmBitsPixel;
    icobmi.biSizeImage = __bmp_bpl(bmiColor.bmBitsPixel,bmiColor.bmWidth)*bmiColor.bmHeight;

    // icoent.dwImageOffset
    store.Write(&icobmi,sizeof(icobmi));

    bits.resize(icobmi.biSizeImage);
    size = GetBitmapBits(hbmColor,bits.count,bits.array);
    store.Write(bits.array,size);
    size = GetBitmapBits(hbmMask,bits.count,bits.array);
    store.Write(bits.array,size);
  }
}

Good luck.
 
Share this answer
 
I am unable to use this code as definition of some of user datatypes such as vstore, ICONDIR, ICONDIRENTRY is not submitted.
 
Share this answer
 
Comments
mbue 23-Feb-11 12:52pm    
i cant do your work - you should be able to substitute a simple in/out class.
btw: internet has a search function :mad:

#pragma pack(push)
#pragma pack(2)
typedef struct
{
BYTE bWidth; // Width, in pixels, of the image
BYTE bHeight; // Height, in pixels, of the image
BYTE bColorCount; // Number of colors in image (0 if >=8bpp)
BYTE bReserved; // Reserved ( must be 0)
WORD wPlanes; // Color Planes
WORD wBitCount; // Bits per pixel
DWORD dwBytesInRes; // How many bytes in this resource?
DWORD dwImageOffset; // Where in the file is this image?

} ICONDIRENTRY, *LPICONDIRENTRY;

typedef struct
{
WORD idReserved; // Reserved (must be 0)
WORD idType; // Resource Type (1 for icons)
WORD idCount; // How many images?

// ICONDIRENTRY idEntries[1]; // An entry for each image (idCount of 'em)
} ICONDIR;

typedef struct
{
BITMAPINFOHEADER icHeader; // DIB header
// RGBQUAD icColors[1]; // Color table
// BYTE icXOR[1]; // DIB bits for XOR mask
// BYTE icAND[1]; // DIB bits for AND mask

} ICONIMAGE;

#pragma pack(pop)

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900