14 MFC多进程

这篇具有很好参考价值的文章主要介绍了14 MFC多进程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

创建进程

分别创建MFC应用程序和Win32应用程序

MFC应用程序界面设置
14 MFC多进程,mfc,c++

win32子进程内容

#include <Windows.h>
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdshow)
{

	MessageBox(NULL, lpCmdLine, L"提示", MB_OK);
	return 0;
}

将*.exe放入到主线程的Debug中
14 MFC多进程,mfc,c++

创建进程传递参数

void CParentDlg::OnBnClickedBtnStart()
{

	for (int i = 0; i < 10; i++)
	{
		//创建子进程
		//第二个参数不能传递常量,而应该传递一块内存
			/*启动顺序:
				1.父进程所在目录
				2.Windows系统目录
					TCHAR szPath[MAX_PATH];
					GetSystemDirectory(szPath,MAX_PATH);//获取系统目录
				3.Windows目录
				4.环境变量指定目录
			*/

		wchar_t szExePath[MAX_PATH] = L"sub.exe";

		wsprintf(szExePath, L"sub.exe %d-%d", i*100, i*100 + 99);

		//第三个参数:进程安全属性填写为NULL,表示为默认安全属性
		SECURITY_ATTRIBUTES sa;
		sa.nLength = sizeof(SECURITY_ATTRIBUTES);
		sa.lpSecurityDescriptor = NULL;//表示默认
		sa.bInheritHandle = TRUE;
		//第四个参数:线程安全属性
		//第五个参数:指示新进程是否从调用进程继承句柄
		//第六个参数:创建标记 0代表默认
		//第七个参数:环境变量
		//第八个参数:工作目录
		//第九个参数:启动信息
		STARTUPINFO si = { sizeof(STARTUPINFO) };
		//si.cb = sizeof(STARTUPINFO);
		//第十个参数进程信息
		PROCESS_INFORMATION pi = { 0 };

		if (TRUE == CreateProcess(NULL, szExePath, &sa, NULL, TRUE, 0, NULL, NULL, &si, &pi))
		{
			m_hSub[i] = pi.hProcess;//获取进程句柄
		}
	}

}

14 MFC多进程,mfc,c++

关闭进程

void CParentDlg::OnBnClickedBtnStop()
{
	for (int i = 0; i < 10; i++)
	{
		if (m_hSub[i] != NULL)
		{
			//等待信号改变
			//WaitForSingleObject(m_hSub[i], INFINITE);

			//引用计数
			CloseHandle(m_hSub[i]);//减小引用技术
			
			MessageBox(L"程序已关闭", L"提示",MB_OK);

			//强制关闭一个进程
			TerminateProcess(m_hSub[i], 0);//关闭代码,退出
		}
	}
}

通过配置文件读取

配置文件14 MFC多进程,mfc,c++

获取配置文件

bool CParentDlg::InitEnvironment()
{
	//读取配置文件
	//address of section name
	//address of key name
	//return value if key name is not found
	//address of initialization filename
	m_subProcessNum=GetPrivateProfileInt(L"Base",L"subProcessNum",0,L"D:\\MFCProject\\Parent\\Debug\\Parent.ini");
	
	if (m_subProcessNum != 0)
	{
		m_hSub = new HANDLE[m_subProcessNum];
	}
	return TRUE;
}

点击按钮

void CParentDlg::OnBnClickedBtnStart()
{
	InitEnvironment();//初始化环境
	for (int i = 0; i < CParentDlg::m_subProcessNum; i++)
	{
		//创建子进程
		//第二个参数不能传递常量,而应该传递一块内存
			/*启动顺序:
				1.父进程所在目录
				2.Windows系统目录
					TCHAR szPath[MAX_PATH];
					GetSystemDirectory(szPath,MAX_PATH);//获取系统目录
				3.Windows目录
				4.环境变量指定目录
			*/

		wchar_t szExePath[MAX_PATH] = L"sub.exe";

		wsprintf(szExePath, L"sub.exe %d-%d", i*100, i*100 + 99);

		//第三个参数:进程安全属性填写为NULL,表示为默认安全属性
		SECURITY_ATTRIBUTES sa;
		sa.nLength = sizeof(SECURITY_ATTRIBUTES);
		sa.lpSecurityDescriptor = NULL;//表示默认
		sa.bInheritHandle = TRUE;
		//第四个参数:线程安全属性
		//第五个参数:指示新进程是否从调用进程继承句柄
		//第六个参数:创建标记 0代表默认
		//第七个参数:环境变量
		//第八个参数:工作目录
		//第九个参数:启动信息
		STARTUPINFO si = { sizeof(STARTUPINFO) };
		//si.cb = sizeof(STARTUPINFO);
		//第十个参数进程信息
		PROCESS_INFORMATION pi = { 0 };

		if (TRUE == CreateProcess(NULL, szExePath, &sa, NULL, TRUE, 0, NULL, NULL, &si, &pi))
		{
			m_hSub[i] = pi.hProcess;//获取进程句柄
		}
	}

	//等待信号的变化
	//WaitForMultipleObjects(m_subProcessNum, CParentDlg::m_hSub,TRUE, INFINITE);
}

