7

I have function implementation of DDE client using Win Api in C#. Everything works fine in case that I call DdeInitializeW and DdeConnect in single thread. Specifically, these are wrapper definitions:

    [DllImport("user32.dll")]
    protected static extern int DdeInitializeW(ref int id, DDECallback cb, int afcmd, int ulres);

    [DllImport("user32.dll")]
    static extern IntPtr DdeConnect(
        int idInst,             // instance identifier
        IntPtr hszService,      // handle to service name string
        IntPtr hszTopic,        // handle to topic name string
        IntPtr pCC              // context data
        );

If I called DdeInitializeW and DdeConnect in different threads, DdeConnect return null pointer.

Also, if I called both of them (established DDE connection) in one thread, I can't use this DDE channel in another thread (i'm getting INVALIDPARAMETER DDE error).

As I said, everything works without problems in single thread.

Majak
  • 1,543
  • 1
  • 14
  • 28

1 Answers1

7

The behaviour you describe is expected.

DDE is tied to the individual thread. This is because DDE (which is generally considered a legacy technology) works internally by passing windows messages, and windows handles (HWND) have thread affinity.

  • You must call DdeInitializeW from the same thread you call DdeConnect.
  • That thread must pump messages (so it cannot be a thread-pool thread).
  • You will get callbacks/replies on that same thread also.

In other words you need to do your DDE from a thread which calls Application.Run, or which frequently calls Application.DoEvents at moments when it is appropriate for the events to be sent or received.

You can use DDE from more than one thread, but each must call DdeInitializeW and replies will always be received on the thread the request was sent from.

Ben
  • 34,935
  • 6
  • 74
  • 113
  • This is exactly how I'm doing it at this moment. OK I was afraid that this is issue of DDE itself. Thank you very much for ensuring me in it. – Majak Sep 23 '15 at 08:54
  • Also, tip if you aren't doing it already: Keep track of multiple DDE conversation by giving each conversation a unique id, using `DdeSetUserHandle` and `DdeQueryConvInfo`. This simplifies everything a lot. https://msdn.microsoft.com/en-us/library/windows/desktop/ms648765(v=vs.85).aspx – Ben Sep 23 '15 at 09:01