zoukankan      html  css  js  c++  java
  • 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.

  • 相关阅读:
    C#在二维码中添加圆角logo
    保存emoji到数据库
    参数名ASCII码从小到大排序(字典序)
    SQL SERVER 2008 获取表字段的类型
    js对Cookie的读写操作
    sql server2008根据经纬度计算两点之间的距离
    sql server2008给数据表,字段,添加修改注释
    关闭浏览器的放大缩小功能
    SQL Server 阻止了对组件 'Ole Automation Procedures' 的 过程'sys.sp_OACreate' 的访问,因为此组件已作为此服务器安全配置的一部分而被关闭。系统管理员可以通过使用 sp_configur
    ASP.NET正则表达式(URL,Email)
  • 原文地址:https://www.cnblogs.com/shangdawei/p/4015350.html
Copyright © 2011-2022 走看看