Qt之提取exe/dll/icon文件图标

简述

在 Windows 中,文件查看有很多模式,比如:

  • 缩略图 16*16
  • 平铺 48*48
  • 图标 32*32
  • 列表 16*16

分别对应了多个不同大小的图标。

如果我们要从指定的可执行文件(exe)、动态链接库(dll)、或者图标文件中提取图标,可以使用 ExtractIconEx、ExtractIcon。

  • 简述
  • 说明
  • 效果
  • 依赖
  • 源码

说明

函数 描述
ExtractIcon() 从一个文件中提取指定索引位置的图标,索引从 0 开始。这个函数总是返回大图标(32 x 32)。
ExtractIconEx() 与 ExtractIcon() 相同,但可以提取大图标(32 x 32)和小图标(16 x 16)。

ExtractIconEx() 函数原型:

UINT EXtractlcohEX (
    LPCTSTR IpSZFile,  // 可执行文件、DLL、或图标文件
    int nlconlndex,  // 抽取第一个图标基于零的变址
    HICON FAR*PhiCORLarge,  // 大图标
    HICON FAR'*phiconSmall,  // 小图标
    UINT nlcons  // 从文件中抽取图标的数目
);

效果

依赖

在 pro中,添加:

QT += winextras
LIBS += -lshell32

这样,就可以使用 QtWin 将 HICON 转换为 QPixmap 了。

源码

头文件:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QtWin>

class QLineEdit;
class QPushButton;
class QListWidget;
class QTextEdit;

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = 0);
    ~Widget();

private slots:
    void onSourceSelected();
    void onSaveSelected();
    void onExtract();

private:
    QLineEdit *m_pSourceLineEdit;
    QLineEdit *m_pSaveLineEdit;
    QListWidget *m_pListWidget;
    QTextEdit *m_pTextEdit;
    QPushButton *m_pSourceButton;
    QPushButton *m_pSaveButton;
    QPushButton *m_pExtractButton;
};

#endif // WIDGET_H

源文件:

#include "widget.h"
#include <QLineEdit>
#include <QListWidget>
#include <QPushButton>
#include <QTextEdit>
#include <QFileDialog>
#include <QScopedArrayPointer>
#include <QPixmap>
#include <QFileInfo>
#include <QDir>
#include <QLayout>
#include <qDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    setWindowTitle(QStringLiteral("Qt之提取exe/dll/icon文件图标"));
    resize(400, 400);

    m_pSourceLineEdit = new QLineEdit(this);
    m_pSaveLineEdit = new QLineEdit(this);
    m_pListWidget = new QListWidget(this);
    m_pTextEdit = new QTextEdit(this);
    m_pSourceButton = new QPushButton(this);
    m_pSaveButton = new QPushButton(this);
    m_pExtractButton = new QPushButton(this);

    m_pSourceLineEdit->setReadOnly(true);
    m_pSaveLineEdit->setReadOnly(true);
    m_pTextEdit->setReadOnly(true);

    m_pSourceButton->setText(QStringLiteral("源文件"));
    m_pSaveButton->setText(QStringLiteral("保存路径"));
    m_pExtractButton->setText(QStringLiteral("提取"));

    QGridLayout *pLayout = new QGridLayout(this);
    pLayout->addWidget(m_pSourceLineEdit, 0, 0);
    pLayout->addWidget(m_pSourceButton, 0, 1);
    pLayout->addWidget(m_pSaveLineEdit, 1, 0);
    pLayout->addWidget(m_pSaveButton, 1, 1);
    pLayout->addWidget(m_pListWidget, 2, 0, 1, 2);
    pLayout->addWidget(m_pTextEdit, 3, 0, 1, 2);
    pLayout->addWidget(m_pExtractButton, 4, 1);
    pLayout->setSpacing(10);
    pLayout->setMargin(10);

    m_pListWidget->setViewMode(QListWidget::IconMode );
    m_pListWidget->setResizeMode(QListWidget::Adjust);
    m_pListWidget->setMovement(QListWidget::Static);

    connect(m_pSourceButton, &QPushButton::clicked, this, &Widget::onSourceSelected);
    connect(m_pSaveButton, &QPushButton::clicked, this, &Widget::onSaveSelected);
    connect(m_pExtractButton, &QPushButton::clicked, this, &Widget::onExtract);
}

