鱼C论坛

 找回密码
 立即注册
查看: 963|回复: 0

[技术交流] MFC之任务管理器

[复制链接]
发表于 2022-1-16 23:34:23 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x


【前言】
1.运用知识点
SDK、MFC、进程、线程

2.设计思路

主对话框:菜单、状态栏、选项卡
选项卡:窗口、进程、线程、模块、堆、文件操作、VS垃圾清理
其他:运行新任务、开机关机、快捷键、窗口置顶

3.难点

1.不同窗口之间传递消息
进程->获取父窗口选项卡指针对象/句柄->发送(自定义)消息选项卡->选项卡接收消息在发(自定义)给线程->线程响应消息

2.如何获取窗口类对象,并且正确发送消息

3.进程对应的CPU使用率计算

【知识点记录】

1.自定义消息
【子类A函数中】【怎么发的消息】----自己给自己发WM_SHOWTHREAD消息
  1. //1.获取进程对话框的父窗口->选项卡
  2.     CWnd* parent = GetParent();
  3.     //2.给选项卡发消息->选项卡在给子窗口线程发消息
  4.     parent->SendMessage(WM_SHOWTHREAD, int_ProcPID[Prorow],0);
复制代码

【自己函数中】【怎么响应消息】-----自定义WM_SHOWTHREAD消息


                               
登录/注册后可看大图


【自己函数中】【解释】

1.定义消息后,立刻马上定义宏-> WM_XXXX WM_USER + X

2.自动生成头文件声明、函数定义、消息映射

3.在函数定义里面写接收此消息后的操作

2.选项卡 -列表-菜单

2.1 【选项卡】表头宽度
  1. m_Tab.SetMinTabWidth(宽度);
复制代码

2.2 【列表】背景图标
  1. // 4.设置列表背景图及风格 CBitmap bmp; bmp.LoadBitmapW(IDB_BITMAP1);
  2. m_WndMsg_List.SetBkImage(bmp);
  3. m_WndMsg_List.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);
复制代码

2.3 右键跳出【菜单】
【SDK和MFC对比】:一个是C版本获取句柄,一个是C++版本获取类对象

句柄 有点等价于 类指针对象

  1. <blockquote><blockquote><blockquote>
复制代码


3.拓展知识
3.1 获取系统时间
  1. //1.获取系统时间
  2. CString Sys_Time;
  3. CTime Time;
  4. Time = CTime::GetCurrentTime();
  5. Sys_Time = Time.Format("北京时间:%Y年%m月%d日%X");
复制代码

