9

I have a situation where I want to SendMessage to a window that was created on another thread than the one that is calling SendMessage.

The default behaviour seems to be block forever and not work.

So I changed the call to PostMessage, which didn't block the sending thread, but the message never appears to arrive at the intended window.

So how do I SendMessage to a window created on a separate thread, or is this impossible?

bobobobo
  • 64,917
  • 62
  • 258
  • 363

5 Answers5

2

The PostThreadMessage function posts a message to the message queue of the specified thread. you can specified Identifier of the thread to which the message is to be posted. is that you want?

chinochan
  • 21
  • 1
2

What is the thread that owns the target window doing? It needs to be pumping messages in order to be able to receive messages that are either sent or posted to it. Typically this is done by having a GetMessage/TranslateMessage/DispatchMessage loop. If the thread is doing something else - such as blocking waiting for an event or mutex or IO to complete, or is busy in some other loop carrying out a calculation, it won't receive messages: SendMessage to the thread will block, and PostMessage will post but not get delivered.

If that target thread needs to both manage events or similar, and it also owns a window, you may need to use MsgWaitForMultipleObjects in that thread's message loop.

BrendanMcK
  • 14,252
  • 45
  • 54
1

Each control you create belongs to the thread that created it, which means that the WndProc for that control will be running in the thread that created the control. You send messages with SendMessage and PostMessage freely to any control.

Seth Carnegie
  • 73,875
  • 22
  • 181
  • 249
  • Does that mean ALL gui elements of the program _must_ be created on the main thread? – bobobobo Aug 15 '11 at 01:09
  • 3
    This is absolutely *incorrect*: one of the reasons that SendMessage exists is to allow one GUI thread to communicate with another GUI thread: it does a bunch of housekeeping work to manage synchronization between the threads. It is perfectly legal to have a process that has many GUI threads, each of which owns windows - provided that each thread is processing messages appropriately. Having said that, it's often a simpler and more appropriate design to have a single GUI thread, with non-GUI workers as appropriate. – BrendanMcK Aug 15 '11 at 03:54
  • That's not true. You can send messages to windows of other threads freely. – hamstergene Aug 15 '11 at 03:54
  • @Brendan but don't windows have to be created on the thread to which they will belong, and don't you want to do that normally on one thread? – Seth Carnegie Aug 15 '11 at 03:57
  • 3
    @Seth: Windows by definition 'belong' to the thread on which they are created: specifically this means that any messages sent or posted to that window will get processed by the thread that created it. But *any* other thread[1] is free to use SendMessage or PostMessage to send/post a message to that window (and Windows does the appropriate work to ensure that the message gets routed/marshaled to the HWND's creator/owner thread). ([1]assuming thread is on same desktop and has appropriate UIPI privileges.) – BrendanMcK Aug 15 '11 at 04:15
1

You are running into a deadlock. An example, if you SendMessage to another thread, then the windowProc in that thread does SendMessage back to your window, they will lock waiting each other forever.

You need to either fix PostMessage (it does deliver messages, there's just error in your code somewhere), or be very careful about who calls who and when.

To protect against threads that are busy or hung, there is SendMessageTimeout.

hamstergene
  • 24,039
  • 5
  • 57
  • 72
0

The issue with CWnd::PostMessage and CWnd::SendMessage is the same. The message is being pushed out, and not being received by anything. SendMessage is blocking by design; it's job is to block the thread until the message is received.

MSDN says this about SendMessage:

"The SendMessage function calls the window procedure for the specified window and does not return until the window procedure has processed the message."

It is possible to send a message to window on another thread using CWnd::PostThreadMessage or winapi PostMessage. When you create the window you can use GetSafeHwnd() to get the handle or you can use a thread ID when the thread is created.

CassieD
  • 129
  • 1
  • 14