VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

有编程疑问吗?还请到提问专区发帖提问!
搜索
查看: 190|回复: 1

VC++基础班-[27]实现一个简单的任务管理器

[复制链接]
01_avatar_middle
online_admins admin 发表于 2018-2-8 00:46:01 | 显示全部楼层 |阅读模式
------------------------------------------ Begin ----------------------------------------

因为任务管理器中涉及到进程的枚举操作,所以把两节课的知识点合并到一起来讲!

①、设计界面、以及列表控件变量的绑定;
②、列表控件样式的指定:
  1. m_TaskList.SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);
  2. m_TaskList.InsertColumn(0, _T("   进程名称"), 0, 100);
  3. m_TaskList.InsertColumn(1, _T("   PID"), 0, 60);
  4. m_TaskList.InsertColumn(2, _T("   文件路径"), 0, 380);
复制代码


③、进程列表的获取:
具体的方法也是多种的,具体见:http://www.cctry.com/thread-11857-1-1.html
这里面我们使用第一种方法给大家讲解:

  1. #include <Tlhelp32.h>
  2. #include <Psapi.h>
  3. #pragma comment(lib, "Psapi.lib")
  4. BOOL CMFCTestDlg::GetProcessList()
  5. {
  6.         BOOL bResult = FALSE;
  7.         HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  8.         if ( hSnap == INVALID_HANDLE_VALUE )
  9.                 return FALSE;

  10.         int idx = 0;
  11.         CString strID;
  12.         HANDLE hProcess = NULL;
  13.         PROCESSENTRY32 info = {0};
  14.         info.dwSize = sizeof(PROCESSENTRY32);

  15.         BOOL bRet = Process32First(hSnap, &info);
  16.         while(bRet) {
  17.                 idx = m_TaskList.InsertItem(m_TaskList.GetItemCount(), _T(""));
  18.                 m_TaskList.SetItemText(idx, 0, info.szExeFile);
  19.                 strID.Empty();
  20.                 strID.Format(_T("%d"), info.th32ProcessID);
  21.                 m_TaskList.SetItemText(idx, 1, strID);

  22.                 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, info.th32ProcessID);
  23.                 if (hProcess) {
  24.                         TCHAR szPath[MAX_PATH] = {0};
  25.                         GetModuleFileNameEx(hProcess, NULL, szPath, MAX_PATH);
  26.                         m_TaskList.SetItemText(idx, 2, szPath);
  27.                 }
  28.                 bRet = Process32Next(hSnap, &info);
  29.         }
  30.         return TRUE;
  31. }
复制代码


④、Debug 权限提升函数:
  1. BOOL AdjustPrivileges()
  2. {
  3.         HANDLE hToken = NULL;
  4.         TOKEN_PRIVILEGES tp = {0};
  5.         TOKEN_PRIVILEGES oldtp = {0};
  6.         DWORD dwSize = sizeof(TOKEN_PRIVILEGES);
  7.         LUID luid = {0};

  8.         if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
  9.                 if (GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
  10.                         return TRUE;
  11.                 else
  12.                         return FALSE;
  13.         }
  14.         if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) {
  15.                 CloseHandle(hToken);
  16.                 return FALSE;
  17.         }

  18.         tp.PrivilegeCount=1;
  19.         tp.Privileges[0].Luid = luid;
  20.         tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

  21.         /* Adjust Token Privileges */
  22.         if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), &oldtp, &dwSize)) {
  23.                 CloseHandle(hToken);
  24.                 return FALSE;
  25.         }

  26.         // close handles
  27.         CloseHandle(hToken);
  28.         return TRUE;
  29. }
复制代码


⑤、菜单资源的添加及编辑:
刷新列表:ID_M_REFRESH_LIST
结束此进程:ID_M_EDN_TASK
定位文件:ID_M_FIND_EXE
拷贝路径:ID_M_COPY_PATH

