[工具-001]C++更换EXE的ICON图标

  我们都知道每个可执行文件EXE都会有自己的图标,它可以在项目生成的时候进行指认,但是有时候我们会遇到两种情况:1.没有源代码,2.我们的项目很多,一个个进行更换很耗时。本人就是因为接到这么一个需求,要用C#做一个批量更换EXE图标的工具,我找了很多的资料,C#并没有提供这方面的API。后面偶然的看到了C++有很多这方面的资料,然后我就有个想法,把C++的代码哪来,然后打成DLL动态链接库不就可以供C#调用了吗?

  下面就我参考的代码贴出。

  首先贴出.H的文件

  #ifndef _MYCODE_H_

  #define _MYCODE_H_

  #ifdef DLLDEMO1_EXPORTS

  #define EXPORTS_DEMO _declspec( dllexport )

  #else #define EXPORTS_DEMO _declspec(dllimport) #endif

  extern "C" EXPORTS_DEMO void ChangeIcon(char* szFileName,char* szIconFile);

  #endif

  然后贴出.CPP文件

  #include "stdafx.h"
  #include "IconChange.h"
  #include <windows.h>
  #include <string>

  using     namespace    std;

  struct TIconHeader
  {
        WORD idReserved;
        WORD idType;
        WORD idCount;            // 目录数
  };

  #pragma pack(1)
  struct TResDirHeader
  {
        BYTE bWidth;             // 图像宽度,以象素为单位。一个字节
        BYTE bHeight;            // 图像高度,以象素为单位。一个字节
        BYTE bColorCount;        // 图像中的颜色数(如果是>=8bpp的位图则为0)
        BYTE bReserved;          // 保留字必须是0
        WORD wPlanes;            // 标设备说明位面数,其值将总是被设为1
        WORD wBitCount;          // 每象素所占位数
        DWORD lBYTEsInRes;       // 每份资源所占字节数
        DWORD lImageOffset;      // 图像数据(iconimage)起点偏移位置
  };
  #pragma pack()

  typedef struct TIconResDirGrp
  {      
     TIconHeader    idHeader ;      
     TResDirHeader idEntries[1];

  } *PIconResDirGrp;

  // =+=+=+=+=+=+=+=+=+=+=+=+=+=+=

  WORD MakeLangID();

  // =+=+=+=+=+=+=+=+=+=+=+=+=+=+=

  WORD MakeLangID()
  {    
    return  (SUBLANG_ENGLISH_US << 10) | LANG_ENGLISH;
  }

  // =+=+=+=+=+=+=+=+=+=+=+=+=+=+=

  void ChangeIcon(char* szFileName,char* szIconFile)
  {     

    int i,FileGrpSize;     
    DWORD dwFileSize,dwBytesRead;     
    void * filemem,*p;     
    PIconResDirGrp FileGrp;     
    HANDLE hFile,hUpdateRes;
    char*   szResName = "AyIcon";  
    WCHAR   szFileNameWCHAR[MAX_PATH]={0};  
    WCHAR   szIconFileWCHAR[MAX_PATH]={0};  
    WCHAR   szResNameWCHAR[MAX_PATH]={0};  

    MultiByteToWideChar(CP_ACP,   0,  szFileName,  -1,  
               szFileNameWCHAR,   sizeof(szFileNameWCHAR));  

    MultiByteToWideChar(CP_ACP,   0,  szIconFile,  -1,  
               szIconFileWCHAR,   sizeof(szIconFileWCHAR));  

    MultiByteToWideChar(CP_ACP,   0, szResName,  -1,  
               szResNameWCHAR,   sizeof(szResNameWCHAR));    

    // open the icon file    
    hFile=CreateFile(szIconFileWCHAR,GENERIC_READ|GENERIC_WRITE, 

             FILE_SHARE_READ|FILE_SHARE_WRITE,

             NULL,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN, 0);

    if (hFile==INVALID_HANDLE_VALUE)     
    {        
      MessageBox(0,L"Failed open Icon File!",NULL,0);       
      return;     
    }    

    // get the file size     
    dwFileSize = GetFileSize(hFile,NULL);

    filemem=malloc(dwFileSize);    

    // read file to memory       
    ReadFile(hFile,filemem, dwFileSize,&dwBytesRead,NULL);

    CloseHandle(hFile);

 
      // assume the TIconResDirGrp STRUCT      
    FileGrp=PIconResDirGrp(filemem);

    // get Icon_Header size    
    FileGrpSize=sizeof(TIconResDirGrp)+(FileGrp->idHeader.idCount-1)
*sizeof(TResDirHeader);     // begin to change the resource        hUpdateRes=BeginUpdateResource(szFileNameWCHAR, false);     // change all frames'resource         for(i=0;i<FileGrp->idHeader.idCount;i++)     {       p=(void *)((DWORD)filemem+FileGrp->idEntries[i].lImageOffset);       // change every frame       UpdateResource(hUpdateRes,RT_ICON,                MAKEINTRESOURCE(FileGrp->idEntries[i].lImageOffset)                , MakeLangID(), p, FileGrp->idEntries[i].lBYTEsInRes);      }     // update header information      UpdateResource(hUpdateRes,RT_GROUP_ICON, szResNameWCHAR, MakeLangID(),              FileGrp, FileGrpSize);     EndUpdateResource(hUpdateRes, false);     free(filemem);   }

  以上就是所有CCP代码。有需要的可以参考下

    结语

  • 受益,C++能操作的底层更多,学会了打DLL包

本站文章为 宝宝巴士 SD.Team 原创,转载务必在明显处注明:(作者官方网站: 宝宝巴士 

转载自【宝宝巴士SuperDo团队】 原文链接: http://www.cnblogs.com/superdo/p/4489019.html

原文地址:https://www.cnblogs.com/superdo/p/4489019.html