原文地址:https://blog.csdn.net/zxxSsdsd/article/details/45504383

在win32程序的消息循环函数中  while (GetMessage (&msg, NULL, 0, 0))  {     TranslateMessage (&msg) ;     DispatchMessage (&msg) ;     }DispatchMessag()会调用WndProc()窗口过程函数,直到WndProc()处理完后DispatchMessag()才返回,继续消息循环检索下一条消息,在此之前while()消息循环会停顿掉在WndProc()函数处理过程中如果又产生了另一个消息B,则必须等这个消息B处理完后wndProc()函数才会返回,而这个消息B也是要由WndProc()函数处理的,即在WndProc()调用的过程中系统接受到消息B后嵌套调用了WndProc(),但此时while消息循环已经停顿了return msg.wParam;根据试验,在WndProc()处理过程中发出消息B后,系统通过某种方式跳过while()消息循环获取了消息B,并且又调用了一个WndProc()来处理消息B,等消息B处理完后第二个WndProc()才返回,然后第一个WndProc()继续执行,等第一个WndProc()执行完毕后DispatchMessage()才会返回,然后继续下一轮while()循环那么,系统是怎样接受到这个消息B的呢?系统是怎样绕过while消息循环获取消息B并且调用第二个WndProc()的,这中间具体发生了哪些事情?网上和书上都没找到详细的处理过程……我想应该还是跟消息队列有关,不知道系统在这种情况下怎样处理消息队列中的消息的?MSG_B Over每个窗口、线程都有自己的消息队列,消息是投递到消息队列里的while (GetMessage (&msg, NULL, 0, 0))  TranslateMessage (&msg) ;     DispatchMessage (&msg) ;     }GetMessage是从消息队列里获取消息,因此,消息传过来的时候,是不占用这个循环的谢谢解答!可是在DispatchMessage (&msg)函数中调用wndproc()窗口过程时,while ()消息循环是停顿掉的,发出消息B后,这时系统是跳过while()消息循环直接到消息队列里取的消息吗?是怎样调用第二个wndproc()窗口过程的?用到了哪些函数呢?你用什么消息测试的。有的消息是不放在消息队列里的。ShowWindow(hwnd, nCmdShow);
 
不是所有消息都会进消息队列,系统会有额外处理,对于SendMessage,类似于直接调用WinProc来实现.谢谢了,我是担心SendMssage()可能会影响测试结果,所以用PostMessage()发送的消息PostMessage的话 消息进消息队列下次取消息的时候才会取到消息。
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,  不是,虽然PostMessage只是投递消息,但是在WndProc窗口过程函数中必须处理完这个新消息后才继续执行WndProc()函数是可重入的,就是说:WndProc()函数虽然没结束,但一个API调用(SendMessage()、PostMessage等)会再次调用WndProc()所以我想知道系统这时是怎样再次调用WndProc()窗口过程函数的SendMessage给自己发才会先处理完这个新消息后才继续执行SendMessageW->SendMessageWorkerSendMessageWorker判断目标窗口的线程是不是当前线程,如果不是就进入内核调用NtUserMessageCall否则就在用户模式调用窗口过程PostMessage的话只是把消息放到消息队列中,下次GetMessage的时候才取到。SendMessage( hwnd , WM_MESS , w , l );内部调用WndProc( hwnd , WM_MESS , w , l );你可以下个断点看看调用栈。
 
谢谢!谢谢各位的解答,在此特别感谢 Lactoferrin qman007 等,感谢你们的解答由于之前测试消息的选择和测试方式的错误,导致我测试的结果不可信,我重新进行了测试,根据测试结果,对于WinProc消息循环的机制我是这样理解的:SendMessage 的话相当于直接调用 WndProc
 
1、在win32程序的while消息循环中,DispatchMessag()会调用WndProc()窗口过程函数,直到WndProc()处理完后DispatchMessag()才返回,继续消息循环检索下一条消息,在这之前while()消息循环会停顿掉
2、在WndProc()函数处理过程中又产生了另一个消息B,如果消息B是由PostMessage()发送的,则消息B会发送到消息队列中,然后WndProc()继续执行,执行完毕后返回到DispatchMessag()函数,继续消息循环检索下一条消息,检索到消息B后才开始执行消息B,
3、在WndProc()函数处理过程中又产生了另一个消息B,如果消息B是由SendMessage()发送的,则必须等这个消息B处理完后wndProc()函数才会返回,这时SendMessage()会调用 SendMessageWorker(),SendMessageWorker()判断目标窗口的线程是不是当前线程,如果不是就进入内核调用NtUserMessageCall(),否则就在用户模式调用窗口过程函数WndProc()

