locked
The .ICO file and it`s struct ? RRS feed

  • Question

  • EDIT: So after retrieving the RT_GROUP_ICON data and RT_ICON`s write them to the ICON structs for the .ICO on disk/ file. But I stile don't get a displayable icon.
    If anyone have the time to point me in the right direction.
    I would be wary grateful.

    Here is a link to the code I have come up with this far.
    http://pastebin.com/zHbA2TFA ( thought to use pastebin as longer codes get so messy. )
    Wednesday, December 4, 2013 8:10 PM

Answers

  • Hi WCode,

    I have tested your code but failed. I'm sorry that I cann't understand you clearly. Would you mind clarifying your sentences? 

    If you want to create an icon, I suggest you create an MFC project and here is a tutorial that you can learn. I think that is a

    If you still want to create an icon in console application, here is a code below that can help you.

    #include <windows.h>
    #include <tchar.h>
    
     typedef struct tagHEADER      
     {      
         WORD idReserved;      
         WORD idType;      
         WORD idCount;      
     }HEADER, *LPHEADER;      
    
     typedef struct tagICONDIRENTRY      
     {      
         BYTE bWidth;      
         BYTE bHeight;      
         BYTE bColorCount;      
         BYTE bReserved;      
         WORD wPlanes;      
         WORD wBitCount;      
         DWORD dwBytesInRes;      
         DWORD dwImageOffset;      
     }ICONDIRENTRY, *LPICONDIRENTRY;      
    
     #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;;      
    
     typedef struct tagGRPICONDIR      
     {      
         WORD idReserved;      
         WORD idType;      
         WORD idCount;      
         GRPICONDIRENTRY idEntries[1];      
     }GRPICONDIR, *LPGRPICONDIR;      
     #pragma pack( pop )     
      
      
     //.CPP file main code:
    //view plaincopy to clipboardprint?
     void ChangeExeIcon(LPCTSTR lpIconFile, LPCTSTR lpExeName) 
     {      
         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);      
         
         //Open the Icon file      
         hIconFile = CreateFile(lpIconFile, GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);      
         if (hIconFile == INVALID_HANDLE_VALUE)      
         {      
             return;      
         }      
         //read the file head pointer      
         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;      
         }      
              
         ret = ReadFile(hIconFile, pIconDirEntry, header.idCount*sizeof(ICONDIRENTRY), &dwReserved, NULL);      
         if (!ret)      
         {      
             delete[] pIconDirEntry;   
             CloseHandle(hIconFile);      
             return;      
         }      
              
         nGSize=sizeof(GRPICONDIR)+header.idCount*sizeof(ICONDIRENTRY);      
         pGrpIconDir=(LPGRPICONDIR)new BYTE[nGSize];   
         ZeroMemory(pGrpIconDir, nSize);
             
         pGrpIconDir->idReserved=header.idReserved;      
         pGrpIconDir->idType=header.idType;      
         pGrpIconDir->idCount=header.idCount;      
              
         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+1;        }      
            
         hUpdate = BeginUpdateResource(lpExeName, false);      
         if (hUpdate!=NULL)      
         {      
             HMODULE hMe= 0; // means load from this module
    
             if (FindResource( hMe, lpExeName, RT_GROUP_ICON))
             {
                        
                 ret = UpdateResource(hUpdate, RT_GROUP_ICON, MAKEINTRESOURCE(0), MAKELANGID(LANG_CHINESE, SUBLANG_SYS_DEFAULT), (LPVOID)pGrpIconDir, nGSize);      
                 if (!ret)      
                 {       
                     delete[] pIconDirEntry;
                     delete[] pGrpIconDir;  
                     CloseHandle(hIconFile);      
                     return;      
                 }      
             }
    
            
             for(i=0;i<header.idCount;i++)      
             {      
                    
                 nSize = pIconDirEntry[i].dwBytesInRes;      
                       
                 dwRet=SetFilePointer(hIconFile, pIconDirEntry[i].dwImageOffset, NULL, FILE_BEGIN);      
                 if (dwRet==INVALID_SET_FILE_POINTER)      
                 {      
                     break;      
                 }      
                             
                 delete[] pIconBytes;
                 
                 pIconBytes = new BYTE[nSize];  
                 ZeroMemory(pIconBytes, nSize);
                 ret = ReadFile(hIconFile, (LPVOID)pIconBytes, nSize, &dwReserved, NULL);      
                 if(!ret)      
                 {      
                     break;      
                 }      
                       
                 ret = UpdateResource(hUpdate, RT_ICON, MAKEINTRESOURCE(pGrpIconDir->idEntries[i].nID), MAKELANGID(LANG_CHINESE, SUBLANG_SYS_DEFAULT), (LPVOID)pIconBytes, nSize);      
                 if(!ret)      
                 {      
                     break;      
                 } 
             }      
                 
             if (pIconBytes!=NULL)      
             {      
                delete[] pIconBytes;
             }      
    
             EndUpdateResource(hUpdate, false);      
         }    
         
         
        SAFE_ARRAY_DELETE(pGrpIconDir); 
         SAFE_ARRAY_DELETE(pIconDirEntry);       
         CloseHandle(hIconFile);      
     }
    If you still have any questions about this issue, please feel free to let me know and privode us with details.

    • Marked as answer by WCode Thursday, December 5, 2013 9:20 PM
    Thursday, December 5, 2013 1:51 PM

