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 icon
100 MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
101 &grData, // Pointer to this structure
102 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 }