#pragma once #include "afxcmn.h" #include <vector> using std::vector; // CDlgModule 对话框 class CDlgModule : public CDialogEx { DECLARE_DYNAMIC(CDlgModule) public: CDlgModule(CWnd* pParent = NULL); // 标准构造函数 virtual ~CDlgModule(); typedef struct _MYMODULE { DWORD dwBaseOfDll;//模块基址 DWORD dwSize;//模块大小 DWORD dwOEP;//OEP CString strName;//模块名称 CString strPath;//模块路径 }MYMODULE; // 对话框数据 enum { IDD = IDD_DIALOG1 }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() public: virtual BOOL OnInitDialog(); CListCtrl m_CtrlList; afx_msg BOOL OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct); protected: afx_msg LRESULT OnModule(WPARAM wParam, LPARAM lParam); void ErgodicModule(DWORD dwPid); vector<MYMODULE> m_vecModule; };
// ProcessDlg.h : 头文件 // #pragma once #include "afxcmn.h" #include <vector> using std::vector ; // CProcessDlg 对话框 class CProcessDlg : public CDialogEx { // 构造 public: CProcessDlg(CWnd* pParent = NULL); // 标准构造函数 // 对话框数据 enum { IDD = IDD_PROCESS_DIALOG }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 typedef struct _MYPROCESS { DWORD dwPid;// PID DWORD dwPPid;//父PID DWORD dwCounts;//线程数 CString strName;//进程名 CString strPath;//进程所在路径 }MYPROCESS; // 实现 protected: HICON m_hIcon; // 生成的消息映射函数 virtual BOOL OnInitDialog(); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); DECLARE_MESSAGE_MAP() public: CDialogEx *pDlg; void ErgodicProcess(); CListCtrl m_CtrlList; vector<MYPROCESS> m_vecProc; afx_msg void OnRclickList1(NMHDR *pNMHDR, LRESULT *pResult); afx_msg void On32771(); };
// ProcessDlg.cpp : 实现文件 // #include "stdafx.h" #include "Process.h" #include "ProcessDlg.h" #include "afxdialogex.h" #include <TlHelp32.h> #include "DlgModule.h" #ifdef _DEBUG #define new DEBUG_NEW #endif // 用于应用程序“关于”菜单项的 CAboutDlg 对话框 class CAboutDlg : public CDialogEx { public: CAboutDlg(); // 对话框数据 enum { IDD = IDD_ABOUTBOX }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 // 实现 protected: DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD) { } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx) END_MESSAGE_MAP() // CProcessDlg 对话框 CProcessDlg::CProcessDlg(CWnd* pParent /*=NULL*/) : CDialogEx(CProcessDlg::IDD, pParent) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CProcessDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Control(pDX, IDC_LIST1, m_CtrlList); } BEGIN_MESSAGE_MAP(CProcessDlg, CDialogEx) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_NOTIFY(NM_RCLICK, IDC_LIST1, &CProcessDlg::OnRclickList1) ON_COMMAND(ID_32771, &CProcessDlg::On32771) END_MESSAGE_MAP() // CProcessDlg 消息处理程序 BOOL CProcessDlg::OnInitDialog() { CDialogEx::OnInitDialog(); // 将“关于...”菜单项添加到系统菜单中。 // IDM_ABOUTBOX 必须在系统命令范围内。 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { BOOL bNameValid; CString strAboutMenu; bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX); ASSERT(bNameValid); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动 // 执行此操作 SetIcon(m_hIcon, TRUE); // 设置大图标 SetIcon(m_hIcon, FALSE); // 设置小图标 // TODO: 在此添加额外的初始化代码 // 1.设置扩展样式->整行选中、带网格 m_CtrlList.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES); // 2.要插入的列标题 TCHAR *szColumn[] = { L"PID", L"进程名", L"进程所在路径",L"PPID",L"线程数" }; // 3.插入列标题 for (int i = 0; i < 5;i++) { m_CtrlList.InsertColumn(i, szColumn[i], LVCFMT_LEFT,80); } // 4.遍历进程获取进程信息 ErgodicProcess(); // 5.插入进程信息 CString temp; for (DWORD i = 0; i < m_vecProc.size(); i++) { // 5.1插入第1行 temp.Format(L"%d", m_vecProc[i].dwPid); m_CtrlList.InsertItem(i, temp); // 5.2设置第2行信息名字 m_CtrlList.SetItem(i, 1, LVIF_TEXT, m_vecProc[i].strName, 0, 0, 0, 0); // 5.3设置第3行信息路径 m_CtrlList.SetItem(i, 2, LVIF_TEXT, m_vecProc[i].strPath, 0, 0, 0, 0); // 5.4设置第4行信息PPID temp.Format(L"%d", m_vecProc[i].dwPPid); m_CtrlList.SetItem(i, 3, LVIF_TEXT, temp, 0, 0, 0, 0); // 5.5设置第5行信息线程数 temp.Format(L"%d", m_vecProc[i].dwCounts); m_CtrlList.SetItem(i, 4, LVIF_TEXT, temp, 0, 0, 0, 0); } return TRUE; // 除非将焦点设置到控件,否则返回 TRUE } void CProcessDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialogEx::OnSysCommand(nID, lParam); } } // 如果向对话框添加最小化按钮,则需要下面的代码 // 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序, // 这将由框架自动完成。 void CProcessDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // 用于绘制的设备上下文 SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0); // 使图标在工作区矩形中居中 int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // 绘制图标 dc.DrawIcon(x, y, m_hIcon); } else { CDialogEx::OnPaint(); } } //当用户拖动最小化窗口时系统调用此函数取得光标 //显示。 HCURSOR CProcessDlg::OnQueryDragIcon() { return static_cast<HCURSOR>(m_hIcon); } void CProcessDlg::ErgodicProcess() { // 1.创建进程镜像 HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (INVALID_HANDLE_VALUE == hSnap) { return; } // 2.查询进程信息 MYPROCESS temp = {}; PROCESSENTRY32 pi = { sizeof(PROCESSENTRY32) }; BOOL Ret = Process32First(hSnap, &pi); if (Ret == FALSE) { CloseHandle(hSnap); return; } do { temp.dwPid = pi.th32ProcessID; temp.dwPPid = pi.th32ParentProcessID; temp.dwCounts = pi.cntThreads; temp.strName = pi.szExeFile; // 2.1打开进程查询进程所在路径 HANDLE hProc = OpenProcess(PROCESS_QUERY_INFORMATION, NULL, pi.th32ProcessID); TCHAR szPath[MAX_PATH] = {}; DWORD dwSize = MAX_PATH; QueryFullProcessImageName(hProc, 0, szPath, &dwSize); // 2.2保存进程所在路径 temp.strPath = szPath; m_vecProc.push_back(temp); } while (Process32Next(hSnap, &pi)); // 4.关闭镜像句柄 CloseHandle(hSnap); } void CProcessDlg::OnRclickList1(NMHDR *pNMHDR, LRESULT *pResult) { LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR); // TODO: 在此添加控件通知处理程序代码 //记录1下点击所在行 // 1.加载菜单 HMENU hMenu = LoadMenu(AfxGetApp()->m_hInstance,MAKEINTRESOURCE(IDR_MENU1)); // 2.获取子菜单 HMENU hSubMenu = GetSubMenu(hMenu,0); // 3.弹出子菜单 /*POINT pt1 = pNMItemActivate->ptAction; CRect rc = { 0, 0, pt1.x, pt1.y }; ClientToScreen(&rc); TrackPopupMenu(hSubMenu, TPM_LEFTALIGN | TPM_TOPALIGN, rc.right,rc.bottom, 0, m_hWnd, 0); */ POINT pt = {}; GetCursorPos(&pt); TrackPopupMenu(hSubMenu, TPM_LEFTALIGN | TPM_TOPALIGN, pt.x, pt.y, 0, m_hWnd, 0); // 4.销毁菜单 DestroyMenu(hMenu); *pResult = 0; } #define WM_MODULE WM_USER+1 //查看模块 void CProcessDlg::On32771() { // TODO: 在此添加命令处理程序代码 int n = m_CtrlList.GetSelectionMark(); COPYDATASTRUCT cp = { m_vecProc[n].dwPid, 0, 0 }; pDlg = new CDlgModule; pDlg->Create(IDD_DIALOG1); // 1.WM_COPYDATA ::SendMessage(pDlg->m_hWnd, WM_COPYDATA, (WPARAM)m_hWnd, (LPARAM)&cp); // 2.自定义消息 //::SendMessage(pDlg->m_hWnd, WM_MODULE, NULL, (LPARAM)m_vecProc[n].dwPid); }