1

Suppose, we have Windows app that interacts with Excel through COM interface:

int APIENTRY wWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
    // Initialize COM for this thread...
    CoInitialize(NULL);

    << Create Excel application >>
    << Create Workbooks collection >>
    << Create Workbook >>
    << Create worksheet >>
    ...
    // Main message loop:
    while (GetMessage(&msg, NULL, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    << Release pointers >>
    CoUninitialize();
    return (int) msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    ...
    switch (message)
    {
        << Process message >>
    }
}

The problem

When the user closes Excel before closing the program, I get an error when I close the program because now the pointers are referencing non-existing app. Is it possible to get a message, indicating that the program is closed. And how should I release the pointers in this case?

user4035
  • 22,508
  • 11
  • 59
  • 94
  • Maybe this can give some idea: https://stackoverflow.com/questions/42531/how-do-i-call-createprocess-in-c-to-launch-a-windows-executable – macroland Sep 16 '18 at 10:40
  • 1
    What do you mean by, **"I get an error"**? Are you crashing? Getting some weird message box popping up? I ask because when a COM server dies, the pointers to COM objects from other processes will still be valid, but all method calls will just return an RPC error. – selbie Sep 16 '18 at 10:44
  • @selbie I get "IDispatch::GetIDsOfNames failed with error 0x80010108" from my function AutoWrap. – user4035 Sep 16 '18 at 10:45
  • 4
    0x80010108 is "The object invoked has disconnected from its clients." You getting that as an HRESULT or as an error dialog? It simply means that the COM object is dead. Just treat this as an expected error and use that as a signal that the COM server died. I suspect you are didn't use the attributes to prevent C++ exceptions being thrown with #import if you are getting an exception thrown. – selbie Sep 16 '18 at 10:55
  • @selbie "I suspect you are didn't use the attributes to prevent C++ exceptions being thrown with #import if you are getting an exception thrown." - no, I think, it's good for debugging. – user4035 Sep 16 '18 at 11:10
  • 1
    That's cool - then you simply need to `catch` these exceptions being thrown by the wrapper code and have your code handle it (and/or re-throw). – selbie Sep 16 '18 at 11:22
  • 1
    That is certainly not supposed to happen. Even if you make the Excel window visible (don't) and the user closes it then the Excel.exe process continues to exist. Because you have a reference to one of its interfaces, like the Application interface. If the user intentionally kills Excel.exe with, say, Task Manager, then you're happy about this error, it tells you to stop trying to use it. – Hans Passant Sep 16 '18 at 11:41
  • @HansPassant I need Excel window, it's a special program, intended to output the results into Excel. Usually the user will close the program and it will close Excel. I just protect it from the opposite action. – user4035 Sep 16 '18 at 11:46
  • Pretty murky. Consider to make the window visible *after* you've done what you needed to do, terminating right after that. Can't go wrong that way. – Hans Passant Sep 16 '18 at 11:50
  • This article may be helpful for something. [Developer Documentation : COM OLE ActiveX hooking](http://jacquelin.potier.free.fr/winapioverride32/documentation.php) – kunif Sep 16 '18 at 12:31

0 Answers0