All replies

  • Hi WCode,

    I have tested your code but failed. I'm sorry that I cann't understand you clearly. Would you mind clarifying your sentences? 

    If you want to create an icon, I suggest you create an MFC project and here is a tutorial that you can learn. I think that is a

    If you still want to create an icon in console application, here is a code below that can help you.

    #include <windows.h>
    #include <tchar.h>
    
     typedef struct tagHEADER      
     {      
         WORD idReserved;      
         WORD idType;      
         WORD idCount;      
     }HEADER, *LPHEADER;      
    
     typedef struct tagICONDIRENTRY      
     {      
         BYTE bWidth;      
         BYTE bHeight;      
         BYTE bColorCount;      
         BYTE bReserved;      
         WORD wPlanes;      
         WORD wBitCount;      
         DWORD dwBytesInRes;      
         DWORD dwImageOffset;      
     }ICONDIRENTRY, *LPICONDIRENTRY;      
    
     #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;;      
    
     typedef struct tagGRPICONDIR      
     {      
         WORD idReserved;      
         WORD idType;      
         WORD idCount;      
         GRPICONDIRENTRY idEntries[1];      
     }GRPICONDIR, *LPGRPICONDIR;      
     #pragma pack( pop )     
      
      
     //.CPP file main code:
    //view plaincopy to clipboardprint?
     void ChangeExeIcon(LPCTSTR lpIconFile, LPCTSTR lpExeName) 
     {      
         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);      
         
         //Open the Icon file      
         hIconFile = CreateFile(lpIconFile, GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);      
         if (hIconFile == INVALID_HANDLE_VALUE)      
         {      
             return;      
         }      
         //read the file head pointer      
         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;      
         }      
              
         ret = ReadFile(hIconFile, pIconDirEntry, header.idCount*sizeof(ICONDIRENTRY), &dwReserved, NULL);      
         if (!ret)      
         {      
             delete[] pIconDirEntry;   
             CloseHandle(hIconFile);      
             return;      
         }      
              
         nGSize=sizeof(GRPICONDIR)+header.idCount*sizeof(ICONDIRENTRY);      
         pGrpIconDir=(LPGRPICONDIR)new BYTE[nGSize];   
         ZeroMemory(pGrpIconDir, nSize);
             
         pGrpIconDir->idReserved=header.idReserved;      
         pGrpIconDir->idType=header.idType;      
         pGrpIconDir->idCount=header.idCount;      
              
         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+1;        }      
            
         hUpdate = BeginUpdateResource(lpExeName, false);      
         if (hUpdate!=NULL)      
         {      
             HMODULE hMe= 0; // means load from this module
    
             if (FindResource( hMe, lpExeName, RT_GROUP_ICON))
             {
                        
                 ret = UpdateResource(hUpdate, RT_GROUP_ICON, MAKEINTRESOURCE(0), MAKELANGID(LANG_CHINESE, SUBLANG_SYS_DEFAULT), (LPVOID)pGrpIconDir, nGSize);      
                 if (!ret)      
                 {       
                     delete[] pIconDirEntry;
                     delete[] pGrpIconDir;  
                     CloseHandle(hIconFile);      
                     return;      
                 }      
             }
    
            
             for(i=0;i<header.idCount;i++)      
             {      
                    
                 nSize = pIconDirEntry[i].dwBytesInRes;      
                       
                 dwRet=SetFilePointer(hIconFile, pIconDirEntry[i].dwImageOffset, NULL, FILE_BEGIN);      
                 if (dwRet==INVALID_SET_FILE_POINTER)      
                 {      
                     break;      
                 }      
                             
                 delete[] pIconBytes;
                 
                 pIconBytes = new BYTE[nSize];  
                 ZeroMemory(pIconBytes, nSize);
                 ret = ReadFile(hIconFile, (LPVOID)pIconBytes, nSize, &dwReserved, NULL);      
                 if(!ret)      
                 {      
                     break;      
                 }      
                       
                 ret = UpdateResource(hUpdate, RT_ICON, MAKEINTRESOURCE(pGrpIconDir->idEntries[i].nID), MAKELANGID(LANG_CHINESE, SUBLANG_SYS_DEFAULT), (LPVOID)pIconBytes, nSize);      
                 if(!ret)      
                 {      
                     break;      
                 } 
             }      
                 
             if (pIconBytes!=NULL)      
             {      
                delete[] pIconBytes;
             }      
    
             EndUpdateResource(hUpdate, false);      
         }    
         
         
        SAFE_ARRAY_DELETE(pGrpIconDir); 
         SAFE_ARRAY_DELETE(pIconDirEntry);       
         CloseHandle(hIconFile);      
     }
    If you still have any questions about this issue, please feel free to let me know and privode us with details.

    • Marked as answer by WCode Thursday, December 5, 2013 9:20 PM
    Thursday, December 5, 2013 1:51 PM
  • Thank you weary much for your help this is great.
    I learned alot from that code, and am sure I understand it correctly now.
    I have one follow up question about two lines of code.
    SAFE_ARRAY_DELETE(pGrpIconDir); 
    SAFE_ARRAY_DELETE(pIconDirEntry);       
    Are they a Visual Studio exclusive macro ?
    I have not been able to find much about them on web, or any headers they may be located in.

    Thanks again for this great reply.
    Cheers
    Kjell "WCode"

    No expert, but an expert in trying.

    Thursday, December 5, 2013 9:27 PM
  • Hi Wcode,

    SAFE_ARRAY_DELETE(p); 

    The macro with parameter is used to release the space that the parameter point to. In a word, it is used to delete a newly assigned array.

    Friday, December 6, 2013 3:41 AM