全部代码

// ParentDlg.cpp: 实现文件
//

#include "pch.h"
#include "framework.h"
#include "Parent.h"
#include "ParentDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CParentDlg 对话框



CParentDlg::CParentDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_PARENT_DIALOG, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	m_subProcessNum = 0;
	m_hSub = NULL;
}

CParentDlg::~CParentDlg()
{
	if (m_hSub != NULL)
	{
		delete[] m_hSub;
		m_hSub = NULL;
	}
}

void CParentDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CParentDlg, CDialogEx)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BTN_START, &CParentDlg::OnBnClickedBtnStart)
	ON_BN_CLICKED(IDC_BTN_STOP, &CParentDlg::OnBnClickedBtnStop)
END_MESSAGE_MAP()


// CParentDlg 消息处理程序

BOOL CParentDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	// TODO: 在此添加额外的初始化代码

	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CParentDlg::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 CParentDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}



void CParentDlg::OnBnClickedBtnStart()
{
	InitEnvironment();//初始化环境
	for (int i = 0; i < CParentDlg::m_subProcessNum; i++)
	{
		//创建子进程
		//第二个参数不能传递常量,而应该传递一块内存
			/*启动顺序:
				1.父进程所在目录
				2.Windows系统目录
					TCHAR szPath[MAX_PATH];
					GetSystemDirectory(szPath,MAX_PATH);//获取系统目录
				3.Windows目录
				4.环境变量指定目录
			*/

		wchar_t szExePath[MAX_PATH] = L"sub.exe";

		wsprintf(szExePath, L"sub.exe %d-%d", i*100, i*100 + 99);

		//第三个参数:进程安全属性填写为NULL,表示为默认安全属性
		SECURITY_ATTRIBUTES sa;
		sa.nLength = sizeof(SECURITY_ATTRIBUTES);
		sa.lpSecurityDescriptor = NULL;//表示默认
		sa.bInheritHandle = TRUE;
		//第四个参数:线程安全属性
		//第五个参数:指示新进程是否从调用进程继承句柄
		//第六个参数:创建标记 0代表默认
		//第七个参数:环境变量
		//第八个参数:工作目录
		//第九个参数:启动信息
		STARTUPINFO si = { sizeof(STARTUPINFO) };
		//si.cb = sizeof(STARTUPINFO);
		//第十个参数进程信息
		PROCESS_INFORMATION pi = { 0 };

		if (TRUE == CreateProcess(NULL, szExePath, &sa, NULL, TRUE, 0, NULL, NULL, &si, &pi))
		{
			m_hSub[i] = pi.hProcess;//获取进程句柄
		}
	}
	//等待信号的变化
	//WaitForMultipleObjects(m_subProcessNum, CParentDlg::m_hSub,TRUE, INFINITE);
}


void CParentDlg::OnBnClickedBtnStop()
{
	for (int i = 0; i < 10; i++)
	{
		if (m_hSub[i] != NULL)
		{
			//等待信号改变
			//WaitForSingleObject(m_hSub[i], INFINITE);

			//引用计数
			CloseHandle(m_hSub[i]);//减小引用技术
			
			MessageBox(L"程序已关闭", L"提示",MB_OK);

			//强制关闭一个进程
			TerminateProcess(m_hSub[i], 0);//关闭代码,退出

			
			
		}
	}
}

bool CParentDlg::InitEnvironment()
{
	//读取配置文件
	//address of section name
	//address of key name
	//return value if key name is not found
	//address of initialization filename
	m_subProcessNum=GetPrivateProfileInt(L"Base",L"subProcessNum",0,L"D:\\MFCProject\\Parent\\Debug\\Parent.ini");
	
	if (m_subProcessNum != 0)
	{
		m_hSub = new HANDLE[m_subProcessNum];
	}
	return TRUE;
}
// ParentDlg.h: 头文件
//