Widget::~Widget()
{

}

// 设置源文件路径
void Widget::onSourceSelected()
{
    QString fileName = QFileDialog::getOpenFileName(this, QString("Open File"),
                                                    "/home",
                                                    QString("All files (*.*);;DLL files (*.exe *.dll);;Images (*.png *.xpm *.jpg)"));
    if (!fileName.isEmpty())
        m_pSourceLineEdit->setText(fileName);
}

// 设置保存路径
void Widget::onSaveSelected()
{
    QString dir = QFileDialog::getExistingDirectory(this, QString("Open Directory"),
                                                    "/home",
                                                    QFileDialog::ShowDirsOnly
                                                    | QFileDialog::DontResolveSymlinks);
    if (!dir.isEmpty())
        m_pSaveLineEdit->setText(dir);
}

// 提取
void Widget::onExtract()
{
    // 删除之前的 item
    int count = m_pListWidget->count();
    for(int i = 0 ; i < count; ++i) {
        QListWidgetItem *item = m_pListWidget->takeItem(0);
        delete item;
    }

    m_pTextEdit->clear();

    const QString sourceFile = m_pSourceLineEdit->text();
    const QString fileRoot = m_pSaveLineEdit->text();
    QString imageFileRoot = fileRoot.isEmpty() ? QDir::currentPath() : fileRoot;
    const QFileInfo imageFileRootInfo(imageFileRoot);

    // ExtractIconEx 从限定的可执行文件、动态链接库(DLL)、或者图标文件中生成图标句柄数组
    const UINT iconCount = ExtractIconEx((wchar_t *)sourceFile.utf16(), -1, 0, 0, 0);
    if (!iconCount) {
        qDebug() << QString("%1 does not appear to contain icons.").arg(sourceFile);
        return;
    }

    QScopedArrayPointer<HICON> icons(new HICON[iconCount]);
    bool large = true;
    const UINT extractedIconCount = large ?
        ExtractIconEx((wchar_t *)sourceFile.utf16(), 0, icons.data(), 0, iconCount) :
        ExtractIconEx((wchar_t *)sourceFile.utf16(), 0, 0, icons.data(), iconCount);
    if (!extractedIconCount) {
        m_pTextEdit->append(QStringLiteral("从 %1 提取图标失败").arg(sourceFile));
        return;
    }

    m_pTextEdit->append(QString("%1 包含 %2 个图标").arg(sourceFile).arg(extractedIconCount));

    imageFileRoot = imageFileRootInfo.absoluteFilePath() + QLatin1Char('/') + QFileInfo(sourceFile).baseName();
    for (UINT i = 0; i < extractedIconCount; ++i) {
        const QPixmap pixmap = QtWin::fromHICON(icons[i]);
        if (pixmap.isNull()) {
            m_pTextEdit->append(QStringLiteral("图标转换错误"));
            continue;
        }

        // 添加新 item
        QListWidgetItem *pItem = new QListWidgetItem(m_pListWidget);
        pItem->setText(QString("%1 * %2").arg(pixmap.height()).arg(pixmap.width()));
        pItem->setIcon(QIcon(pixmap));
        m_pListWidget->addItem(pItem);

        // 保存图片
        const QString fileName = QString::fromLatin1("%1%2.png").arg(imageFileRoot)
            .arg(i, 3, 10, QLatin1Char('0'));
        if (!pixmap.save(fileName)) {
            m_pTextEdit->append(QStringLiteral("写入图像文件 %1 错误").arg(fileName));
            continue;
        }

        m_pTextEdit->append(QStringLiteral("保存图片文件 %1.").arg(QDir::toNativeSeparators(fileName)));
    }
}

注意: large 表示大图标(32 * 32)如果要提取小图标(16 * 16),将 large 设置为 false 即可。

时间: 2025-01-29 22:21:35

Qt之提取exe/dll/icon文件图标的相关文章

Delphi提取EXE,DLL文件图标

//uses ShellAPI procedure   TForm1.Button1Click(Sender:   TObject); var       IconIndex:Word;       h:hICON; begin       IconIndex:=0;       h:=ExtractIcon(HInstance,pchar('c:"windows"notepad.exe'),IconIndex);       DrawICon(Form1.canvas.Handle,

Qt之根据扩展名获取文件图标、类型

