前言:这两天为exe文件做一个随机图标的功能,要求每次运行后图标都动态改变,在网上找了很多代码,都有一部分缺陷,参考了一些文档后进行了修改,现在在此进行总结:
一个icon资源(可以是*.ico文件,也可以是windows资源节区里的icon group),可以包含多张图片。这些图片有着各自的size或者颜色深度,这些图片可以是bmp格式或者png格式(vista之后支持,一般256*256时使用)
****************如果我们在win32环境下打开一个*.ico文件**************************

Icon文件结构由两部分组成:icon文件头和多张图片数据,图片可以是bmp、png:

Icon文件头
typedef struct
    WORD idReserved; 	//必须为0
    WORD idType; 		//如果是icons则必须是1
    WORD idCount; 		//表示有多少张图片
} ICONDIR, *LPICONDIR;
其中idReserved必须是0;idType对于ICON文件来说必须是1;idCount指明icon文件有多少张图片,也就指明了接下来有多少个ICONDIRENTRY结构体数据。
//在文件头后面则是 idCount个结构体  ICONDIRENTRY idEntries[x]; 
每张图片详情结构体,图片数据不在这其中
typedef struct
    BYTE bWidth;
    BYTE bHeight; 
    BYTE bColorCount; // Number of colors in image (0 if >=8bpp)
    BYTE bReserved; // Reserved ( must be 0)
    WORD wPlanes; // Color Planes
    WORD wBitCount; // Bits per pixel
    DWORD dwBytesInRes; // How many bytes in this resource?
    DWORD dwImageOffset; // Where in the file is this image?
} ICONDIRENTRY, *LPICONDIRENTRY;
//下面例子为从一个*.ico文件中更改exe文件的图标
void changedExeIcon(LPCTSTR lpExeName, LPCTSTR lpIconFile)
	LPICONDIRENTRY pIconDirEntry(NULL);
	LPGRPICONDIR pGrpIconDir(NULL);
	HEADER header;
	LPBYTE pIconBytes(NULL);
	HANDLE hIconFile(NULL);
	DWORD dwRet(0), nSize(0), nGSize(0), dwReserved(0);
	HANDLE hUpdate(NULL);
	BOOL ret(FALSE);
	WORD i(0);
	//打开图标文件  
	hIconFile = CreateFile(lpIconFile, GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if (hIconFile == INVALID_HANDLE_VALUE)
		return;
	//读取文件头部信息  
	ret = ReadFile(hIconFile, &header, sizeof(HEADER), &dwReserved, NULL);
	if (!ret)
		CloseHandle(hIconFile);
		return;
	//建立每一个图标的目录信息存放区域  
	pIconDirEntry = (LPICONDIRENTRY)new BYTE[header.idCount*sizeof(ICONDIRENTRY)];
	if (pIconDirEntry == NULL)
		CloseHandle(hIconFile);
		return;
	//从Icon文件中读取每一个图标的目录信息  
	ret = ReadFile(hIconFile, pIconDirEntry, header.idCount*sizeof(ICONDIRENTRY), &dwReserved, NULL);
	if (!ret)
		delete[] pIconDirEntry;
		CloseHandle(hIconFile);
		return;
	//建立EXE文件中RT_GROUP_ICON所需的数据结构存放区域  
	nGSize = sizeof(GRPICONDIR) + header.idCount*sizeof(ICONDIRENTRY);
	pGrpIconDir = (LPGRPICONDIR)new BYTE[nGSize];
	//填充信息,这里相当于一个转换的过程  
	pGrpIconDir->idReserved = header.idReserved;
	pGrpIconDir->idType = header.idType;
	pGrpIconDir->idCount = header.idCount;
	//复制信息并设置每一个图标对应的ID。ID为位置索引号  
	for (i = 0; i < header.idCount; i++)
		pGrpIconDir->idEntries[i].bWidth = pIconDirEntry[i].bWidth;
		pGrpIconDir->idEntries[i].bHeight = pIconDirEntry[i].bHeight;
		pGrpIconDir->idEntries[i].bColorCount = pIconDirEntry[i].bColorCount;
		pGrpIconDir->idEntries[i].bReserved = pIconDirEntry[i].bReserved;
		pGrpIconDir->idEntries[i].wPlanes = pIconDirEntry[i].wPlanes;
		pGrpIconDir->idEntries[i].wBitCount = pIconDirEntry[i].wBitCount;
		pGrpIconDir->idEntries[i].dwBytesInRes = pIconDirEntry[i].dwBytesInRes;
		pGrpIconDir->idEntries[i].nID = i;
	//开始更新EXE中的图标资源,ID定为最小0,如果原来存在0ID的图标信息则被替换为新的。  
	hUpdate = BeginUpdateResource(lpExeName, false);
	if (hUpdate != NULL)
		//首先更新RT_GROUP_ICON信息  
		ret = UpdateResource(hUpdate, RT_GROUP_ICON, MAKEINTRESOURCE(128), MAKELANGID(LANG_CHINESE, SUBLANG_SYS_DEFAULT), (LPVOID)pGrpIconDir, nGSize);
		if (!ret)
			delete[] pIconDirEntry;
			delete[] pGrpIconDir;
			CloseHandle(hIconFile);
			return;
		//接着的是每一个Icon的信息存放  
		for (i = 0; i < header.idCount; i++)
			//Icon的字节数  
			nSize = pIconDirEntry[i].dwBytesInRes;
			//偏移文件的指针到当前图标的开始处  
			dwRet = SetFilePointer(hIconFile, pIconDirEntry[i].dwImageOffset, NULL, FILE_BEGIN);
			if (dwRet == INVALID_SET_FILE_POINTER)
				break;
			//准备pIconBytes来存放文件里的Byte信息用于更新到EXE中。  
			delete[] pIconBytes;
			pIconBytes = new BYTE[nSize];
			ret = ReadFile(hIconFile, (LPVOID)pIconBytes, nSize, &dwReserved, NULL);
			if (!ret)
				break;
			//更新每一个ID对应的RT_ICON信息  
			ret = UpdateResource(hUpdate, RT_ICON, MAKEINTRESOURCE(pGrpIconDir->idEntries[i].nID), MAKELANGID(LANG_CHINESE, SUBLANG_SYS_DEFAULT), (LPVOID)pIconBytes, nSize);
			if (!ret)
				break;
		//结束EXE资源的更新操作  
		if (pIconBytes != NULL)
			delete[] pIconBytes;
		EndUpdateResource(hUpdate, false);
	//清理资源并关闭Icon文件,到此更新操作结束!  
	delete[] pGrpIconDir;
	delete[] pIconDirEntry;
	CloseHandle(hIconFile);


****************如果我们在一个exe或者ico的资源文件中使用icon**************************
它的结构有些微改变,如下:

注意:g_hModule为本进程实例句柄,也可以通过g_hModule = LoadLibrary(_TEXT("C:\\Ohter.exe")); 来获取其他exe中的资源文件,达到复制图标的效果。

//在使用时,这儿需要重新设置结构体对其方式,不然系统会默认为4个字节,我们就不能正确读取资源文件了
#pragma pack( push ) 
#pragma pack( 2 )  //我们调整为2个字节对其
typedef struct tagGRPICONDIR
	WORD idReserved;
	WORD idType;
	WORD idCount;
	GRPICONDIRENTRY idEntries[1];
}GRPICONDIR, *LPGRPICONDIR;
#pragma pack( pop ) //恢复对齐状态
#pragma pack( push )
#pragma pack( 2 )
typedef struct tagGRPICONDIRENTRY
	BYTE bWidth;
	BYTE bHeight;
	BYTE bColorCount;
	BYTE bReserved;
	WORD wPlanes;
	WORD wBitCount;
	DWORD dwBytesInRes;
	WORD nID;
}GRPICONDIRENTRY, *LPGRPICONDIRENTRY;;
#pragma pack( pop )
//下面例子为从一个Icon资源文件中更改exe文件的图标
void changedExeIcon(LPCTSTR lpExeName, UINT ulIconID)
	HRSRC	hRsrc = NULL;
	HGLOBAL	hGlobal = NULL;
	HANDLE  hUpdateRes = NULL;
	LPVOID	lpRes = NULL;
	LPGRPICONDIR lpIcon;
	if ((hRsrc = FindResource(g_hModule, MAKEINTRESOURCE(ulIconID), RT_GROUP_ICON)) == NULL)//获取ID为ulIconID1的Icon图标资源
		return ;
	if ((hGlobal = LoadResource(g_hModule, hRsrc)) == NULL)
		return ;
	if ((lpIcon = (LPGRPICONDIR)LockResource(hGlobal)) == NULL)
		return ;
	hUpdateRes = BeginUpdateResource(lpExeName, FALSE);
	if (hUpdateRes == NULL)
		return;
	DWORD szRes = SizeofResource(g_hModule, hRsrc);
	//128是WINDOWS系统默认图标
	//更新exe的RT_GROUP_ICON
	BOOL bSuc = UpdateResource(hUpdateRes, RT_GROUP_ICON, MAKEINTRESOURCE(128), MAKELANGID(LANG_CHINESE, SUBLANG_SYS_DEFAULT), LockResource(hGlobal), szRes);
	//读取Icon中每一个图片
	for (size_t i = 0; i < lpIcon->idCount; i++)
		if ((hRsrc = FindResource(g_hModule, MAKEINTRESOURCE(lpIcon->idEntries[i].nID), RT_ICON)) == NULL)
			return;
		if ((hGlobal = LoadResource(g_hModule, hRsrc)) == NULL)
			return;
		szRes = SizeofResource(g_hModule, hRsrc);
		//更新exe相应的RT_ICON
		UpdateResource(hUpdateRes, RT_ICON, MAKEINTRESOURCE(i), MAKELANGID(LANG_CHINESE, SUBLANG_SYS_DEFAULT), LockResource(hGlobal), szRes);
		//这儿有个疑问,在DLL中修改exe则为下面这样的格式,不知道为什么?
		//UpdateResource(hUpdateRes, RT_ICON, MAKEINTRESOURCE(lpIcon->idEntries[i].nID), MAKELANGID(LANG_CHINESE, SUBLANG_SYS_DEFAULT), LockResource(hGlobal), szRes);
	EndUpdateResource(hUpdateRes, FALSE);

