How do I SendMessage() to a window created on another thread? - c++

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?

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?

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.

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.

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.

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.

Related

How to get message from other thread winapi

I need to run message loop in other thread using std::async, is it possible to get messages from main thread? Can you give some exampels?
And second question: i do not need to call wndproc, what i need is just getting messages and avoid "program not responding", do i need to call dispatchmessage()?
Each thread manages its own message queue. If you want the main thread's messages, the main thread must get them and post them to you. But it sounds like that would defeat the purpose altogether.
Sounds like what you really want is to switch your threads' places. Have the main thread run your message pump and do your intensive processing on another thread.
As for DispatchMessage, you can get by without it if you don't have a window. But if you do, you should call it. You have to handle window messages in order to appear responsive, and it hides some of the details of doing so.

Which thread calls the windows proc callback function?

I am a bit unsure which thread calls the wndproc callback function. Is it the main thread from the application, like in the message loop or is a seperate windows thread ? The function has access to class objects and I dont want there to be any corruption of data if 2 thread happend to access the class object at the same time.
Yes, it is main thread of application.
An application's main thread starts its message loop after
initializing the application and creating at least one window. After
it is started, the message loop continues to retrieve messages from
the thread's message queue and to dispatch them to the appropriate
windows. The message loop ends when the GetMessage function removes
the WM_QUIT message from the message queue.
Source: About Messages and Message Queues

Run windows GUI application in synchronized mode?

I am debugging GUI app on windows and I want to find out who is the sender of some message. On linux, I can run app in synchronized mode and find the sender in call stack. Is there any equivalent mode in windows?
AFAIK there's no built-in ability to do this.
But let's first investigate the problem. You want to know who's the sender of the message. You should know however that windows message processing can be classified by the following criterias:
Posted vs Sent messages (PostMessage vs SendMessage).
Messages sent to the window belonging to another thread vs sender thread.
Messages posted to a thread (not bound to a specific window, hence not processed by the window procedure).
You may trace directly the sender only when the message is sent (not posted) to a window, whereas the call to the SendMessage (or similar) was issued in the thread to which the window belongs. In such you will see the sender in the call stack.
In case the message was sent from another thread - you will not see it in the call stack. Simply because the call stack shows the call chain that belongs to the current thread only. When a message is sent from another thread the system performs the following:
Suspends the caller thread.
Puts this message to the queue of the thread that owns the window.
When that thread calls GetMessage (or similar) - the message is dispatched to the window.
Finally the OS resumes the caller thread. The SendMessage returns with the result that was returned by the window procedure.
In such a case you may try to identify the caller indirectly. Interrupt your program with the breakpoint, and try to search for suspended threads, which are blocked in a call to SendMessage or similar.
Finally, messages that are posted are impossible to trace by the above method. You may try to put a conditional breakpoint on a call to PostMessage, but if the caller belongs to another problem - this will be more complex.
valdo is correct. Calls to SendMessage call your applications wndproc directly. Calls to PostMessage posts the message to the message que and your application then recives the message via the message pump (the loop, getmessage, translatemessage, dispatchmessage). So , like he said, if the messages were sent via a SendMessage then the callee of the function will show in the call stack. If it was sent via PostMessage , it will not.

Why is my DCOM client locking on a call to SendMessage?

Running on XP. I have a client that calls calls CoInitializeEx(NULL, COINIT_MULTITHREADED), loads a (local) DCOM object, and attaches an event interface so the DCOM object can send back events. The client looks a lot like notepad with a multi-line textbox covering the client area to display event messages. Here are the calls that create a lock-up:
Client calls p->DoStuff() on the DCOM object.
The DCOM object calls c->DoStuffEvent() on the client while processing DoStuff().
The client sends a EM_REPLACESEL message to the child textbox to have it display "stuff is happening"
The client freezes on the SendMessage(EM_REPLACESEL). The client's call to p->DoStuff() is done on a the main thread while the SendMessage(EM_REPLACESEL) is done on a different thread. I'm sure this has something to do with the problem.
Can someone explain what's causing the lock and how I might work around it? The client and DCOM objects are coded by me in MSVC/ATL, so I can modify them both as needed.
It would appear that the window was created by the main thread. So that is the only thread that can call the window proc. When you SendMessage from the other thread, what it actually does it to put the message into the main thread's queue and then wait for the main thread to call GetMessage or PeekMessage. Inside the call to GetMessage or PeekMessage, Windows notices a waiting cross-thread SendMessage and passes that message to the window proc, then it wakes the second thread and lets it continue.
If you don't care about the return value of SendMessage(EM_REPLACESEL), you can use SendNotifyMessage instead. But if you do this, you need to make sure that the string you pass with the EM_REPLACESEL message is still valid when the message is finally delivered.
As per the SendMessage documentation, SendMessage does not return until the function is completed. It is synchronous. I believe it is always answered on the UI thread as well. If you want to do an asynchronous message pass, then you should use PostMessage.

MoveWindow deadlock?

I have a window on thread A, which at some point (as a result of a message being received on its wndproc) triggers an action on thread B, and then waits for the action to complete (using some sort of sync mechanism). Thread B then calls MoveWindow(), to move a child window within thread A's window (a standard textbox, for example). At this point the program goes into a state of deadlock for some reason. If MoveWindow() is being called from thread A, everything works. Any ideas why?
You could use SetWindowPos with the flag SWP_ASYNCWINDOWPOS, instead of MoveWindow.
The reason may be that ThreadA waits for ThreadB to handle some event but meanwhile ThreadB wait for ThreadA (the thread owning the window) to return the result of MoveWindow.
What is the "some sort of sync mechanism"? If it is WaitFor(Multiple)Object(s), you can use [MsgWaitForMultipleObjects](http://msdn.microsoft.com/en-us/library/ms684242(VS.85).aspx)(Ex instead to wake up when you have a message and dispatch it as Lucero suggests.
I think that #1800's explanation is the closest yet.
When you move a window from a thread that does not own the window, I think that Windows does not use SendMessage to deliver things like WM_WINDOWPOSCHANGING to the window procedure of the moved window. Instead, to ensure that the window procedure is only called on the right thread, it posts the WM_WINDOWPOSCHANGING message and blocks untill it's picked by event loop running in the right thread. However, that event loop is not running - it's blocked, waiting for MoveWindow to complete.
The solutions from #totaland and from #Logan Capaldo will work.
May be you don't need to wait until your window has moved. Or, if you do need to be sure, use MsgWaitForMultipleObjectsEx and run a small event loop to process posted messages.
You need to make sure that the message pump of the thread is running while you are waiting.
You may want to loop with PeekMessage() (or maybe GetMessage()) and DispatchMessage().
Thread affinity of user interface objects, part 1: Window handles:
Different objects have different
thread affinity rules, but the
underlying principles come from 16-bit
Windows.
The most important user interface
element is of course the window.
Window objects have thread affinity.
The thread that creates a window is
the one with which the window has an
inseparable relationship. Informally,
one says that the thread "owns" the
window. Messages are dispatched to a
window procedure only on the thread
that owns it, and generally speaking,
modifications to a window should be
made only from the thread that owns
it. Although the window manager
permits any thread to access such
things as window properties, styles,
and other attributes such as the
window procedure, and such accesses
are thread safe from the window
manager's point of view,
load-modify-write sequences should
typically be restricted to the owner
thread.