简述 在C++根据扩展名获取文件图标.类型一节中我们分享了如何根据扩展名来获取对应的文件图标.类型,下面.我们在Qt中使用它. 简述 示例 效果 源码 更多参考 示例 如下,我们根据扩展名来获取对应的文件图标.类型. 效果 源码 首先在pro中添加winextras模块: QT += winextras 然后,在源码中包含:#include <QtWin>,之后,方可使用. std::string strArray[13] = {"folder", ".exe&q

Qt之QFileIconProvider(根据扩展名获取文件图标、类型)

简述 在Qt之QFileIconProvider一节中已经讲解关于如何获取文件图标与类型.但只仍针对本地已存在的文件,此节,我们主要运用前面分享的内容,讲述如何通过任意后缀或本地不存在的文件来获取相关的图标与类型. 简述 步骤 示例 效果 源码 更多参考 步骤 因为Qt本身并没有提供对于不存在文件获取图标.类型的接口,所以我们只能另寻出路. 步骤: 通过扩展名(如:txt.exe.pptx)构建临时文件QTemporaryFile. 通过QFileIconProvider获取对应的图标.类型 .

delphi编写提取exe文件的ICO图标

会写自己的EXE程序,但没一个好看的EXE图标,是不是很遗憾啊?很多软件都有很好看的图标,我们为什么不提取出来呢?下面教你怎么用delphi编程提取EXE文件的图标,并保存为ICO格式的. 代码如下: procedureTForm1.getIcon; var Count:Integer; FileName:String; i:integer; begin if(FileName<>Edit1.Text)then begin FileName:=Edit1.Text; I:=0; Count:=

vb.net怎样提取EXE文件的64*64图标?

问题描述 Icon.ExtractAssociatedIcon只能提取32*32的EXE文件图标,有无方法提取64*64图标? 解决方案 解决方案二:可以用API来实现(可获取任意文件的图标):ClassFileAttributes'声明一个WindowsAPI函数.PrivateDeclareFunctionSHGetFileInfoLib"shell32"_(ByValpszPathAsString,ByValdwFileAttributesAsInteger,_ByRefsfiA

Iconworkshop如何提取包含在程序文件中的图标

平时,我们在电脑中会安装很多程序,8630.html">有时候看到不错的http://www.aliyun.com/zixun/aggregation/13277.html">应用程序图标图案,我们可能会希望借鉴使用,该如何做到呢?今天小编在这里就向大家推荐一款ico图标制作软件iconworkshop,通过这款软件大家可以提取包含在程序文件中的图标,同时可以建立起一个图标库来保存这些图标,非常的实用. Iconworkshop风信网下载地址:http://www.itho

VS 2008潜在强大的功能:提取EXE文件中的ICO等资源

先打开VS 2008,然后用文件菜单中的打开文件功能打开一个EXE文件,即可提取QQ等EXE中的资源,如图: 直接在ICON 下的 129 上面点鼠标右键,即可导出一个129.ico的文件了,是不是很神奇呢?呵呵   双击打开ICON下的图片资源,即可看到该ICO资源的内容,如下:   还可以提取EXE中的其它资源,例如SWF MP3等,有些用EXE打包加密的视频资源也可以这样破解了,微软真是强大啊.   像我们做程序开发的,经常会要碰到为自己的EXE程序弄个好点的图标,而网络上下载的ICO提取

qt c++-QT打包发布,找依赖文件DLL

问题描述 QT打包发布,找依赖文件DLL 5C GPSVC.DLL IESHIMS.DLL.QT打包找依赖文件时这两个文件老是不可以.求大神解答.我已经拷贝了这两个文件.怎么还是不可以?我是按照http://blog.csdn.net/gzshun/article/details/7495488这里面的教程.![图片说明](http://img.ask.csdn.net/upload/201604/14/1460603135_724936.png)![图片说明](http://img.ask.c

C++根据扩展名获取文件图标、类型

简述 在Windows系统中,根据扩展名来区分文件类型,比如:.txt(文本文件)..exe(可执行程序).*.zip(压缩文件),下面,我们来根据扩展名来获取对应的文件图标.类型. 简述 源码 源码 如下,我们根据扩展名来获取对应的文件图标.类型. #include <windows.h> #include <iostream> // 获取文件图标 HICON fileIcon(std::string extention) { HICON icon = NULL; if (ext