SendMessage与直接调用消息响应函数的区别

科学家 2014-02-24 01:55:00
SendMessage就是发送消息,并且死等消息被处理完毕才走下一步代码。
PostMessage则是消息发完走人,并不等待消息处理完毕。

于是我认为,SendMessage与直接调用消息响应函数是一样的(如果消息响应函数是public的话),但今天我发现不一样了:我在线程内想做一些事情,通过两种方式做,效果竟不一样。

#define WM_MYMSG xxxxx

消息响应函数:
OnMyMsg(WP.., LP...)
{
//这个消息响应函数内部又调用了SendMessage发送其他消息做其他的事情
SendMessage(WM_其他消息,.....);
}

方法一:
//直接调用消息响应函数
OnMyMsg(0,0);//---------------------------死机,几乎每次都死机。

方法二:
SendMessage(m_hWnd,WM_MYMSG,0,0);//-------没问题,很健壮,经得起疯狂点击蹂躏

求解:SendMessage是不是被系统插手调度过了,所以不死机?求详解!


...全文
1129 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
Bountyhunt 2016-02-18
  • 打赏
  • 举报
回复
上面吵起来是一个人的两个小号吧 我是小号三号,前来揭开真相
科学家 2014-02-25
  • 打赏
  • 举报
回复
谢谢,二位的解答正在我关心的点上,不过讨论问题而已,不需要互相伤害。
debugmonkey 2014-02-24
  • 打赏
  • 举报
回复
引用 11 楼 jzycode 的回复:
[quote=引用 9 楼 my3439955 的回复:] [quote=引用 8 楼 jzycode 的回复:] [quote=引用 7 楼 my3439955 的回复:] [quote=引用 6 楼 jzycode 的回复:] [quote=引用 5 楼 my3439955 的回复:] [quote=引用 1 楼 jzycode 的回复:] 建议楼主去看看windows的消息队列。SendMessage对于在一个线程中调用,直接调用的窗口过程函数;跨线程调用,放到登记消息队列中,登记消息队列中的消息优先级最高,能够立即得到响应,处理完后,SendMessage函数返回。
SendMessage并非将消息插入的消息队列的最前端,而是直接调用窗口过程。 ------------------------------------ SendMessage和直接调用函数类似,但还是有关键的不同 关键不同: SendMessage调用后,消息处理在窗口所在的线程; 直接调用后,消息处理在调用的线程; 这下差别就大了[/quote] 我建议你去看看书吧!然后再来发表意思! 我给你举一个例子,两个不同进程A和B,A中调用SendMessage给B某个窗口发送消息,难道也是直接调用窗口过程?猪脑子![/quote] SendMessage跨进程也不进消息队列,系统跨进程界限完成调用,也相当于“直接调用”。 争论的关键在于进不进消息队列,而非是否直接调用。[/quote] 我建议你去好好看看windows核心编程第26章,看完后,再来发表看法!对于你这种人,我彻底无语了!最后提醒你一句:如果自己不确定或是不懂的时候,最好别在装!免得误导他人![/quote] 服了你了[/quote] 你跟我犟个屁,让你个SB 去看书,你就是不看,为了证明你就是个SB ,我把《windows核心编程》26章中的相关内容贴出来,让你个SB看看: [/quote] 这得是什么样的家庭教育环境才能培养出你这样的“高素质人才”啊。已举报!
_船长_ 2014-02-24
  • 打赏
  • 举报
回复
引用 9 楼 my3439955 的回复:
[quote=引用 8 楼 jzycode 的回复:]
[quote=引用 7 楼 my3439955 的回复:]
[quote=引用 6 楼 jzycode 的回复:]
[quote=引用 5 楼 my3439955 的回复:]
[quote=引用 1 楼 jzycode 的回复:]
建议楼主去看看windows的消息队列。SendMessage对于在一个线程中调用,直接调用的窗口过程函数;跨线程调用,放到登记消息队列中,登记消息队列中的消息优先级最高,能够立即得到响应,处理完后,SendMessage函数返回。


SendMessage并非将消息插入的消息队列的最前端,而是直接调用窗口过程。

------------------------------------
SendMessage和直接调用函数类似,但还是有关键的不同

关键不同:
SendMessage调用后,消息处理在窗口所在的线程;
直接调用后,消息处理在调用的线程;
这下差别就大了[/quote]

我建议你去看看书吧!然后再来发表意思!

我给你举一个例子,两个不同进程A和B,A中调用SendMessage给B某个窗口发送消息,难道也是直接调用窗口过程?猪脑子![/quote]

SendMessage跨进程也不进消息队列,系统跨进程界限完成调用,也相当于“直接调用”。
争论的关键在于进不进消息队列,而非是否直接调用。[/quote]


我建议你去好好看看windows核心编程第26章,看完后,再来发表看法!对于你这种人,我彻底无语了!最后提醒你一句:如果自己不确定或是不懂的时候,最好别在装!免得误导他人![/quote]

服了你了[/quote]

你跟我犟个屁,让你个SB 去看书,你就是不看,为了证明你就是个SB ,我把《windows核心编程》26章中的相关内容贴出来,让你个SB看看:




  • 打赏
  • 举报
