Archives

Archives / 2008 / October
  • 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.  :)

  • Windows 7 and Concurrency

    Now that the Windows 7 keynote is over we can finally start exploring some of the improvements. This is going to be a truly awesome upgrade. As Paul puts it, Windows 7 is Windows Vista done right.

    If you’re not sure where to start then I’d suggest starting right at the bottom. Listen to Mark Russinovich introduce many of the improvements made to the Windows kernel. This is really going to benefit those of you with more than 64 processing cores.  :)

    Incidentally, if you’re wondering why Mark referred to the Concurrency Runtime as “concert” the reason is that the APIs for the scheduler are included in the concrt.h header file. For more on that check out what Rick has to say about Visual C++ 10.

  • Time to Move?

    I’m starting to think it’s about time I moved this blog. I’ve appreciated not having to worry about hosting and taking advantage of Microsoft’s hosting bandwidth, but it has been frustrating at times not having as much control as I wanted. The weblogs.asp.net server in particular seems to have branched from the blogs.msdn.com server some time back. Originally they were running the same code if I remember correctly.

  • Recent Reading List

    My family loves books. Here are a few of the better books I've read this year.   

  • The Biggest Release of the Year...

    I’ve been a bit distracted over the last few weeks as our third son Samuel John was born earlier this month. I hope to catch up on email soon.

  • MSDN Library without the Bling

    The MSDN Library is one of those things I install locally right after installing Visual Studio. It’s an invaluable resource to have at your fingertips. There are however occasions when I don’t have it installed or I’m using the web for some extra search power. Inevitably I end up with something like this: