因为任务管理器中涉及到进程的枚举操作,所以把两节课的知识点合并到一起来讲!
 
①、设计界面、以及列表控件变量的绑定;
②、列表控件样式的指定:
m_TaskList.SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);
m_TaskList.InsertColumn(0, _T(" 进程名称"), 0, 100);
m_TaskList.InsertColumn(1, _T(" PID"), 0, 60);
m_TaskList.InsertColumn(2, _T(" 文件路径"), 0, 380);
 
③、进程列表的获取:
具体的方法也是多种的,具体见:http://www.cctry.com/thread-11857-1-1.html
这里面我们使用第一种方法给大家讲解:
 
#include <Tlhelp32.h>
#include <Psapi.h>
#pragma comment(lib, "Psapi.lib")
BOOL CMFCTestDlg::GetProcessList()
{
 BOOL bResult = FALSE;
 HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
 if ( hSnap == INVALID_HANDLE_VALUE )
  return FALSE;
 
 int idx = 0;
 CString strID;
 HANDLE hProcess = NULL;
 PROCESSENTRY32 info = {0};
 info.dwSize = sizeof(PROCESSENTRY32);
 
 BOOL bRet = Process32First(hSnap, &info);
 while(bRet) {
  idx = m_TaskList.InsertItem(m_TaskList.GetItemCount(), _T(""));
  m_TaskList.SetItemText(idx, 0, info.szExeFile);
  strID.Empty();
  strID.Format(_T("%d"), info.th32ProcessID);
  m_TaskList.SetItemText(idx, 1, strID);
 
  hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, info.th32ProcessID);
  if (hProcess) {
   TCHAR szPath[MAX_PATH] = {0};
   GetModuleFileNameEx(hProcess, NULL, szPath, MAX_PATH);
   m_TaskList.SetItemText(idx, 2, szPath);
  }
  bRet = Process32Next(hSnap, &info);
 }
 return TRUE;
}
 
④、Debug 权限提升函数:
BOOL AdjustPrivileges()
{
 HANDLE hToken = NULL;
 TOKEN_PRIVILEGES tp = {0};
 TOKEN_PRIVILEGES oldtp = {0};
 DWORD dwSize = sizeof(TOKEN_PRIVILEGES);
 LUID luid = {0};
 
 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
  if (GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
   return TRUE;
  else
   return FALSE;
 }
 if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) {
  CloseHandle(hToken);
  return FALSE;
 }
 
 tp.PrivilegeCount=1;
 tp.Privileges[0].Luid = luid;
 tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
 
 /* Adjust Token Privileges */
 if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), &oldtp, &dwSize)) {
  CloseHandle(hToken);
  return FALSE;
 }
 
 // close handles
 CloseHandle(hToken);
 return TRUE;
}
 
⑤、菜单资源的添加及编辑:
刷新列表:ID_M_REFRESH_LIST
结束此进程:ID_M_EDN_TASK
定位文件:ID_M_FIND_EXE
拷贝路径:ID_M_COPY_PATH
 
⑥、菜单资源的弹出:
void CMFCTestDlg::OnNMRClickTaskList(NMHDR *pNMHDR, LRESULT *pResult)
{
 LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
 if ( pNMItemActivate->iItem < 0 ) return;
 
 CString strID = m_TaskList.GetItemText(pNMItemActivate->iItem, 1);
 
 CPoint pt;
 GetCursorPos(&pt);
 CMenu mMenu, *pMenu;
 mMenu.LoadMenu(IDR_MENU);
 pMenu = mMenu.GetSubMenu(0);
 if (strID == _T("0") || strID == _T("4")){
  pMenu->EnableMenuItem(ID_M_EDN_TASK, MF_BYCOMMAND|MF_GRAYED);
  pMenu->EnableMenuItem(ID_M_FIND_EXE, MF_BYCOMMAND|MF_GRAYED);
  pMenu->EnableMenuItem(ID_M_COPY_PATH, MF_BYCOMMAND|MF_GRAYED);
 }
 pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, this);
 
 *pResult = 0;
}
 
⑦、菜单响应函数的实现:
void CMFCTestDlg::OnMRefreshList()
{
 for (int idx = 0; idx < m_ImgList.GetImageCount(); idx++) {
  m_ImgList.Remove(idx);
 }
 
 m_TaskList.DeleteAllItems();
 GetProcessList();
}
 
