我們都知道每個可執行文件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