Change GUI in thread

c++, mfc, multithreading, sendmessage, thread-safety

Solution

The documentation for `ERROR_MESSAGE_SYNC_ONLY` says:

The message can be used only with synchronous operations.

This means that you can use synchronous message delivery, i.e. `SendMessage` and similar, but you cannot use asynchronous message delivery, i.e. `PostMessage`.

The reason is that `WM_SETTEXT` is a message whose parameters include a reference. The parameters cannot be copied by value. If you could deliver `WM_SETTEXT` asynchronously then how would the system guarantee that the pointer that the recipient window received was still valid?

So the system simply rejects your attempt to send this message, and indeed any other message that has parameters that are references.

It is reasonable for you to use `SendMessage` here. That will certainly work.

However, you are forcing your worker thread to block on the UI. It may take the UI some time to update the caption's text. The alternative is to post a custom message to the UI thread that instructs the UI thread to update the UI. Then your worker thread thread can continue its tasks and let the UI thread update in parallel, without blocking the worker thread.

In order for that to work you need a way for the UI thread to get the progress information from the worker thread. If the progress is as simple as a percentage then all you need to do is have the worker thread write to, and the UI thread read from, a shared variable.

Problem

I have an operation which ends in about 20 seconds. To avoid freezing, I want to create a thread and update a label text in it every second. I searched a lot, since everyone has different opinion, I couldn't decide which method to use. I tried SendMessage and it works but some people believe that using SendMessage is not safe and I should use PostMessage instead. But PostMessage fails with `ERROR_MESSAGE_SYNC_ONLY` (1159). ``` char text[20] = "test text"; SendMessage(label_hwnd, WM_SETTEXT, NULL, text); ``` I searched about this and I think it's because of using pointers in PostMessage which is not allowed. That's why it fails. So, what should I do? I'm confused. What do you suggest? Is this method is good for change UI elements in other thread? Thanks

Original source