最近正在学习《win32多线程程序设计》,这是其中一段重写消息循环的代码事例,以后可能用的上。

  while (!quit || gNumPrinting > 0)
{ // Wait for next message or object being signaled
DWORD dwWake;
dwWake = MsgWaitForMultipleObjects(
gNumPrinting,
gPrintJobs,
FALSE,
INFINITE,
QS_ALLEVENTS); if (dwWake >= WAIT_OBJECT_0 && dwWake < WAIT_OBJECT_0 + gNumPrinting)
{ // Object has been signaled
// Reorder the handle array so we do not leave
// empty slots. Take the handle at the end of
// the array and move it into the now-empty slot.
int index = dwWake - WAIT_OBJECT_0;
gPrintJobs[index] = gPrintJobs[gNumPrinting-1];
gPrintJobs[gNumPrinting-1] = 0;
gNumPrinting--;
SendMessage(hDlgMain, WM_THREADCOUNT, gNumPrinting, 0L);
} // end if
else if (dwWake == WAIT_OBJECT_0 + gNumPrinting)
{
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{ // Get Next message in queue
if(hDlgMain == NULL || !IsDialogMessage(hDlgMain,&msg))
{
if (msg.message == WM_QUIT)
{
quit = TRUE;
exitCode = msg.wParam;
break;
} // end if
TranslateMessage(&msg);
DispatchMessage(&msg);
}
} // end while
}
} // end while

说明:

MsgWaitForMultipleObjects函数

该函数的特点是它不但可以等待内核对象,还可以等消息。也就是当有消息到来时,该函数也一样可以返回,并处理消息,这样就给了工作线程退出的机会。

DWORD MsgWaitForMultipleObjects(

DWORD nCount, //要等待的内核对象数目

LPHANDLE pHandles, //要等待的内核对象句柄数组指针

BOOL fWaitAll, //是等待全部对象还是单个对象

DWORD dwMilliseconds,//等待时间 

DWORD dwWakeMask );//等待的消息类型

下面就详解一下该函数的参数使用方法:

DWORD nCount:要等待的内核对象的数目。如果等待两个线程退出,则nCount=2;

LPHANDLE pHandles:要等待的内核对象句柄数组指针。

如果只要等待一个线程退出,则直接设置该线程句柄的指针即可:

MsgWaitForMultipleObjects(1,&m_pThread->m_hThread,…)

如果要等待两个线程退出,则使用方法为:

HANDLE hArray[2]={ m_pThread1->m_hThread , m_pThread2->m_hThread };

MsgWaitForMultipleObjects(2,hArray,…)

BOOL fWaitAll: TRUE-表示只有要等待的线程全部退出后,此函数才返回,

               FALSE-表示要等待的线程中任意一个退出了,或是有消息到达了,此函数均会返回。

在上面的OnButton2()函数中,我要等待一个线程退出,将fWaitAll设置为

FALSE,目的是无论是线程真的退出了,还是有消息到达了,该函数都能返回。

如果将该fWaitAll设置为TRUE,那么函数返回的唯一条件是线程退出了,即便

是有消息到来了,该函数也一样不会返回。

DWORD dwMilliseconds:等待的事件,单位是毫秒。可以设置为INFINITE,无

穷等待

DWORD dwWakeMask:等待的消息类型,通常可以设置为QS_ALLINPUT。此宏表示的是可以等待任意类型的消息。当然,也可以指定等待的消息类型。

#define QS_ALLINPUT        (QS_INPUT         | \

                            QS_POSTMESSAGE   | \

                            QS_TIMER         | \

                            QS_PAINT         | \

                            QS_HOTKEY        | \

                            QS_SENDMESSAGE)

返回值:DWORD dRet 通过函数返回值,可以得到一些有效信息。函数返回值依fWaitAll设置的不同而有所不同。下面是函数返回值的几种常见类型:

dRet = 0xFFFFFFFF :   表示函数调用失败,可用GetLastError()得到具体的出错信息;

dRet =WAIT_OBJECT_0+nCount:表示有消息到达了;

如果fWaitAll设置为TRUE

dRet = WAIT_OBJECT_0,表示所有等待的核心对象都激发了,或是线程都退出了;

如果fWaitAll设置为FALSE

dRet = WAIT_OBJECT_0 ~ WAIT_OBJECT_0+nCount-1:表示等待的内核对象被激发了,index=dRet - WAIT_OBJECT_0,表示hArray[]数组中索引为index的那个对象被激发了。