⑥、菜单资源的弹出:
  1. void CMFCTestDlg::OnNMRClickTaskList(NMHDR *pNMHDR, LRESULT *pResult)
  2. {
  3.         LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
  4.         if ( pNMItemActivate->iItem < 0 ) return;

  5.         CString strID = m_TaskList.GetItemText(pNMItemActivate->iItem, 1);

  6.         CPoint pt;
  7.         GetCursorPos(&pt);
  8.         CMenu mMenu, *pMenu;
  9.         mMenu.LoadMenu(IDR_MENU);
  10.         pMenu = mMenu.GetSubMenu(0);
  11.         if (strID == _T("0") || strID == _T("4")){
  12.                 pMenu->EnableMenuItem(ID_M_EDN_TASK, MF_BYCOMMAND|MF_GRAYED);
  13.                 pMenu->EnableMenuItem(ID_M_FIND_EXE, MF_BYCOMMAND|MF_GRAYED);
  14.                 pMenu->EnableMenuItem(ID_M_COPY_PATH, MF_BYCOMMAND|MF_GRAYED);
  15.         }
  16.         pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, this);

  17.         *pResult = 0;
  18. }
复制代码


⑦、菜单响应函数的实现:
  1. void CMFCTestDlg::OnMRefreshList()
  2. {
  3.         for (int idx = 0; idx < m_ImgList.GetImageCount(); idx++) {
  4.                 m_ImgList.Remove(idx);
  5.         }

  6.         m_TaskList.DeleteAllItems();
  7.         GetProcessList();
  8. }
复制代码

  1. void CMFCTestDlg::OnMEdnTask()
  2. {
  3.         int idx = m_TaskList.GetSelectionMark();
  4.         CString strID = m_TaskList.GetItemText(idx, 1);
  5.         CString strName = m_TaskList.GetItemText(idx, 0);

  6.         int iRet = MessageBox(_T("您确定要结束 ")+strName+_T(" 吗?"), _T("友情提示"), MB_OKCANCEL);
  7.         if (iRet == IDCANCEL) return;

  8.         if ( strID == _T("0") || strName == _T("4")) { //实际上这个位置的判断是多余的
  9.                 MessageBox(_T("系统进程,无法结束!"), _T("提示"));
  10.         }else{
  11.                 BOOL bRet = FALSE;
  12.                 HANDLE hProcess = OpenProcess(PROCESS_TERMINATE|PROCESS_QUERY_INFORMATION, FALSE, _tstoi(strID));
  13.                 if ( hProcess != NULL ) {
  14.                         bRet = TerminateProcess(hProcess, -1);
  15.                         CloseHandle(hProcess);
  16.                 }

  17.                 if ( !bRet ) {
  18.                         MessageBox(_T("结束进程 " ") + strName + _T(" " 失败,请重试!"), _T("提示"));
  19.                 }else{
  20.                         m_TaskList.DeleteItem(idx);
  21.                 }
  22.         }
  23. }
复制代码

  1. void CMFCTestDlg::OnMFindExe()
  2. {
  3.         int idx = m_TaskList.GetSelectionMark();
  4.         CString strPath = m_TaskList.GetItemText(idx, 2);
  5.         if (strPath.GetLength() > 0)
  6.                 ShellExecute(m_hWnd, _T("open"), _T("Explorer.exe"), _T("/select,")+strPath, NULL, SW_SHOW);
  7. }
复制代码

  1. void CMFCTestDlg::OnMCopyPath()
  2. {
  3.         int idx = m_TaskList.GetSelectionMark();
  4.         CString strPath = m_TaskList.GetItemText(idx, 2);

  5.         if (!OpenClipboard()) return;
  6.         if(!EmptyClipboard()) {
  7.                 CloseClipboard();
  8.                 return;
  9.         }

  10.         size_t cbStr = (strPath.GetLength()+1)*sizeof(TCHAR);
  11.         HGLOBAL hData = GlobalAlloc(GMEM_MOVEABLE, cbStr);
  12.         memcpy_s(GlobalLock(hData), cbStr, strPath.LockBuffer(), cbStr);
  13.         GlobalUnlock(hData);
  14.         strPath.UnlockBuffer();

  15.         UINT uiFormat = (sizeof(TCHAR) == sizeof(WCHAR)) ? CF_UNICODETEXT : CF_TEXT;
  16.         if (::SetClipboardData(uiFormat, hData) == NULL) {
  17.                 MessageBox(_T("设置剪贴板数据失败!"));
  18.                 CloseClipboard();
  19.                 return;
  20.         }

  21.         CloseClipboard();
  22. }
