【Qt】获取当前系统进程并展示(带Icon,同附带扩展名Icon测试 #附效果图#)

39 篇文章 6 订阅
16 篇文章 3 订阅

效果图

在这里插入图片描述

运行和编译环境

	git clone https://gitee.com/fole-del/qt_-process-with-icon_show.git 

Qt 获取当前系统进程并展示

实现手段

  1. 调用Win API先获取系统当前的进程名和PID
  2. 根据进程PIDPROCESSENTRY32W.th32ProcessID)获取进程全路径,全路径接口为GetModuleFileNameEx
  3. Icon:获取Icon并显示,根据第二步获取的全路径,依旧是调用系统API,获取Icon,得到HICON句柄,使用Qt的QtWin::fromHICON接收即可获取QIcon

获取Icon函数

HICON QueryExeIcon(LPCTSTR lpszExePath)
{
    HICON hIcon = NULL;
    SHFILEINFO FileInfo;
    DWORD_PTR dwRet = ::SHGetFileInfo(lpszExePath, 0, &FileInfo, sizeof(SHFILEINFO), SHGFI_ICON);

    // 目标文件不存在
    if (dwRet)
    {
        hIcon = FileInfo.hIcon;
    }
    return hIcon;
}

获取进程相关函数

int Widget::getAllProcess()
{
    int countProcess = 0;	//当前进程数量计数变量
    HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); // 创建进程快照
    PROCESSENTRY32W currentProcess;	// 用来接收 hProcessSnap 的信息

    currentProcess.dwSize = sizeof(currentProcess);		//在使用这个结构之前,先设置它的大小
    HANDLE hProcess = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);//给系统内的所有进程拍一个快照

    if (hProcess == INVALID_HANDLE_VALUE)
    {
        printf("CreateToolhelp32Snapshot()调用失败!\n");
        return -1;
    }

    bool bMore = Process32First(hProcessSnap, &currentProcess);	//获取第一个进程信息
    while (bMore) {
        QString str;
        TCHAR szProcessName[MAX_PATH] = { 0 };
        GetProcessFullPath(currentProcess.th32ProcessID, szProcessName, str); // 该函数后文有完整源码
        m_ProList.append(str);
        bMore = Process32Next(hProcessSnap, &currentProcess);	//遍历下一个
        countProcess++;
    }

    CloseHandle(hProcess);	//清除hProcess句柄

    // QMessageBox::information(this,QString::fromLocal8Bit("检测完毕"),QString::fromLocal8Bit("共有以上%1个进程在运行\n").arg(countProcess), QMessageBox::Ok);
}

源码

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QtWin>
#include <QIcon>
#include <QString>
#include <QListWidget>
#include <QListWidgetItem>
#include <QTableWidgetItem>
#include <QHBoxLayout>
#include <QMessageBox>
#include <QDebug>
#include <QStandardItemModel>
#include <QTableWidget>
#include <QTableView>
#include <QSet> // !!! 使用 Set 过滤进程重复项 可注释相关代码尝试获取全部进程

class Widget : public QWidget
{
    Q_OBJECT

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

public:
    int getAllProcess();
private:
    void getExtIcon();
    void getProIcon();
private:
    QListWidget *m_ExtListWidget;
    QListWidget *m_ProListWidget;
    QHBoxLayout *m_Hbox;

private:
    QStringList m_ProList;
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"

#include <iostream>
#include <windows.h>
#include <tlhelp32.h>	//进程快照函数头文件
#include <string>
#include <stdio.h>
#include <tchar.h>
#include <Psapi.h>
#pragma comment (lib,"Psapi.lib")
using namespace std;

#ifdef UNICODE

#define QStringToTCHAR(x)     (wchar_t*) x.utf16()
#define PQStringToTCHAR(x)    (wchar_t*) x->utf16()
#define TCHARToQString(x)     QString::fromUtf16((x))
#define TCHARToQStringN(x,y)  QString::fromUtf16((x),(y))

#else

#define QStringToTCHAR(x)     x.local8Bit().constData()
#define PQStringToTCHAR(x)    x->local8Bit().constData()
#define TCHARToQString(x)     QString::fromLocal8Bit((x))
#define TCHARToQStringN(x,y)  QString::fromLocal8Bit((x),(y))

#endif

BOOL DosPathToNtPath(LPTSTR pszDosPath, LPTSTR pszNtPath)
{
    TCHAR			szDriveStr[500];
    TCHAR			szDrive[3];
    TCHAR			szDevName[100];
    INT				cchDevName;
    INT				i;

    //检查参数
    if (!pszDosPath || !pszNtPath)
        return FALSE;

    //获取本地磁盘字符串
    if (GetLogicalDriveStrings(sizeof(szDriveStr), szDriveStr))
    {
        for (i = 0; szDriveStr[i]; i += 4)
        {
            if (!wcscmp(&(szDriveStr[i]), (L"A:\\")) || !wcscmp(&(szDriveStr[i]), _T(L"B:\\")))
                continue;

            szDrive[0] = szDriveStr[i];
            szDrive[1] = szDriveStr[i + 1];
            szDrive[2] = '\0';
            if (!QueryDosDevice(szDrive, szDevName, 100))//查询 Dos 设备名
                return FALSE;

            cchDevName = lstrlen(szDevName);
            if ((pszDosPath, szDevName, cchDevName) == 0)//命中
            {
                lstrcpy(pszNtPath, szDrive);//复制驱动器
                lstrcat(pszNtPath, pszDosPath + cchDevName);//复制路径

                return TRUE;
            }
        }
    }

    lstrcpy(pszNtPath, pszDosPath);

    return FALSE;
}

//获取进程完整路径
BOOL GetProcessFullPath(DWORD dwPID, TCHAR pszFullPath[MAX_PATH], __out QString& str)
{
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);
    if (!hProcess)
    {
        //QMessageBox::warning(NULL,"GetPathByProcessID","无权访问该进程");
        str = "";
    }
    WCHAR filePath[MAX_PATH];
    DWORD ret= GetModuleFileNameEx(hProcess, NULL, filePath, MAX_PATH) ;
    QString file = QString::fromStdWString( filePath );
    //QMessageBox::warning(NULL,"GetPathByProcessID ret=", QString::number(ret)+":"+file);
    CloseHandle(hProcess);
    str = ret == 0 ? "" : file;

