如果得到一个图标句柄HICON。不知道如何把它保存为图标文件呢?
比如:
SHFILEINFO stFileInfo;
SHGetFileInfo("c:\\1.exe",0,&stFileInfo,sizeof(stFileInfo),SHGFI_ICON);
这样可以得到图标句柄stFileInfo.hIcon的图标句柄。如何将其保存为ICON文件呢。
我主要想得到它的图标数据。有人能帮我么。
比如:
SHFILEINFO stFileInfo;
SHGetFileInfo("c:\\1.exe",0,&stFileInfo,sizeof(stFileInfo),SHGFI_ICON);
这样可以得到图标句柄stFileInfo.hIcon的图标句柄。如何将其保存为ICON文件呢。
我主要想得到它的图标数据。有人能帮我么。
*
* 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() **************************************************/
*
* 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的图标数据
VOID **ppvBits, // bit values
VOID **ppvBits, // bit values
这个或许可以用。
不过。CreateDIBSection该如何来创建BITMAP呢。应该需要高、宽、色深等一些参数吧。能不能具体些呢。谢谢啦。