复制代码


⑧、为列表控件加上程序的前缀图标:
  1. // H 头文件中进行图像列表的定义:
  2. CImageList m_ImgList;

  3. // OnInitDialog() 函数中进行图像列表的创建及设置:
  4. m_ImgList.Create(16, 16, ILC_COLOR24, 10, 10);
  5. m_TaskList.SetImageList(&m_ImgList, LVSIL_SMALL);
复制代码


⑨、修改GetProcessList()函数为如下:
  1. BOOL CMFCTestDlg::GetProcessList()
  2. {
  3.         BOOL bResult = FALSE;
  4.         HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  5.         if ( hSnap == INVALID_HANDLE_VALUE )
  6.                 return FALSE;

  7.         int idx = 0, imgIdx = -1;
  8.         CString strID;
  9.         HANDLE hProcess = NULL;
  10.         CString strPath, strSys(_T("SystemRoot"));
  11.         PROCESSENTRY32 info = {0};
  12.         info.dwSize = sizeof(PROCESSENTRY32);

  13.         BOOL bRet = Process32First(hSnap, &info);
  14.         while(bRet) {
  15.                 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, info.th32ProcessID);
  16.                 if (hProcess) {
  17.                         strPath.Empty();
  18.                         GetModuleFileNameEx(hProcess, NULL, strPath.GetBufferSetLength(MAX_PATH), MAX_PATH);
  19.                         strPath.ReleaseBuffer();
  20.                         strPath.TrimLeft(_T("\\?"));
  21.                         if (strPath.Left(strSys.GetLength()).CompareNoCase(strSys) == 0){
  22.                                 TCHAR szWin[MAX_PATH] = {0};
  23.                                 GetWindowsDirectory(szWin, MAX_PATH);
  24.                                 strPath.Replace(strSys, szWin);
  25.                         }

  26.                         SHFILEINFO shInfo = {0};
  27.                         SHGetFileInfo(strPath, 0, &shInfo, sizeof(SHFILEINFO), SHGFI_SMALLICON|SHGFI_ICON);
  28.                         imgIdx = m_ImgList.Add(shInfo.hIcon);
  29.                 }

  30.                 //进行列表项的插入
  31.                 idx = m_TaskList.InsertItem(m_TaskList.GetItemCount(), _T(""), imgIdx);
  32.                 m_TaskList.SetItemText(idx, 0, info.szExeFile);
  33.                 strID.Empty();
  34.                 strID.Format(_T("%d"), info.th32ProcessID);
  35.                 m_TaskList.SetItemText(idx, 1, strID);
  36.                 m_TaskList.SetItemText(idx, 2, strPath);

  37.                 //继续遍历进程列表
  38.                 bRet = Process32Next(hSnap, &info);
  39.         }

  40.         return TRUE;
  41. }
复制代码



★ 课后作业:
1、使用 EnumProcesses 函数进行进程的枚举;
2、针对选中多个进程进行结束时的处理!
------------------------------------- End -------------------------------------------

相关课程演示细节还请观看视频教程!
本套教程由VC驿站原创,提供视频教程+售后答疑服务!
教程介绍及详情请见:http://www.cctry.com/thread-17282-1-1.html
VC驿站Vip会员详情请见:http://www.cctry.com/static/vip/index.html

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你已经在论坛发帖求助,并且从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友?可以给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

您需要登录后才可以回帖 登录 | 加入驿站 qq_login

本版积分规则

关闭

站长提醒上一条 /1 下一条

QQ
QQ在线咨询
联系电话
13591366679
手机扫一扫 关注本站精彩内容
wxqrcode

QQ|小黑屋|手机版|VC驿站 ( 辽ICP备09019393号tongdun|网站地图wx_jqr

GMT+8, 2018-5-24 10:08

Powered by Discuz! X3.4

© 2009-2018 cctry.com

快速回复 返回顶部 返回列表