win32编程中消息循环和WndProc()窗口过程函数的更多相关文章

  1. windows窗口过程函数名词解析

    windows窗口过程函数名词解析 LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) 1. LR ...

  2. win32程序通过LPCREATESTRUCT中的lpCreateParams传递参数给窗口过程函数

    win32窗口程序中如果需要给窗口过程函数传递自定义参数,可以通过LPCREATESTRUCT结构体中的lpCreateParams进行传递. 创建窗口实例函数: m_hWnd = CreateWin ...

  3. MSG结构体和WndProc窗口过程详解

    MSG结构体和WndProc窗口过程对于Windows编程非常重要,如果不了解它们,可以说就没有学会Windows编程. MSG结构体 MSG 结构体用来表示一条消息,各个字段的含义如下: typed ...

  4. QT中关闭应用程序和窗口的函数(quit(),exit()以及close()的区别)

    使用QT编辑界面,其中带来很大方便的一点就是Qt中自带丰富的.种类齐全的类及其功能函数,程序员可以在编辑程序的过程中简单地直接调用.关于窗口关闭的操作,在这里指出常用的三个槽,即quit(),exit ...

  5. win32多线程-重写消息循环

    最近正在学习<win32多线程程序设计>,这是其中一段重写消息循环的代码事例,以后可能用的上. while (!quit || gNumPrinting > 0) { // Wait ...

  6. Win32编程中如何处理控制台消息

    这篇文章讨论如何处理所有的控制台消息. 第一步,首先要安装一个事件钩子,也就是说要建立一个回调函数.调用Win32 API,原型如下: BOOL SetConsoleCtrlHandler(PHAND ...

  7. shell编程中的循环语句

    while循环直接从文件中读取 while read line do command done < filename until循环 until 条件 do command done for循环 ...

  8. 孙鑫视频学习:改变窗口过程函数中出现error C2440错误的解决方法

    在Visual Studio 2010中,即使代码是完完全全按照孙鑫视频中的敲,也会在出现error C2440,这是因为开发平台由VC6.0升级至VS2010,需要将原有的项目迁移.VS2010对消 ...

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

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

随机推荐

  1. python css功能补充讲解

    ###########总结#### 标签选择器 标签名     id选择器  #box1   类选择器.box2 css高级选择器 *子选择器* 子选择器用 大于号 .box1>.box2{ w ...

  2. 跳到IE9的一个坑里了(枚举 JavaScript 属性)

    有一段Json如下 [{"SaleName_ID":"0","SaleName":"","28":& ...

  3. 致备战noip2018的勇士

    戒骄戒躁,自律当先.稳扎稳打,颗粒归仓.目标高远,落实当下.无惧将来,无畏过往.愿你们承担一份荣耀,愿你们书写一段辉煌.——致备战noip2018的你们 ——退役学姐致gryz备战中的勇士 ——lpy ...

  4. 解决svn检出后不显示图标的问题

    解决svn检出后不显示图标的问题: 此文经过个人验证,可以解决TortoiseSVN图标显示异常问题: 问题出现原因:Windows Explorer Shell 支持 Overlay Icon 最多 ...

  5. Vuex笔记

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 Vuex - 状态管理器,可以管理你的数据状态(类似于 React的 Redux) 一个 Vuex 应用的核心是 store(仓库,一个 ...

  6. vue-router中query与params区别

    query和params两者都是在Vue路由中传参. 用法: query用path来引入,params只能用name来传递,不能使用path 展示效果:query更像ajax中get请求(会在地址栏显 ...

  7. 使用wget命令下载JDK失败(文件特别小)

    问题RT: 我们在网页上下载的时候要点一下 “Accept License Agreement ” ,使用wget下载的时候也需要提交这个 accept,方法如下: wget --no-check-c ...

  8. django生产环境启动问题

    unavailable modifier requested: 0 环境: nginx+uwsgi+django *** Starting uWSGI 2.0.16 (64bit) on [Wed J ...

  9. maven项目配置框架

    任何一个maven项目都会继承一个默认的父pom配置:Super POM,详见:https://maven.apache.org/guides/introduction/introduction-to ...

  10. 数据库设计理论与实践·<一>总结

    一.数据库生命周期 数据库生命周期流程图如下: 二.各阶段附图 附图1.1 数据流图 附图1.2 数据字典-方式1 补充说明:数据字典既可以单张表格表示,也可以多种(数据项表/数据结构表/数据流表/外 ...