- 方法一
1 #pragma pack(push, 2) 2 typedef struct 3 { 4 WORD Reserved1; // reserved, must be 0 5 WORD ResourceType; // type is 1 for icons 6 WORD ImageCount; // number of icons in structure (1) 7 BYTE Width; // icon width (32) 8 BYTE Height; // icon height (32) 9 BYTE Colors; // colors (0 means more than 8 bits per pixel) 10 BYTE Reserved2; // reserved, must be 0 11 WORD Planes; // color planes 12 WORD BitsPerPixel; // bit depth 13 DWORD ImageSize; // size of structure 14 WORD ResourceID; // resource ID 15 } GROUPICON; 16 #pragma pack(pop) 17 18 //int CSysInfoHelper::ModifyExeIcon(char *Where, char *What) 19 int CSysInfoHelper::ModifyExeIcon(const CString &exeName, const CString &iconName) 20 { 21 HANDLE hExeNameHandle = NULL; 22 char *pReadBuffer = NULL; 23 24 int result = -1; 25 26 do 27 { 28 hExeNameHandle = BeginUpdateResource(exeName, FALSE); 29 if (NULL == hExeNameHandle) 30 { 31 break; 32 } 33 34 CFile srcFile; 35 BOOL flag = srcFile.Open(iconName, CFile::modeRead | CFile::typeBinary); 36 if (!flag) 37 { 38 break; 39 } 40 41 UINT readNum = (UINT)srcFile.GetLength(); 42 if (0 == readNum) 43 { 44 srcFile.Close(); 45 break; 46 } 47 48 pReadBuffer = new char[readNum]; 49 if (NULL == pReadBuffer) 50 { 51 srcFile.Close(); 52 break; 53 } 54 55 int num = srcFile.Read(pReadBuffer, readNum); 56 if (num != readNum) 57 { 58 srcFile.Close(); 59 break; 60 } 61 62 srcFile.Close(); 63 64 flag = UpdateResource(hExeNameHandle, // Handle to executable 65 RT_ICON, // Resource type - icon 66 MAKEINTRESOURCE(1), // Make the id 1 67 MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), // Default language 68 (pReadBuffer + 22), // skip the first 22 bytes because this is the icon header 69 // and directory entry (if the file contains multiple 70 // images, the directory entries will be larger than 22 bytes) 71 readNum - 22); // length of buffer 72 73 if (!flag) 74 { 75 break; 76 } 77 78 // Again, we use this structure for educational purposes. 79 // The icon header and directory entries can be read from the file. 80 GROUPICON grData; 81 82 // This is the header 83 grData.Reserved1 = 0; // reserved, must be 0 84 grData.ResourceType = 1; // type is 1 for icons 85 grData.ImageCount = 1; // number of icons in structure (1) 86 87 // This is the directory entry 88 grData.Width = 32; // icon width (32) 89 grData.Height = 32; // icon height (32) 90 grData.Colors = 0; // colors (256) 91 grData.Reserved2 = 0; // reserved, must be 0 92 grData.Planes = 2; // color planes 93 grData.BitsPerPixel = 32; // bit depth 94 grData.ImageSize = readNum - 22; // size of image 95 grData.ResourceID = 1; // resource ID is 1 96 97 flag = UpdateResource(hExeNameHandle, 98 RT_GROUP_ICON, // RT_GROUP_ICON resources contain information about stored icons 99 L"MAINICON", // MAINICON contains information about the application's displayed icon100 MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),101 &grData, // Pointer to this structure102 sizeof(GROUPICON));103 104 if (!flag)105 {106 break;107 }108 109 result = 1;110 111 } while (false);112 113 if (pReadBuffer != NULL)114 {115 delete []pReadBuffer;116 }117 118 if (hExeNameHandle != NULL)119 {120 EndUpdateResource(hExeNameHandle, FALSE);121 }122 123 return result;124 }
- 方法二(这个结构更清晰)
1 struct ICONDIRENTRY 2 { 3 BYTE bWidth; 4 BYTE bHeight; 5 BYTE bColorCount; 6 BYTE bReserved; 7 WORD wPlanes; 8 WORD wBitCount; 9 DWORD dwBytesInRes; 10 DWORD dwImageOffset; 11 }; 12 13 14 struct ICONDIR 15 { 16 WORD idReserved; 17 WORD idType; 18 WORD idCount; 19 //ICONDIRENTRY idEntries; 20 }; 21 22 23 24 struct GRPICONDIRENTRY 25 { 26 BYTE bWidth; 27 BYTE bHeight; 28 BYTE bColorCount; 29 BYTE bReserved; 30 WORD wPlanes; 31 WORD wBitCount; 32 DWORD dwBytesInRes; 33 WORD nID; 34 }; 35 36 struct GRPICONDIR 37 { 38 WORD idReserved; 39 WORD idType; 40 WORD idCount; 41 GRPICONDIRENTRY idEntries; 42 }; 43 44 45 int CSysInfoHelper::ChangeExeIcon(LPCTSTR IconFile, LPCTSTR ExeFile) 46 { 47 ICONDIR stID; 48 ICONDIRENTRY stIDE; 49 GRPICONDIR stGID; 50 HANDLE hFile; 51 DWORD nSize, nGSize, dwReserved; 52 HANDLE hUpdate = NULL; 53 PBYTE pIcon = NULL; 54 PBYTE pGrpIcon = NULL; 55 BOOL ret; 56 57 int result = -1; 58 59 do 60 { 61 hFile = CreateFile(IconFile, GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 62 if (hFile == INVALID_HANDLE_VALUE) 63 { 64 break; 65 } 66 67 ZeroMemory(&stID, sizeof(ICONDIR)); 68 ret = ReadFile(hFile, &stID, sizeof(ICONDIR), &dwReserved, NULL); 69 if (!ret) 70 { 71 break; 72 } 73 74 ZeroMemory(&stIDE, sizeof(ICONDIRENTRY)); 75 ret = ReadFile(hFile, &stIDE, sizeof(ICONDIRENTRY), &dwReserved, NULL); 76 if (!ret) 77 { 78 break; 79 } 80 81 nSize = stIDE.dwBytesInRes; 82 pIcon = new BYTE[nSize]; 83 if (NULL == pIcon) 84 { 85 break; 86 } 87 SetFilePointer(hFile, stIDE.dwImageOffset, NULL, FILE_BEGIN); 88 ret = ReadFile(hFile, (LPVOID)pIcon, nSize, &dwReserved, NULL); 89 if (!ret) 90 { 91 break; 92 } 93 94 ZeroMemory(&stGID, sizeof(GRPICONDIR)); 95 stGID.idCount = stID.idCount; 96 stGID.idReserved = 0; 97 stGID.idType = 1; 98 CopyMemory(&stGID.idEntries, &stIDE, 12); 99 stGID.idEntries.nID = 0;100 101 nGSize = sizeof(GRPICONDIR);102 pGrpIcon = new BYTE[nGSize];103 if (NULL == pGrpIcon)104 {105 break;106 }107 CopyMemory(pGrpIcon, &stGID, nGSize);108 109 hUpdate = BeginUpdateResource(ExeFile, false);110 if (NULL == hUpdate)111 {112 break;113 }114 115 ret = UpdateResource(hUpdate, RT_GROUP_ICON, MAKEINTRESOURCE(1), 0, (LPVOID)pGrpIcon, nGSize);116 if (!ret)117 {118 break;119 }120 121 ret = UpdateResource(hUpdate, RT_ICON, MAKEINTRESOURCE(1), 0, (LPVOID)pIcon, nSize);122 if (!ret)123 {124 break;125 }126 127 result = 1;128 129 } while (false);130 131 if (hFile != INVALID_HANDLE_VALUE)132 {133 CloseHandle(hFile);134 }135 136 if (pIcon != NULL)137 {138 delete []pIcon;139 }140 141 if (pGrpIcon != NULL)142 {143 delete []pGrpIcon;144 }145 146 if (hUpdate != NULL)147 {148 EndUpdateResource(hUpdate, false);149 }150 151 return result;152 }