#pragma once


// CParentDlg 对话框
class CParentDlg : public CDialogEx
{
// 构造
public:
	CParentDlg(CWnd* pParent = nullptr);	// 标准构造函数
	~CParentDlg();
// 对话框数据
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_PARENT_DIALOG };
#endif

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持


// 实现
protected:
	HICON m_hIcon;

	// 生成的消息映射函数
	virtual BOOL OnInitDialog();
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()
public:
	HANDLE* m_hSub;
	afx_msg void OnBnClickedBtnStart();
	afx_msg void OnBnClickedBtnStop();
	bool InitEnvironment();
	int m_subProcessNum;
};

打开进程

ui界面
14 MFC多进程,mfc,c++设置关联变量
14 MFC多进程,mfc,c++
14 MFC多进程,mfc,c++获取窗口句柄
14 MFC多进程,mfc,c++

关闭按钮

void COpenDlg::OnBnClickedBtnClose()
{
	UpdateData(TRUE);//刷新 TRUE 代表把界面上显示的数值,更新到关联变量中
	//获得一个窗口名和类型名
	HWND hWnd = ::FindWindow(m_strWindowClass,m_strWindowTitle);
	if (hWnd == NULL)
	{
		MessageBox(L"没有找到");
		return;
	}


	//通过窗口句柄获得进程ID
	DWORD dwPID;
	GetWindowThreadProcessId(hWnd, &dwPID);



	//打开进程
	//第一个参数:访问权限
	//第二个参数:

	HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS,TRUE, dwPID);

	if (hProcess == NULL)
	{
		MessageBox(L"打开进程失败");
		return;
	}

	//关闭进程
	TerminateProcess(hProcess,0);

}

14 MFC多进程,mfc,c++

便利进程

14 MFC多进程,mfc,c++

初始化列表

BOOL CergodicProcessDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	m_list.InsertColumn(0, _T("进程名"), LVCFMT_LEFT, 120);
	m_list.InsertColumn(1, _T("PID"), LVCFMT_LEFT, 100);
	m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT);//扩展样式,显示高亮

	m_list2.InsertColumn(0, _T("模块路径"), LVCFMT_LEFT, 200);
	m_list2.SetExtendedStyle(LVS_EX_FULLROWSELECT);//扩展样式

	EnumProcess();

	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

创建进程快照

void CergodicProcessDlg::EnumProcess()
{
	//创建进程快照
	HANDLE hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
	//返回进程列表
	PROCESSENTRY32 pe32{sizeof(PROCESSENTRY32)};//枚举驻留的进程
	BOOL b=Process32First(hSnapshot, &pe32);
	int i = 0;
	while (b)
	{
		m_list.InsertItem(i, pe32.szExeFile);
		CString str;
		str.Format(L"%d", pe32.th32ParentProcessID);
		m_list.SetItemText(i, 1, str);
		b=Process32Next(hSnapshot, &pe32);//获取下一个进程
		i++;
	}
}

创建进程模块

void CergodicProcessDlg::EnumModule(DWORD dwPID)
{
	//创建进程快照
	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID);
	//返回进程列表
	MODULEENTRY32 me32{ sizeof(MODULEENTRY32) };//枚举驻留的进程
	BOOL b = Module32First(hSnapshot, &me32);
	int i = 0;
	while (b)
	{
		m_list2.InsertItem(i, me32.szExePath);
		
		b = Module32Next(hSnapshot, &me32);//获取下一个进程
		i++;
	}
	
}

点击进程获取进程模块

14 MFC多进程,mfc,c++文章来源地址https://www.toymoban.com/news/detail-528520.html

void CergodicProcessDlg::OnDblclkList1(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
	
	int nSel = m_list.GetSelectionMark();//获取选中的

	if (nSel < 0)
		return;
	DWORD dwPID = _wtoi(m_list.GetItemText(nSel, 1));
	m_list2.DeleteAllItems();//删除原来的
	EnumModule(dwPID);
	*pResult = 0;
}

