INFO: SendMessage() in a Multithreaded Environment
ID: Q95000
|
The information in this article applies to:
-
Microsoft Win32 Software Development Kit (SDK)
-
Microsoft Windows 2000
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 query words:
GP-fault
Keywords : kbNTOS kbWinOS2000 kbSDKWin32 kbGrpUser kbWinOS95 kbWinOS98 kbWndw kbWndwMsg
Version : WINDOWS:
Platform : WINDOWS
Issue type : kbinfo