MFC之消息传递(A->B->C, C为主窗口且没有启动)

13 篇文章 0 订阅
8 篇文章 0 订阅

情形一

你希望启动一个进程A,然后希望在进程A中再启动B,并暂停当前进程A,直到进程B结束后再返回进程A?

这时就可以调用API函数WaitForSingleObject函数

注意:Linux内核其实也提供了类似的函数,可以执行进程A的同时创建B,并且以不同的顺序执行

	STARTUPINFO si;
	::ZeroMemory(&si, sizeof(STARTUPINFO));
	si.cb = sizeof(STARTUPINFO);
	PROCESS_INFORMATION pi;
	if (::CreateProcess(NULL, _T("Notepad"), NULL, NULL,FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL,&si,&pi))
	{
		::CloseHandle(pi.hThread);
		::WaitForSingleObject(pi.hProcess, INFINITE);
		::CloseHandle(pi.hProcess);
	}

这里createProcess为创建进程的函数,里面参数可以自行查找,当创建成功后,先关闭了线程句柄,

注意:Window一般将对象和句柄绑定,当对象销毁的时候,句柄会随之销毁,但是需要一定时间(实际很短)

这里面我使用WaitForSingleObject阻止当前线程直到指定的对象进入信号发出状态,即是去等待线程B的结束信号,只有线程B结束的时候才会处于信号发出状态,其实也是线程A一直在阻塞状态,应该是休眠让出CPU,然后B线程去执行,直到B线程执行结束后,OS才会唤醒线程A,A线程才得以继续执行。

情形二:

如果A窗口先创建,然后在A窗口创建了B,在B窗口(有一些选项按钮)创建了C窗口(主窗口),当选择了按钮之后进入C,在C退出后如何返回到B?同时在C还没有创建前,如何由B向C发送消息呢?如下实例图:

 

例子不是使用窗口,而是进程,其实原理是想通的:这里我们可以使用函数WaitForInputIdle函数

	STARTUPINFO si;
	::ZeroMemory(&si, sizeof(STARTUPINFO));
	si.cb = sizeof(STARTUPINFO);
	PROCESS_INFORMATION pi;
	if (::CreateProcess(NULL, _T("Notepad"), NULL, NULL,FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL,&si,&pi))
	{
		::CloseHandle(pi.hThread);
		//::WaitForSingleObject(pi.hProcess, INFINITE);
		WaitForInputIdle(pi.hProcess, INFINITE)
		::CloseHandle(pi.hProcess);
	}

这里面设线程A、B,WaitForInputIdle直到线程B开始处理消息并清空消息队列,才会执行当前线程A;

试想上面的情况:如果A创建了B窗口,当然AB都是C的子窗口,MFC默认一般要有一个主窗口,可以进行消息的发送,这样消息会自动传递到主窗口,这里我们就可以进行消息的传递,A可以使用也可以不使用,假设B使用消息传递到C,这时候我们就可以使用上面类似的函数进行处理。这里面是进程,因为上面窗口创建的时候可以使用线程

题外话:当然你可以指定窗口句柄,发送到任意窗口,其实窗口的东西的很乱,你需要获得好多东西,还需要转换,像Linux那种界面内核分离的机制就很好,不用关心太多界面的东西

情形三:

当执行一个大量在主线程执行的任务,这时候主线程可能会出现假死,如果在主线程响应主任务的同时,又可以响应用户的操作呢?

这里面说的就是消息泵,我们知道在MFC有钩子,就是在事件在到达消息循环处理队列之前(消息被分派到Windows函数TranslateMessage和DispatchMessage之前过滤窗口消息)就被处理了,然后可以清除队列了,同样我们可以在主函数无法响应的处理函数里面添加一个消息处理函数

如下函数:

	MSG msg;
	while (::PeekMessage(&msg,NULL,0,0,PM_NOREMOVE))
	{
		if (!AfxGetApp()->PumpMessage())
		{
			::PostQuitMessage(0);
			return FALSE;
		}
	}

	long lIdel = 0;
	while (AfxGetApp()->OnIdle(lIdel++));

	return TRUE;

PeekMessage 从消息队列里面取出消息,放入msg结构,跟GetMessage有些不同,不会等待消息放入队列才返回,就是说空队列会直接返回。

PumpMessage 包含线程的消息循环,CWinThread 调用发送线程的消息,可以直接调用PumpMessage 强制消息处理,处理失败就发送退出消息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值