Why isn't there a SendThreadMessage function?

Here‘s an interesting customer question:

Windows has PostMessage and SendMessage. It also has PostThreadMessage but no SendThreadMessage.
Why isn‘t there a SendThreadMessage function? Am I forced to simulate it with an event?

What would this imaginary SendThreadMessage function do?

Recall that SendMessage delivers the message directly to the window procedure;

the message pump never sees it.

The imaginary SendThreadMessage function would have to deliver the message directly to.... what?

There is no "thread window procedure" to deliver it to.

Okay, maybe you still intend to process the thread message in your message pump,

but you want the caller of the imaginary SendThreadMessage function to wait until you‘ve finished processing the message.

But how does it know when you‘re finished?

It can‘t wait for DispatchMessage to return, since DispatchMessage can‘t dispatch thread messages.

(Where would it dispatch them to?)

The processing of the thread message is completely under the control of the message pump.

The window manager gives it a thread message, and as far as the window manager is concerned, that‘s the end of the story.

You might say that the processing of the thread message is complete

when somebody next calls GetMessage orPeekMessage,

but there‘s no guarantee that the next call to a message-retrieval function will come from the message pump.

Handling the thread message may result in a call to MessageBox, and as a modal function,

it will have its own message loop, which will call GetMessage,

resulting in your imaginary SendThreadMessage function deciding that message processing is complete when in fact it‘s still going on.

What should you do instead?

Just create a window and send it a message.

The scenarios where you would want to use the PostThreadMessage function are very limited and specialized.

Under normal circumstances, you should just send a regular window message.

Thread messages (as generated by the PostThreadMessage function) do not go anywhere

when passed to the DispatchMessage function.

This is obvious if you think about it, because there is no window handle associated with a thread message.

DispatchMessage has no idea what to do with a message with no associated window.

It has no choice but to throw the message away.

This has dire consequences for threads which enter modal loops,

which any thread with a window almost certainly will do at one time or another.

Recall that the traditional modal loop looks like this:

while (GetMessage(&msg, NULL, 0, 0)) {
 TranslateMessage(&msg);
 DispatchMessage(&msg);
}

If a thread message is returned by the GetMessage function,

it will just fall through the TranslateMessage and DispatchMessage without any action being taken.

Lost forever.

Thread messages are generally to be avoided on threads that create windows, for this very reason.

Of course, if you‘re going to create a window, why not use PostMessage instead,

passing that window as the target of the posted message?

Since there is now a window handle, the DispatchMessage function knows to give the message to your window procedure.

Result: Message not lost.

Why do messages posted by PostThreadMessage disappear?

The only thread message you can meaningfully post to a thread displaying UI is WM_NULL,

and even then, it‘s only because you want to wake up the message loop for some reason.

A common problem I see is people who use PostThreadMessage to talk to a thread that is displaying UI

and then wonder why the message never arrives.

Oh, the message arrived all right. It arrived and then was thrown away.

This is actually a repeat of an earlier entry with the title

Thread messages are eaten by modal loops,

but I‘m repeating it with a better subject line to help search engines.

But since I‘m here, I may as well augment the existing article.

Obvious places where you have modal loops on a UI thread are functions that are explicitly modal l

ike DialogBox orMessageBox or TrackPopupMenuEx(TPM_RETURNCMD) or DoDragDrop.

But there are less obvious modal loops, like the modal loop that runs when you click on the caption bar and hold the button

or the modal loop that runs when COM is waiting for a cross-thread call to complete.

And since you don‘t control those modal loops, when they call DispatchMessage,

your thread message will simply be thrown away.

If you need to communicate reliably with a thread that also displays UI,

then create a hidden window and send or post messages to that window.

I think this bit from the Platform SDK is relevant to the article:

Message-Only Windows

A message-only window enables you to send and receive messages.

It is not visible, has no z-order, cannot be enumerated, and does not receive broadcast messages.

The window simply dispatches messages.

To create a message-only window, specify the HWND_MESSAGE constant

or a handle to an existing message-only window in the hWndParent parameter of the CreateWindowEx function.

You can also change an existing window to a message-only window by specifying HWND_MESSAGE

in the hWndNewParent parameter of the SetParent function.

To find message-only windows, specify HWND_MESSAGE in the hwndParent parameter of the FindWindowEx function.

In addition, FindWindowEx searches message-only windows as well as top-level windows

