ActiveX(COM)控件在被其父级关闭时,应该采取什么适当的清理方式?

4
我在使用.net控件包装ActiveX时遇到了清理问题。默认行为是当我尝试关闭SDK的测试容器应用程序(TstCon32.exe)时,该应用程序将作为无GUI进程运行。
我最初通过Google找到的解决方法是重写WndProc并手动调用Environment.Exit(0)。这确实使TstCon32.exe完全关闭;然而,它破坏了我需要托管控件的应用程序。
该应用程序是MDI的,当包含控件的页面关闭时,将发送WM_DESTROY,此时Environment.Exit(0)调用将使整个应用程序崩溃。我尝试过Application.Exit()作为替代方案,但这仍然会导致TstCon32.exe以隐形模式运行。
protected override void WndProc(ref Message m)
{
    base.WndProc(ref m);

    // WM_DESTROY
    if (m.Msg == 2)
        Environment.Exit(0);
}

我有一个类似的问题。你找到解决方案了吗? - Michael Stoll
@Michael Stoll 我不认为我这样做了。 - Dan Is Fiddling By Firelight
1个回答

2

通常情况下,ActiveX容器在关闭之前会调用IOleObject::Close和IOleObject::SetClientSite(null)。System.Windows.Forms.Control有自己的IOleObject实现,我认为你不能在派生类中重写它。

通过Application::Exit发送WM_QUIT不适用于MDI,因为它会关闭承载ActiveX页面的整个程序。如果容器泄漏接口指针,则无法做太多事情。

System.Windows.Forms.Control的IOleObject实现仅在容器实现了IHTMLDocument2时才调用Control.Dispose。但我不认为您可以指望容器实现此接口。


谢谢。我会研究你提到的OLE方法。我正在为第三方编写的宿主应用程序编写代码,所以我无法修改它。 - Dan Is Fiddling By Firelight
我在两个提到的IOleObject方法中都加入了MessageBox调用;看起来TstCon32和我的目标应用程序都没有调用这两种方法,因为消息框没有显示出来。 - Dan Is Fiddling By Firelight
如何解决?Windows Forms Control 类的 IOleObject 实现在外部不可见。 - Sheng Jiang 蒋晟
在MyActiveXControl.cs中,我添加了IOleObject接口,并实现了以下方法:public void SetClientSite(IOleClientSite pClientSite) { MessageBox.Show("SetClientSite方法,pClientSite = " + pClientSite); } - Dan Is Fiddling By Firelight
你可能对我正在编码的内容感到困惑吗?我正在编写ActiveX控件,而不是使用它的应用程序。 - Dan Is Fiddling By Firelight
你可以声明一个事件,让容器优雅地关闭自己。对于那些你无法控制的容器,你几乎不能做其他任何事情。 - Sheng Jiang 蒋晟

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接