Excel RTD Servers: C++ Interfaces

Excel provides a function called RTD (real-time data) that lets you specify a COM server via its ProgId so that you can push data into Excel. Recently I had to implement an RTD server for a client and was frustrated at how hard it was to find the COM interface definitions to implement. It doesn’t appear to be documented anywhere. They’re clearly geared toward VB6 or VBA or VBScript or whatever. Anyway, I sucked out the necessary COM interfaces from the type library embedded inside the Excel executable. Here’s what an RTD server written in C++ needs to implement:

struct __declspec(novtable) __declspec(uuid("A43788C1-D91B-11D3-8F39-00C04F3651B8"))
IRTDUpdateEvent : IDispatch
{
    virtual HRESULT __stdcall UpdateNotify() = 0;

    virtual HRESULT __stdcall get_HeartbeatInterval(/*[out]*/ long* value) = 0;

    virtual HRESULT __stdcall put_HeartbeatInterval(long value) = 0;

    virtual HRESULT __stdcall Disconnect() = 0;
};

struct __declspec(novtable) __declspec(uuid("EC0E6191-DB51-11D3-8F3E-00C04F3651B8"))
IRtdServer : IDispatch
{
    virtual HRESULT __stdcall ServerStart(/*[in]*/ IRTDUpdateEvent* callback,
                                          /*[out]*/ long* result) = 0;

    virtual HRESULT __stdcall ConnectData(long topicId,
                                          /*[in]*/ SAFEARRAY** strings,
                                          /*[in,out]*/ VARIANT_BOOL* newValues,
                                          /*[out]*/ VARIANT* values) = 0;

    virtual HRESULT __stdcall RefreshData(/*[in,out]*/ long* topicCount,
                                          /*[out]*/ SAFEARRAY** data) = 0;

    virtual HRESULT __stdcall DisconnectData(long topicId) = 0;

    virtual HRESULT __stdcall Heartbeat(/*[out]*/ long* result) = 0;

    virtual HRESULT __stdcall ServerTerminate() = 0;
};

I’m posting this mostly so that I can quickly find it in future but perhaps it will come in handy for others. I could write some more about how the heck you implement these crazy interfaces and other tricks I’ve picked up but I suspect there’s a very small number of developers who care.  :)

4 Comments

  • I, for one, do care! ;)

    I would be very interested in this information. We may replace old-fashioned DDE links with RTD, but I have had a hard time finding the right information. We doing the programming in Delphi, btw, but translating from a C++ solution should be no problem.

  • There's a TODO for you.

    weblogs.asp.net/.../visual-c-in-short-converting-between-numbers-and-strings.aspx

    :)

  • Tanveer Badar: Ah sorry... :) I've been kinda busy lately, thus the lack of any meaty posts.

  • Piers: I’m not familiar with that KB sample. Regarding the in/out comments, they indicate the direction in which the parameter values are passed/marshaled. An [in] parameter means the value is passed from the caller to the function. An [out] parameter means the value is (typically) allocated by the function and passed back to the caller. An [in,out] parameter means the value is passed to the function by the caller and can be modified by the function before it returns. I’m using “value” generically. It may be a pointer to a pointer, it may be a BSTR (with its own allocation rules), etc. The COM specification explains all of this.

Comments have been disabled for this content.