原文地址: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. Windows 运行库

    Microsoft Visual C++ 2005 Redistributable - 8.0.61001http://download.microsoft.com/download/8/B/4/8B ...

  2. 【英文文档】Solidifier for Windows Installation Guide

    Page 1Solidifier for Windows  Installation Guide Page 2McAfee, Inc.McAfee® Solidifier for Windows In ...

  3. 2016vijos 6-1 松鼠聚会(LCA+卡空间)

    求LCA,N=1e6,原空间限制8MB 求LCA需要深度,需要跳跃一定距离的祖先,需要父节点 把一个整数压成3个char,f[]存父节点 g[],深度为奇数的点存往上跳576步能到的点,深度为偶数的点 ...

  4. 在CentOS7上安装Zabbix3.0

    #!/bin/bash # # .配置无人值守的安装,定义安装过程中需要用到的一些信息 # mysql_root_pw=root_pw mysql_zabbix_pw=zabbix_pw DBPass ...

  5. treap基本操作

    利用rand保持堆的特性 const int N=; int ls[N],rs[N],v[N],p[N],cnt[N],siz[N]; // 权值 优先级 inline void update(int ...

  6. 【PgSQL安装(含配置)】PostgreSQL简称PgSQL,是1980以加利福尼亚大学开发的DBMS,严格遵守标准SQL。

    [下载地址]http://www.enterprisedb.com/products-services-training/pgdownload#windows …………………………………………………… ...

  7. pycharm上传代码到github

    一.配置pycharm 点击create API,添加自己的github账号,切记将clone git 那个对勾去掉,不然会报: Successfully created project ‘…’ on ...

  8. Ubuntu、Windows输入命令appium-doctor提示未找到命令

    输入命令:appium-doctor时,一直报错,提示“未找到命令”,但是输入命令:appium -v能够正确输出我安装版本,这是怎么回事呢? 原来appiu-doctor在1.5.3版本之后没有了需 ...

  9. Java基础_0206:方法的定义与使用

    方法的基本概念 方法的主要功能是封装可以执行的一段代码,这样不仅可以进行重复调用,更可以方便的实现代码的维护,而本次使用的方法定义语法如下所示. public static 返回值类型 方法名称(参数 ...

  10. 【报错】java.lang.ClassNotFoundException: org.apache.ibatis.session.SqlSession

    报错 java.lang.ClassNotFoundException: org.apache.ibatis.session.SqlSession 或者 java.lang.ClassNotFound ...