refer:http://stackoverflow.com/questions/2289894/how-can-i-save-hicon-to-an-ico-file

answer1:

 #include "stdafx.h"
#include <windows.h>
#include <olectl.h>
#pragma comment(lib, "oleaut32.lib") HRESULT SaveIcon(HICON hIcon, const wchar_t* path) {
// Create the IPicture intrface
PICTDESC desc = { sizeof(PICTDESC) };
desc.picType = PICTYPE_ICON;
desc.icon.hicon = hIcon;
IPicture* pPicture = ;
HRESULT hr = OleCreatePictureIndirect(&desc, IID_IPicture, FALSE, (void**)&pPicture);
if (FAILED(hr)) return hr; // Create a stream and save the image
IStream* pStream = ;
CreateStreamOnHGlobal(, TRUE, &pStream);
LONG cbSize = ;
hr = pPicture->SaveAsFile(pStream, TRUE, &cbSize); // Write the stream content to the file
if (!FAILED(hr)) {
HGLOBAL hBuf = ;
GetHGlobalFromStream(pStream, &hBuf);
void* buffer = GlobalLock(hBuf);
HANDLE hFile = CreateFile(path, GENERIC_WRITE, , , CREATE_ALWAYS, , );
if (!hFile) hr = HRESULT_FROM_WIN32(GetLastError());
else {
DWORD written = ;
WriteFile(hFile, buffer, cbSize, &written, );
CloseHandle(hFile);
}
GlobalUnlock(buffer);
}
// Cleanup
pStream->Release();
pPicture->Release();
return hr; }
int _tmain(int argc, _TCHAR* argv[])
{
HICON hIcon = (HICON)LoadImage(, L"c:\\windows\\system32\\perfcentercpl.ico", IMAGE_ICON, , , LR_LOADFROMFILE);
if (!hIcon) return GetLastError();
HRESULT hr = SaveIcon(hIcon, L"c:\\temp\\test.ico");
return hr;
}

answer2:

 #include <afx.h>