到了这里,关于14 MFC多进程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【MFC】01.MFC框架-笔记

    MFC Microsoft Fundation class 微软基础类库 框架 基于Win32 SDK进行的封装 属性:缓解库关闭 属性-C/C++/代码生成/运行库/MTD 属性-常规-MFC的使用:在静态库中使用MFC,默认是使用的共享DLL,运行时库 SDK版本:开发软件的套件 WSK:开发驱动的套件 MFC基于类的管理 预编译头: Demo01.h

    2024年02月14日
    浏览(27)
  • MFC——我的第一个MFC

    我的第一个MFC是在图像软件设计课程中创建的,使用Visual Studio 2022软件,基于C++语言,依赖freeimage图像库,实现在窗口应用中对一幅图像进行各种处理功能(如中值滤波等) 微软基础类库(Microsoft Foundation Classes,简称MFC)是微软公司提供的一个类库,以C++类的形式封装了W

    2024年02月06日
    浏览(43)
  • 《MFC编程》:MFC的概念和作用

    MFC(Microsoft Foundation Classes),是微软公司提供的一个类库(class libraries),以C++类的形式封装了Windows的API,并且包含一个应用程序框架,以减少应用程序开发人员的工作量。其中包含的类包含大量Windows句柄封装类和很多Windows的内建控件和组件的封装类。 所以在MFC中,你可以直

    2024年02月02日
    浏览(23)
  • 【MFC】07.MFC六大机制:消息映射-笔记

    本专栏上两篇文章分别介绍了【MFC】05.MFC第一大机制:程序启动机制和【MFC】06.MFC第二大机制:窗口创建机制,这篇文章来为大家介绍MFC的第三大机制:消息映射 typfd要实现消息映射,必须满足的三个条件: 类必须继承于CmdTargert 类必须声明重定义 DECLARE_MESSAGE_MAP 类外必须实

    2024年02月13日
    浏览(34)
  • 【MFC】05.MFC六大机制:程序启动机制-笔记

    MFC程序开发所谓是非常简单,但是对于我们逆向人员来说,如果想要逆向MFC程序,那么我们就必须了解它背后的机制,这样我们才能够清晰地逆向出MFC程序,今天这篇文章就来带领大家了解MFC的第一大机制:程序启动机制: 首先,我们创建一个单文档架构程序,我们来观察一

    2024年02月13日
    浏览(26)
  • 【MFC】06.MFC六大机制:窗口创建机制-笔记

    接上文【MFC】05.MFC第一大机制:程序启动机制-笔记,这一篇文章来带领大家逆向分析MFC第二大机制:窗口创建机制的源码。 我们知道,在Win32编程中,如果我们要创建一个窗口,基本步骤为: 注册窗口 创建一个窗口,必须要给一个类名称 消息处理回调函数 那么MFC的窗口创建

    2024年02月13日
    浏览(22)
  • 【MFC】07.MFC第三大机制:消息映射-笔记

    本专栏上两篇文章分别介绍了【MFC】05.MFC第一大机制:程序启动机制和【MFC】06.MFC第二大机制:窗口创建机制,这篇文章来为大家介绍MFC的第三大机制:消息映射 typfd要实现消息映射,必须满足的三个条件: 类必须继承于CmdTargert 类必须声明重定义 DECLARE_MESSAGE_MAP 类外必须实

    2024年02月14日
    浏览(28)
  • 【MFC】06.MFC第二大机制:窗口创建机制-笔记

    接上文【MFC】05.MFC第一大机制:程序启动机制-笔记,这一篇文章来带领大家逆向分析MFC第二大机制:窗口创建机制的源码。 我们知道,在Win32编程中,如果我们要创建一个窗口,基本步骤为: 注册窗口 创建一个窗口,必须要给一个类名称 消息处理回调函数 那么MFC的窗口创建

    2024年02月14日
    浏览(28)
  • 【MFC】05.MFC第一大机制:程序启动机制-笔记

    MFC程序开发所谓是非常简单,但是对于我们逆向人员来说,如果想要逆向MFC程序,那么我们就必须了解它背后的机制,这样我们才能够清晰地逆向出MFC程序,今天这篇文章就来带领大家了解MFC的第一大机制:程序启动机制: 首先,我们创建一个单文档架构程序,我们来观察一

    2024年02月14日
    浏览(26)
  • vs mfc未加载mfc140u导致无法启动

    在非MFC程序中添加MFC时出现了报错显示 0x00007FFEB46D3F57 (mfc140ud.dll)处(位于 .exe 中)引发的异常: 0xC0000005: 读取位置 0x00000000 ,查了好多资料都认为是dll丢失,要么去下载要么去连接微软的服务器,如果连接微软的服务器启动的时候巨慢,并且我其它的mfc工程不受影响证明我的电

    2024年04月14日
    浏览(25)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包