if both the hwndParent and hwndChildAfter parameters are NULL.

Why isn't there a SendThreadMessage function?

时间: 2024-10-01 08:03:53

Why isn't there a SendThreadMessage function?的相关文章

通过百度echarts实现数据图表展示功能

现在我们在工作中,在开发中都会或多或少的用到图表统计数据显示给用户.通过图表可以很直观的,直接的将数据呈现出来.这里我就介绍说一下利用百度开源的echarts图表技术实现的具体功能. 1.对于不太理解echarts是个怎样技术的开发者来说,可以到echarts官网进行学习了解,官网有详细的API文档和实例供大家参考学习. 2.以下是我在工作中实现整理出来的实例源码: 公用的支持js文件 echarts.js.echarts.min.js,还有其他的图表需要支持的js文件也可以到官网下载 echa

帮同学做的大一大作业:《我的家乡—郑州》

---恢复内容开始--- 最近在上海上学的一个高中同学让我帮忙,帮她做她们的计算机课程大作业. 由于关系不错我也不好意思拒绝就帮忙做了,因为这个学期刚刚开始接触HTML5和css,所以制作过程中有很多不懂的,而且由于HTML5是选修课,一星期只有一节,所以做这个花费了比较多的时间,这个网站是我制作的第一个网站,比较有纪念意义,所以发在博客上,作为纪念. 通过去做这个作业,我了解到很多课上学不到的东西.因为没有美工,从头到尾,都是我一个人在臆想,刚开始的时候,根本无从下手,我去参考别人做的家乡网站

Adding New Functions to MySQL(User-Defined Function Interface UDF、Native Function)

catalog 1. How to Add New Functions to MySQL 2. Features of the User-Defined Function Interface 3. User-Defined Function 4. UDF Argument Processing 5. UDF Return Values and Error Handling 6. UDF Compiling and Installing 7. Adding a New Native Functio

安装python 第三方库遇到的安装问题 microsoft visual studio c++ 10.0 is required,Could not find function xmlCheckVersion in library libxml2. Is libxml2 installed?

问题一: microsoft visual studio c++ 10.0 is required 安装scrapy时候出现需要vc c++ 10,有时安装其他也会有. 解决方法:安装vc 2010,安装过2017无效,安装过程也不一样. 问题二: 安装好,出现Could not find function xmlCheckVersion in library libxml2. Is libxml2 installed? 解决办法: 1.pip install wheel 2. 到http://

[c++] Inline Function

The inline functions are a C++ enhancement feature to increase the execution time of a program. Compiler replace the definition at compile time instead of referring function defination at runtime. NOTE - This is a suggestion to compiler to make the f

js instanceof Object Function

Object.Function是javascript中顶级的两个对象,同时也属于两个顶级的构造器,function Object(){}.function Function(){}.Object.Function为两个独立的预先创建的两个对象.new Object创建一个具有Object特性的新的一个对象,new Function创建一个具有Function特性的一个新对象. Object是一个对象,包含__proto__.prototype属性. Object.__proto__ = func

different between method and function

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 15.0px Arial; color: #242729 } p.p2 { margin: 0.0px 0.0px 0.0px 0.0px; font: 15.0px Arial; color: #242729; background-color: #ffffff } span.s1 { background-color: #ffffff } span.s2 { } A method is on an o

qt.network.ssl: QSslSocket: cannot call unresolved function SSLv23_client_method

最近在做一个网络音乐播放器时,由于出现qt.network.ssl: QSslSocket: cannot call unresolved function SSLv23_client_method, 而不能播放网络歌曲. 上网搜了半天,都说要在电脑那里安装openssl,然后把C:\OpenSSL-Win64\bin下的libeay32.dll和ssleay32.dll拷贝到D:\Qt\Qt5.4.2\5.4\mingw491_32\bin, 然而并没什么卵用! 我的解决办法是: Qt的这个目

JavaScript中Function的拓展

Function 是什么东西,就是JavaScript中的顶级类,系统级别的类.我们平时写的函数方法例如下. function Animal() { } Animal就是Function的实例,但是在我们的逻辑中 Animal是类,是自定义类. Function是类,Animal是类也是实例,Animal是Function的实例,Animal是自定义类.这点大家一定要搞清楚. 我们在顶级类上定义一个method的方法,用于进行键值对的方式进行方法链式的设定, Function.prototype