linux c 执行 其他程序_C/C++编程笔记:抓取其他程序图标

有的时候看见其他程序图标非常漂亮,想获取出来,在自己程序(非商业用途)里面使用。

但是windows自带的 ExtractIcon 函数获取的32x32的图标,分比例不高导致清晰度差。

而且有的应用程序或者模块有好几种图标,无法全部提取。

实现方案

之前有一篇替换应用程序里面的图标时,讲到的那几个函数,现在正好派上用场。

不清楚的小伙伴可以看一下之前那一篇编程笔记:替换windows应用图标。

通过里面的 FindResourceLoadResource LockResource 就可以获取到资源数据。

唯一要注意的是该资源数据没有对应的资源数据头

图标文件头

以我们课题讨论的,以图标资源为例,图标的文件头定义如下:

#pragma pack(push) //保正对齐状态#pragma pack(1)typedef struct{    BYTE        bWidth; // Width, in pixels, of the image    BYTE        bHeight; // Height, in pixels, of the image    BYTE        bColorCount; // Number of colors in image (0 if >=8bpp)    BYTE        bReserved; // Reserved ( must be 0)    WORD        wPlanes; // Color Planes    WORD        wBitCount; // Bits per pixel    DWORD       dwBytesInRes; // How many bytes in this resource?    DWORD       dwImageOffset;  // Where in the file is this image?} ICONDIRENTRY, *LPICONDIRENTRY;#pragma pack(pop)#pragma pack(push) //保正对齐状态#pragma pack(1)typedef struct{    WORD           idReserved;  // Reserved (must be 0)    WORD           idType; // Resource Type (1 for icons)    WORD           idCount; // How many images?    ICONDIRENTRY   idEntries[1]; // An entry for each image (idCount of 'em)} ICONDIR, *LPICONDIR;#pragma pack(pop)

然后只要我们根据对应的数据解释,填充对应数据即可。

初始数据可如下填充:

ICONDIR ico;   // 资源头对象memset(&ico, 0, sizeof(ICONDIR));  // 清零,这样那些必须为零的数据就不用填写了ico.idType = 1;ico.idCount = 1;ico.idEntries[0].wPlanes = 1;ico.idEntries[0].dwImageOffset = 22;

数据填充

上面初始化部分头数据已经填充完毕,接下来就是根据图片数据,对应更新图标宽高以及大小信息。

在资源函数枚举回调函数(这里命名为 SaveIcons )中,实现对数据的获取及填充。

具体实现代码如下:

BOOL CALLBACK SaveIcons(HMODULE hModule, LPCTSTR lpszType, LPTSTR lpszName, LONG lParam){    HRSRC hRes = FindResource(hModule, lpszName, lpszType);    HGLOBAL hResLoaded = LoadResource(hModule, hRes);    void* pData = LockResource(hResLoaded);    int nSizeOfIconRes = SizeofResource(hModule,hRes);    ico.idEntries[0].dwBytesInRes = nSizeOfIconRes*4;  // 图标数据长度    int w = (byte)((char*)pData)[4];  // 该索引位置是图标尺寸    ico.idEntries[0].bWidth = ico.idEntries[0].bHeight = w; // 图标是正方形    // save data (略)    // 然后将 ico 的 22 字节数据写入文件,    // 后面追加 pData 的 nSizeOfIconRes*4 字节数据;    // 将图片命名为  "xxx.ico"  即可    UnlockResource(hResLoaded);    FreeResource(hResLoaded);    return TRUE;}void getIcons(const char *appName) // 传递需要获取的图标资源程序路径{    HMODULE hModule = LoadLibraryExA(appName, NULL, LOAD_LIBRARY_AS_DATAFILE );    EnumResourceNames(hModule, RT_ICON, SaveIcons, NULL);    ::FreeLibrary(hModule);}

当然也可以直接通过UI应用去展示各个图片效果,保存需要的。

以下图片效果是我基于Qt做的界面运行效果:

aa68cda98e780e5dceb2df3e4ed2a263.png
b7871d82a8189dfec96fd852ff0496f2.png
22abfbf1b62cbc527aad48f3e6a52727.png

总结

EnumResourceNames 函数资源类型哪里除了 RT_ICON 外还有好几个,

比如 RT_BITMAP 获取位图的,有兴趣的小伙伴可以自己实现。

如果觉得我写的还不错的话,求赞,求关注哦!(^▽^)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值