3.2 窗口置顶功能
  1. //1.获取菜单指针对象->GetMenu()此窗口的菜单指针->GetSubMenu()菜单的第几个子菜单
  2.         CMenu* menu = GetMenu()->GetSubMenu(1);
  3.         //2.返回指定菜单项的状态或弹出菜单中的项数->MF_BYCOMMAND指定参数提供现有菜单项的命令 ID
  4.         //  感觉是在获取这个菜单是否被选中信息
  5.         UINT state = menu->GetMenuState(ID_32783, MF_BYCOMMAND);
  6.         ASSERT(state != 0xFFFFFFFF);
  7.         //3.将复选标记属性设置为所选状态
  8.         if (state & MF_CHECKED)
  9.         {
  10.                 //4.选中状态:点击就取消
  11.                 menu->CheckMenuItem(ID_32783, MF_UNCHECKED | MF_BYCOMMAND);
  12.                 //4.1窗口取消置顶
  13.                 SetWindowPos(&CWnd::wndNoTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
  14.         }
  15.         else
  16.         {
  17.                 //5.未选中状态下:点击就选中
  18.                 menu->CheckMenuItem(ID_32783, MF_CHECKED | MF_BYCOMMAND);
  19.                 //5.1窗口置顶
  20.                 SetWindowPos(&CWnd::wndTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
  21.         }
复制代码

3.3 获取更改权限开关机
      
  1. //1.请求令牌
  2.         HANDLE hToken = NULL;
  3.         //2.进程伪句柄
  4.         HANDLE hProcess = GetCurrentProcess();
  5.         //3.OpenProcessToken函数打开与进程关联的访问令牌
  6.         //  所有权限可以写TOKEN_ALL_ACCESS ,去查看一个令牌特权可以用TOKEN_QUERY
  7.         OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
  8.         //4.使用AdjustTokenPrivileges需要的内容
  9.         //  在这个函数中的第3和第5个参数中需要用到一个TOKEN_PRIVILEGES的结构体
  10.         //  在这个结构体中还有个LUID_AND_ATTRIBUTES结构体
  11.         //  TOKEN_PRIVILEGES:参数1.要修改的特权数目  参数2.特权数组
  12.         //  LUID_AND_ATTRIBUTES:
  13.         //  参数1.第一个参数是Luid是一个标志,不同的Luid代表着各种不同的特权类型
  14.         //        Luid的值需要用LookupPrivilegeValue来获取
  15.         //  参数2.第二个参数是要这个特权干嘛,如启用这个特权(SE_PRIVILEGE_ENABLED)
  16.         //  LookupPrivilegeValue:
  17.         //  第一个参数是系统的名字,如果为NULL,就是本地名字
  18.         //  第二个参数是特权的名字
  19.         //  第三个参数就可以通过指针返回一个LUID类型的Luid的标识了
  20.         TOKEN_PRIVILEGES tp = { 0 };
  21.         LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tp.Privileges[0].Luid);
  22.         tp.PrivilegeCount = 1;
  23.         //5.权限使用
  24.         tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  25.         //6.调用函数提升权限
  26.         //AdjustTokenPrivileges(
  27.         //         HANDLE TokenHandle,                  OpenProcessToken第三个指针参数传出的句柄值
  28.         //         BOOL DisableAllPrivileges,           是否禁用所有所有的特权
  29.         //         PTOKEN_PRIVILEGES NewState,          新的TOKEN_PRIVILEGES的特权结构体指针
  30.         //         DWORD BufferLength,                  新的TOKEN_PRIVILEGES的特权结构体指针
  31.         //         PTOKEN_PRIVILEGES PreviousState,     接受原先的特权的结构体
  32.         //         PDWORD ReturnLength                  这个结构体的字节长度的指针
  33.         //);
  34.         AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);
  35.         switch (nID)
  36.         {
  37.         //A.关机
  38.         case ID_32792:
  39.         {
  40.                 //ExitWindowsEx注销交互式用户、关闭系统或关闭并重新启动系统
  41.                 //  EWX_POWEROFF 关闭系统并关闭电源
  42.                 //  EWX_FORCE 如果启用了终端服务,则此标志不起作用,这可能会导致应用程序丢失数据
  43.                 //  SHTDN_REASON_MAJOR_APPLICATION 应用程序问题
  44.                 //  EWX_REBOOT 关闭系统,然后重新启动系统
  45.                 //  EWX_LOGOFF 它会将用户注销
  46.                 //ExitWindowsEx(EWX_POWEROFF | EWX_POWEROFF, SHTDN_REASON_MAJOR_APPLICATION);
  47.                 MessageBox(_T("电脑已关机--注释"));
  48.                 break;
  49.         }
  50.         //B.重启
  51.         case ID_32793:
  52.         {
  53.                 //ExitWindowsEx(EWX_REBOOT | EWX_POWEROFF, SHTDN_REASON_MAJOR_APPLICATION);
  54.                 MessageBox(_T("电脑已重启--注释"));
  55.                 break;
  56.         }
  57.         //C.注销
  58.         case ID_32794:
  59.         {
  60.                 //ExitWindowsEx(EWX_LOGOFF | EWX_POWEROFF, SHTDN_REASON_MAJOR_APPLICATION);
  61.                 MessageBox(_T("电脑已注销--注释"));
  62.                 break;
  63.         }
  64.         //D.休眠
  65.         case ID_32795:
  66.         {
  67.                 //包含头文件:挂起或休眠系统,或请求挂起或休眠系统
  68.         //#include<powrprof.h>
  69.         //#pragma comment(lib,"PowrProf.lib")
  70.                 SetSuspendState(TRUE, FALSE, FALSE);
  71.                 break;
  72.         }
  73.         //E.睡眠
  74.         case ID_32796:
  75.         {
  76.                 SetSuspendState(FALSE, FALSE, FALSE);
  77.                 break;
  78.         }
  79.         //F.锁屏
  80.         case ID_32797:
  81.         {
  82.                 LockWorkStation();
  83.                 break;
  84.         }
  85.         default:
  86.                 break;
  87.         }