回复
对这些伪专家说多了也没意思,伪代码有条件的试一下 LRESULT WndProc(...) { if (msg == WM_TEST) { MessageBox(... } } main { createwindow.... while (GetMessage....) { //输出消息码 TranslateMessage DispatchMessage } } 这个例子中,用其他进程无论是Send还是Post消息,都会弹出MessageBox,但是Send的不会输出消息码。 如果是我说得这样,就证明是我对了。
  • 打赏
  • 举报
回复
引用 8 楼 jzycode 的回复:
[quote=引用 7 楼 my3439955 的回复:] [quote=引用 6 楼 jzycode 的回复:] [quote=引用 5 楼 my3439955 的回复:] [quote=引用 1 楼 jzycode 的回复:] 建议楼主去看看windows的消息队列。SendMessage对于在一个线程中调用,直接调用的窗口过程函数;跨线程调用,放到登记消息队列中,登记消息队列中的消息优先级最高,能够立即得到响应,处理完后,SendMessage函数返回。
SendMessage并非将消息插入的消息队列的最前端,而是直接调用窗口过程。 ------------------------------------ SendMessage和直接调用函数类似,但还是有关键的不同 关键不同: SendMessage调用后,消息处理在窗口所在的线程; 直接调用后,消息处理在调用的线程; 这下差别就大了[/quote] 我建议你去看看书吧!然后再来发表意思! 我给你举一个例子,两个不同进程A和B,A中调用SendMessage给B某个窗口发送消息,难道也是直接调用窗口过程?猪脑子![/quote] SendMessage跨进程也不进消息队列,系统跨进程界限完成调用,也相当于“直接调用”。 争论的关键在于进不进消息队列,而非是否直接调用。[/quote] 我建议你去好好看看windows核心编程第26章,看完后,再来发表看法!对于你这种人,我彻底无语了!最后提醒你一句:如果自己不确定或是不懂的时候,最好别在装!免得误导他人![/quote] 服了你了
_船长_ 2014-02-24
  • 打赏
  • 举报
回复
引用 7 楼 my3439955 的回复:
[quote=引用 6 楼 jzycode 的回复:] [quote=引用 5 楼 my3439955 的回复:] [quote=引用 1 楼 jzycode 的回复:] 建议楼主去看看windows的消息队列。SendMessage对于在一个线程中调用,直接调用的窗口过程函数;跨线程调用,放到登记消息队列中,登记消息队列中的消息优先级最高,能够立即得到响应,处理完后,SendMessage函数返回。
SendMessage并非将消息插入的消息队列的最前端,而是直接调用窗口过程。 ------------------------------------ SendMessage和直接调用函数类似,但还是有关键的不同 关键不同: SendMessage调用后,消息处理在窗口所在的线程; 直接调用后,消息处理在调用的线程; 这下差别就大了[/quote] 我建议你去看看书吧!然后再来发表意思! 我给你举一个例子,两个不同进程A和B,A中调用SendMessage给B某个窗口发送消息,难道也是直接调用窗口过程?猪脑子![/quote] SendMessage跨进程也不进消息队列,系统跨进程界限完成调用,也相当于“直接调用”。 争论的关键在于进不进消息队列,而非是否直接调用。[/quote] 我建议你去好好看看windows核心编程第26章,看完后,再来发表看法!对于你这种人,我彻底无语了!最后提醒你一句:如果自己不确定或是不懂的时候,最好别在装!免得误导他人!
  • 打赏
  • 举报
回复
引用 6 楼 jzycode 的回复:
[quote=引用 5 楼 my3439955 的回复:] [quote=引用 1 楼 jzycode 的回复:] 建议楼主去看看windows的消息队列。SendMessage对于在一个线程中调用,直接调用的窗口过程函数;跨线程调用,放到登记消息队列中,登记消息队列中的消息优先级最高,能够立即得到响应,处理完后,SendMessage函数返回。
SendMessage并非将消息插入的消息队列的最前端,而是直接调用窗口过程。 ------------------------------------ SendMessage和直接调用函数类似,但还是有关键的不同 关键不同: SendMessage调用后,消息处理在窗口所在的线程; 直接调用后,消息处理在调用的线程; 这下差别就大了[/quote] 我建议你去看看书吧!然后再来发表意思! 我给你举一个例子,两个不同进程A和B,A中调用SendMessage给B某个窗口发送消息,难道也是直接调用窗口过程?猪脑子![/quote] SendMessage跨进程也不进消息队列,系统跨进程界限完成调用,也相当于“直接调用”。 争论的关键在于进不进消息队列,而非是否直接调用。
_船长_ 2014-02-24
  • 打赏
  • 举报
回复
引用 5 楼 my3439955 的回复:
[quote=引用 1 楼 jzycode 的回复:] 建议楼主去看看windows的消息队列。SendMessage对于在一个线程中调用,直接调用的窗口过程函数;跨线程调用,放到登记消息队列中,登记消息队列中的消息优先级最高,能够立即得到响应,处理完后,SendMessage函数返回。
SendMessage并非将消息插入的消息队列的最前端,而是直接调用窗口过程。 ------------------------------------ SendMessage和直接调用函数类似,但还是有关键的不同 关键不同: SendMessage调用后,消息处理在窗口所在的线程; 直接调用后,消息处理在调用的线程; 这下差别就大了[/quote] 我建议你去看看书吧!然后再来发表意思! 我给你举一个例子,两个不同进程A和B,A中调用SendMessage给B某个窗口发送消息,难道也是直接调用窗口过程?猪脑子!
  • 打赏
  • 举报
回复
引用 1 楼 jzycode 的回复:
建议楼主去看看windows的消息队列。SendMessage对于在一个线程中调用,直接调用的窗口过程函数;跨线程调用,放到登记消息队列中,登记消息队列中的消息优先级最高,能够立即得到响应,处理完后,SendMessage函数返回。
SendMessage并非将消息插入的消息队列的最前端,而是直接调用窗口过程。 ------------------------------------ SendMessage和直接调用函数类似,但还是有关键的不同 关键不同: SendMessage调用后,消息处理在窗口所在的线程; 直接调用后,消息处理在调用的线程; 这下差别就大了
Eleven 2014-02-24
  • 打赏
  • 举报
回复
OnMyMsg(0,0);//---------------------------死机,几乎每次都死机。 ------------------ 要看你的OnMyMsg()函数中写了些什么东西?
gfm688 2014-02-24
  • 打赏
  • 举报
回复
If the specified window was created by the calling thread, the window procedure is called immediately as a subroutine. If the specified window was created by a different thread, the system switches to that thread and calls the appropriate window procedure. Messages sent between threads are processed only when the receiving thread executes message retrieval code. The sending thread is blocked until the receiving thread processes the message.
schlafenhamster 2014-02-24
  • 打赏
  • 举报
回复
方法一: //直接调用消息响应函数 OnMyMsg(0,0);//---------------------------死机,几乎每次都死机。 缺 窗口句柄 , 不知道 发 哪里 去了 ?
_船长_ 2014-02-24
  • 打赏
  • 举报
回复
建议楼主去看看windows的消息队列。SendMessage对于在一个线程中调用,直接调用的窗口过程函数;跨线程调用,放到登记消息队列中,登记消息队列中的消息优先级最高,能够立即得到响应,处理完后,SendMessage函数返回。
在C#中SendMessage和PostMessage的参数传递 在C#中可以使用Window API提供的SendMessage和PostMessage来传递参数。两者的区别简单介绍下:返回值的不同,我们先看一下 MSDN 里的声明: LRESULT SendMessage( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam ); BOOL PostMessage( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam ); 其中 4 个参数的意义是一样的,返回值类型不同(其实从数据上看他们一样是一个 32 位的数,只是意义不一样),LRESULT 表示的是消息被处理后的返回值,BOOL 表示的是消息是不是 Post 成功。 2、PostMessage 是异步的,SendMessage 是同步的。 PostMessage 只把消息放入队列,不管消息是否被处理就返回,消息可能不被处理;而 SendMessage 等待消息被处理完了之后才返回,如果消息不被处理,发送消息的线程将一直被阻塞。 3、如果在同一个线程内,SendMessage 发送消息时,由 USER32.DLL 模块调用目标窗口的消息处理程序,并将结果返回。SendMessage 在同一线程中发送消息并不入线程消息队列。PostMessage 发送消息时,消息要先放入线程的消息队列,然后通过消息循环分派到目标窗口(DispatchMessage)。 如果在不同线程内,SendMessage 发送消息到目标窗口所属线程的消息队列,然后发送消息的线程在 USER32.DLL 模块内监视和等待消息处理,直到目标窗口处理完返回。SendMessage 在返回前还做了很多工作,比如,响应别的线程向它 SendMessage。Post 到别的线程时,最好用 PostThreadMessage 代替 PostMessage,PostMessage 的 hWnd 参数可以是 NULL,等效于 PostThreadMessage + GetCurrentThreadId。Post WM_QUIT 时,应使用 PostQuitMessage 代替。 4、系统只整编(marshal)系统消息(0 到 WM_USER 之间的消息),发送用户消息(WM_USER 以上)到别的进程时,需要自己做整编。 用 PostMessage、SendNotifyMessage、SendMessageCallback 等异步函数发送系统消息时,参数里不可以使用指针,因为发送者并不等待消息的处理就返回,接受者还没处理指针就已经被释放了。 5、在 Windows 2000/XP 里,每个消息队列最多只能存放 10,000 个 Post 的消息,超过的还没被处理的将不会被处理,直接丢掉。这个值可以改得更大:[HKEY_LOCAL_MACHINE/SOFTWARE/ Microsoft/Windows NT/CurrentVersion/Windows] USERPostMessageLimit,最小可以是 4000。 PostMessage只负责将消息放到消息队列中,不确定何时及是否处理 SendMessage要等到受到消息处理的返回码(DWord类型)后才继续 PostMessage执行后马上返回 SendMessage必须等到消息被处理后才会返回。

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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