1

I have a problem and I have done several day's worth of research but found no answer.

I have a c++ application that controls Excel programmatically. Specifically I use VS2017 and MS Office 2019.

To cut a long story short, I don't seem to have away to get feedback from Excel on its status and its readiness to receive a command from my application. As a result if Excel is busy and my application sends a command, there is a memory leak in the application leading it to crash.

In particular I am using Microsoft's Autowrap function to send commands to the com interface.

The relevant block of code is this:

{
    VARIANT hresult;
    VariantInit(&hresult);
    try{ 
        AutoWrap(DISPATCH_PROPERTYGET, &hresult, xlApp, L"ActiveCell", 0);
    }
    catch (...)
    {
        std::wcout << "crashed!" << '\n';
    }
        xlActiveCell[book - 1] = hresult.pdispVal;

}

There is actually nothing wrong with that code. It works fine in 99% of the cases. The problem is that if I click repeatedly on an excel cell with high frequency (double click for example), Excel is busy processing the first click when my App sends the next query 500ms later to get the active cell, and at that point Autowrap throws a message window saying:

IDispatch GetIDsOfNames("ActiveCell") failed w/err 0x80010001

I researched into this and this error means RPC_E_CALL_REJECTED.

it seems obvious that if the above condition occurs, it should be handled and the method calling Autowrap should return empty handed but not crash the application.

Somehow I cannot find a way to do this. try/catch block doesn't seem to do anything, and I cannot modify Autowrap to not open a message window but instead just return with an error to be handled later. It seems that Autowrap is made to stop execution of everything if it hits this error.

Why? Is there no way around this? Am I missing something?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
jboy
  • 11
  • 4
  • Which specific error are you trying to catch – Girspoon Dec 06 '19 at 13:29
  • One of the tests I did was to comment out the ::MessageBox and the exit(0) command in Autowrap, then run the debugger to see where it will crash. And it crashes on the return statement of Autowrap with a memory leak "around szName". To be more specific, the leak is inside the Autowrap function around the statement *hr = pDisp->GetIDsOfNames(IID_NULL, &ptName, 1, LOCALE_USER_DEFAULT, &dispID);* and the subsequent error handling block. I guess I would be trying to catch that leak. BTW I am not a big expert with try/catch loops. – jboy Dec 06 '19 at 17:36
  • Have you tried to implement an iMessageFilter, https://blogs.msdn.microsoft.com/andreww/2008/11/19/implementing-imessagefilter-in-an-office-add-in/ – Girspoon Dec 06 '19 at 23:28
  • thank you, that's very relevant. I will try to implement that. – jboy Dec 08 '19 at 15:02

0 Answers0