C/C++编程笔记:抓取其他程序图标_c++获取窗口截图

C/C++编程笔记:抓取其他程序图标_c++获取窗口截图

编码文章call10242025-02-07 16:25:2914A+A-

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

但是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做的界面运行效果:



总结

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

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

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

点击这里复制本文地址 以上内容由文彬编程网整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!
qrcode

文彬编程网 © All Rights Reserved.  蜀ICP备2024111239号-4