复制代码


3.4 静态文本控件超链接并设置颜色

【静态文本超链接】

  
  1. RECT rc;
  2.         //1.获取的是电脑屏幕的坐标
  3.         m_About_15PB.GetWindowRect(&rc);
  4.         //2.转换客户区坐标
  5.         ScreenToClient(&rc);
  6.         //3.判断鼠标位置
  7.         if (point.x >= rc.left && point.x <= rc.right && point.y >= rc.top && point.y <= rc.bottom)
  8.         {
  9.                 ShellExecute(NULL, _T("open"), TEXT("http://www.15pb.com.cn/"), NULL, NULL, SW_SHOW);
  10.         }
复制代码

【静态文本颜色】--响应消息WM_CtlColor

  1. HBRUSH CTaskManagerDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
  2. {
  3.         HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
  4.         if (IDC_STATIC100 == pWnd->GetDlgCtrlID())//判断发出消息的空间是否是该静态文本框
  5.         {
  6.                 pDC->SetTextColor(RGB(0, 0, 255));//设置文本颜色为红色
  7.                 pDC->SetBkMode(OPAQUE);//设置文本背景模式为透明
  8.             //pDC->SetBkColor(RGB(0, 0, 255));//设置文本背景为蓝色
  9.                 //hbr = CreateSolidBrush(RGB(0, 255, 0));//控件的背景色为绿色
  10.         }
  11.         return hbr;
  12. }
复制代码

3.5 枚举窗口信息
【理解】:EnumWindows这个函数获得了当前的窗口信息,进入到回调函数EnumWinProc遍历;

一直在回调函数循环遍历窗口的信息!

  1. // 2.枚举窗口信息->获取行内容
  2.     BOOL CALLBACK EnumWinProc(HWND hwnd, LPARAM);
  3.     EnumWindows(&EnumWinProc, NULL);
  4.     BOOL CALLBACK EnumWinProc(HWND hwnd, LPARAM)
  5. {
  6.     TCHAR buff[200];
  7.     //1.获取窗口名
  8.     GetWindowText(hwnd, buff, 200);
  9.     //2.判定窗口存在并且窗口名不等于0
  10.     if (IsWindowVisible(hwnd) == true && wcslen(buff) != 0)
  11.     {
  12.         int temp = 0;
  13.         //3.限制窗口名重复
  14.         for (int i = 0; i < WndName.size(); i++)  
  15.         {                                         
  16.             if (WndName == buff)               
  17.             {                                    
  18.                 temp = 1;
  19.                 break;                           
  20.             }                                    
  21.         }                                         
  22.         if (temp == 0)
  23.         {                                         
  24.             WndName.push_back(buff);              
  25.         }                                         
  26.     }
  27.     return true;
  28. }
复制代码

3.6 当前进程内存使用情况

