我们有一个本机C++应用程序,它支持一些不同类型的VBA宏.其中一种类型,VBAExtension使用核心C++应用程序注册自己,从而产生(一个派生自的类)的实例IConnectionPointImpl<Extension, &DIID_IExtensionEvents, CComDynamicUnkArray>.这很好用; 在给定适当的VBAExtension对象的情况下,核心和其他VBA宏都可以访问IExtensionEvents上的方法.
我们还有一个.NET程序集(用C#编写),它也在运行时加载到核心应用程序中.由于历史原因,程序集由自动运行的VBA宏加载; 然后,当用户按下特定按钮时,另一个VBA宏运行程序集的主入口点,这会打开一个System.Windows.Forms对话框以进行进一步的交互.
这就是设置.我看到一些奇怪的行为VBAExtension从.NET程序集中访问方法.具体来说,我从程序集中的各个位置运行以下代码:
foreach (VBAExtension ve in app.Extensions)
{
System.Diagnostics.Debug.Print("Ext: " + ve.Name);
}
Run Code Online (Sandbox Code Playgroud)
如果我从程序集的主对象的构造函数中运行它; 或者从程序集的主入口点(在显示对话框之前),一切都很好 - 我得到了VBAExtension打印出的s 的名称.
但是,如果我从程序集中的一个按钮(模态 - 我们正在调用form.ShowDialog())WinForm 启动的命令中运行相同的代码,则ve.Names都是空白的.子类的pDispatch->Invoke调用IConnectionPointImpl成功(返回S_OK),但不设置任何返回变量.
如果我将对话框更改为非模态(调用方式form.Show()),则名称会再次起作用.表单的模态(模态?)似乎会影响IConnectionPointImpl调用是否成功.
有谁知道发生了什么?
编辑:自从第一次发布以来,我已经证明了重要的不是调用调用堆栈; 相反,它是否是从模态对话框进行调用.我已经更新了正文.
编辑2:根据Hans Passant的回答,以下是他的诊断问题的答案:
Err,我可以告诉我,如果我们在VBA处理程序中遇到异常,我们会得到一个VBA错误对话框.清除后,C++ Invoke调用将0x80020009("异常发生")作为返回码,并且pExcepInfo填入一般故障值(VBA已吞下实际细节)我将尝试深入挖掘我们的消息循环作为下一步.
试图了解这是什么IConnectionPoint以及如何连接到IConnectionPointContainer,IEnumConnectionPoints,IEnumConnections和EventHandling.
阅读MSDN和CodeProject中的artcicles,它解释了其他方法,如:QueryInterface()和其他方法.
我无法弄清楚所有这些东西(IConnectionPointContainer,IEnumConnectionPoints,IEnumConnections)是如何相互关联和事件处理.
我只想创建一个simpleClient,它将触发COM对象中的事件.
如果有任何文章或代码片段可以解释事物如何通过简单和小块代码相互关联将是有帮助的.
值得一提的是我最近开始在C开发,一个初学者.
编辑@sharptooth
对于线" typically your client will receive events and the COM object will trigger those events. "
从许多文章中,我理解的是当我们在那时使用连接点时,
the client exposes a set of methods that the server uses.
我只是概述来自TechRepublich的文章的一部分:
客户端服务器与接收源
因此,在标准客户端 - 服务器系统中使用COM进行正常编程和使用连接点之间的主要区别在于,在标准客户端 - 服务器情况下,服务器公开客户端使用的方法列表,并且在连接点情况下,客户端公开服务器使用的一组方法.
我是C#和WPF编程的新手,现在这个问题令我头疼.
程序应该做什么:程序显示一个带有文本框的欢迎屏幕,客户可以在其中输入他的名字.如果设备靠近无线局域网接入点并成功连接,则此主窗口上的"开始"按钮应该可见.
什么不起作用:在事件处理程序中设置按钮可见性.新样式不适用.此外,如果我在设置可见性属性/属性(?)后尝试调用任何其他代码,它将不会运行(如果我在设置visib之前将MessageBox.Show设置为右.如果我在设置之后放置它,它将会显示该属性,甚至不再达到此代码).
代码:
这是按钮元素:
<Button Height="72" HorizontalAlignment="Center" Margin="319,507,315,0"
Name="buttonStart" VerticalAlignment="Top" Width="168" FontSize="32"
Content="Los geht's" Click="buttonStart_Click" />
Run Code Online (Sandbox Code Playgroud)
这是MainWindow.xaml.cs中的事件处理程序注册
public partial class MainWindow : Window, INetworkListManagerEvents
{
private INetworkListManager nlm_;
private IConnectionPoint nlmICP_;
private int nlmCookie_ = 0;
private void InitNetManager()
{
nlm_ = new NetworkListManager();
IConnectionPointContainer icpc = (IConnectionPointContainer)nlm_;
Guid tempGuide = typeof(INetworkListManagerEvents).GUID;
icpc.FindConnectionPoint(ref tempGuide, out nlmICP_);
nlmICP_.Advise(this, out nlmCookie_);
}
Run Code Online (Sandbox Code Playgroud)
最后,事件处理程序:
public void ConnectivityChanged(NLM_CONNECTIVITY newConnectivity)
{
if (newConnectivity == NLM_CONNECTIVITY.NLM_CONNECTIVITY_DISCONNECTED ||
((int)newConnectivity & (int)NLM_CONNECTIVITY.NLM_CONNECTIVITY_IPV4_NOTRAFFIC) != 0)
{ …Run Code Online (Sandbox Code Playgroud)