win32多线程-重写消息循环的更多相关文章

  1. win32编程中消息循环和WndProc()窗口过程函数

    原文地址:https://blog.csdn.net/zxxSsdsd/article/details/45504383 在win32程序的消息循环函数中  while (GetMessage (&a ...

  2. Win32消息循环机制等【转载】http://blog.csdn.net/u013777351/article/details/49522219

    Dos的过程驱动与Windows的事件驱动 在讲本程序的消息循环之前,我想先谈一下Dos与Windows驱动机制的区别: DOS程序主要使用顺序的,过程驱动的程序设计方法.顺序的,过程驱动的程序有一个 ...

  3. 什么是消息循环,一个简单的win32程序如何运行?

    预备知识 1.什么是句柄? (HANDLE) 在win32编程中有各种句柄,那么什么是句柄呢? #define DECLARE_HANDLE(name) struct name##_ { int un ...

  4. Win32编程API 基础篇 -- 4.消息循环

    消息循环 理解消息循环 为了编写任何即使是最简单的程序,了解windows程序的消息循环和整个消息发送结构是非常有必要的.既然我们已经尝试了一点消息处理的东西,我们应该对整个程序有更深入的理解,如果你 ...

  5. Win32 SDK 编程开始, 创建窗口, 消息的处理, 消息循环

    Windows SDK 编程的一般步骤为: 1. 注册窗口类, 使用到的结构 WNDCLASSEX, 函数 RegisterClassEx. 2. 创建窗口, 函数 CreateWindowEx. 3 ...

  6. Android的消息循环机制 Looper Handler类分析

    Android的消息循环机制 Looper Handler类分析 Looper类说明   Looper 类用来为一个线程跑一个消息循环. 线程在默认情况下是没有消息循环与之关联的,Thread类在ru ...

  7. 深入浅出Win32多线程程序设计之基本概念

    一.深入浅出Win32多线程程序设计之基本概念[转] 引言 从单进程单线程到多进程多线程是操作系统发展的一种必然趋势,当年的DOS系统属于单任务操作系统,最优秀的程序员也只能通过驻留内存的方式实现所谓 ...

  8. 深入探讨MFC消息循环和消息泵

    首先,应该清楚MFC的消息循环(::GetMessage,::PeekMessage),消息泵(CWinThread::PumpMessage)和MFC的消息在窗口之间的路由是两件不同的事情.在MFC ...

  9. 多线程学习:win32多线程编程基本概念(转)

    一.定义: 1.进程和线程的区别 进程:是程序的执行过程,具有动态性,即运行的程序就叫进程,不运行就叫程序 ,每个进程包含一到多个线程.线程:系统中的最小执行单元,同一进程中有多个线程,线程可以共享资 ...

随机推荐

  1. Iframe父页面与子页面之间的调用

    原文:Iframe父页面与子页面之间的调用 Iframe父页面与子页面之间的调用 专业词语解释如下:     Iframe:iframe元素是文档中的文档.     window对象: 浏览器会在其打 ...

  2. Java Persistence with MyBatis 3(中国版) 第五章 与Spring集成

    MyBatis-Spring它是MyBatis子模块框.它用来提供流行的依赖注入框架Spring无缝集成. Spring框架是一个基于依赖注入(Dependency Injection)和面向切面编程 ...

  3. ActiveReports 9实战教程(1): 手把手搭建环境Visual Studio 2013 社区版

    原文:ActiveReports 9实战教程(1): 手把手搭建环境Visual Studio 2013 社区版 ActiveReports 9刚刚发布3天,微软就发布了 Visual Studio ...

  4. Fedora21无法播放MP4[已解决]

    首先,安装安装rpmfusion源 http://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-21.noarch.rpm ht ...

  5. C#:判断当前程序是否通过管理员运行

    原文:C#:判断当前程序是否通过管理员运行 public bool IsAdministrator() { WindowsIdentity current = WindowsIdentity.GetC ...

  6. asp.net访问WebService的各种方式

    WebService的访问形式主要有:SOAP调用.XMLHTTP POST.GET调用.MicroSoft.XMLDOMC调用.webbehavior.htc调用 我们知道的在C#后台本地调用Web ...

  7. Mysql高级之索引

    原文:Mysql高级之索引 索引:是针对数据所建立的目录. 作用: 可以加快查询速度 负面影响: 降低了增删改的速度. 索引的创建原则: 1:不要过度索引 2:在where条件最频繁的列上加.在重复度 ...

  8. 国内外最全面和主流的JS框架与WEB UI库

    当下对于网站前段开发人员来说,很少有人不使用一些JS框架或者WEB UI库,因此这些可以有效提高网站前段开发速度,并且能够统一开发环境,对于不同浏览器的兼容性也不需要程序员操心,有了这些优点,当然大家 ...

  9. Android项目---常用动画

    在项目中经常会有闪屏的效果 在这里主要是通过定时器,将已经设定好的效果展现出来 /* * 2.5秒以后开始执行Runnable的run方法 */ new Handler().postDelayed(n ...

  10. .net创建并安装windows服务案例

    1. 创建windows服务[引用博文]: 1. 将这个服务程序切换到设计视图2. 右击设计视图选择“添加安装程序”3. 切换到刚被添加的ProjectInstaller的设计视图4. 设置servi ...