WM_TIMER和MessageBox的问题

heroboy2000 2004-05-10 02:56:25
为什么在WM_TIMER中的MessageBox会不停的出现
MessageBox不是要等到关闭了才会返回吗
似乎MessageBox会调用WndProc
请大侠帮我详细介绍一下WM_TIMER
...全文
252 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
myazhe 2004-05-13
  • 打赏
  • 举报
回复
MessageBox后并不会阻塞主消息循环。
IFoo 2004-05-12
  • 打赏
  • 举报
回复
wm_timer会定时发送这是不用怀疑的.
问题是messagebox后,为什么消息循环还在转?
CounterHack 2004-05-12
  • 打赏
  • 举报
回复
To: lmtz007yan(忽隐忽现)

Sleep()是挂起主线程!所以你这样是正常的;

-------------
WM_TIMER消息是入队列的,但此消息较特殊,"The WM_TIMER message is posted to the installing thread's message queue",主thread会定时 POST WM_TIMER 消息到窗口,因为POST不等待,所以可以不停弹出。

测试一下:
1、建立窗口,响应WM_TIMER消息,但不在程序中调用SetTimer注册消息!
2、模拟主thread定时POST消息。建立线程,定时POST:

extern HWND hWnd;// 主窗口句柄(处理WM_TIMER消息)
int timer_id = 123;// 注册timer ID
int delay = 100;// 定时时间,ms

DWORD PostThread(PVOID pParam)
{
while (true)
{
PostMessage(hWnd, WM_TIMER, WPARAM (timer_id), LPARAM (NULL));
Sleep(delay);
}
}

lmtz007yan 2004-05-12
  • 打赏
  • 举报
回复
To IFoo(我不是色盲,但我的世界却是黑白的):
"SetTimer(间隔设为500ms),然后在onTimer中sleep(5000)后执行一个函数..."

这个函数会每隔5500ms执行一次
shootingstars 2004-05-12
  • 打赏
  • 举报
回复
MessageBox后并不会阻塞主消息循环。
举个简单的例子,创建一个简单的窗口,在WM_PAINT中TextOut一个字符串,想象一下,MessageBox弹出后,移动MessageBox框,你TextOut的字符串并没有乱,而是老老实实的在重绘,说明WM_PAINT一直在得到执行。

既然主消息没有阻塞,那么很显然会一直的弹出MessageBox的对话框。
lmtz007yan 2004-05-12
  • 打赏
  • 举报
回复
WM_TIMER首先发送到主线程的消息队列,主线程再把该消息发送给对应窗口,也就是传到
对应窗口的子线程的消息队列,之后被处理的

halfdream 2004-05-12
  • 打赏
  • 举报
回复
毫不神奇的。。
MessageBox实际就是创建一个Message对话框,然后这个对话框ShowModal

而ShowModal也就是Show了之后,不断循环检查对话框状态,在这个循环中,
在不断处理消息对列的,
当对话框关闭时,这个循环才会被跳出,继续往下执行。。



lshadow 2004-05-11
  • 打赏
  • 举报
回复
WM_TIMER消息是无须等待执行完毕的,也就是POST消息啦。
而你的MessageBox函数需要你点击确定后才能执行完毕,你把这个函数放到了WM_TIMER消息中,那么就是说你的每个WM_TIMER消息的响应函数都没有执行完,因为你都没有点击MessageBox的确定,那么就无限的WM_TIMER下去了……
暗黑帝国 2004-05-11
  • 打赏
  • 举报
回复
hoho,讲的很全了
wbusy 2004-05-11
  • 打赏
  • 举报
回复
同意楼上的。
而且消息是被POST到程序的,而不是SEND。
IFoo 2004-05-11
  • 打赏
  • 举报
回复
WM_TIMER属于那种不进入消息队列,由操作系统直接调用窗口过程(在窗口建立时注册)进行处理的消息.只要时间到,就会执行相关代码.建议在MessageBox前调用KillTimer,返回后重新设定定义器.

=================
我不同意.
这个消息是进消息队列的!!你上面列出的英文参考里说得很清楚"The WM_TIMER message is posted to the installing thread's message queue"

halfdream(哈欠)说的应该是正解.messageBox内部有一个循环会处理当前线程的消息队列.
subtop 2004-05-11
  • 打赏
  • 举报
回复
多任务
lmtz007yan 2004-05-11
  • 打赏
  • 举报
回复
同意(哈欠)所述,没有阻塞当前主线程
用线程解释狠明白!

WM_TIMER
The WM_TIMER message is posted to the installing thread's message queue when a timer expires. The message is posted by the GetMessage or PeekMessage function.
A window receives this message through its WindowProc function.
再加上(李群康)的英文文献,学到很多!

IFoo 2004-05-11
  • 打赏
  • 举报
回复
ra3(可乐)
是吗?
你倒试试SetTimer(间隔设为500ms),然后在onTimer中sleep(5000)后执行一个函数,看是不是时间一到他就做.
ra3 2004-05-11
  • 打赏
  • 举报
回复
WM_TIMER 不会里你哪么多, 只要到时间它就做一次。
halfdream 2004-05-11
  • 打赏
  • 举报
回复
MessageBox运行未返回时,这时候并没有阻塞当前主线程,
而是使用了一个循环,不断的去处理队列里面的消息。

这时候,
WM_TIMER消息仍然
会被再次处理....
byry 2004-05-11
  • 打赏
  • 举报
回复
WM_TIMER与一般的循环语句不同,只要时间到了,就会执行你的语句,而一般的循环,比如:for, while等,这些循环是需要等到关闭掉MessageBox后才会返回的
ohbaby 2004-05-11
  • 打赏
  • 举报
回复
同意,hoho
QunKangLi 2004-05-11
  • 打赏
  • 举报
回复
WM_TIMER
The WM_TIMER message is posted to the installing thread's message queue when a timer expires. The message is posted by the GetMessage or PeekMessage function.

A window receives this message through its WindowProc function.

WM_TIMER属于那种不进入消息队列,由操作系统直接调用窗口过程(在窗口建立时注册)进行处理的消息.只要时间到,就会执行相关代码.建议在MessageBox前调用KillTimer,返回后重新设定定义器.
快乐鹦鹉 2004-05-11
  • 打赏
  • 举报
回复
WM_TIMER是定时器消息。系统定时会响应,自然就会有多个MessageBox消息窗了。它可不管你当前有没有MessageBox显示着
加载更多回复(6)

16,466

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