提取Windows中系统自带的图标资源

news2025/1/11 23:38:15

写应用程序,如果想使用Windows下的图标,可以使用Visual Studio中的图标,比如VS2008的ImageLibrary(笔者已经打包上传到CSDN),也可以使用Windows系统自带的图标。

Windows系统自带了不少高质量的图标资源,只需要将其提取出来即可使用。

在Windows 95到Windows 10 1903之前的版本,都可以直接在dll中提取系统图标,比如最常用的图标都在shell32.dll中。

一、使用IconsExtract提取

可以使用IconsExtract,它是nirsoft开发的软件,该公司开发了许多工具软件,可以去官网查看,http://launcher.nirsoft.net/utilities_list.html有一个列表。

下图是Win10下使用IconsExtract列出的shell32.dll中的图标:

在这里插入图片描述
如果想要提取(导出)图标,选中要导出的图标,可以多选,在右键弹出菜单中选择“Save Selected Icons”。

二、使用ResourceHacker提取

ResourceHacker也可以提取图标,它的功能强大之处在于可以替换资源和编译资源。对于提取图标,但它一次只能提取一个图标,如果要提取大量图标,很繁琐。同时它只能操作dll文件本身嵌入的资源,对Win10 1903及之后版本中的shell32.dll查看不了图标资源。

三、使用7zip解压缩DLL中的资源

其实,Windows下不管是EXE文件,还是DLL文件它都是一个ZIP压缩文件,都可以使用ZIP解压缩来查看内容。比如使用7zip来查看ResourceHacker.exe中的内容:

在这里插入图片描述

查看shell32.dll的内容:

在这里插入图片描述

其中的.rsrc就是内嵌的资源文件所在目录。ICON图标文件就在其中:

在这里插入图片描述

但是在Win10 1903及之后版本,shell32.dll中并不包括图标资源了,它被分离到了C:\Windows\SystemResources\下的同名mun文件中,即shell32.dll.mun

在这里插入图片描述

所以直接解压shell32.dll是无法提取图标文件的,需要使用7zip解压C:\Windows\SystemResources\shell32.dll.mun

在这里插入图片描述

下图是解压出来的文件:

在这里插入图片描述

四、号外

使用VC++创建Windows桌面程序读取并显示图标。

#include <map>
#include <vector>

std::map<HICON,int> mapIcon;
std::vector<HICON> vctIcon;
HMODULE hShell32;

void DebugError(DWORD errorCode)
{
    LPVOID lpMsgBuf;
    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                NULL, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                (LPTSTR)&lpMsgBuf, 0, NULL);
    OutputDebugString((LPTSTR)lpMsgBuf);
    LocalFree(lpMsgBuf);
}

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // TODO: 在此处放置代码。
    DWORD errorCode = 0;
    HMODULE hShell32 = LoadLibrary(_T("shell32.dll"));
    if (hShell32 == nullptr)
    {
        errorCode = GetLastError();
        DebugError(errorCode);
        return FALSE;
    }
    // 由于资源号达到80000+,所以取100000
    for (int i = 1; i < 100000; ++i)
    {
        HICON hIcon = (HICON)LoadImage(hShell32, MAKEINTRESOURCE(i), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);
        if (hIcon != nullptr)
        {
          mapIcon[hIcon] = i;
          vctIcon.push_back(hIcon);
        }
    }

    // 初始化全局字符串
    LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadStringW(hInstance, IDC_WINDOWSPROJECT1, szWindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance);

    // 执行应用程序初始化:
    if (!InitInstance (hInstance, SW_SHOWMAXIMIZED))
    {
        FreeLibrary(hShell32);
        return FALSE;
    }

    HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOWSPROJECT1));

    MSG msg;

    // 主消息循环:
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return (int) msg.wParam;
}