/
  1. /显示当前程序的内存使用情况
  2. void LogCurrentProcessMemoryInfo()
  3. {
  4.         HANDLE handle=GetCurrentProcess();
  5.         PROCESS_MEMORY_COUNTERS_EX pmc = {0};
  6.         int a = sizeof(pmc);
  7.         if (!GetProcessMemoryInfo(handle,(PROCESS_MEMORY_COUNTERS*)&pmc,sizeof(pmc)))
  8.         {
  9.                 DWORD errCode = GetLastError();
  10.                 DEBUG_TRACE("GetProcessMemoryInfo fail, lastErrorCode:%d",errCode);
  11.                 return;
  12.         }

  13.         CString strInfo;
  14.         //占用的物理内存峰值
  15.         strInfo.Format("PeakWorkingSetSize:%d(KB)\n",pmc.PeakWorkingSetSize/1024);
  16.         OutputDebugString(strInfo);

  17.         //当前占用的物理内存
  18.         strInfo.Format("WorkingSetSize:%d(KB)\n",pmc.WorkingSetSize/1024);
  19.         OutputDebugString(strInfo);

  20.         //占用的虚拟内存峰值(物理内存+页文件),对应任务管理器中的commit列值
  21.         strInfo.Format("PeakPagefileUsage:%d(KB)\n",pmc.PeakPagefileUsage/1024);
  22.         OutputDebugString(strInfo);

  23.         //当前占用的虚拟内存(物理内存+页文件),对应任务管理器中的commit列值
  24.         strInfo.Format("PagefileUsage:%d(KB)\n",pmc.PagefileUsage/1024);
  25.         OutputDebugString(strInfo);

  26.         //等同于当前占用的虚拟内存(物理内存+页文件),对应任务管理器中的commit列值,并不是任务管理器中的私有独占内存的意思。
  27.         strInfo.Format("PrivateUsage:%d(KB)\n",pmc.PrivateUsage/1024);
  28.         OutputDebugString(strInfo);
  29. }
复制代码

3.7 【lstrcmp】比较函数
      
  1. // 3.判断是否是本级目录或上级目录的名称,是的话则结束本次循环
  2. if (!lstrcmp(wfd.cFileName, L".")|| !lstrcmp(wfd.cFileName, L".."))
  3. {
  4.         continue;
  5. }
复制代码

3.8 【CString】的使用
【Find】找到对应的字符在哪里,返回顺序(0开始)

【Mid】 从左移动到什么位置

【Right】返回右边第几个元素

  1. CString VSFileClean::GetExtName(CString fileName)
  2. {
  3.         //1.根据.获得位置
  4.         int pos = fileName.Find(_T("."));
  5.         //2.如果没有就返回剩余的就是后缀
  6.         if (pos == -1) {
  7.                 return fileName;
  8.         }
  9.         //3.找到在进去遍历,找到最后一个
  10.         else {
  11.                 return GetExtName(fileName.Mid(pos + 1));
  12.         }
  13. }
复制代码

3.9 【StringCbPrintf】拼接函数

StringCbPrintf(WCHAR数组名,数组长度,格式化字符)->"%sADD%s",s1,s2->s1+ADD+s2


3.10 【MFC】分割字符串函数


                               
登录/注册后可看大图

                               
登录/注册后可看大图




3.11.快捷键注册
  1. //1.快捷键注册
  2. ::RegisterHotKey(g_hDlg, 0x1995, MOD_CONTROL | MOD_ALT, 'Z');
  3. //2.调用虚函数
  4. BOOL CTaskManagerDlg::PreTranslateMessage(MSG* pMsg)
  5. {
  6.         if ((pMsg->message == WM_HOTKEY) && (pMsg->wParam == 0x1995))
  7.         {
  8.                 if (::IsWindowVisible(m_hWnd) == TRUE)
  9.                 {
  10.                         ShowWindow(SW_HIDE);
  11.                 }
  12.                 else {
  13.                         ShowWindow(SW_SHOW);
  14.                 }
  15.         }
  16.         return CDialogEx::PreTranslateMessage(pMsg);
复制代码



想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-10 02:43

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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