zoukankan      html  css  js  c++  java
  • [工具-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

  • 相关阅读:
    使用CORS解决flask前端页面跨域问题
    re.search 与 re.match的区别
    jupyter-notebook快捷键的使用
    docker端口的映射顺序
    [转]/dev/null 命令用法
    [转]Docker容器内不能联网的6种解决方案
    牛客网python试题-错误整理-20180711
    docker常用命令
    linux实用命令-待补充
    docker exec小脚本
  • 原文地址:https://www.cnblogs.com/superdo/p/4489019.html
Copyright © 2011-2022 走看看