原文地址: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. Oracle分析函数-rank() over(partition by...order by...)

    select *from ( SELECT t.s#,---学号 t.c#,---课程号 T.SCCORE, ---成绩 RANK() OVER(PARTITION BY t.c# ORDER BY ...

  2. 关于PHP中会话技术的知识点分享

    前言:在PHP中会话技术也是特别重要的,主要应用在免登录,保存一些持久化数据等等的方面,但是后期的介绍中,我将会放弃这种技术改用redis方法来替换这种方法. (一)cookie技术(即数据缓存在客户 ...

  3. Postman系列之@RequestBody修饰的对象传参数

    例如有如下接口: @RequestMapping(value = "/api/user/validate", method = RequestMethod.POST) UserIn ...

  4. c++中sizeof的理解

    1. 例题 #include <iostream> class A {}; class B { char m_data; }; class C { ]; }; class D { char ...

  5. 微信小程序入门教程(一)API接口数据记录

    今天测试用小程序调用API接口,发现有些数据打印都是对象,怎么全部打印详细点来 小程序代码: httpsearch: function (name, offset, type, cb) { wx.re ...

  6. Android弹出窗口

    protected void PopUp() { final PopupWindow popup = new PopupWindow(TestActivity.this); View popView ...

  7. Newtonsoft.Json序列化字符串-格式化

    转自:https://blog.csdn.net/wlphlj/article/details/51982866最近C#中需要将实体进行json序列化,使用了Newtonsoft.Json publi ...

  8. idea 2018.1破解激活方法,有效期至2099年

    优点:有效期至2099年,不出意外,这辈子肯定够用了 缺点:稍微麻烦些,不过不要紧,为了以后省事,都值了 下面是具体的破解激活步骤: 1. 下载破解补丁文件,路径为:http://idea.lanyu ...

  9. Docker 容器暂停服务 - 七

    docker pause :暂停容器中所有的进程docker unpause :恢复容器中所有的进程 docker pause [OPTIONS] CONTAINER [CONTAINER...] d ...

  10. js的执行环境学习笔记

    js执行全局代码或者执行函数代码的时候,首先进行准备,然后再执行.准备阶段,就是创建执行环境的阶段. 1.执行环境 当一段js代码遇到解释器的时候,比如浏览器打开一段js代码时候,第一件事并不是马上执 ...