自己手工的进程管理器
最近在学MFC。以前习惯了向导,总感觉有哪里不对劲。现在知道了是对框架的不熟悉引起的。狠啃了好几天框架,艰深无比,看得脑大。写个程序练练手,算是应用吧。程序运行效果如下:
创建W32工程,添加资源脚本。使用通用控件要加载 comctl32.dll库,#pragma comment(lib,"comctl32.lib")。使用前要初始化,调用InitCommonControlsEx()。用ToolHelp函数列出当前正在运行的进程,要先声明 #include<tlhelp32.h>。首先用CreateToolHelp32Snapshot拍快照,再用Process32First,Process32Next遍历快照表。代码如下
#include <windows.h>
#include <commctrl.h>
#include <tlhelp32.h>
#include "resource.h"
// 链接到comctl32.lib库
#pragma comment(lib,"comctl32.lib")
// 状态栏ID号
#define IDC_STATUS 101
BOOL __stdcall DlgProc(HWND, UINT, WPARAM, LPARAM);
void UpdateProcess(HWND hWndList);
int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)
{
// 初始化Comctl32.dll库
::InitCommonControls();
::DialogBoxParam(hInstance, (LPCTSTR)IDD_DIALOG1, NULL, DlgProc, NULL);
return 0;
}
BOOL __stdcall DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_INITDIALOG:
{
// 初始化列表视图控件
HWND hWndList = ::GetDlgItem(hDlg, IDC_LIST2);
// 设置它的扩展风格
::SendMessage(hWndList, LVM_SETEXTENDEDLISTVIEWSTYLE,
0, LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);
LVCOLUMN column;
// 指定LVCOLUMN结构中的pszText、fmt、cx域有效
column.mask = LVCF_TEXT|LVCF_FMT|LVCF_WIDTH;
// 设置有效的域的属性
column.fmt = LVCFMT_CENTER; // 指定文本居中显示
column.cx = 100; // 指定此栏的宽度
column.pszText = "映象名称"; // 指定此栏显示的文本
// 添加一个新的专栏
::SendMessage(hWndList, LVM_INSERTCOLUMN, 0, (LPARAM)&column);
// 再添加一个专栏
column.pszText = "PID";
column.cx = 50;
::SendMessage(hWndList, LVM_INSERTCOLUMN, 1, (LPARAM)&column);
// 初始化状态栏
// 创建状态栏
HWND hWndStatus = ::CreateStatusWindow(WS_CHILD|WS_VISIBLE|SBS_SIZEGRIP,
NULL, hDlg, IDC_STATUS);
// 设置背景色
::SendMessage(hWndStatus, SB_SETBKCOLOR, 0, RGB(0xa6, 0xca, 0xf0));
// 给状态栏分栏
int pInt[] = { 152, -1 };
::SendMessage(hWndStatus, SB_SETPARTS, 2, (long)pInt);
// 设置各栏的文本
::SendMessage(hWndStatus, SB_SETTEXT, 0, (long)" 以上进程");
::SendMessage(hWndStatus, SB_SETTEXT, 1, (long)" 学习中!");
// 刷新进程列表
UpdateProcess(hWndList);
}
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDC_BUT_EXIT:
::EndDialog(hDlg, IDOK);
break;
case IDCANCEL:
::EndDialog(hDlg, IDCANCEL);
break;
case IDC_BUT_XIN:
UpdateProcess(::GetDlgItem(hDlg, IDC_LIST2));
break;
}
break;
case WM_NOTIFY:
{
if(wParam == IDC_LIST2)
{
NMHDR* pHeader = (NMHDR*)lParam;
HWND hWndList = pHeader->hwndFrom;
if(pHeader->code == NM_DBLCLK) // 双击事件
{
NMLISTVIEW* pNMListView = (NMLISTVIEW*)pHeader;
// 用户双击的项号
int nIndex = pNMListView->iItem;
// 取得进程ID号
char szID[56];
LVITEM lvi;
memset(&lvi, 0, sizeof(LVITEM));
lvi.iSubItem = 1; // nIndex项目中的第1个子项
lvi.cchTextMax = 56;
lvi.pszText = szID;
::SendMessage(hWndList, LVM_GETITEMTEXT, (WPARAM)nIndex, (long)&lvi);
// 询问用户
if(::MessageBox(hDlg, "确实要终止进程吗?",
"07ComctlDemo", MB_OKCANCEL|MB_DEFBUTTON2) == IDCANCEL)
return 0;
// 试图打开目标进程,终止它
HANDLE hProcess = ::OpenProcess(PROCESS_TERMINATE, FALSE, atoi(szID));
if(hProcess != NULL)
{
HWND hWndStatus = ::GetDlgItem(hDlg, IDC_STATUS);
if(::TerminateProcess(hProcess, 0))
{
::SendMessage(hWndStatus, SB_SETTEXT, 0, (long)"你终止了我!");
UpdateProcess(hWndList);
}
else
{
::SendMessage(hWndStatus, SB_SETTEXT, 0, (long)"进程不让你终止!");
}
}
}
}
}
break;
}
return 0;
}
void UpdateProcess(HWND hWndList)
{
// 删除所有的项
::SendMessage(hWndList, LVM_DELETEALLITEMS, 0, 0);
int nItem = 0; // 项计数
PROCESSENTRY32 pe32 = { sizeof(PROCESSENTRY32) };
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(hProcessSnap == INVALID_HANDLE_VALUE)
return;
if(Process32First(hProcessSnap, &pe32))
{
do
{
// 取得进程ID号
char szID[56];
wsprintf(szID, "%u", pe32.th32ProcessID);
// 插入一个项
LVITEM item = { 0 };
item.iItem = nItem;
item.mask = LVIF_TEXT; // 指定pszText域有效
item.pszText = (LPTSTR)pe32.szExeFile; // 设置文本
::SendMessage(hWndList, LVM_INSERTITEM, 0, (long)&item);
// 设置新项的文本
LVITEM lvi;
lvi.iSubItem = 1; // 指定要设置第1个专栏的文本
lvi.pszText = (LPTSTR)szID; // 要设置的文本
::SendMessage(hWndList, LVM_SETITEMTEXT, nItem, (LPARAM)&lvi);
nItem++;
}
while(Process32Next(hProcessSnap, &pe32));
}
::CloseHandle(hProcessSnap);
}
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课