void draw(HDC hdc)
{
   TCHAR buf[16];
   int x = 0, y = 0;
   DWORD maxY = 0;
   ICONINFOEX info;
   info.cbSize = sizeof(info);
   for (int i = 0; i < vctIcon.size(); ++i)
   {
      if (GetIconInfoEx(vctIcon[i], &info))
      {
            if (!info.fIcon)
              continue;

            DrawIcon(hdc, x, y, vctIcon[i]);
            int n = _stprintf_s(buf, ARRAYSIZE(buf), _T("%d"), mapIcon[vctIcon[i]]);
            TextOut(hdc, x, y + info.yHotspot * 2 + 2, buf, n);
            x += info.xHotspot * 3 + 2;
            if (info.yHotspot > maxY)
              maxY = info.yHotspot;
            if (x >= 1900) {
              y += maxY * 3 + 4;
              x = 0;
            }
      }
   }
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_COMMAND:
        {
            int wmId = LOWORD(wParam);
            // 分析菜单选择:
            switch (wmId)
            {
            case IDM_ABOUT:
                DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                break;
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
        }
        break;
    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            // TODO: 在此处添加使用 hdc 的任何绘图代码...
            draw(hdc);            
            EndPaint(hWnd, &ps);
        }
        break;
    case WM_DESTROY:
        for (int i = 0; i < vctIcon.size(); ++i)
        {
            DestroyIcon(vctIcon[i]);
        }
        FreeLibrary(hShell32);
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

执行结果:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/492204.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2019临沂中考数学解析

一、选择 考点&#xff1a; 绝对值&#xff1a;数轴上某个数与原点的距离叫做这个数的绝对值。 其中距离一定是非负的&#xff0c;即大于等于0 考点&#xff1a; 两直线平行&#xff0c;同位角相等邻补角&#xff1a; 指两条直线相交后所得的有一个公共顶点且有一条公共边的两…

一篇SEO指南:新手如何从零开始优化自己的网站

在如今的数字时代&#xff0c;拥有一个优化良好的网站对于任何企业或个人来说都是至关重要的。但是&#xff0c;对于SEO新手来说&#xff0c;如何从零开始优化自己的网站可能是一项看似艰巨的任务。在本文中&#xff0c;我们将为您提供一份SEO指南&#xff0c;帮助您了解从零开…

C++之STL顺序容器

目录 一、STL容器简介 二、顺序容器 一、STL容器简介 STL容器是一个通用的数据结构&#xff0c;可以处理不同数据类型&#xff0c;包含基本的数据结构如链表、堆栈、队列等。可以分为顺序容器、关联容器、 容器适配器、特殊容器。本篇博客将简要介绍一下STL容器中的顺序容器…

Mysql 学习(八)单表查询方法 一

单表访问方法 前面几节我们了解 innodb 的底层数据结构的设计&#xff0c;究其本源我们其实是为了更好的理解如何查询&#xff0c;并且如何使得查询语句更加快速的问题&#xff0c;这节我们就来好好讲一讲首先我们先来创建一个表 CREATE TABLE index_value_table (id INT NOT…

Redis --- 哨兵、分片集群

一、Redis哨兵 Redis提供了哨兵&#xff08;Sentinel&#xff09;机制来实现主从集群的自动故障恢复。 1.1、哨兵原理 集群结构和作用 哨兵的结构如图&#xff1a; 哨兵的作用如下&#xff1a; 监控&#xff1a;Sentinel 会不断检查您的master和slave是否按预期工作 自动故障…

mysql 排名与排序

MySQL 8.0 版本新增 两个排名函数 分别是 ROW_NUMBER() 与 RANK() 用法 SELECT ROW_NUMBER() OVER(ORDER BY id) AS rowNo, name FROM users; SELECT RANK() OVER(ORDER BY score DESC) AS rankNo, name, score FROM students;后面跟 OVER&#xff08;&#xff09;括号里…

惠普星 TP01-055ccn电脑重装系统步骤

如果你的惠普星 TP01-055ccn电脑出现了系统问题&#xff0c;或者你想更换一个全新的微软操作系统&#xff0c;自己有不清楚相关的重装系统步骤怎么办&#xff1f;别担心&#xff0c;你可以参考以下的惠普星 TP01-055ccn电脑重装系统步骤来执行。 ​ 惠普星 TP01-055ccn电脑怎…

第1章 .Net7 Areas实现

1 集成路由匹配模式 var builder WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllersWithViews(); var app builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { …

【LeetCode】376. 摆动序列

376. 摆动序列 思路 首先&#xff0c;我们可以将摆动序列分为两种&#xff1a; 「上升摆动序列」&#xff0c;当且仅当该序列是摆动序列&#xff0c;且最后一个元素呈上升趋势。如序列 [1,3,2,4] 即为「上升摆动序列」。 「下降摆动序列」&#xff0c;当且仅当该序列是摆动序…

深度解读:《数字孪生世界白皮书(2023)》全方位剖析

2023年初&#xff0c;中国信息通信研究院发布了《数字孪生城市产业图谱研究报告&#xff08;2022&#xff09;》&#xff0c;报告中提出我国数字孪生产业四阶段体系&#xff0c;2020年到2030年是我国数字孪生产业增长期&#xff0c;当前数字孪生市场需求和技术均处于高速发展阶…

腹部肿瘤内科专家朱利明:化疗也能“订制”,晚期结直肠癌不再“无药可救”

肠癌是发生在结肠和直肠的癌症&#xff0c;近二三十年来发病率快速上升。就在近期&#xff0c;“日本女大胃王菅原初代患肠癌病逝”的消息登上热搜&#xff0c;一时引发网友关注热议。 “人生有哲学三问&#xff1a;我是谁&#xff1f;我从哪里来&#xff1f;我到哪里去&#x…

window下sql-server备份后,拷贝到centos上

一.window下sql-server management 打开本地数据库&#xff0c;点备份 二.拷贝到centos下对应目录 mkdir -p /var/opt/mssql/backup 三.在 Linux 上还原数据库 下列步骤使用 sqlcmd 工具。 如果尚未安装 SQL Server 工具&#xff0c;请按照以下步骤安装&#xff1a; ●(1)用…

DJ5-3/4 中断处理程序和设备驱动程序

目录 5.3 中断机构和中断处理程序 5.3.1 中断简介 5.3.2 中断处理程序 5.4 设备驱动程序 5.4.1 设备驱动程序概述 5.4.2 设备驱动程序的处理过程 5.4.3 对 I/O 设备的控制方式 5.3 中断机构和中断处理程序 5.3.1 中断简介 1、中断和陷入 -- CPU 外部事件和内…

基于C++的通讯管理系统

1、系统需求 通讯录是一个可以记录亲人、好友信息的工具。本教程主要利用C来实现-个通讯录管理系统 系统中需要实现的功能如下: ●添加联系人:向通讯录中添加新人&#xff0c;信息包括(姓名、性别、年龄、联系电话、家庭住址)最多记录1000人 ●显示联系人:显示通讯录中所有联系…

手把手教你搭建ROS阿克曼转向小车之(增量式PID代码实现)

在上一篇文章中我们已经成功的把编码器的反馈值给计算出来&#xff0c;这篇文章将会讲解怎么使用反馈回来的速度值进行PID计算&#xff0c;从而闭环控制电机的速度。 PID算法介绍 1.开环控制系统 开环控制系统(open-loop control system)是指被控对象的输出(被控制量)对控制器…

【软件开发】从单机到分布式

从单机到分布式 1.单台服务器应用 问题&#xff1a;由于流量越来越大出现服务器性能问题。 2.应用服务器和数据库服务器分离 对架构增加了一台服务器&#xff0c;应用和数据库分别部署到不同的服务器上&#xff0c;对于开发和测试没有任何影响&#xff0c;只需要应用服务器新…

画了个 MSP430F149的最小系统板 开源出来了

使用MSP430F149单片机设计的一个最小系统板&#xff0c;包含晶振电路、复位电路、CH340串口和BSL下载电路、按键和LED电路等&#xff0c;使用了Type-C接口作为供电和串口通信&#xff0c;另外引出了JTAG接口&#xff0c;所有IO口都引出了。 板载了3个按键和LED&#xff0c;可以…

项目范围说明书如何编写?

范围说明书是一份定义了项目范围的所有要素以及假设、项目要求和验收标准的文件。项目范围说明书将作为主要工具&#xff0c;供利益相关者和团队成员参考&#xff0c;并作为准确衡量项目成功的准则。 项目范围说明书是范围管理计划的一部分&#xff0c;包含了管理项目范围的所…

百度智能云联合发布《雄安新区2022年大数据研究报告》

近日&#xff0c;百度智能云、百度研究院商业智能实验室联合发布《未来之城 雄姿初显——雄安新区2022年大数据研究报告》&#xff08;以下简称《报告》&#xff09;&#xff0c;运用人工智能和大数据分析技术&#xff0c;全面呈现过去一年雄安新区在承接疏解、生态治理、城市建…

Golang当中的定时器

定时器 前言定时器的基本使用 前言 在平时写代码的时候&#xff0c;我们经常会遇到在将来某个时间点或者间隔一段时间重复执行函数。这个时候我们就可以考虑使用定时器。本片文章主要介绍一下golang当中的几个常用的定时器。time.Timer,time.Ticker,time.After以及time.AfterF…