事件与消息编程

(一) 利用用户定义的 消息通信

  在Windows程序设计中,应用程序的每一个线程都拥有自己的 消息队列,甚至工作线程也不例外,这样一来,就使得线程之间利用 消息来传递信息就变的非常简单。首先用户要定义一个用户 消息,如下所示:#define WM_USERMSG WMUSER+100;在需要的时候,在一个线程中调用::PostMessage((HWND)param,WM_USERMSG,0,0)或CwinThread::PostThradMessage()来向另外一个线程发送这个 消息,上述函数的四个参数分别是 消息将要发送到的目的窗口的句柄、要发送的 消息标志符、 消息的参数WPARAM和LPARAM。下面的代码的结果是在线程结束时显示一个对话框,提示线程结束:

UINT ThreadFunction(LPVOID pParam)
{
 while(!bend)
 {
  Beep(100,100);
  Sleep(1000);
 }
 ::PostMessage(hWnd,WM_USERMSG,0,0);
 return 0;
}
WM_USERMSG消息的响应函数为OnThreadended(WPARAM wParam,
LPARAM lParam)
LONG CTestView::OnThreadended(WPARAM wParam,LPARAM lParam)
{
 AfxMessageBox("Thread ended.");
 Retrun 0;
}

  上面的例子是工作者线程向用户界面线程发送 消息,对于工作者线程,如果它的设计模式也是 消息驱动的,那么调用者可以向它发送初始化、退出、执行某种特定的处理等 消息,让它在后台完成。在控制函数中可以直接使用::GetMessage()这个SDK函数进行 消息分检和处理,自己实现一个 消息循环。GetMessage()函数在判断该线程的 消息队列为空时,线程将系统分配给它的时间片让给其它线程,不无效的占用CPU的时间,如果 消息队列不为空,就获取这个 消息,判断这个 消息的内容并进行相应的处理。

  (二)用 事件对象实现通信

  在线程之间传递信号进行通信比较复杂的方法是使用 事件对象,用MFC的Cevent类的对象来表示。 事件对象处于两种状态之一:有信号和无信号,线程可以监视处于有信号状态的 事件,以便在适当的时候执行对 事件的操作。上述例子代码修改如下:


Cevent threadStart ,threadEnd;
UINT ThreadFunction(LPVOID pParam)
{
 ::WaitForSingleObject(threadStart.m_hObject,INFINITE);
 AfxMessageBox("Thread start.");
 while(!bend)
 {
  Beep(100,100);
  Sleep(1000);
  Int result=::WaitforSingleObject(threadEnd.m_hObject,0);
  //等待threadEnd事件有信号,无信号时线程在这里悬停
  If(result==Wait_OBJECT_0)
   Bend=TRUE;
 }
 ::PostMessage(hWnd,WM_USERMSG,0,0);
 return 0;
}
/
Void CtestView::OninitialUpdate()
{
 hWnd=GetSafeHwnd();
 threadStart.SetEvent();//threadStart事件有信号
 pThread=AfxBeginThread(ThreadFunction,hWnd);//启动线程
 pThread->m_bAutoDelete=FALSE;
 Cview::OnInitialUpdate();
}

Void CtestView::OnDestroy()
{
 threadEnd.SetEvent();
 WaitForSingleObject(pThread->m_hThread,INFINITE);
 delete pThread;
 Cview::OnDestroy();
}

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值