    return true;
}

string GetProcessInfo(__in HANDLE hProcess, __in WCHAR* processName)
{
    PROCESSENTRY32* pinfo = new PROCESSENTRY32; //进程信息 (pinfo->dwSize = sizeof(PROCESSENTRY32);)
    MODULEENTRY32* minfo = new MODULEENTRY32; //模块信息 (minfo->dwSize = sizeof(MODULEENTRY32);)
    char shortpath[MAX_PATH];				//保存路径变量

    int flag = Process32First(hProcess, pinfo);	// 从第一个进程开始
    while (flag) {

        if (wcscmp(pinfo->szExeFile, processName) == 0) {

            // 创建进程快照
            HANDLE hModule = CreateToolhelp32Snapshot(
                        TH32CS_SNAPMODULE,		//(DWORD) 快照返回的对象,TH32CS_SNAPMODULE 是指 "特定进程的使用模块的列表"
                        pinfo->th32ProcessID	//(DWORD) 要获取快照进程的PID,当前进程/系统列表 快照时设为0
                        );

            // 把第一个模块信息给 minfo
            Module32First(
                        hModule,  //(HANDLE) CreateToolhelp32Snapshot 的返回句柄
                        minfo	 // (LPMODULEENTRY32)  接收模块信息
                        );

            // 把文件路径给 shortpath
            GetShortPathName(
                        minfo->szExePath,	//  文件路径(但最好不要用这个,因为这个碰到中文会出现乱码)
                        (LPWSTR)shortpath,		// 用来接收 minfo->szExePath 兼容中文的值
                        256			// 缓冲区大小
                        );

            return shortpath;
        }

        // 下一个进程
        flag = Process32Next(hProcess, pinfo);
    }

    return NULL;
}

int Widget::getAllProcess()
{
    int countProcess = 0;	//当前进程数量计数变量
    HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); // 创建进程快照
    PROCESSENTRY32W currentProcess;	// 用来接收 hProcessSnap 的信息

    currentProcess.dwSize = sizeof(currentProcess);		//在使用这个结构之前,先设置它的大小
    HANDLE hProcess = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);//给系统内的所有进程拍一个快照

    if (hProcess == INVALID_HANDLE_VALUE)
    {
        printf("CreateToolhelp32Snapshot()调用失败!\n");
        return -1;
    }

    bool bMore = Process32First(hProcessSnap, &currentProcess);	//获取第一个进程信息
    while (bMore) {
        QString str;
        TCHAR szProcessName[MAX_PATH] = { 0 };
        GetProcessFullPath(currentProcess.th32ProcessID, szProcessName, str);
        m_ProList.append(str);
        bMore = Process32Next(hProcessSnap, &currentProcess);	//遍历下一个
        countProcess++;
    }

    CloseHandle(hProcess);	//清除hProcess句柄

    // QMessageBox::information(this,QString::fromLocal8Bit("检测完毕"),QString::fromLocal8Bit("共有以上%1个进程在运行\n").arg(countProcess), QMessageBox::Ok);
}