void CMFCTestDlg::OnMEdnTask()
{
 int idx = m_TaskList.GetSelectionMark();
 CString strID = m_TaskList.GetItemText(idx, 1);
 CString strName = m_TaskList.GetItemText(idx, 0);
 
 int iRet = MessageBox(_T("您确定要结束 ")+strName+_T(" 吗?"), _T("友情提示"), MB_OKCANCEL);
 if (iRet == IDCANCEL) return;
 
 if ( strID == _T("0") || strName == _T("4")) { //实际上这个位置的判断是多余的
  MessageBox(_T("系统进程,无法结束!"), _T("提示"));
 }else{
  BOOL bRet = FALSE;
  HANDLE hProcess = OpenProcess(PROCESS_TERMINATE|PROCESS_QUERY_INFORMATION, FALSE, _tstoi(strID));
  if ( hProcess != NULL ) {
   bRet = TerminateProcess(hProcess, -1);
   CloseHandle(hProcess);
  }
 
  if ( !bRet ) {
   MessageBox(_T("结束进程 \" ") + strName + _T(" \" 失败,请重试!"), _T("提示"));
  }else{
   m_TaskList.DeleteItem(idx);
  }
 }
}
 
void CMFCTestDlg::OnMFindExe()
{
 int idx = m_TaskList.GetSelectionMark();
 CString strPath = m_TaskList.GetItemText(idx, 2);
 if (strPath.GetLength() > 0)
  ShellExecute(m_hWnd, _T("open"), _T("Explorer.exe"), _T("/select,")+strPath, NULL, SW_SHOW);
}
 
void CMFCTestDlg::OnMCopyPath()
{
 int idx = m_TaskList.GetSelectionMark();
 CString strPath = m_TaskList.GetItemText(idx, 2);
 
 if (!OpenClipboard()) return;
 if(!EmptyClipboard()) {
  CloseClipboard();
  return;
 }
 
 size_t cbStr = (strPath.GetLength()+1)*sizeof(TCHAR);
 HGLOBAL hData = GlobalAlloc(GMEM_MOVEABLE, cbStr);
 memcpy_s(GlobalLock(hData), cbStr, strPath.LockBuffer(), cbStr);
 GlobalUnlock(hData);
 strPath.UnlockBuffer();
 
 UINT uiFormat = (sizeof(TCHAR) == sizeof(WCHAR)) ? CF_UNICODETEXT : CF_TEXT;
 if (::SetClipboardData(uiFormat, hData) == NULL) {
  MessageBox(_T("设置剪贴板数据失败!"));
  CloseClipboard();
  return;
 }
 
 CloseClipboard();
}
 
⑧、为列表控件加上程序的前缀图标:
// H 头文件中进行图像列表的定义:
CImageList m_ImgList;
 
// OnInitDialog() 函数中进行图像列表的创建及设置:
m_ImgList.Create(16, 16, ILC_COLOR24, 10, 10);
m_TaskList.SetImageList(&m_ImgList, LVSIL_SMALL);
 
⑨、修改GetProcessList()函数为如下:
BOOL CMFCTestDlg::GetProcessList()
{
 BOOL bResult = FALSE;
 HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
 if ( hSnap == INVALID_HANDLE_VALUE )
  return FALSE;
 
 int idx = 0, imgIdx = -1;
 CString strID;
 HANDLE hProcess = NULL;
 CString strPath, strSys(_T("SystemRoot"));
 PROCESSENTRY32 info = {0};
 info.dwSize = sizeof(PROCESSENTRY32);
 
 BOOL bRet = Process32First(hSnap, &info);
 while(bRet) {
  hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, info.th32ProcessID);
  if (hProcess) {
   strPath.Empty();
   GetModuleFileNameEx(hProcess, NULL, strPath.GetBufferSetLength(MAX_PATH), MAX_PATH);
   strPath.ReleaseBuffer();
   strPath.TrimLeft(_T("\\?"));
   if (strPath.Left(strSys.GetLength()).CompareNoCase(strSys) == 0){
    TCHAR szWin[MAX_PATH] = {0};
    GetWindowsDirectory(szWin, MAX_PATH);
    strPath.Replace(strSys, szWin);
   }
 
   SHFILEINFO shInfo = {0};
   SHGetFileInfo(strPath, 0, &shInfo, sizeof(SHFILEINFO), SHGFI_SMALLICON|SHGFI_ICON);
   imgIdx = m_ImgList.Add(shInfo.hIcon);
  }
 
  //进行列表项的插入
  idx = m_TaskList.InsertItem(m_TaskList.GetItemCount(), _T(""), imgIdx);
  m_TaskList.SetItemText(idx, 0, info.szExeFile);
  strID.Empty();
  strID.Format(_T("%d"), info.th32ProcessID);
  m_TaskList.SetItemText(idx, 1, strID);
  m_TaskList.SetItemText(idx, 2, strPath);
 
  //继续遍历进程列表
  bRet = Process32Next(hSnap, &info);
 }
 
 return TRUE;
}
 
 
1、使用 EnumProcesses 函数进行进程的枚举;
2、针对选中多个进程进行结束时的处理!
 

