Is CWnd :: GetSafeHwnd () and CWnd :: m_hWnd ThreadSafe?

I am facing numerous crashes in an application that is multithreaded.

By reading this MSDN page , a technical note, and this article on TLS , I realized that CWnd objects CWnd displayed in HWND in TLS (which is thread-dependent memory access).

I was going to separate everything that looks like CWnd stream-remote access and convert it to HWND links and then use ::PostMessage as the communication port.

But one of my colleagues really insisted that I just CWnd* in CWnd* threads, adopt the ::PostMessage policy, but use CWnd::GetSafeHwnd() or pMyCWnd->m_hWnd in external threads to restore the native HWND .

I claimed that I had never seen GetSafeHwnd() be thread safe, and that CWnd is in TLS, its value in a different thread is different.

I am wrong? MSDN explicitly uses the term " unexpected results" .

What is your point of view regarding calling CWnd::GetSafehwnd() or pMyCWnd->m_hWnd in external threads from the creator thread?

Do you have any MSDN documentation that says it is safe or not.

+8
source share
3 answers

CWnd are not displayed in HWND; HWNDs are mapped to CWnds, and this happens separately. The CWnd object is not in TLS (how does it work?), But temporary CWnd objects are created in the stream.

Accessing a temporary CWnd object from the wrong thread is definitely a bad idea (for the reasons described by Mark Ransom).

However, if you have a permanent CWnd object (representing the main window of your application, say), then after creating it there is no problem accessing the m_hWnd member from any stream. It is simply a value in memory that never changes.

If this bothers you (because it is not explicitly documented), just make a copy of the HWND and give the threads access to it.

PS Here's an article you linked to in English.

+10
source

GetSafeHwnd is just a wrapper that checks if this NULL, returns m_hWnd if not, and NULL if it is. It will not be more threaded than m_hWnd .

When you create a temporary CWnd *, the MFC will destroy it at the point that it considers safe, for example, the next pass through the message loop. If you have multiple threads using MFC, your temporary object may be destroyed while you use it. Nothing in your thread can detect this error.

+5
source

If you have a multi-threaded application in which several threads try to access HWND right away, it sounds to me as if you have a design problem. Can't you limit your threads to doing computations and handle user interface problems in the main thread? This is a typical design of a good multi-threaded application.

+1
source

All Articles