(第四版中文版)[十一]Windows消息处理和多线程

来源:互联网 发布:淘宝网天猫毛呢长裙 编辑:程序博客网 时间:2024/05/15 09:25

PeekMessage () :类似于 GetMessage () ,放在一个长时间工作的函数中,使控制交出。但即使没有消息到达,它也会马上返回,从而使函数继续执行。如果有一个消息到达,函数被暂停,消息函数被调用,返回后被暂停函数继续执行。 

空状态处理:OnIdle () :在消息队列为空的时候被调用,但如果没有持续的消息,函数不会被持续调用。基类的 OnIdle () 会更新工具栏和状态指示器,并清除各种临时对象。重载 OnIdle () 可用来更新用户界面。如果重载了 CWinApp::OnIdle() ,一定要重载基类的 OnIdle(),否则工具栏按钮不会被更新,临时对象也不会被清除。如果用户运行在一个模式对话框里或者正在使用菜单,则这时 OnIdle() 不会被调用,如果希望在这咱情况下使用后台处理,则必须加入 WM_ENTERIDLE消息控制函数,但必须加到框架类而不是视图类,这是因为弹出式对话框总是属于应用程序的主框架窗口而不是视图窗口。

多线程编程:大多数情况下,进程的所有代码和数据空间被进程内所有的线程所利用。线程由操作系统管理,且每个线程都有自己的堆栈。Windows提供 辅助线程和用户界面线程 两种。MFC对两种线程都支持。用户界面线程有窗口,因此有自己的消息循环;辅助线程没有窗口,所以不需要处理消息。辅助线程容易编程通常也很有用。

辅助线程:在启动一个辅助线程前,必须为线的主程序写一个全局函数,该函数返回一个UINT,并且带一个32位值(声明为LPVOID)作为参数。可以在线程启动时,用该参数传送线程任何适当的数据。当全局函数返回时,线程就终止,如果进程被终止,线程也会被终止,但在终止辅助线程前最好确保没有内存泄漏。为了启用辅助线程,程序如下调用 :

CWindThread *pThread =AfxBeginThread(ComputeThreadProc,GetSafeHwnd(),THREAD_PRIORITY_NOMAL );

线程函数:

UINT  ComputeThreadProc ( LPVIOD pParam )

{

       // 处理代码

      return 0 ;

}

函数 AfxBeginThread 会立即返回,返回值是一个指向新创建的线程对象的指针。可以用这个指针挂起或恢复线程。第二个参数是一个32位值,用来传给全局函数,第三个为线程的优先权码。

主、辅线程通话:不能通过消息,因为辅助线程没有消息循环。最简单的方法是利用全局变量,因为进程的所有线程都可以访问全局变量。为了使变量不会被保存到一个寄存器里,可以声明为 volatile 变量。

辅、主线程通话:通过 Windows消息,因为主线程总是有消息循环的,而辅助线程有相应窗口的变量。在调用 AfxBeginThread() 时把句柄传过去。最好用 Post 消息的方法,因为如果用 Send () ,会引起主线程的MFC消息处理代码的重入,而这在模式对话框中会出现问题。