如果得到一个图标句柄HICON。不知道如何把它保存为图标文件呢?
比如:
SHFILEINFO stFileInfo;
SHGetFileInfo("c:\\1.exe",0,&stFileInfo,sizeof(stFileInfo),SHGFI_ICON);
这样可以得到图标句柄stFileInfo.hIcon的图标句柄。如何将其保存为ICON文件呢。
我主要想得到它的图标数据。有人能帮我么。

解决方案 »

  1.   

    http://www.vckbase.com/vckbase/vckbase12/vc/nonctrls/gdi_17/1217001.htmpIcons->WriteIconToICOFile (lpIR,szSaveFileName);
      

  2.   

    /****************************************************************************
    *
    *     FUNCTION: WriteICOHeader
    *
    *     PURPOSE:  Writes the header to an ICO file
    *
    *     PARAMS:   HANDLE hFile       - handle to the file
    *               UINT   nNumEntries - Number of images in file
    *
    *     RETURNS:  BOOL - TRUE for success, FALSE for failure
    *
    *
    \****************************************************************************/
    BOOL CIcons::WriteICOHeader( HANDLE hFile, UINT nNumEntries )
    {
        WORD    Output;
        DWORD dwBytesWritten;    // Write 'reserved' WORD
        Output = 0;
        if( ! WriteFile( hFile, &Output, sizeof( WORD ), &dwBytesWritten, NULL ) )
            return FALSE;
        // Did we write a WORD?
        if( dwBytesWritten != sizeof( WORD ) )
            return FALSE;
        // Write 'type' WORD (1)
        Output = 1;
        if( ! WriteFile( hFile, &Output, sizeof( WORD ), &dwBytesWritten, NULL ) )
            return FALSE;
        // Did we write a WORD?
        if( dwBytesWritten != sizeof( WORD ) )
            return FALSE;
        // Write Number of Entries
        Output = (WORD)nNumEntries;
        if( ! WriteFile( hFile, &Output, sizeof( WORD ), &dwBytesWritten, NULL ) )
            return FALSE;
        // Did we write a WORD?
        if( dwBytesWritten != sizeof( WORD ) )
            return FALSE;
        return TRUE;
    }
    /* End WriteICOHeader() ****************************************************//****************************************************************************
    *
    *     FUNCTION: CalculateImageOffset
    *
    *     PURPOSE:  Calculates the file offset for an icon image
    *
    *     PARAMS:   LPICONRESOURCE lpIR   - pointer to icon resource
    *               UINT           nIndex - which image?
    *
    *     RETURNS:  DWORD - the file offset for that image
    *
    *
    \****************************************************************************/
    DWORD CIcons::CalculateImageOffset( LPICONRESOURCE lpIR, UINT nIndex )
    {
        DWORD dwSize;
        UINT    i;    // Calculate the ICO header size
        dwSize = 3 * sizeof(WORD);
        // Add the ICONDIRENTRY's
        dwSize += lpIR->nNumImages * sizeof(ICONDIRENTRY);
        // Add the sizes of the previous images
        for(i=0;i<nIndex;i++)
            dwSize += lpIR->IconImages[i].dwNumBytes;
        // we're there - return the number
        return dwSize;
    }
    /* End CalculateImageOffset() ***********************************************//****************************************************************************
    *
    *     FUNCTION: WriteIconToICOFile
    *
    *     PURPOSE:  Writes the icon resource data to an ICO file
    *
    *     PARAMS:   LPICONRESOURCE lpIR       - pointer to icon resource
    *               LPCTSTR        szFileName - name for the ICO file
    *
    *     RETURNS:  BOOL - TRUE for success, FALSE for failure
    *
    *
    \****************************************************************************/
    BOOL CIcons::WriteIconToICOFile( LPICONRESOURCE lpIR, LPCTSTR szFileName )
    {
        HANDLE     hFile;
        UINT        i;
        DWORD     dwBytesWritten;    // open the file
        if( (hFile = CreateFile( szFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL )) == INVALID_HANDLE_VALUE )
        {
            MessageBox( AfxGetMainWnd()->m_hWnd , "文件建立时出错!", szFileName, MB_OK );
            return FALSE;
        }
        // Write the header
        if( ! WriteICOHeader( hFile, lpIR->nNumImages ) )
        {
            MessageBox( AfxGetMainWnd()->m_hWnd , "写图标文件头时出错!", szFileName, MB_OK );
            CloseHandle( hFile );
            return FALSE;
        }
        // Write the ICONDIRENTRY's
        for( i=0; i<lpIR->nNumImages; i++ )
        {
            ICONDIRENTRY    ide;        // Convert internal format to ICONDIRENTRY
            ide.bWidth = lpIR->IconImages[i].Width;
            ide.bHeight = lpIR->IconImages[i].Height;
            ide.bReserved = 0;
            ide.wPlanes = lpIR->IconImages[i].lpbi->bmiHeader.biPlanes;
            ide.wBitCount = lpIR->IconImages[i].lpbi->bmiHeader.biBitCount;
            if( (ide.wPlanes * ide.wBitCount) >= 8 )
                ide.bColorCount = 0;
            else
                ide.bColorCount = 1 << (ide.wPlanes * ide.wBitCount);
            ide.dwBytesInRes = lpIR->IconImages[i].dwNumBytes;
            ide.dwImageOffset = CalculateImageOffset( lpIR, i );
            // Write the ICONDIRENTRY out to disk
            if( ! WriteFile( hFile, &ide, sizeof( ICONDIRENTRY ), &dwBytesWritten, NULL ) )
                return FALSE;
            // Did we write a full ICONDIRENTRY ?
            if( dwBytesWritten != sizeof( ICONDIRENTRY ) )
                return FALSE;
        }
        // Write the image bits for each image
        for( i=0; i<lpIR->nNumImages; i++ )
        {
            DWORD dwTemp = lpIR->IconImages[i].lpbi->bmiHeader.biSizeImage;        // Set the sizeimage member to zero
            lpIR->IconImages[i].lpbi->bmiHeader.biSizeImage = 0;
            // Write the image bits to file
            if( ! WriteFile( hFile, lpIR->IconImages[i].lpBits, lpIR->IconImages[i].dwNumBytes, &dwBytesWritten, NULL ) )
                return FALSE;
            if( dwBytesWritten != lpIR->IconImages[i].dwNumBytes )
                return FALSE;
            // set it back
            lpIR->IconImages[i].lpbi->bmiHeader.biSizeImage = dwTemp;
        }
        CloseHandle( hFile );
        return FALSE;
    }
    /* End WriteIconToICOFile() **************************************************/
      

  3.   

    这个代码我看了一下。好像没有从HICON中提取图标数据的部分啊。它的图标是直接从EXE文件中得到的。如果只有一个图标句柄的话。是不是就不行了呢。
      

  4.   

    /****************************************************************************
    *
    *     FUNCTION: ReadIconFromEXEFile
    *
    *     PURPOSE:  Load an Icon Resource from a DLL/EXE file
    *
    *     PARAMS:   LPCTSTR szFileName - name of DLL/EXE file
    *               LPCTSTR lpID - Index of DLL/EXE file
    *
    *     RETURNS:  LPICONRESOURCE - pointer to icon resource
    *
    *
    \****************************************************************************/
    LPICONRESOURCE CIcons::ReadIconFromEXEFile( LPCTSTR szFileName,LPTSTR lpID )
    {
        LPICONRESOURCE     lpIR = NULL, lpNew = NULL;
        HINSTANCE         hLibrary;
        EXEDLLICONINFO     EDII;    // Load the DLL/EXE - NOTE: must be a 32bit EXE/DLL for this to work
        if( (hLibrary = LoadLibraryEx( szFileName, NULL, LOAD_LIBRARY_AS_DATAFILE )) == NULL )
        {
            // Failed to load - abort
            MessageBox(AfxGetMainWnd()->m_hWnd , "装入文件时出错 - 请选择一个WIN32的DLL或EXE文件!", szFileName, MB_OK );
            return NULL;
        }
        // Store the info
        EDII.szFileName = szFileName;
        EDII.hInstance = hLibrary;
        // Ask the user, "Which Icon?"
        if( lpID != NULL )
        {
            HRSRC         hRsrc = NULL;
            HGLOBAL         hGlobal = NULL;
            LPMEMICONDIR    lpIcon = NULL;
            UINT            i;        // Find the group icon resource
            if( (hRsrc = FindResource( hLibrary, lpID, RT_GROUP_ICON )) == NULL )
            {
                FreeLibrary( hLibrary );
                return NULL;
            }
            if( (hGlobal = LoadResource( hLibrary, hRsrc )) == NULL )
            {
                FreeLibrary( hLibrary );
                return NULL;
            }
            if( (lpIcon = (LPMEMICONDIR)LockResource(hGlobal)) == NULL )
            {
                FreeLibrary( hLibrary );
                return NULL;
            }
            // Allocate enough memory for the images
            if( (lpIR = (LPICONRESOURCE)malloc( sizeof(ICONRESOURCE) + ((lpIcon->idCount-1) * sizeof(ICONIMAGE)) )) == NULL )
            {
                MessageBox( AfxGetMainWnd()->m_hWnd, "内存分配出错!", szFileName, MB_OK );
                FreeLibrary( hLibrary );
                return NULL;
            }
            // Fill in local struct members
            lpIR->nNumImages = lpIcon->idCount;
            lstrcpy( lpIR->szOriginalDLLFileName, szFileName );
            lstrcpy( lpIR->szOriginalICOFileName, "" );
            // Loop through the images
            for( i = 0; i < lpIR->nNumImages; i++ )
            {
                // Get the individual image
                if( (hRsrc = FindResource( hLibrary, MAKEINTRESOURCE(lpIcon->idEntries[i].nID), RT_ICON )) == NULL )
                {
                    free( lpIR );
                    FreeLibrary( hLibrary );
                    return NULL;
                }
                if( (hGlobal = LoadResource( hLibrary, hRsrc )) == NULL )
                {
                    free( lpIR );
                    FreeLibrary( hLibrary );
                    return NULL;
                }
                // Store a copy of the resource locally
                lpIR->IconImages[i].dwNumBytes =SizeofResource( hLibrary, hRsrc );
                lpIR->IconImages[i].lpBits = (LPBYTE)malloc( lpIR->IconImages[i].dwNumBytes );
                memcpy( lpIR->IconImages[i].lpBits, LockResource( hGlobal ), lpIR->IconImages[i].dwNumBytes );
                // Adjust internal pointers
                if( ! AdjustIconImagePointers( &(lpIR->IconImages[i]) ) )
                {
                    MessageBox(AfxGetMainWnd()->m_hWnd, "转换成图标内部格式时出错!", szFileName, MB_OK );
                    free( lpIR );
                    FreeLibrary( hLibrary );
                    return NULL;
                }
            }
        }
        FreeLibrary( hLibrary );
        return lpIR;
    }
    /* End ReadIconFromEXEFile() ************************************************/lpIR->IconImages[i].lpBits就是exe的图标数据
      

  5.   

    如果单单HICON,可以通过GetIconInfo得到ICONINFO结构中的hbmColorBitblt到CreateDIBSection创建的BITMAP中,这样就才存到CreateDIBSection返回的 
    VOID **ppvBits,          // bit values
      

  6.   

    可不可以用IPicture整一下,然后用IPicture的savetofile方法保存呀。
      

  7.   

    有了HICON,可以把它画到HBITMAP里面,通过CDC的DrawIcon函数然后可以用GDI+的Bitmap类进行保存,Bitmap有个构造函数可以通过HBITMAP进行构造然后用Bitmap的Save方法就可以保存成文件了
      

  8.   

    如果单单HICON,可以通过GetIconInfo得到ICONINFO结构中的hbmColorBitblt到CreateDIBSection创建的BITMAP中,这样就才存到CreateDIBSection返回的 
    VOID **ppvBits,          // bit values
    这个或许可以用。
    不过。CreateDIBSection该如何来创建BITMAP呢。应该需要高、宽、色深等一些参数吧。能不能具体些呢。谢谢啦。