一、添加进程操作类
右键、添加类
添加变量
二、获取所有32位进程
2.1 获取所有进程
- 创建进程快照
- 判断第一个进程
- 遍历剩余进程
2.2 判断是否为32位进程
2.3 判断是否为32位操作系统
2.4 获取路径与图标
三、加载
3.1 打开进程列表界面
双击主界面中的进程列表,在生成代码中打开进程列表界面:
3.2 类向导添加OnInitDialog函数
右键类向导,添加OnInitDialog函数,加入以下代码
3.3 双击获取选择进程
右键添加时间处理程序,选择双击,然后加入以下代码:
四、运行
运行程序,点击进程列表
五、DlgProgress类全部代码
.h文件
#pragma once
// DlgProgress 对话框
class DlgProgress : public CDialogEx
{
DECLARE_DYNAMIC(DlgProgress)
public:
DlgProgress(CWnd* pParent = nullptr); // 标准构造函数
virtual ~DlgProgress();
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_DIALOG_PROGRESS_LIST };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
DECLARE_MESSAGE_MAP()
private:
BOOL GetAllProcess(); // 获取所有进程
BOOL Is32OS(); // 判断是否为32位系统
BOOL Is32BitProgress(DWORD dwProcessId); // 判断是否是32位进程
BOOL GetFullPathProcess(DWORD dwProcessId, TCHAR szBuffer[], DWORD dwMaxLen); // 获取进程路径
BOOL GetProcessIco(DWORD dwProcessId, HICON& hIco); // 获取进程图标
BOOL InitProcessList(); // 初始化进程列表
public:
CListCtrl m_list;
CImageList m_imgList;
virtual BOOL OnInitDialog();
public:
// 选中的进程的ID
static DWORD m_dwProcessId;
// 选中的进程名
static CString m_strProcessName;
afx_msg void OnNMDblclkList1(NMHDR* pNMHDR, LRESULT* pResult);
};
.cpp文件
// DlgProgress.cpp: 实现文件
//
#include "pch.h"
#include "Modifier.h"
#include "DlgProgress.h"
#include "afxdialogex.h"
#include <TlHelp32.h>
// DlgProgress 对话框
IMPLEMENT_DYNAMIC(DlgProgress, CDialogEx)
DWORD DlgProgress::m_dwProcessId = 0;
CString DlgProgress::m_strProcessName = _T("");
DlgProgress::DlgProgress(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_DIALOG_PROGRESS_LIST, pParent)
{
}
DlgProgress::~DlgProgress()
{
}
void DlgProgress::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST1, m_list);
}
BOOL DlgProgress::GetAllProcess()
{
// 1. 创建进程快照
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE) {
return FALSE;
}
// 2. 判断首个进程
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(PROCESSENTRY32);
if (!Process32First(hProcessSnap, &pe32)) {
CloseHandle(hProcessSnap);
return FALSE;
}
// 3.遍历所有进程
do
{
// 3.1 若不是32位进程
if (!Is32BitProgress(pe32.th32ProcessID)) {
continue;
}
// 3.2 若是32位进程
// 3.2.1 加载图标
int indexIco = -1;
HICON hIco = 0;
if (GetProcessIco(pe32.th32ProcessID, hIco)) {
indexIco = m_imgList.Add(hIco);
}
// 3.2.2 插入新行
int index = m_list.InsertItem(m_list.GetItemCount(), pe32.szExeFile, indexIco);
CString id;
id.Format(_T("%d"), pe32.th32ProcessID);
m_list.SetItemText(index, 1, id);
m_list.SetItemData(index, (DWORD_PTR)pe32.th32ProcessID);
} while (Process32Next(hProcessSnap, &pe32));
// 4.关闭快照句柄
CloseHandle(hProcessSnap);
return 0;
}
BOOL DlgProgress::Is32OS()
{
SYSTEM_INFO si;
GetNativeSystemInfo(&si);
if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64
|| si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64) {
return FALSE;
}
else {
return TRUE;
}
}
BOOL DlgProgress::Is32BitProgress(DWORD dwProcessId)
{
// 1. 排除系统空闲进程 0 和system进程 4
if (dwProcessId == 0 || dwProcessId == 4) {
return FALSE;
}
// 2. 判断是否为32位系统
if (Is32OS()) {
return TRUE; // 32位系统的进程必为32位进程
}
// 3. 判断是否是64位系统下的32位进程
HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcessId);
if (!h || h == INVALID_HANDLE_VALUE) {
return FALSE;
}
BOOL b32;
IsWow64Process(h, &b32);
CloseHandle(h);
return b32;
}
BOOL DlgProgress::GetFullPathProcess(DWORD dwProcessId, TCHAR szBuffer[], DWORD dwMaxLen)
{
HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcessId);
if (h && h != INVALID_HANDLE_VALUE) {
DWORD dwLen = dwMaxLen;
BOOL b = QueryFullProcessImageName(h, 0, szBuffer, (PDWORD)&dwLen);
if (b) {
szBuffer[dwLen] = _T('\0');
}
CloseHandle(h);
return b;
}
return FALSE;
}
BOOL DlgProgress::GetProcessIco(DWORD dwProcessId, HICON& hIco)
{
TCHAR szPath[MAX_PATH] = { 0 };
if (GetFullPathProcess(dwProcessId, szPath, sizeof(szPath))) {
SHFILEINFO info = { 0 };
DWORD_PTR dwRet = ::SHGetFileInfo(szPath, 0, &info, sizeof(info), SHGFI_ICON | SHGFI_LARGEICON);
if (dwRet == 0) {
hIco = 0;
}
else {
hIco = info.hIcon;
}
}
return hIco != 0;
}
BOOL DlgProgress::InitProcessList()
{
LONG lStyle = GetWindowLong(m_list.m_hWnd, GWL_STYLE);
lStyle &= ~LVS_TYPEMASK;
lStyle |= LVS_REPORT;
SetWindowLong(m_list.GetSafeHwnd(), GWL_STYLE, lStyle);
DWORD dwStyle = m_list.GetExtendedStyle();
dwStyle |= LVS_EX_FULLROWSELECT; //选中行 整征高亮
dwStyle |= LVS_EX_GRIDLINES; //网络线
m_list.SetExtendedStyle(dwStyle);
// 设置列,并设置大小
{
CRect rc;
m_list.GetClientRect(rc);
m_list.InsertColumn(0, _T("进程名"), LVCFMT_LEFT, rc.Width() / 2);
m_list.InsertColumn(1, _T("进程ID"), LVCFMT_LEFT, rc.Width() / 2);
}
// 设置控件关联的图标列表,这样才可以在每行的开头显示图标
m_imgList.Create(16, 16, ILC_COLOR32, 1, 1);
m_list.SetImageList(&m_imgList, LVSIL_SMALL);
return true;
}
BEGIN_MESSAGE_MAP(DlgProgress, CDialogEx)
ON_NOTIFY(NM_DBLCLK, IDC_LIST1, &DlgProgress::OnNMDblclkList1)
END_MESSAGE_MAP()
// DlgProgress 消息处理程序
BOOL DlgProgress::OnInitDialog()
{
CDialogEx::OnInitDialog();
// TODO: 在此添加额外的初始化
InitProcessList(); // 初始化控件
GetAllProcess(); // 加载所有32位进程
return TRUE; // return TRUE unless you set the focus to a control
// 异常: OCX 属性页应返回 FALSE
}
void DlgProgress::OnNMDblclkList1(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
int nItem = pNMItemActivate->iItem;
// 如果有选中的行,设置回传给父窗口的变量,使父窗口可以知道当前选择的进程信息
if (nItem >= 0) {
m_dwProcessId = (DWORD)m_list.GetItemData(nItem);
m_strProcessName = m_list.GetItemText(nItem, 0);
OnOK();
}
*pResult = 0;
}