#include <afxwin.h>
#include <atlbase.h> struct ICONDIRENTRY
{
UCHAR nWidth;
UCHAR nHeight;
UCHAR nNumColorsInPalette; // 0 if no palette
UCHAR nReserved; // should be 0
WORD nNumColorPlanes; // 0 or 1
WORD nBitsPerPixel;
ULONG nDataLength; // length in bytes
ULONG nOffset; // offset of BMP or PNG data from beginning of file
}; // Helper class to release GDI object handle when scope ends:
class CGdiHandle
{
public:
CGdiHandle(HGDIOBJ handle) : m_handle(handle) {};
~CGdiHandle(){DeleteObject(m_handle);};
private:
HGDIOBJ m_handle;
}; // Save icon referenced by handle 'hIcon' as file with name 'szPath'.
// The generated ICO file has the color depth specified in 'nColorBits'.
//
bool SaveIcon(HICON hIcon, int nColorBits, const TCHAR* szPath)
{
ASSERT(nColorBits == || nColorBits == || nColorBits == || nColorBits == ); if (offsetof(ICONDIRENTRY, nOffset) != )
{
return false;
} CDC dc;
dc.Attach(::GetDC(NULL)); // ensure that DC is released when function ends // Open file for writing:
CFile file;
if (!file.Open(szPath, CFile::modeWrite | CFile::modeCreate))
{
return false;
} // Write header:
UCHAR icoHeader[] = {, , , , , }; // ICO file with 1 image
file.Write(icoHeader, sizeof(icoHeader)); // Get information about icon:
ICONINFO iconInfo;
GetIconInfo(hIcon, &iconInfo);
CGdiHandle handle1(iconInfo.hbmColor), handle2(iconInfo.hbmMask); // free bitmaps when function ends
BITMAPINFO bmInfo = {};
bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmInfo.bmiHeader.biBitCount = ; // don't get the color table
if (!GetDIBits(dc, iconInfo.hbmColor, , , NULL, &bmInfo, DIB_RGB_COLORS))
{
return false;
} // Allocate size of bitmap info header plus space for color table:
int nBmInfoSize = sizeof(BITMAPINFOHEADER);
if (nColorBits < )
{
nBmInfoSize += sizeof(RGBQUAD) * (int)( << nColorBits);
} CAutoVectorPtr<UCHAR> bitmapInfo;
bitmapInfo.Allocate(nBmInfoSize);
BITMAPINFO* pBmInfo = (BITMAPINFO*)(UCHAR*)bitmapInfo;
memcpy(pBmInfo, &bmInfo, sizeof(BITMAPINFOHEADER)); // Get bitmap data:
ASSERT(bmInfo.bmiHeader.biSizeImage != );
CAutoVectorPtr<UCHAR> bits;
bits.Allocate(bmInfo.bmiHeader.biSizeImage);
pBmInfo->bmiHeader.biBitCount = nColorBits;
pBmInfo->bmiHeader.biCompression = BI_RGB;
if (!GetDIBits(dc, iconInfo.hbmColor, , bmInfo.bmiHeader.biHeight, (UCHAR*)bits, pBmInfo, DIB_RGB_COLORS))
{
return false;
} // Get mask data:
BITMAPINFO maskInfo = {};
maskInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
maskInfo.bmiHeader.biBitCount = ; // don't get the color table
if (!GetDIBits(dc, iconInfo.hbmMask, , , NULL, &maskInfo, DIB_RGB_COLORS))
{
return false;
}
ASSERT(maskInfo.bmiHeader.biBitCount == );
CAutoVectorPtr<UCHAR> maskBits;
maskBits.Allocate(maskInfo.bmiHeader.biSizeImage);
CAutoVectorPtr<UCHAR> maskInfoBytes;
maskInfoBytes.Allocate(sizeof(BITMAPINFO) + * sizeof(RGBQUAD));
BITMAPINFO* pMaskInfo = (BITMAPINFO*)(UCHAR*)maskInfoBytes;
memcpy(pMaskInfo, &maskInfo, sizeof(maskInfo));
if (!GetDIBits(dc, iconInfo.hbmMask, , maskInfo.bmiHeader.biHeight, (UCHAR*)maskBits, pMaskInfo, DIB_RGB_COLORS))
{
return false;
} // Write directory entry:
ICONDIRENTRY dir;
dir.nWidth = (UCHAR) pBmInfo->bmiHeader.biWidth;
dir.nHeight = (UCHAR) pBmInfo->bmiHeader.biHeight;
dir.nNumColorsInPalette = (nColorBits == ? : );
dir.nReserved = ;
dir.nNumColorPlanes = ;
dir.nBitsPerPixel = pBmInfo->bmiHeader.biBitCount;
dir.nDataLength = pBmInfo->bmiHeader.biSizeImage + pMaskInfo->bmiHeader.biSizeImage + nBmInfoSize;
dir.nOffset = sizeof(dir) + sizeof(icoHeader);
file.Write(&dir, sizeof(dir)); // Write DIB header (including color table):
int nBitsSize = pBmInfo->bmiHeader.biSizeImage;
pBmInfo->bmiHeader.biHeight *= ; // because the header is for both image and mask
pBmInfo->bmiHeader.biCompression = ;
pBmInfo->bmiHeader.biSizeImage += pMaskInfo->bmiHeader.biSizeImage; // because the header is for both image and mask
file.Write(&pBmInfo->bmiHeader, nBmInfoSize); // Write image data:
file.Write((UCHAR*)bits, nBitsSize); // Write mask data:
file.Write((UCHAR*)maskBits, pMaskInfo->bmiHeader.biSizeImage); file.Close(); return true;
} // Test program for SaveIcon() function.
//
// Usage: first argument is input ICO file (must be 32x32 pixels); second argument is output ICO file
//
int _tmain(int argc, _TCHAR* argv[])
{
ASSERT(argc == ); // Load a 32x32 icon:
HICON hIcon = (HICON)LoadImage(, argv[], IMAGE_ICON, , , LR_LOADFROMFILE | LR_CREATEDIBSECTION);
ASSERT(hIcon != NULL); // Save with 24-bits colors:
if (!SaveIcon(hIcon, , argv[]))
{
_ftprintf(stderr, _T("Error: saving icon to %s failed"), argv[]);
return EXIT_FAILURE;
} return EXIT_SUCCESS;
}

answer3:

 #include <windows.h>
