消息和事件的区别 VC++解惑

来源:互联网 发布:淘宝鞋子关键词 编辑:程序博客网 时间:2024/04/29 02:15
首先要明确VC++中使用消息映射技术处理“消息”和“事件” ,通过DECLARE_MESSAGE_MAP()等宏通杀    

     事件就是“当....的时候”,事件总是和一个ID有关    

     消息就是“嗨!你该干....了” VS2005以上的“消息”标签中就是VC6 Windows Messages Handler中的内容

     我们一般都是在 "当...的时候" 干 XXX0 或者 XXX1 XXX2 .... 也可以 “这件事情我不想理会”(让Windows去干)。 我们也可能在正干XXXn中突然想起: “嗨!我该晚餐了!” 再附上不经典的描述:事件是一个动作——用户触发的动作。 消息是一个信息——传递给系统的信息。 事件与消息的概念在计算机中较易混淆,但本质不同: 事件由用户(操作电脑的人)触发且只能由用户触发,操作系统能够感觉到由用户触发的事件,并将此事件转换为一个(特定的)消息发送到程序的消息队列中。 这里强调的是: 可以说“用户触发了一个事件”,而不能说“用户触发了一个消息”。 用户只能触发事件,而事件只能由用户触发。 一个事件产生后,将被操作系统转换为一个消息,所以一个消息可能是由一个事件转换而来(或者由操作系统产生)。 一个消息可能会产生另一个消息,但一个消息决不能产生一个事件——时间只能由用户触发。  

     总结(事件,消息的来源):

    事件:只能由用户通过外设的输入产生。

    消息:(产生消息的来源有三个) (1) 由操作系统产生。 (2) 由用户触发的事件转换而来。 (3) 由另一个消息产生。

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

       在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); 

d elete pThread;

 Cview::OnDestroy();

}

原创粉丝点击