// 获取文件图标
HICON fileIcon(std::string extention)
{
    HICON icon = NULL;
    if (extention.length() > 0)
    {
        LPCSTR name = extention.c_str();

        SHFILEINFOA info;
        if (SHGetFileInfoA(name,
                           FILE_ATTRIBUTE_NORMAL,
                           &info,
                           sizeof(info),
                           SHGFI_SYSICONINDEX | SHGFI_ICON | SHGFI_USEFILEATTRIBUTES))
        {
            icon = info.hIcon;
        }
    }

    return icon;
}

HICON QueryExeIcon(LPCTSTR lpszExePath)
{
    HICON hIcon = NULL;
    SHFILEINFO FileInfo;
    DWORD_PTR dwRet = ::SHGetFileInfo(lpszExePath, 0, &FileInfo, sizeof(SHFILEINFO), SHGFI_ICON);

    // 目标文件不存在
    if (dwRet)
    {
        hIcon = FileInfo.hIcon;
    }
    return hIcon;
}
// 获取文件类型
std::string fileType(std::string extention)
{
    std::string type = "";
    if (extention.length() > 0)
    {
        LPCSTR name = extention.c_str();

        SHFILEINFOA info;
        if (SHGetFileInfoA(name,
                           FILE_ATTRIBUTE_NORMAL,
                           &info,
                           sizeof(info),
                           SHGFI_TYPENAME | SHGFI_USEFILEATTRIBUTES))
        {
            type = info.szTypeName;
        }
    }

    return type;
}

// 获取文件夹图标
HICON folderIcon()
{
    std::string str = "folder";
    LPCSTR name = str.c_str();

    HICON icon = NULL;

    SHFILEINFOA info;
    if (SHGetFileInfoA(name,
                       FILE_ATTRIBUTE_DIRECTORY,
                       &info,
                       sizeof(info),
                       SHGFI_SYSICONINDEX | SHGFI_ICON | SHGFI_USEFILEATTRIBUTES))
    {
        icon = info.hIcon;
    }

    return icon;
}

// 获取文件夹类型
std::string folderType()
{
    std::string str = "folder";
    LPCSTR name = str.c_str();

    std::string type;

    SHFILEINFOA info;
    if (SHGetFileInfoA(name,
                       FILE_ATTRIBUTE_DIRECTORY,
                       &info,
                       sizeof(info),
                       SHGFI_TYPENAME | SHGFI_USEFILEATTRIBUTES))
    {
        type = info.szTypeName;
    }

    return type;
}

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    setGeometry(200, 200, 800, 800);
    setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Preferred);

    m_Hbox = new QHBoxLayout(this);

    m_ExtListWidget = new QListWidget;
    m_ExtListWidget->setSizePolicy(QSizePolicy::Maximum,QSizePolicy::Preferred);

    m_ProListWidget = new QListWidget;
    m_ProListWidget->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Preferred);

    m_Hbox->addWidget(m_ExtListWidget);
    m_Hbox->addWidget(m_ProListWidget);

    m_Hbox->setStretch(0,3);
    m_Hbox->setStretch(1,7);

    getExtIcon();
    getProIcon();
}


Widget::~Widget()
{
}

void Widget::getExtIcon()
{

    m_ExtListWidget->setViewMode(QListView::ListMode);

    std::string strArray[13] = {"folder", ".exe", ".zip", ".har", ".hwl", ".accdb",
                                ".xlsx", ".pptx", ".docx", ".txt", ".h", ".cpp", ".pro"};
    int nCount = sizeof(strArray) / sizeof(std::string);
    for (int i = 0; i < nCount ; ++i)
    {
        // 获取图标、类型
        QPixmap pixmap;
        std::string type;
        int nPos = -1;
        nPos = strArray[i].find(".");
        if (nPos >= 0)
        {
            // Qt4:QPixmap::fromWinHICON(icon)
            pixmap = QtWin::fromHICON(fileIcon(strArray[i]));
            type = fileType(strArray[i]);
        }
        else
        {
            pixmap = QtWin::fromHICON(folderIcon());
            type = folderType();
        }

        QIcon icon;
        icon.addPixmap(pixmap);
        QString strType = QString::fromLocal8Bit(type.c_str());

        // 添加单元项
        QListWidgetItem *pItem = new QListWidgetItem;
        pItem->setIcon(icon);
        pItem->setText(strType);
        m_ExtListWidget->addItem(pItem);
    }
}

