tags:

views:

61

answers:

1

I'm having problems with my .net controls not getting cleaned up properly when wrapped for activeX use. Default behavior leaves the SDK's test container app (TstCon32.exe) running as a GUIless process when I try and close it. The workaround I initially found via google was to override WndProc and call Environment.Exit(0) manually. This did get TstCon32.exe to shut down completely; however it's breaking the application where i need to have the control hosted. The App is MDI and WM_DESTROY is being sent when the page containing the control is closed, at which point the Environment.Exit(0) call is blowing away the entire app. I've tried Application.Exit() as an alternative, but that leaves TstCon32 still running invisibly.

protected override void WndProc(ref Message m)
{
    base.WndProc(ref m);

    // WM_DESTROY
    if (m.Msg == 2)
        Environment.Exit(0);
}
+1  A: 

Generally an ActiveX container would call IOleObject::Close and IOleObject::SetClientSite(null) before closing. System.Windows.Forms.Control has its own implementation of IOleObject. I do not think you can override it in a derived class.

Sending WM_QUIT via Application::Exit is not an option for MDI, as it will close the whole program instead of the page hosting the ActiveX. If the container is leaking interface pointers there is not much you can do.

System.Windows.Forms.Control's IOLeObject implementation calls Control.Dispose only if the container implements IHTMLDocument2. But I do not think your can count on the container to implement this interface.

Sheng Jiang 蒋晟
Thanks. I'll look into the OLE methods you mentioned. The host app I'm writing for belongs to a 3rd party, so I can't modify it.
Dan Neely
I stuck MessageBox calls into both mentioned IOleObject methods; it appears that neither TstCon32 nor my target application are calling either method because the messageboxes are not being displayed.
Dan Neely
How? The Windows Forms Control class's IOleObject implementation is not visible externally.
Sheng Jiang 蒋晟
In MyActiveXControl.cs, I added the IOleObject interface, and iplemented the methods like this: public void SetClientSite(IOleClientSite pClientSite) { MessageBox.Show("SetClientSite Method, pClientSite = " + pClientSite); }
Dan Neely
Are you perhaps confused about what I'm coding? I'm writing the activeX control. Not the application that uses it.
Dan Neely
You can declare an event and let the container to close itself gracefully. There is not much else you can do to a container that you have no control of.
Sheng Jiang 蒋晟