DWORD CIconExtractor::WriteIconToICOFile(LPICONRESOURCE lpIR, LPCTSTR szFileName) { DWORD dwBytesWritten = 0; CAutoFile hFile = CreateFile(szFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); // open the file if (!hFile) return GetLastError(); // Write the header if (WriteICOHeader(hFile, lpIR->nNumImages)) return GetLastError(); // Write the ICONDIRENTRY's for (UINT i = 0; i < lpIR->nNumImages; ++i) { ICONDIRENTRY ide; // Convert internal format to ICONDIRENTRY ide.bWidth = (BYTE)lpIR->IconImages[i].Width; ide.bHeight = (BYTE)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 to disk if (!WriteFile(hFile, &ide, sizeof(ICONDIRENTRY), &dwBytesWritten, NULL)) return GetLastError(); if (dwBytesWritten != sizeof(ICONDIRENTRY)) return GetLastError(); } // Write the image bits for each image for (UINT i = 0; i < lpIR->nNumImages; ++i) { DWORD dwTemp = lpIR->IconImages[i].lpbi->bmiHeader.biSizeImage; bool bError = false; // fix size even on error // Set the sizeimage member to zero lpIR->IconImages[i].lpbi->bmiHeader.biSizeImage = 0; if (!WriteFile( hFile, lpIR->IconImages[i].lpBits, lpIR->IconImages[i].dwNumBytes, &dwBytesWritten, NULL)) bError = true; if (dwBytesWritten != lpIR->IconImages[i].dwNumBytes) bError = true; // set it back lpIR->IconImages[i].lpbi->bmiHeader.biSizeImage = dwTemp; if (bError) return GetLastError(); } return NO_ERROR; }
/**************************************************************************** * * 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 * * History: * July '95 - Created * \****************************************************************************/ BOOL 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( hWndMain, "Error Opening File for Writing", szFileName, MB_OK ); return FALSE; } // Write the header if( ! WriteICOHeader( hFile, lpIR->nNumImages ) ) { MessageBox( hWndMain, "Error Writing ICO File", 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; }
DWORD CIconExtractor::WriteIconToICOFile(LPICONRESOURCE lpIR, LPCTSTR szFileName) { CAutoFile hFile = ::CreateFile(szFileName, GENERIC_WRITE, FILE_SHARE_READ, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); // open the file if (!hFile) return GetLastError(); // Write the header if (WriteICOHeader(hFile, lpIR->nNumImages)) return GetLastError(); // Write the ICONDIRENTRY's for (UINT i = 0; i < lpIR->nNumImages; ++i) { ICONDIRENTRY ide = { 0 }; // Convert internal format to ICONDIRENTRY ide.bWidth = static_cast<BYTE>(lpIR->IconImages[i].Width); ide.bHeight = static_cast<BYTE>(lpIR->IconImages[i].Height); if (ide.bHeight == 0) // 256x256 icon, both width and height must be 0 ide.bWidth = 0; 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 to disk DWORD dwBytesWritten = 0; if (!WriteFile(hFile, &ide, sizeof(ICONDIRENTRY), &dwBytesWritten, nullptr)) return GetLastError(); if (dwBytesWritten != sizeof(ICONDIRENTRY)) return GetLastError(); } // Write the image bits for each image for (UINT i = 0; i < lpIR->nNumImages; ++i) { DWORD dwTemp = lpIR->IconImages[i].lpbi->bmiHeader.biSizeImage; bool bError = false; // fix size even on error // Set the sizeimage member to zero, but not if the icon is PNG if (lpIR->IconImages[i].lpbi->bmiHeader.biCompression != 65536) lpIR->IconImages[i].lpbi->bmiHeader.biSizeImage = 0; DWORD dwBytesWritten = 0; if (!WriteFile(hFile, lpIR->IconImages[i].lpBits, lpIR->IconImages[i].dwNumBytes, &dwBytesWritten, nullptr)) bError = true; if (dwBytesWritten != lpIR->IconImages[i].dwNumBytes) bError = true; // set it back lpIR->IconImages[i].lpbi->bmiHeader.biSizeImage = dwTemp; if (bError) return GetLastError(); } return NO_ERROR; }