766 lines
26 KiB
C++
766 lines
26 KiB
C++
// Icons.cpp: implementation of the CIcons class.
|
||
//////////////////////////////////////////////////////////////////////
|
||
//
|
||
//用途:IconSnap所需调用的类
|
||
//功能:图标基础操作类
|
||
//作者:徐景周
|
||
//日期:2001年9月
|
||
//
|
||
//////////////////////////////////////////////////////////////////////
|
||
#include "stdafx.h"
|
||
#include "Icons.h"
|
||
#include "Dib.h"
|
||
|
||
#ifdef _DEBUG
|
||
#undef THIS_FILE
|
||
static char THIS_FILE[]=__FILE__;
|
||
#define new DEBUG_NEW
|
||
#endif
|
||
|
||
CDib *pDib;
|
||
//////////////////////////////////////////////////////////////////////
|
||
// Construction/Destruction
|
||
//////////////////////////////////////////////////////////////////////
|
||
|
||
CIcons::CIcons()
|
||
{
|
||
|
||
}
|
||
|
||
CIcons::~CIcons()
|
||
{
|
||
|
||
}
|
||
|
||
/****************************************************************************
|
||
*
|
||
* FUNCTION: MakeIconFromResource
|
||
*
|
||
* PURPOSE: Makes an HICON from an icon resource
|
||
*
|
||
* PARAMS: LPICONIMAGE lpIcon - pointer to the icon resource
|
||
*
|
||
* RETURNS: HICON - handle to the new icon, NULL for failure
|
||
*
|
||
*
|
||
\****************************************************************************/
|
||
HICON CIcons::MakeIconFromResource( LPICONIMAGE lpIcon )
|
||
{
|
||
HICON hIcon = NULL;
|
||
|
||
// Sanity Check
|
||
if( lpIcon == NULL )
|
||
return NULL;
|
||
if( lpIcon->lpBits == NULL )
|
||
return NULL;
|
||
// Let the OS do the real work :)
|
||
hIcon = CreateIconFromResourceEx( lpIcon->lpBits, lpIcon->dwNumBytes, TRUE, 0x00030000,
|
||
(*(LPBITMAPINFOHEADER)(lpIcon->lpBits)).biWidth, (*(LPBITMAPINFOHEADER)(lpIcon->lpBits)).biHeight/2, 0 );
|
||
|
||
// It failed, odds are good we're on NT so try the non-Ex way
|
||
if( hIcon == NULL )
|
||
{
|
||
// We would break on NT if we try with a 16bpp image
|
||
if(lpIcon->lpbi->bmiHeader.biBitCount != 16)
|
||
{
|
||
hIcon = CreateIconFromResource( lpIcon->lpBits, lpIcon->dwNumBytes, TRUE, 0x00030000 );
|
||
}
|
||
}
|
||
return hIcon;
|
||
}
|
||
/* End MakeIconFromResource() **********************************************/
|
||
|
||
/****************************************************************************
|
||
*
|
||
* FUNCTION: ReadIconFromICOFile
|
||
*
|
||
* PURPOSE: Reads an Icon Resource from an ICO file
|
||
*
|
||
* PARAMS: LPCTSTR szFileName - Name of the ICO file
|
||
*
|
||
* RETURNS: LPICONRESOURCE - pointer to the resource, NULL for failure
|
||
*
|
||
*
|
||
\****************************************************************************/
|
||
LPICONRESOURCE CIcons::ReadIconFromICOFile( LPCTSTR szFileName )
|
||
{
|
||
LPICONRESOURCE lpIR = NULL, lpNew = NULL;
|
||
HANDLE hFile = NULL;
|
||
LPRESOURCEPOSINFO lpRPI = NULL;
|
||
UINT i;
|
||
DWORD dwBytesRead;
|
||
LPICONDIRENTRY lpIDE = NULL;
|
||
|
||
|
||
// Open the file
|
||
if( (hFile = CreateFile( szFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL )) == INVALID_HANDLE_VALUE )
|
||
{
|
||
MessageBox( AfxGetMainWnd()->m_hWnd, "图标文件打开时出错!", szFileName, MB_OK );
|
||
return NULL;
|
||
}
|
||
// Allocate memory for the resource structure
|
||
if( (lpIR = (LPICONRESOURCE)malloc( sizeof(ICONRESOURCE) )) == NULL )
|
||
{
|
||
MessageBox( AfxGetMainWnd()->m_hWnd, "图标分配内存时出错!", szFileName, MB_OK );
|
||
CloseHandle( hFile );
|
||
return NULL;
|
||
}
|
||
// Read in the header
|
||
if( (lpIR->nNumImages = ReadICOHeader( hFile )) == (UINT)-1 )
|
||
{
|
||
MessageBox( AfxGetMainWnd()->m_hWnd, "读图标文件头时出错!", szFileName, MB_OK );
|
||
CloseHandle( hFile );
|
||
free( lpIR );
|
||
return NULL;
|
||
}
|
||
// Adjust the size of the struct to account for the images
|
||
if( (lpNew = (LPICONRESOURCE)realloc( lpIR, sizeof(ICONRESOURCE) + ((lpIR->nNumImages-1) * sizeof(ICONIMAGE)) )) == NULL )
|
||
{
|
||
MessageBox( AfxGetMainWnd()->m_hWnd, "图标内存重新分配出错!", szFileName, MB_OK );
|
||
CloseHandle( hFile );
|
||
free( lpIR );
|
||
return NULL;
|
||
}
|
||
lpIR = lpNew;
|
||
// Store the original name
|
||
lstrcpy( lpIR->szOriginalICOFileName, szFileName );
|
||
lstrcpy( lpIR->szOriginalDLLFileName, "" );
|
||
// Allocate enough memory for the icon directory entries
|
||
if( (lpIDE = (LPICONDIRENTRY)malloc( lpIR->nNumImages * sizeof( ICONDIRENTRY ) ) ) == NULL )
|
||
{
|
||
MessageBox( AfxGetMainWnd()->m_hWnd, "图标文件内存重新分配出错!", szFileName, MB_OK );
|
||
CloseHandle( hFile );
|
||
free( lpIR );
|
||
return NULL;
|
||
}
|
||
// Read in the icon directory entries
|
||
if( ! ReadFile( hFile, lpIDE, lpIR->nNumImages * sizeof( ICONDIRENTRY ), &dwBytesRead, NULL ) )
|
||
{
|
||
MessageBox( AfxGetMainWnd()->m_hWnd, "读图标文件时出错!", szFileName, MB_OK );
|
||
CloseHandle( hFile );
|
||
free( lpIR );
|
||
return NULL;
|
||
}
|
||
if( dwBytesRead != lpIR->nNumImages * sizeof( ICONDIRENTRY ) )
|
||
{
|
||
MessageBox( AfxGetMainWnd()->m_hWnd, "读图标文件时出错!", szFileName, MB_OK );
|
||
CloseHandle( hFile );
|
||
free( lpIR );
|
||
return NULL;
|
||
}
|
||
// Loop through and read in each image
|
||
for( i = 0; i < lpIR->nNumImages; i++ )
|
||
{
|
||
// Allocate memory for the resource
|
||
if( (lpIR->IconImages[i].lpBits = (LPBYTE)malloc(lpIDE[i].dwBytesInRes)) == NULL )
|
||
{
|
||
MessageBox( AfxGetMainWnd()->m_hWnd, "图标内存重新分配出错!", szFileName, MB_OK );
|
||
CloseHandle( hFile );
|
||
free( lpIR );
|
||
free( lpIDE );
|
||
return NULL;
|
||
}
|
||
lpIR->IconImages[i].dwNumBytes = lpIDE[i].dwBytesInRes;
|
||
// Seek to beginning of this image
|
||
if( SetFilePointer( hFile, lpIDE[i].dwImageOffset, NULL, FILE_BEGIN ) == 0xFFFFFFFF )
|
||
{
|
||
MessageBox( AfxGetMainWnd()->m_hWnd, "图标内容定位时出错!", szFileName, MB_OK );
|
||
CloseHandle( hFile );
|
||
free( lpIR );
|
||
free( lpIDE );
|
||
return NULL;
|
||
}
|
||
// Read it in
|
||
if( ! ReadFile( hFile, lpIR->IconImages[i].lpBits, lpIDE[i].dwBytesInRes, &dwBytesRead, NULL ) )
|
||
{
|
||
MessageBox( AfxGetMainWnd()->m_hWnd, "读图标内容出错!", szFileName, MB_OK );
|
||
CloseHandle( hFile );
|
||
free( lpIR );
|
||
free( lpIDE );
|
||
return NULL;
|
||
}
|
||
if( dwBytesRead != lpIDE[i].dwBytesInRes )
|
||
{
|
||
MessageBox(AfxGetMainWnd()->m_hWnd, "读图标内容出错!", szFileName, MB_OK );
|
||
CloseHandle( hFile );
|
||
free( lpIDE );
|
||
free( lpIR );
|
||
return NULL;
|
||
}
|
||
// Set the internal pointers appropriately
|
||
if( ! AdjustIconImagePointers( &(lpIR->IconImages[i]) ) )
|
||
{
|
||
MessageBox( AfxGetMainWnd()->m_hWnd, "图标内部格式转换出错!", szFileName, MB_OK );
|
||
CloseHandle( hFile );
|
||
free( lpIDE );
|
||
free( lpIR );
|
||
return NULL;
|
||
}
|
||
}
|
||
// Clean up
|
||
free( lpIDE );
|
||
free( lpRPI );
|
||
CloseHandle( hFile );
|
||
return lpIR;
|
||
}
|
||
/* End ReadIconFromICOFile() **********************************************/
|
||
|
||
/****************************************************************************
|
||
*
|
||
* FUNCTION: AdjustIconImagePointers
|
||
*
|
||
* PURPOSE: Adjusts internal pointers in icon resource struct
|
||
*
|
||
* PARAMS: LPICONIMAGE lpImage - the resource to handle
|
||
*
|
||
* RETURNS: BOOL - TRUE for success, FALSE for failure
|
||
*
|
||
*
|
||
\****************************************************************************/
|
||
BOOL CIcons::AdjustIconImagePointers( LPICONIMAGE lpImage )
|
||
{
|
||
// Sanity check
|
||
if( lpImage==NULL )
|
||
return FALSE;
|
||
// BITMAPINFO is at beginning of bits
|
||
lpImage->lpbi = (LPBITMAPINFO)lpImage->lpBits;
|
||
// Width - simple enough
|
||
lpImage->Width = lpImage->lpbi->bmiHeader.biWidth;
|
||
// Icons are stored in funky format where height is doubled - account for it
|
||
lpImage->Height = (lpImage->lpbi->bmiHeader.biHeight)/2;
|
||
// How many colors?
|
||
lpImage->Colors = lpImage->lpbi->bmiHeader.biPlanes * lpImage->lpbi->bmiHeader.biBitCount;
|
||
// XOR bits follow the header and color table
|
||
lpImage->lpXOR = (LPBYTE)pDib->FindDIBBits((LPSTR)lpImage->lpbi);
|
||
// AND bits follow the XOR bits
|
||
lpImage->lpAND = lpImage->lpXOR + (lpImage->Height*pDib->BytesPerLine((LPBITMAPINFOHEADER)(lpImage->lpbi)));
|
||
return TRUE;
|
||
}
|
||
/* End AdjustIconImagePointers() *******************************************/
|
||
|
||
/****************************************************************************
|
||
*
|
||
* FUNCTION: ReadICOHeader
|
||
*
|
||
* PURPOSE: Reads the header from an ICO file
|
||
*
|
||
* PARAMS: HANDLE hFile - handle to the file
|
||
*
|
||
* RETURNS: UINT - Number of images in file, -1 for failure
|
||
*
|
||
*
|
||
\****************************************************************************/
|
||
UINT CIcons::ReadICOHeader( HANDLE hFile )
|
||
{
|
||
WORD Input;
|
||
DWORD dwBytesRead;
|
||
|
||
// Read the 'reserved' WORD
|
||
if( ! ReadFile( hFile, &Input, sizeof( WORD ), &dwBytesRead, NULL ) )
|
||
return (UINT)-1;
|
||
// Did we get a WORD?
|
||
if( dwBytesRead != sizeof( WORD ) )
|
||
return (UINT)-1;
|
||
// Was it 'reserved' ? (ie 0)
|
||
if( Input != 0 )
|
||
return (UINT)-1;
|
||
// Read the type WORD
|
||
if( ! ReadFile( hFile, &Input, sizeof( WORD ), &dwBytesRead, NULL ) )
|
||
return (UINT)-1;
|
||
// Did we get a WORD?
|
||
if( dwBytesRead != sizeof( WORD ) )
|
||
return (UINT)-1;
|
||
// Was it type 1?
|
||
if( Input != 1 )
|
||
return (UINT)-1;
|
||
// Get the count of images
|
||
if( ! ReadFile( hFile, &Input, sizeof( WORD ), &dwBytesRead, NULL ) )
|
||
return (UINT)-1;
|
||
// Did we get a WORD?
|
||
if( dwBytesRead != sizeof( WORD ) )
|
||
return (UINT)-1;
|
||
// Return the count
|
||
return Input;
|
||
}
|
||
/* End ReadICOHeader() ****************************************************/
|
||
|
||
/****************************************************************************
|
||
*
|
||
* FUNCTION: GetIconFromInstance
|
||
*
|
||
* PURPOSE: Callback for enumerating resources in a DLL/EXE
|
||
*
|
||
* PARAMS: HINSTANCE hInstance - Instance handle for this module
|
||
* LPTSTR nIndex - Resource index
|
||
*
|
||
* RETURNS: HICON - Handle to the icon, NULL for failure
|
||
*
|
||
*
|
||
\****************************************************************************/
|
||
HICON CIcons::GetIconFromInstance( HINSTANCE hInstance, LPTSTR nIndex )
|
||
{
|
||
HICON hIcon = NULL;
|
||
HRSRC hRsrc = NULL;
|
||
HGLOBAL hGlobal = NULL;
|
||
LPVOID lpRes = NULL;
|
||
int nID;
|
||
|
||
// Find the group icon
|
||
if( (hRsrc = FindResource( hInstance, nIndex, RT_GROUP_ICON )) == NULL )
|
||
return NULL;
|
||
if( (hGlobal = LoadResource( hInstance, hRsrc )) == NULL )
|
||
return NULL;
|
||
if( (lpRes = LockResource(hGlobal)) == NULL )
|
||
return NULL;
|
||
|
||
// Find this particular image
|
||
nID = LookupIconIdFromDirectory((LPBYTE) lpRes, TRUE );
|
||
if( (hRsrc = FindResource( hInstance, MAKEINTRESOURCE(nID), RT_ICON )) == NULL )
|
||
return NULL;
|
||
if( (hGlobal = LoadResource( hInstance, hRsrc )) == NULL )
|
||
return NULL;
|
||
if( (lpRes = LockResource(hGlobal)) == NULL )
|
||
return NULL;
|
||
// Let the OS make us an icon
|
||
hIcon = CreateIconFromResource((LPBYTE) lpRes, SizeofResource(hInstance,hRsrc), TRUE, 0x00030000 );
|
||
return hIcon;
|
||
}
|
||
/* End GetIconFromInstance() ***********************************************/
|
||
|
||
/****************************************************************************
|
||
*
|
||
* 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() ************************************************/
|
||
|
||
/****************************************************************************
|
||
*
|
||
* 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: IconImageToClipBoard
|
||
*
|
||
* PURPOSE: Copies an icon image to the clipboard in CF_DIB format
|
||
*
|
||
* PARAMS: LPICONIMAGE lpii - pointer to icon image data
|
||
*
|
||
* RETURNS: BOOL - TRUE for success, FALSE for failure
|
||
*
|
||
*
|
||
\****************************************************************************/
|
||
BOOL CIcons::IconImageToClipBoard( LPICONIMAGE lpii )
|
||
{
|
||
HANDLE hGlobal;
|
||
LPSTR lpBits;
|
||
|
||
// Open the clipboard
|
||
if( OpenClipboard(AfxGetMainWnd()->m_hWnd ) )
|
||
{
|
||
// empty it
|
||
if( EmptyClipboard() )
|
||
{
|
||
if(lpii->dwNumBytes ==NULL)
|
||
return false;
|
||
// Make a buffer to send to clipboard
|
||
hGlobal = GlobalAlloc( GMEM_MOVEABLE | GMEM_DDESHARE, lpii->dwNumBytes );
|
||
lpBits = (LPSTR)GlobalLock( hGlobal );
|
||
// Copy the bits to the buffer
|
||
memcpy( lpBits, lpii->lpBits, lpii->dwNumBytes );
|
||
// Adjust for funky height*2 thing
|
||
((LPBITMAPINFOHEADER)lpBits)->biHeight /= 2;
|
||
GlobalUnlock( hGlobal );
|
||
// Send it to the clipboard
|
||
SetClipboardData( CF_DIB, hGlobal );
|
||
CloseClipboard();
|
||
return TRUE;
|
||
}
|
||
}
|
||
return FALSE;
|
||
}
|
||
/* End IconImageToClipBoard() ***********************************************/
|
||
|
||
/****************************************************************************
|
||
*
|
||
* FUNCTION: IconImageFromClipBoard
|
||
*
|
||
* PURPOSE: Creates an icon image from the CF_DIB clipboard entry
|
||
*
|
||
* PARAMS: LPICONIMAGE lpii - pointer to icon image data
|
||
* BOOL bStretchToFit - TRUE to stretch, FALSE to take
|
||
* the upper left corner of the DIB
|
||
*
|
||
* RETURNS: BOOL - TRUE for success, FALSE for failure
|
||
*
|
||
*
|
||
\****************************************************************************/
|
||
BOOL CIcons::IconImageFromClipBoard( LPICONIMAGE lpii, BOOL bStretchToFit )
|
||
{
|
||
LPBITMAPINFO lpbi;
|
||
HANDLE hClipGlobal;
|
||
BOOL bRet = FALSE;
|
||
|
||
// Open the clipboard
|
||
if( OpenClipboard( AfxGetMainWnd()->m_hWnd ) )
|
||
{
|
||
// Get the CF_DIB data from it
|
||
if( (hClipGlobal = GetClipboardData( CF_DIB )) != NULL )
|
||
{
|
||
// Lock it down
|
||
if( (lpbi=(LPBITMAPINFO)GlobalLock(hClipGlobal)) != NULL )
|
||
{
|
||
// Convert it to an icon image
|
||
bRet = DIBToIconImage( lpii, (LPBYTE)lpbi, bStretchToFit );
|
||
GlobalUnlock( hClipGlobal );
|
||
}
|
||
}
|
||
CloseClipboard();
|
||
}
|
||
return bRet;
|
||
}
|
||
/* End IconImageFromClipBoard() ********************************************/
|
||
|
||
/****************************************************************************
|
||
*
|
||
* FUNCTION: DIBToIconImage
|
||
*
|
||
* PURPOSE: Converts a CF_DIB memory block to an icon image
|
||
*
|
||
* PARAMS: LPICONIMAGE lpii - pointer to icon image data
|
||
* LPBYTE lpDIB - a pointer to the CF_DIB block
|
||
* BOOL bStretchToFit - TRUE to stretch, FALSE to take
|
||
* the upper left corner of the DIB
|
||
*
|
||
* RETURNS: BOOL - TRUE for success, FALSE for failure
|
||
*
|
||
*
|
||
\****************************************************************************/
|
||
BOOL CIcons::DIBToIconImage( LPICONIMAGE lpii, LPBYTE lpDIB, BOOL bStretch )
|
||
{
|
||
LPBYTE lpNewDIB;
|
||
|
||
// Sanity check
|
||
if( lpDIB == NULL )
|
||
return FALSE;
|
||
|
||
// Let the DIB engine convert color depths if need be
|
||
lpNewDIB = pDib->ConvertDIBFormat( (LPBITMAPINFO)lpDIB, lpii->Width, lpii->Height, lpii->Colors, bStretch );
|
||
|
||
// Now we have a cool new DIB of the proper size/color depth
|
||
// Lets poke it into our data structures and be done with it
|
||
|
||
// How big is it?
|
||
lpii->dwNumBytes = sizeof( BITMAPINFOHEADER ) // Header
|
||
+ pDib->PaletteSize( (LPSTR)lpNewDIB ) // Palette
|
||
+ lpii->Height * pDib->BytesPerLine( (LPBITMAPINFOHEADER)lpNewDIB ) // XOR mask
|
||
+ lpii->Height * WIDTHBYTES( lpii->Width ); // AND mask
|
||
|
||
// If there was already an image here, free it
|
||
if( lpii->lpBits != NULL )
|
||
free( lpii->lpBits );
|
||
// Allocate enough room for the new image
|
||
if( (lpii->lpBits = (LPBYTE)malloc( lpii->dwNumBytes )) == NULL )
|
||
{
|
||
free( lpii );
|
||
return FALSE;
|
||
}
|
||
// Copy the bits
|
||
memcpy( lpii->lpBits, lpNewDIB, sizeof( BITMAPINFOHEADER ) + pDib->PaletteSize( (LPSTR)lpNewDIB ) );
|
||
// Adjust internal pointers/variables for new image
|
||
lpii->lpbi = (LPBITMAPINFO)(lpii->lpBits);
|
||
lpii->lpbi->bmiHeader.biHeight *= 2;
|
||
lpii->lpXOR =(LPBYTE) pDib->FindDIBBits( (LPSTR)(lpii->lpBits) );
|
||
memcpy( lpii->lpXOR, pDib->FindDIBBits((LPSTR)lpNewDIB), lpii->Height * pDib->BytesPerLine( (LPBITMAPINFOHEADER)lpNewDIB ) );
|
||
lpii->lpAND = lpii->lpXOR + lpii->Height * pDib->BytesPerLine( (LPBITMAPINFOHEADER)lpNewDIB );
|
||
memset( lpii->lpAND, 0, lpii->Height * WIDTHBYTES( lpii->Width ) );
|
||
// Free the source
|
||
free( lpNewDIB );
|
||
return TRUE;
|
||
}
|
||
/* End DIBToIconImage() ***************************************************/
|
||
|
||
/****************************************************************************
|
||
*
|
||
* FUNCTION: IconImageFromBMPFile
|
||
*
|
||
* PURPOSE: Creates an icon image from a BMP file
|
||
*
|
||
* PARAMS: LPCTSTR szFileName - Filename for BMP file
|
||
* LPICONIMAGE lpii - pointer to icon image data
|
||
* BOOL bStretchToFit - TRUE to stretch, FALSE to take
|
||
* the upper left corner of the DIB
|
||
*
|
||
* RETURNS: BOOL - TRUE for success, FALSE for failure
|
||
*
|
||
*
|
||
\****************************************************************************/
|
||
BOOL CIcons::IconImageFromBMPFile( LPCTSTR szFileName, LPICONIMAGE lpii, BOOL bStretchToFit )
|
||
{
|
||
LPBYTE lpDIB = NULL;
|
||
BOOL bRet = FALSE;
|
||
|
||
if( (lpDIB=pDib->ReadBMPFile(szFileName)) == NULL )
|
||
return FALSE;
|
||
// Convert it to an icon image
|
||
bRet = DIBToIconImage( lpii, lpDIB, bStretchToFit );
|
||
free( lpDIB );
|
||
return bRet;
|
||
}
|
||
/* End IconImageFromBMPFile() ********************************************/
|
||
|
||
/****************************************************************************
|
||
*
|
||
* FUNCTION: IconImageToBMPFile
|
||
*
|
||
* PURPOSE: Creates BMP file from an icon image
|
||
*
|
||
* PARAMS: LPCTSTR szFileName - Filename for BMP file
|
||
* LPICONIMAGE lpii - pointer to icon image data
|
||
*
|
||
* RETURNS: BOOL - TRUE for success, FALSE for failure
|
||
*
|
||
*
|
||
\****************************************************************************/
|
||
BOOL CIcons::IconImageToBMPFile( LPCTSTR szFileName, LPICONIMAGE lpii )
|
||
{
|
||
return pDib->WriteBMPFile( szFileName, (LPBYTE)lpii->lpbi );
|
||
}
|