We have our own C ++ application that supports some VBA macros of various types over COM. One of these VBAExtension types VBAExtension registered using the main C ++ application, which results in an instance (derived from the class) IConnectionPointImpl<Extension, &DIID_IExtensionEvents, CComDynamicUnkArray> . This works great; both kernels and other VBA macros can access the methods in IExtensionEvents, given the corresponding VBAExtension object.
We also have a .NET assembly (written in C #) that also loads into the main application at runtime. For historical reasons, the assembly is loaded with a VBA macro with automatic start; then, when the user clicks a specific button, another VBA macro launches the main entry point of the assembly, which calls the System.Windows.Forms dialog for further interaction.
This is a setting. I see some strange behavior when accessing the VBAExtension methods from the .NET assembly. In particular, I run the following code from different places in the assembly:
foreach (VBAExtension ve in app.Extensions) { System.Diagnostics.Debug.Print("Ext: " + ve.Name); }
If I run it from the constructor of the main assembly object; or from the main entry point of the assembly (before the dialog box VBAExtension ), everything is fine - I get the VBAExtension names printed.
However, if I run the same code from the command launched by the button in assemblies ( modal - we call form.ShowDialog() )) WinForm, all ve.Name empty. The pDispatch->Invoke call created by the IConnectionPointImpl subclass succeeds (returns S_OK), but does not set any return vars.
If I changed the dialog to non-modal (called using form.Show() ), the names will work again. Modality (modality?) Forms, apparently, affect the success of IConnectionPointImpl calls.
Does anyone know what is going on?
Edit:. After the first publication, I demonstrated that this is not a calling call stack, which matters; instead, whether a call is made from a modal dialog. I updated the main text.
Edit 2: Answer the Hans question, answer his diagnostic questions:
- As expected, there is no error in the good (weak) case if I rename the VBA event handler. A call simply does not return data.
- I put the MsgBox call in the VBA handler; it is displayed in an incompatible case, but not in a modal case. Ergo, the handler does not execute in the modal case.
- Using
Err , I can say that if we remove the exception in the VBA handler, we get a VBA error dialog. After clearing this call, C ++ Invoke has 0x80020009 ("An exception occurred") as the return code, and pExcepInfo is populated with general failure values ββ(VBA swallowed the actual data). - The event does not fire on the second display of the modal dialog, either immediately after the first dialog, or during the second call to the C # add-in.
I will try to dig our message loops as the next step.