void Widget::getProIcon()
{
    getAllProcess();

    QSet<QString> SetList;
    for(auto it : m_ProList)
    {
        SetList.insert(it);
    }

    int nCount = SetList.size();
    foreach(const QString& value, SetList)
    {
        if(value.isEmpty())
        {
            continue;
        }

        // 获取图标、类型
        QPixmap pixmap;
        std::string type;

        // Qt4:QPixmap::fromWinHICON(icon)
        pixmap = QtWin::fromHICON(QueryExeIcon(value.toStdWString().c_str()));
        type = fileType(value.toStdString());

        QIcon icon;
        icon.addPixmap(pixmap);
        QString strType = value;

        // 添加单元项
        QListWidgetItem *pItem = new QListWidgetItem;
        pItem->setCheckState(Qt::Unchecked);
        pItem->setIcon(icon);
        pItem->setText(strType);
        m_ProListWidget->addItem(pItem);
    }
}


  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
### 回答1: qtdesign内置icon是指在QtDesign Studio中预先提供了一系列图标开发者可以直接使用这些图标来设计和美化自己的应用程序界面。 qtdesign内置的icon具有以下特点: 1. 丰富多样:QtDesign Studio内置的icon包含了很多常用的图标形状和符号,涵盖了各个领域和功能,包括按钮、菜单、工具栏等常见的界面元素,以及一些通用的icons,如箭头、勾选框、警告符号等。 2. 多种尺寸支持:QtDesign Studio内置的icon支持多种不同的尺寸,开发者可以根据实际需要选择合适的图标尺寸。这样可以确保图标在不同的设备和分辨率下显示效果一致。 3. 可定制性:开发者可以通过QtDesign Studio对内置的icon进行一定程度的定制,例如调整颜色、大小、样式等。这样可以使得图标更好地适应应用程序的整体设计风格。 4. 资源管理:QtDesign Studio内置的icon使用资源管理的方式进行管理,可以方便地进行导入、导出和共享。这样开发者可以更好地组织和管理icon资源,提高团队协作效率。 通过使用qtdesign内置icon开发者可以快速搭建漂亮的应用程序界面,减少自行设计icon的时间和工作量,提高开发效率。同时,这些内置的icon设计合理,具有一致性和美观性,能够提升应用程序的用户体验。 ### 回答2: qtdesign是Qt框架中用于构建图形用户界面的工具,它提供了一些内置的图标icon)供开发者使用。这些内置图标可以用于按钮、菜单、工具栏等组件上,以增强用户界面的美观和交互性。 在Qt中,可以通过QIcon类来使用内置的图标。QIcon类提供了许多静态函数,用于返回各种内置图标的实例。开发者可以根据自己的需求选择合适的内置图标进行界面设计。例如,可以使用QIcon::fromTheme()函数来获取主题样式下的图标,或者使用QIcon::fromTheme()函数来获取特定风格下的图标。 以下是一些常用的内置图标的实例获取方法: 1. 使用QIcon::fromTheme()函数获取主题样式下的图标: QIcon icon = QIcon::fromTheme("document-save"); 2. 使用QIcon::fromTheme()函数获取特定风格下的图标: QIcon icon = QIcon::fromTheme("folder-open", QIcon(":/images/folder-open.png")); 3. 直接使用静态函数返回某个内置图标的实例: QIcon icon = QIcon::fromTheme("edit-copy"); // 返回一个剪贴板图标实例 使用这些内置图标可以方便地为界面添加一些标准化的图标,使得用户能够更加直观地理解和操作界面。同时,Qt还支持自定义图标的加载和使用,开发者可以通过将自己的图标文件添加到项目资源中,并在代码中指定图标文件的路径来使用自定义图标。 ### 回答3: Qt Design Studio是一个专业的用户界面设计工具,它的主要功能是简化和加速用户界面开发流程。在Qt Design Studio中,内置了大量的图标资源,方便开发者在界面设计中使用。 Qt Design Studio内置的图标资源包括了各种常见的图标,如按钮图标、菜单图标、工具栏图标等,这些图标资源可以直接在设计工具的“资源管理器”中浏览和使用。开发者可以根据需要选择合适的图标,然后将其拖放到设计界面中,轻松实现UI元素的完善。 除了内置的图标资源,Qt Design Studio还支持导入自定义图标开发者可以根据自己的需求,设计和制作独特的图标,并将其导入到设计工具中使用。导入自定义图标的过程也非常简便,只需将图标文件拖放到资源管理器中即可。 通过使用Qt Design Studio内置的图标资源,开发者可以快速构建出美观、直观的用户界面。使用内置图标可以避免从零开始设计图标的时间和精力,同时也能保证UI界面的一致性和可复用性。 总之,Qt Design Studio内置了丰富的图标资源,使得开发者可以轻松地在界面设计中使用图标。内置图标的选择和使用非常方便,能够大大提升开发效率,同时还能够保证UI界面的美观和一致性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

欧恩意

如有帮助,感谢打赏!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值