Threading, com + calls using SendMessage messages

I have an application that creates a thread that communicates with the main user interface through Windows messages. It simply sends a message to the main application thread and receives status.

This way I show modal windows and do other things.

The problem is when I need to display a form that makes a call to com + server. Thus, I get OLE error 8001010D: an outgoing call could not be completed because the application is sending a synchronous input call.

I think this is because the primary SendMessage is used, and com + calls require Windows messaging for their tasks.

In any case, in delphi I cannot display the form from the stream, but how can I solve the problem ...?

thanks

EDIT:

  • MAIN (UI) 2. THREAD

a. A Thread (2) sends a message to the main thread (1) B. The main thread (1) receives the msg message and before allowing it to return to the thread, it displays a window. C. A modal window in the main thread wants to make a com + call, the error is higher.


  • What thread is the modal window in? 2. What thread does a COM call make? 3. In which thread was the instance of the COM object created? 4. Is the background thread initialized by STA? 5. Is a modal form displayed from the SendMessage handler? - Roman R. 2 minutes ago

    • MAIN
    • MAIN
    • MAIN
    • CoInitializeEx (zero, COINIT_MULTITHREADED);
    • Yes.
+6
source share
1 answer

The problem is related to the inability of COM to marshal an outgoing COM call while processing a SendMessage request. The error that appears is RPC_E_CANTCALLOUT_ININPUTSYNCCALL (0x8001010D) that you are talking about. It seemed to me that this applies only to SendMessage calls, which are part of the interthread incoming COM requests, however this could be a false assumption.

A typical workaround would be to replace SendMessage with PostMessage , followed by waiting for an object, event, or synchronization semaphore. Thus, the background thread of your caller does not support messaging to synchronize calls and waits offline, in the main thread, the message is sent through a regular message queue and ultimately reaches the same handler.

As a bonus, you have the option to safely terminate the background thread. If it is currently blocked by the SendMessage API waiting for a modal dialog, the proposed change will allow you to signal a synchronization object from the main thread and continue to work, for example. if you want to complete it safely.

An alternative solution could be to call the InSendMessage function, and if true, cancel the modal user interface, for example. sending the message to yourself again to put the form in another message handler later.

+12
source

Source: https://habr.com/ru/post/911091/


All Articles