Is there any API to send message to a thread?
Basically I have only threadId available and I want to send a custom message to that thread.
PostThreadMessage. Not very reliable though.
See The Old New Thing blog here and here for details on why. Basically modal message loops make a mess of the whole idea. Since a message posted to a thread has no window handle, calling DispatchMessage will throw the message away. Any modal loop you run - directly or indirectly - will call DispatchMessage, so a good proportion of the time this strategy will fail and your message will disappear into the ether.
you can use QueueUserAPC if the target thread is alertable
Related
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.
I have a thread that send update messages to a window, I use ::SendMessage() and ::PostMessage() APIs.
I go in and out of multiple dialogs and register the dialog that I am currently in with the thread via the window handle (m_hWnd). If I exit all the way out, the main application window doesn't handle these messages. For that reason I don't register that window. At this point the thread will have the handle of an older window which now doesn't exist.
Is it okay if it sends messages to that non-existent window? I am assuming it should not do any harm but wanted to double check.
No, it is not ok to post a message to a deleted window.
There is no guarantee noone will set up shop at that address just after the previous tennant is gone.
If you use a NULL window handle, you'll post a thread message to the current threads message queue. SendMessage as far as I could google shoul be a no-op.
Might be harmless enough.
Now, we get tricky:
Under specific cicumstances it does not matter, pre-supposing well-behaved applications.
A message like WM_NULL should not make anything happen.
A window-message you globally registered in your application using RegisterWindowMessage, if you can guarantee none of your applications windows created in the meantime will choke on it.
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.
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.
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.