SendMessage() in a Multithreaded Environment

Last reviewed: November 2, 1995
Article ID: Q95000
The information in this article applies to:
  • Microsoft Win32 Application Programming Interface (API) included with:

        - Microsoft Windows NT versions 3.5 and 3.51
        - Microsoft Windows 95 version 4.0
    

SUMMARY

When thread X calls SendMessage() to send a message to a window created by thread Y, it must wait until thread Y calls PeekMessage(), GetMessage(), or WaitMessage() before the SendMessage() call can continue. This process prevents synchronization problems.

MORE INFORMATION

Because of the multithreaded environment of Windows NT, SendMessage() does not behave in the same manner as it does under Windows 3.1. Under Windows 3.1, SendMessage() simply calls the window procedure given to it. In Windows 3.1, if you use the SendMessage() function to send a message to a window of another task, the system will perform a task switch to the target window (change to the stack of the target Windows-based application), let the target window process the message [when it calls GetMessage() or PeekMessage()], and then switch back to the original message.

Under Windows NT, however, only the thread that created a window may process the window's messages. Therefore, if thread X sends a message [via SendMessage()] to a window that was created by thread Y, thread X must wait for thread Y to be in a receiving state, and handle the message for it.

Thread Y is only in a receiving state when it calls PeekMessage(), GetMessage(), or WaitMessage(), because synchronization problems may occur if a thread is interrupted while processing other messages. While in a receiving state, thread Y may process messages sent to its windows via SendMessage() (in this case, by thread X).

Note that PeekMessage() and GetMessage() look in thread Y's message queue for messages. Because SendMessage() does not post any messages, PeekMessage() and GetMessage() will not see any indication of the SendMessage() call. The two functions merely serve as a point in time at which SendMessage() (thread X) may "interrupt," and have thread Y process its message next. Then PeekMessage() or GetMessage() continues normal operation under thread Y.

Because of this behavior, if thread X sends a message to thread Y, and thread Y is locked in a tight loop, thread X is now locked as well. This may be prevented by using SendNotifyMessage(), which behaves as SendMessage() does above, but returns immediately. This may be an advantage if it is not important that the sent message be completed before thread Y continues. Note, however, that because SendNotifyMessage() is asynchronous, thread X should not pass pointers to any of its local variables when making the call, because they may be gone by the time thread Y attempts to look at them. This would result in a general protection violation (GP fault) when thread Y accesses the pointer.


Additional reference words: 3.10 3.50 3.51 4.00 95 GP-fault
KBCategory: kbui
KBSubcategory: UsrMisc


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: November 2, 1995
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.