本文参考:http://blog.csdn.net/hbxtlhx/article/details/5026725 前言:这两天为exe文件做一个随机图标的功能,要求每次运行后图标都动态改变,在网上找了很多代码,都有一部分缺陷,参考了一些文档后进行了修改,现在在此进行总结:一个icon资源(可以是*.ico文件,也可以是windows资源节区里的icon group),可以包含多张图片。这些图片有着各自的size或者颜色深度,这些图片可以是bmp格式或者png格式(vista之后支持,一般256*256时使
matlab改变GUI和figure左上角图标的方法并生成exe文件-修改Matlab Figure图标的方法.rar 1. GUI左上角图标的更改,假设GUI的Tag为figure1,在其OpeningFcn里添加 h = handles.figure1; %返回其句柄 newIcon = javax.swing.ImageIcon figFrame = get; %取得Figure的JavaFrame。 figFrame.setFigureIcon; %修改图标 %%%生成exe文件的方法在附件里 2. 一般图形窗口的左上角图标的更改 clear newIcon=javax.swing.ImageIcon; h=figure; %创建一个Figure,并返回其句柄 figFrame = get; %取得Figure的JavaFrame。 figFrame.setFigureIcon; %修改图标 程序放在附件里了,大家可以试试,效果如下
因为项目打包使用的打包软件是installshield 2010,有需要更改EXEIcon及安装界面的需求,在网上找了一大堆资料,并且自己试过之后得出以下结论:(只在installshield 2010下使用过,其它版本请自行摸索) 1、修改文件的资源文件的方法:使用Visual Studio 的文件→打开→文件,打开指定文件,然后再修改替换资源文件即可,下不赘述; 。。。。。。。。。。
平台:QT5.12.9 + Windows + mingw32(可直接编译,默认是桌面路径) 实现QFileSystemModel+QTableView创建文件管理系统,基于windows平台。 进一步优化该功能,为了适配嵌入式arm平台,实现QFileSystemModel的自定义修改图标功能。这样用户可以通过不同文件类型需求,自定义自己所要显示的图标。 说明:该程序默认文件路径为桌面路径,测试自定义的文件后缀类型为.txt,如果需要改为其他类型,仿照txt部分进行实现
1.打包的库pyinstaller 通过PC端win+R,输入cmd进入控制台界面,cd到你的文件夹下 可以通过pip命令操作安装:pip install pyinstaller 有时候会出现两种错误: 其中一种是pip命令也许需要更新,此时就可以先更新pip, python -m pip install --upgrade pip 第二种错误,是由于网络超时造成的,可能是网络不稳定,因为下载的镜...
Delphi是一种可视化的编程语言和集成开发环境,可用于创建各种应用程序。修改文件图标是其中的一个功能,下面介绍如何使用Delphi来实现该功能。 我们可以使用ShellAPI单元中的ExtractIconEx函数来获取系统中的图标,并使用SHChangeNotify函数通知系统文件更改。 首先,在程序中添加ShellAPI单元,然后创建一个TImageList组件,其用于存储我们获取到的图标。接下来定义一个函数GetFileIcon用于获取文件图标。 函数的代码如下: procedure GetFileIcon(const AFileName: string; ImageList: TImageList; var IconIndex: integer); Icon: HICON; IconCount: integer; begin IconCount := ExtractIconEx(PChar(AFileName), -1, nil, nil, 0); if IconCount > 0 then begin IconIndex := ImageList.AddIcon(Icon); DestroyIcon(Icon); 接着,在主窗体的OnCreate事件中定义一个图标索引值,用于保存我们刚刚添加的图标IconIndex: integer; procedure TForm1.FormCreate(Sender: TObject); begin IconIndex := -1; 最后,在我们需要修改文件图标的地方,我们可以调用GetFileIcon函数来获取需要修改文件图标,然后将其设置为相应的文件图标。 代码如下: procedure TForm1.Button1Click(Sender: TObject); Icon: HICON; FileInfo: TSHFileInfo; begin if SelectDirectory('请选择需要修改图标的目录', '', s) then begin if IconIndex = -1 then begin Icon := LoadIcon(hInstance, 'MAINICON'); ImageList1.Clear; ImageList_AddIcon(ImageList1.Handle, Icon); IconIndex := ImageList1.Count - 1; SHGetFileInfo(PChar(s), 0, FileInfo, SizeOf(FileInfo), SHGFI_ICON or SHGFI_SMALLICON); FileInfo.hIcon := ImageList1.GetIcon(IconIndex); SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nil, nil); ShowMessage('文件图标修改成功!'); 通过以上步骤,我们就可以使用Delphi实现修改文件图标的功能了。