vc++基础班[27]---实现一个简单的任务管理器的更多相关文章

  1. vc++基础班[24]---系统各种路径信息的获取

    vc++基础班[24]---系统各种路径信息的获取 ------------------------------------------ Begin ------------------------- ...

  2. vc++基础班[25]---系统信息的获取

    --------------------------------------------------------------------------- VC 驿站 WwW.CcTry.CoM 多抽出一 ...

  3. vc++基础班[28]---动态数组及动态链表的讲解

    C++中也有相应的动态数组.动态链表.映射表的模板类,就是STL中的:vector.list.map 他们属于C++标准中的一部分,对于程序的移植性来说也是不错的,但是在MFC编程中使用 CArray ...

  4. vc++基础班[26]---进程的相关操作

      ①.ShellExecute 进行进程的创建,属于 shell api: //int iRet = (int)ShellExecute(m_hWnd, _T("open"), ...

  5. vc++基础班[23]---文件夹的基本操作

      ①.文件夹的创建:CreateDirectory ※※※ 注意:此函数只能创建一层目录,比如想在 C 盘下的 Temp 目录下创建新目录为:123 那么前提是 Temp 这个目录存在才可以!   ...

  6. vc++基础班[22]---文件的基本操作2

      MFC 中的 CFile 及其派生类中没有提供直接进行文件的复制操作,因而要借助于SDK API: SDK中的文件相关函数常用的有CopyFile().CreateDirectory().Dele ...

  7. vc++基础班[21]---文件的基本操作之CFile

    ①.文件的创建.打开.关闭: 文件的创建.打开:CFile::Open 文件的关闭:CFile::Close   CFile::modeCreate:以新建方式打开,如果文件不存在,则新建:如果文件已 ...

  8. PHP基础班初学感悟

    不知不觉差不多一个月就过去了 刚到培训班那时候的心情,现在也还能有所感觉 作为今年6月份的毕业生,刚从大学的实习期出来,辞掉了上一份工作,本来是打算找一份更加与专业挂钩的工作做的 也许是90后对网络的 ...

  9. 【SpringBoot 基础系列】实现一个自定义配置加载器(应用篇)

    [SpringBoot 基础系列]实现一个自定义配置加载器(应用篇) Spring 中提供了@Value注解,用来绑定配置,可以实现从配置文件中,读取对应的配置并赋值给成员变量:某些时候,我们的配置可 ...

随机推荐

  1. Nginx自定义404页面并返回404状态码

    Nginx定义404页面并返回404状态码, WebServer是nginx,直接告诉我应该他们配置了nginx的404错误页面,虽然请求不存在的资源可以成功返回404页面,但返回状态码确是200. ...

  2. linux之awk命令获取最后一列

    统计分析中经常用的awk命令,其中用的最多的还是切分 cat  test | awk -F',' '{print $1,$2} 能够很好的将记录按照需要切分开, 但是如何获取最后一列呢? 可以使用aw ...

  3. idea打开项目没有文件目录

    如题,利用idea打开一个项目,然而并没有src等主要文件目录. 方法:使用ctrl+shift+alt+s打开目录结构,选择module,再选择import module,注意选择SDK,即JDK.

  4. HDU - 6304(2018 Multi-University Training Contest 1) Chiaki Sequence Revisited(数学+思维)

    http://acm.hdu.edu.cn/showproblem.php?pid=6304 题意 给出一个数列的定义,a[1]=a[2]=1,a[n]=a[n-a[n-1]]+a[n-1-a[n-2 ...

  5. HDU 1025(最长上升子序列)

    题意是要在两条平行线间连点,要在线不交叉的前提下尽可能多的连线,问最多能连多少条线. 现假定题中所给的是 9 组点,分别是:1—3,2—8,3—5,4—9,5—2,6—4,7—6,8—7,9—1,如图 ...

  6. Golang入门教程(三)beego 框架安装

    beego 是一个快速开发 Go 应用的 HTTP 框架,他可以用来快速开发 API.Web 及后端服务等各种应用,是一个 RESTful 的框架,主要设计灵感来源于 tornado.sinatra ...

  7. Nginx+Tomcat+Https 服务器负载均衡配置

    这篇过气了! 重新补一个:http://www.cnblogs.com/hackyo/p/6809773.html 由于需要,得搭建个nginx+tomcat+https的服务器,搜了搜网上的发现总是 ...

  8. json日期字符串格式化时间

    var str = '/Date(1333245600000+0800)/';   function data_string(str) {     var d = eval('new ' + str. ...

  9. 判断质数(Java)

    package day01; //输出1-100中质数,并且每十个换行 public class PrimeNum { public static void main(String[] args) { ...

  10. 使用js请求Servlet时的路径

    项目结构如下: 全是web的html页面 js部分重要代码: function ajaxValidate() { var flag=false; $.ajax({ "url":&q ...