You should generally access windows (HWND
s) in Windows only from the thread they were created in. Any message sent to the window will be performed in the thread that created it, that's why the crashes stopped happening when you replaced all direct calls to the Scintilla functions by sending messages. If you use SendMessage()
in your spell check thread this will cause the following to happen:
- the spell check thread will block
- a context switch to the GUI thread will be performed
- the message loop will process the message (but not necessarily immediately, messages in the queue will be handled in the order they were added, so the message will be handled only after all previously added messages have been handled)
- a context switch to the spell check thread will be performed
- the
SendMessage()
call returns the result
So you have indeed fixed the problem, but at a very high price. Every misspelt word will cause two thread context switches, and the spell checking will block for each misspelt word. This could actually be quite a long time, if any other messages that take long to handle were still queued up.
You should change the design of your program. Ideally both threads will be able to work independently, and this can be achieved by adding a thread-safe data structure that the spell check thread adds information about misspelt words to, and that the main thread retrieves the information from. Boost has lots of classes to help you out. By doing so you can continue to use the direct calls, since they will be performed in the context of the main thread. Performance should improve, as multiple words could be underlined in one go, causing only a single repaint of the control. If you use PostMessage()
instead of SendMessage()
the spell check thread will be able to continue its work independently of the main thread being ready to handle the message.
If you remember to never call any Scintilla code from secondary threads you will not encounter other quirks. And this is nothing specific to the Scintilla control, calling Windows API functions that do not use Windows messages internally would be problematic for any other control just as well.