#include <stdio.h>
#include <tchar.h> //
// ICONS (.ICO type 1) are structured like this:
//
// ICONHEADER (just 1)
// ICONDIR [1...n] (an array, 1 for each image)
// [BITMAPINFOHEADER+COLOR_BITS+MASK_BITS] [1...n] (1 after the other, for each image)
//
// CURSORS (.ICO type 2) are identical in structure, but use
// two monochrome bitmaps (real XOR and AND masks, this time).
// typedef struct
{
WORD idReserved; // must be 0
WORD idType; // 1 = ICON, 2 = CURSOR
WORD idCount; // number of images (and ICONDIRs) // ICONDIR [1...n]
// ICONIMAGE [1...n] } ICONHEADER; //
// An array of ICONDIRs immediately follow the ICONHEADER
//
typedef struct
{
BYTE bWidth;
BYTE bHeight;
BYTE bColorCount;
BYTE bReserved;
WORD wPlanes; // for cursors, this field = wXHotSpot
WORD wBitCount; // for cursors, this field = wYHotSpot
DWORD dwBytesInRes;
DWORD dwImageOffset; // file-offset to the start of ICONIMAGE } ICONDIR; //
// After the ICONDIRs follow the ICONIMAGE structures -
// consisting of a BITMAPINFOHEADER, (optional) RGBQUAD array, then
// the color and mask bitmap bits (all packed together
//
typedef struct
{
BITMAPINFOHEADER biHeader; // header for color bitmap (no mask header)
//RGBQUAD rgbColors[1...n];
//BYTE bXOR[1]; // DIB bits for color bitmap
//BYTE bAND[1]; // DIB bits for mask bitmap } ICONIMAGE; //
// Write the ICO header to disk
//
static UINT WriteIconHeader(HANDLE hFile, int nImages)
{
ICONHEADER iconheader;
DWORD nWritten; // Setup the icon header
iconheader.idReserved = ; // Must be 0
iconheader.idType = ; // Type 1 = ICON (type 2 = CURSOR)
iconheader.idCount = nImages; // number of ICONDIRs // Write the header to disk
WriteFile( hFile, &iconheader, sizeof(iconheader), &nWritten, ); // following ICONHEADER is a series of ICONDIR structures (idCount of them, in fact)
return nWritten;
} //
// Return the number of BYTES the bitmap will take ON DISK
//
static UINT NumBitmapBytes(BITMAP *pBitmap)
{
int nWidthBytes = pBitmap->bmWidthBytes; // bitmap scanlines MUST be a multiple of 4 bytes when stored
// inside a bitmap resource, so round up if necessary
if(nWidthBytes & )
nWidthBytes = (nWidthBytes + ) & ~; return nWidthBytes * pBitmap->bmHeight;
} //
// Return number of bytes written
//
static UINT WriteIconImageHeader(HANDLE hFile, BITMAP *pbmpColor, BITMAP *pbmpMask)
{
BITMAPINFOHEADER biHeader;
DWORD nWritten;
UINT nImageBytes; // calculate how much space the COLOR and MASK bitmaps take
nImageBytes = NumBitmapBytes(pbmpColor) + NumBitmapBytes(pbmpMask); // write the ICONIMAGE to disk (first the BITMAPINFOHEADER)
ZeroMemory(&biHeader, sizeof(biHeader)); // Fill in only those fields that are necessary
biHeader.biSize = sizeof(biHeader);
biHeader.biWidth = pbmpColor->bmWidth;
biHeader.biHeight = pbmpColor->bmHeight * ; // height of color+mono
biHeader.biPlanes = pbmpColor->bmPlanes;
biHeader.biBitCount = pbmpColor->bmBitsPixel;
biHeader.biSizeImage = nImageBytes; // write the BITMAPINFOHEADER
WriteFile(hFile, &biHeader, sizeof(biHeader), &nWritten, ); // write the RGBQUAD color table (for 16 and 256 colour icons)
if(pbmpColor->bmBitsPixel == || pbmpColor->bmBitsPixel == )
{ } return nWritten;
} //
// Wrapper around GetIconInfo and GetObject(BITMAP)
//
static BOOL GetIconBitmapInfo(HICON hIcon, ICONINFO *pIconInfo, BITMAP *pbmpColor, BITMAP *pbmpMask)
{
if(!GetIconInfo(hIcon, pIconInfo))
return FALSE; if(!GetObject(pIconInfo->hbmColor, sizeof(BITMAP), pbmpColor))
return FALSE; if(!GetObject(pIconInfo->hbmMask, sizeof(BITMAP), pbmpMask))
return FALSE; return TRUE;
} //
// Write one icon directory entry - specify the index of the image
//
static UINT WriteIconDirectoryEntry(HANDLE hFile, int nIdx, HICON hIcon, UINT nImageOffset)
{
ICONINFO iconInfo;
ICONDIR iconDir; BITMAP bmpColor;
BITMAP bmpMask; DWORD nWritten;
UINT nColorCount;
UINT nImageBytes; GetIconBitmapInfo(hIcon, &iconInfo, &bmpColor, &bmpMask); nImageBytes = NumBitmapBytes(&bmpColor) + NumBitmapBytes(&bmpMask); if(bmpColor.bmBitsPixel >= )
nColorCount = ;
else
nColorCount = << (bmpColor.bmBitsPixel * bmpColor.bmPlanes); // Create the ICONDIR structure
iconDir.bWidth = (BYTE)bmpColor.bmWidth;
iconDir.bHeight = (BYTE)bmpColor.bmHeight;
iconDir.bColorCount = nColorCount;
iconDir.bReserved = ;
iconDir.wPlanes = bmpColor.bmPlanes;
iconDir.wBitCount = bmpColor.bmBitsPixel;
iconDir.dwBytesInRes = sizeof(BITMAPINFOHEADER) + nImageBytes;
iconDir.dwImageOffset = nImageOffset; // Write to disk
WriteFile(hFile, &iconDir, sizeof(iconDir), &nWritten, ); // Free resources
DeleteObject(iconInfo.hbmColor);
DeleteObject(iconInfo.hbmMask); return nWritten;
} static UINT WriteIconData(HANDLE hFile, HBITMAP hBitmap)
{
BITMAP bmp;
int i;
BYTE * pIconData; UINT nBitmapBytes;
DWORD nWritten; GetObject(hBitmap, sizeof(BITMAP), &bmp); nBitmapBytes = NumBitmapBytes(&bmp); pIconData = (BYTE *)malloc(nBitmapBytes); GetBitmapBits(hBitmap, nBitmapBytes, pIconData); // bitmaps are stored inverted (vertically) when on disk..
// so write out each line in turn, starting at the bottom + working
// towards the top of the bitmap. Also, the bitmaps are stored in packed
// in memory - scanlines are NOT 32bit aligned, just 1-after-the-other
for(i = bmp.bmHeight - ; i >= ; i--)
{
// Write the bitmap scanline
WriteFile(
hFile,
pIconData + (i * bmp.bmWidthBytes), // calculate offset to the line
bmp.bmWidthBytes, // 1 line of BYTES
&nWritten,
); // extend to a 32bit boundary (in the file) if necessary
if(bmp.bmWidthBytes & )
{
DWORD padding = ;
WriteFile(hFile, &padding, - bmp.bmWidthBytes, &nWritten, );
}
} free(pIconData); return nBitmapBytes;
} //
// Create a .ICO file, using the specified array of HICON images
//
BOOL SaveIcon3(TCHAR *szIconFile, HICON hIcon[], int nNumIcons)
{
HANDLE hFile;
int i;
int * pImageOffset; if(hIcon == || nNumIcons < )
return FALSE; // Save icon to disk:
hFile = CreateFile(szIconFile, GENERIC_WRITE, , , CREATE_ALWAYS, , ); if(hFile == INVALID_HANDLE_VALUE)
return FALSE; //
// Write the iconheader first of all
//
WriteIconHeader(hFile, nNumIcons); //
// Leave space for the IconDir entries
//
SetFilePointer(hFile, sizeof(ICONDIR) * nNumIcons, , FILE_CURRENT); pImageOffset = (int *)malloc(nNumIcons * sizeof(int)); //
// Now write the actual icon images!
//
for(i = ; i < nNumIcons; i++)
{
ICONINFO iconInfo;
BITMAP bmpColor, bmpMask; GetIconBitmapInfo(hIcon[i], &iconInfo, &bmpColor, &bmpMask); // record the file-offset of the icon image for when we write the icon directories
pImageOffset[i] = SetFilePointer(hFile, , , FILE_CURRENT); // bitmapinfoheader + colortable
WriteIconImageHeader(hFile, &bmpColor, &bmpMask); // color and mask bitmaps
WriteIconData(hFile, iconInfo.hbmColor);
WriteIconData(hFile, iconInfo.hbmMask); DeleteObject(iconInfo.hbmColor);
DeleteObject(iconInfo.hbmMask);
} //
// Lastly, skip back and write the icon directories.
//
SetFilePointer(hFile, sizeof(ICONHEADER), , FILE_BEGIN); for(i = ; i < nNumIcons; i++)
{
WriteIconDirectoryEntry(hFile, i, hIcon[i], pImageOffset[i]);
} free(pImageOffset); // finished!
CloseHandle(hFile); return TRUE;
} int saveIcon(TCHAR* filename, TCHAR* iconFile) {
HICON hIconLarge;
HICON hIconSmall;
BOOL ret; if ( ExtractIconEx(filename, , &hIconLarge, &hIconSmall, ) == ) {
return ;
} ret = SaveIcon3(iconFile, &hIconSmall, );
if ( ret ) {
return ;
}
return -;
} int _tmain(int argc, TCHAR* argv[]) {
if ( argc < ) {
printf("Usage: <exe/dll file> <output ico file>");
return EXIT_FAILURE;
}
_tprintf(_T("src = %s\n"), argv[]);
_tprintf(_T("dest = %s\n"), argv[]);
saveIcon(argv[], argv[]); return ;
}

How can I save HICON to an .ico file的更多相关文章

  1. save tracking results into csv file for oxuva long-term tracking dataset (from txt to csv)

    save tracking results into csv file for oxuva long-term tracking dataset (from txt to csv) 2019-10-2 ...

  2. Save output to a text file from Mac terminal

      Simply with output redirection: system_profiler > file.txt Basically, this will take the output ...

  3. Save matrix to a txt file - matlab 在matlab中将矩阵变量保存为txt格式

    Source: Baidu Wenku % Original code has been modified dirMain = 'D:\test\'; fid = fopen([dirMain, 't ...

  4. How to save console output to a file in Eclipse

    https://coderanch.com/t/278299/java/Writing-output-console-file-system File file = new File("te ...

  5. 【转载】Save terminal output to a file

    To write the output of a command to a file, there are basically 10 commonly used ways. Overview: Ple ...

  6. ICO图标在线生成,php生成ICO图标在线制作源码

    我们做web系统的时候,每个浏览器的tab这里都会有一个图标,这个图标叫favicon图标,favicon.ico文件放在系统的根目录 如果程序员没有ICO制作工具,那么要如何生成图标呢?可以用程序来 ...

  7. 修改stb_image.c以让Duilib直接支持Ico格式的图标显示

    duilib不支持ico格式的图标资源, 但是我要想显示ico格式的图标... 发现网上那些转换ico为bmp或其它格式的都不是一个好办法, 也还是不能让duilib直接显示ico... 昨晚稍微研究 ...

  8. Save results to different files when executing multi SQL statements in DB Query Analyzer 7.01

        1 About DB Query Analyzer DB Query Analyzer is presented by Master Genfeng,Ma from Chinese Mainl ...

  9. Console.Out 属性和 XmlDocument.Save 方法 (String)

    Console.Out 属性 默认情况下,此属性设置为标准输出流. 此属性可以设置为另一个流SetOut方法. 请注意,调用Console.Out.WriteLine方法是等效于调用相应WriteLi ...

随机推荐

  1. html文字有光晕

    <style> .tb{ font-size:40px; filter:glow(color=pink,direction=); font-family:华文行楷; } </styl ...

  2. 突破路由mac地址过滤思路

    一.获取合法的mac地址 在拿到无线网络的密码时,主要思路就是,用类似airodump-ng这类监听软件(WildPackets OmniPeek,Kismet),获得合法客户端的mac地址,然后再更 ...

  3. MYSQL如何导出存储过程和触发器?

    今天遇到.. 类似下面的就可以: mysqldump -u root -p -ntd -R  nxsc>nxsc_trigger.sql

  4. 导出excel的三种方式

    第一种是Response输出,这种方式输出的文件不符合标准的excel格式,在打开的时候会有提示,而且不好控制内容.第一种是Response输出,这种方式输出的文件不符合标准的excel格式,在打开的 ...

  5. Usage、Usage Minimum和Usage Maximum项目详解

    (1)一个产生多个数据域(Report Count>1)的主项目之前有一个以上的[用途]时,每个[用途]与一个数据域依次对应,如果数据域个数(Report Count)超过[用途]的个数,则剩余 ...

  6. Intel hex 文件格式解密

    Intel hex 文件常用来保存单片机或其他处理器的目标程序代码.它保存物理程序存储区中的目标代码映象.一般的编程器都支持这种格式. Intel hex 文件全部由可打印的ASCII字符组成(可以用 ...

  7. kill,killall,top,free,vmstat,iostat,watch命令

    kill命令 Linux 中的kill命令用来终止指定的进程(terminate a process)的运行,是Linux下进程管理的常用命令.通常,终止一个前台进程可以 使用Ctrl+C键,但是,对 ...

  8. COJ 0999 WZJ的数据结构(负一)

    WZJ的数据结构(负一) 难度级别:D: 运行时间限制:1000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 输入N个模板串Pi和文本串T,输出每个模板串Pi在T ...

  9. 设计模式(十三): Proxy代理模式 -- 结构型模式

      设计模式(十一)代理模式Proxy(结构型) 1.概述 因为某个对象消耗太多资源,而且你的代码并不是每个逻辑路径都需要此对象, 你曾有过延迟创建对象的想法吗 ( if和else就是不同的两条逻辑路 ...

  10. HDU5140---Hun Gui Wei Company (主席树)

    主席树太强大了,,如果仅仅用来求第k大就太屈才了..貌似和HDU4605差不多,那个是在图上根据点的顺序建立主席树,这个是根据年龄大小 或者等级高低建立主席树. 题意 大致就是一个二维区间的求和,但是 ...