refer:http://stackoverflow.com/questions/2289894/how-can-i-save-hicon-to-an-ico-file
answer1:
1 #include "stdafx.h" 2 #include <windows.h> 3 #include <olectl.h> 4 #pragma comment(lib, "oleaut32.lib") 5 6 HRESULT SaveIcon(HICON hIcon, const wchar_t* path) { 7 // Create the IPicture intrface 8 PICTDESC desc = { sizeof(PICTDESC) }; 9 desc.picType = PICTYPE_ICON; 10 desc.icon.hicon = hIcon; 11 IPicture* pPicture = 0; 12 HRESULT hr = OleCreatePictureIndirect(&desc, IID_IPicture, FALSE, (void**)&pPicture); 13 if (FAILED(hr)) return hr; 14 15 // Create a stream and save the image 16 IStream* pStream = 0; 17 CreateStreamOnHGlobal(0, TRUE, &pStream); 18 LONG cbSize = 0; 19 hr = pPicture->SaveAsFile(pStream, TRUE, &cbSize); 20 21 // Write the stream content to the file 22 if (!FAILED(hr)) { 23 HGLOBAL hBuf = 0; 24 GetHGlobalFromStream(pStream, &hBuf); 25 void* buffer = GlobalLock(hBuf); 26 HANDLE hFile = CreateFile(path, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0); 27 if (!hFile) hr = HRESULT_FROM_WIN32(GetLastError()); 28 else { 29 DWORD written = 0; 30 WriteFile(hFile, buffer, cbSize, &written, 0); 31 CloseHandle(hFile); 32 } 33 GlobalUnlock(buffer); 34 } 35 // Cleanup 36 pStream->Release(); 37 pPicture->Release(); 38 return hr; 39 40 } 41 int _tmain(int argc, _TCHAR* argv[]) 42 { 43 HICON hIcon = (HICON)LoadImage(0, L"c:\\windows\\system32\\perfcentercpl.ico", IMAGE_ICON, 32, 32, LR_LOADFROMFILE); 44 if (!hIcon) return GetLastError(); 45 HRESULT hr = SaveIcon(hIcon, L"c:\\temp\\test.ico"); 46 return hr; 47 }
answer2:
1 #include <afx.h> 2 #include <afxwin.h> 3 #include <atlbase.h> 4 5 struct ICONDIRENTRY 6 { 7 UCHAR nWidth; 8 UCHAR nHeight; 9 UCHAR nNumColorsInPalette; // 0 if no palette 10 UCHAR nReserved; // should be 0 11 WORD nNumColorPlanes; // 0 or 1 12 WORD nBitsPerPixel; 13 ULONG nDataLength; // length in bytes 14 ULONG nOffset; // offset of BMP or PNG data from beginning of file 15 }; 16 17 // Helper class to release GDI object handle when scope ends: 18 class CGdiHandle 19 { 20 public: 21 CGdiHandle(HGDIOBJ handle) : m_handle(handle) {}; 22 ~CGdiHandle(){DeleteObject(m_handle);}; 23 private: 24 HGDIOBJ m_handle; 25 }; 26 27 28 // Save icon referenced by handle 'hIcon' as file with name 'szPath'. 29 // The generated ICO file has the color depth specified in 'nColorBits'. 30 // 31 bool SaveIcon(HICON hIcon, int nColorBits, const TCHAR* szPath) 32 { 33 ASSERT(nColorBits == 4 || nColorBits == 8 || nColorBits == 24 || nColorBits == 32); 34 35 if (offsetof(ICONDIRENTRY, nOffset) != 12) 36 { 37 return false; 38 } 39 40 CDC dc; 41 dc.Attach(::GetDC(NULL)); // ensure that DC is released when function ends 42 43 // Open file for writing: 44 CFile file; 45 if (!file.Open(szPath, CFile::modeWrite | CFile::modeCreate)) 46 { 47 return false; 48 } 49 50 // Write header: 51 UCHAR icoHeader[6] = {0, 0, 1, 0, 1, 0}; // ICO file with 1 image 52 file.Write(icoHeader, sizeof(icoHeader)); 53 54 // Get information about icon: 55 ICONINFO iconInfo; 56 GetIconInfo(hIcon, &iconInfo); 57 CGdiHandle handle1(iconInfo.hbmColor), handle2(iconInfo.hbmMask); // free bitmaps when function ends 58 BITMAPINFO bmInfo = {0}; 59 bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 60 bmInfo.bmiHeader.biBitCount = 0; // don't get the color table 61 if (!GetDIBits(dc, iconInfo.hbmColor, 0, 0, NULL, &bmInfo, DIB_RGB_COLORS)) 62 { 63 return false; 64 } 65 66 // Allocate size of bitmap info header plus space for color table: 67 int nBmInfoSize = sizeof(BITMAPINFOHEADER); 68 if (nColorBits < 24) 69 { 70 nBmInfoSize += sizeof(RGBQUAD) * (int)(1 << nColorBits); 71 } 72 73 CAutoVectorPtr<UCHAR> bitmapInfo; 74 bitmapInfo.Allocate(nBmInfoSize); 75 BITMAPINFO* pBmInfo = (BITMAPINFO*)(UCHAR*)bitmapInfo; 76 memcpy(pBmInfo, &bmInfo, sizeof(BITMAPINFOHEADER)); 77 78 // Get bitmap data: 79 ASSERT(bmInfo.bmiHeader.biSizeImage != 0); 80 CAutoVectorPtr<UCHAR> bits; 81 bits.Allocate(bmInfo.bmiHeader.biSizeImage); 82 pBmInfo->bmiHeader.biBitCount = nColorBits; 83 pBmInfo->bmiHeader.biCompression = BI_RGB; 84 if (!GetDIBits(dc, iconInfo.hbmColor, 0, bmInfo.bmiHeader.biHeight, (UCHAR*)bits, pBmInfo, DIB_RGB_COLORS)) 85 { 86 return false; 87 } 88 89 // Get mask data: 90 BITMAPINFO maskInfo = {0}; 91 maskInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 92 maskInfo.bmiHeader.biBitCount = 0; // don't get the color table 93 if (!GetDIBits(dc, iconInfo.hbmMask, 0, 0, NULL, &maskInfo, DIB_RGB_COLORS)) 94 { 95 return false; 96 } 97 ASSERT(maskInfo.bmiHeader.biBitCount == 1); 98 CAutoVectorPtr<UCHAR> maskBits; 99 maskBits.Allocate(maskInfo.bmiHeader.biSizeImage); 100 CAutoVectorPtr<UCHAR> maskInfoBytes; 101 maskInfoBytes.Allocate(sizeof(BITMAPINFO) + 2 * sizeof(RGBQUAD)); 102 BITMAPINFO* pMaskInfo = (BITMAPINFO*)(UCHAR*)maskInfoBytes; 103 memcpy(pMaskInfo, &maskInfo, sizeof(maskInfo)); 104 if (!GetDIBits(dc, iconInfo.hbmMask, 0, maskInfo.bmiHeader.biHeight, (UCHAR*)maskBits, pMaskInfo, DIB_RGB_COLORS)) 105 { 106 return false; 107 } 108 109 // Write directory entry: 110 ICONDIRENTRY dir; 111 dir.nWidth = (UCHAR) pBmInfo->bmiHeader.biWidth; 112 dir.nHeight = (UCHAR) pBmInfo->bmiHeader.biHeight; 113 dir.nNumColorsInPalette = (nColorBits == 4 ? 16 : 0); 114 dir.nReserved = 0; 115 dir.nNumColorPlanes = 0; 116 dir.nBitsPerPixel = pBmInfo->bmiHeader.biBitCount; 117 dir.nDataLength = pBmInfo->bmiHeader.biSizeImage + pMaskInfo->bmiHeader.biSizeImage + nBmInfoSize; 118 dir.nOffset = sizeof(dir) + sizeof(icoHeader); 119 file.Write(&dir, sizeof(dir)); 120 121 // Write DIB header (including color table): 122 int nBitsSize = pBmInfo->bmiHeader.biSizeImage; 123 pBmInfo->bmiHeader.biHeight *= 2; // because the header is for both image and mask 124 pBmInfo->bmiHeader.biCompression = 0; 125 pBmInfo->bmiHeader.biSizeImage += pMaskInfo->bmiHeader.biSizeImage; // because the header is for both image and mask 126 file.Write(&pBmInfo->bmiHeader, nBmInfoSize); 127 128 // Write image data: 129 file.Write((UCHAR*)bits, nBitsSize); 130 131 // Write mask data: 132 file.Write((UCHAR*)maskBits, pMaskInfo->bmiHeader.biSizeImage); 133 134 file.Close(); 135 136 return true; 137 } 138 139 // Test program for SaveIcon() function. 140 // 141 // Usage: first argument is input ICO file (must be 32x32 pixels); second argument is output ICO file 142 // 143 int _tmain(int argc, _TCHAR* argv[]) 144 { 145 ASSERT(argc == 3); 146 147 // Load a 32x32 icon: 148 HICON hIcon = (HICON)LoadImage(0, argv[1], IMAGE_ICON, 32, 32, LR_LOADFROMFILE | LR_CREATEDIBSECTION); 149 ASSERT(hIcon != NULL); 150 151 // Save with 24-bits colors: 152 if (!SaveIcon(hIcon, 24, argv[2])) 153 { 154 _ftprintf(stderr, _T("Error: saving icon to %s failed"), argv[2]); 155 return EXIT_FAILURE; 156 } 157 158 return EXIT_SUCCESS; 159 }