Crashes on application exit while hosting an VB ActiveX Control providing UI in a MFC application
-
Hello, perhaps somebody can help me to find the reason for the crashes I have. I have a MFC Application with MFC extension DLLs. One of the dialogs is a window with a CPropertySheet. One CPropertyPage is a host for ActiveX Controls providing extending UI. This CPropertyPage has a CWnd member to host the ActiveX Controls dynamically created runtime using the CWnd::CreateControl method. I have a VB ActiveX Control providing needed extending UI. It can be loaded and used without problems. The only problem occurs, when the application exits: 1. The CPropertySheet is destroyed ... the CPropertyPage is destroyed, ... ... which releases its previously queried interfaces, ... sends a WM_DESTROY to the CWnd hosting the ActiveX Control and ... deletes/frees the CWnd 2. Somewhere at the end just before invoking "exit" open "OLE" connections/loaded "OLE" libraries are terminated by Microsoft internal code. I saw that the ActiveX OCX module was active until this moment. 3. In the "exit" invocation the MFC application crashes from within the VB ActiveX Control. The VB ActiveX Control does not execute its UserControl_Terminate handler, so it seems, that there happens an irregular deletion of the VB ActiveX Control. This crash happens currently only in the debug version of our application. But adding CommonControls to the VB ActiveX Control UI causes a crash even in the release version of this MFC application. Using a MFC ActiveX Control providing some UI, too, no problems occur. The only difference seen while releasing the last reference to the previously queried interface are that ... ... the release on the interface of VB ActiveX Control returns 4 still valid references, ... while the release on the interface of the MFC ActiveX Control returns only 3 still valid references. Thus I suspect, that at application end there is still a last reference valid, not released, which causes a crash after the OCX is unloaded from Microsoft internal code cleaning up before the real application exit. Something in the VB ActiveX Control wants still to work (like executing UserControl_Terminate), but the OCX is already unloaded. But ... where and how can I find this last reference? Debugging through the MFC code hosting the ActiveX Control didn't help really? Has somebody here experienced a similar problem? Or can somebody help? Thanks in advance, Martin
-
Hello, perhaps somebody can help me to find the reason for the crashes I have. I have a MFC Application with MFC extension DLLs. One of the dialogs is a window with a CPropertySheet. One CPropertyPage is a host for ActiveX Controls providing extending UI. This CPropertyPage has a CWnd member to host the ActiveX Controls dynamically created runtime using the CWnd::CreateControl method. I have a VB ActiveX Control providing needed extending UI. It can be loaded and used without problems. The only problem occurs, when the application exits: 1. The CPropertySheet is destroyed ... the CPropertyPage is destroyed, ... ... which releases its previously queried interfaces, ... sends a WM_DESTROY to the CWnd hosting the ActiveX Control and ... deletes/frees the CWnd 2. Somewhere at the end just before invoking "exit" open "OLE" connections/loaded "OLE" libraries are terminated by Microsoft internal code. I saw that the ActiveX OCX module was active until this moment. 3. In the "exit" invocation the MFC application crashes from within the VB ActiveX Control. The VB ActiveX Control does not execute its UserControl_Terminate handler, so it seems, that there happens an irregular deletion of the VB ActiveX Control. This crash happens currently only in the debug version of our application. But adding CommonControls to the VB ActiveX Control UI causes a crash even in the release version of this MFC application. Using a MFC ActiveX Control providing some UI, too, no problems occur. The only difference seen while releasing the last reference to the previously queried interface are that ... ... the release on the interface of VB ActiveX Control returns 4 still valid references, ... while the release on the interface of the MFC ActiveX Control returns only 3 still valid references. Thus I suspect, that at application end there is still a last reference valid, not released, which causes a crash after the OCX is unloaded from Microsoft internal code cleaning up before the real application exit. Something in the VB ActiveX Control wants still to work (like executing UserControl_Terminate), but the OCX is already unloaded. But ... where and how can I find this last reference? Debugging through the MFC code hosting the ActiveX Control didn't help really? Has somebody here experienced a similar problem? Or can somebody help? Thanks in advance, Martin
Hi Martin, I think you are on right track. Just make sure you are not holding any reference in your own code. Use smart pointer (CComPtr, CComQIPtr). If you queried for an interface, make sure you release it in your OnDestroy. I don't think it matters that you are using an MFC extension DLL, as long you release your interface, it should work fine. Did you try creating a separate project (simple dialogbox) using the activeX in question?
In the end, we will remember not the words of our enemies, but the silence of our friends. - Martin Luther King Jr. Ernest Laurentin
-
Hi Martin, I think you are on right track. Just make sure you are not holding any reference in your own code. Use smart pointer (CComPtr, CComQIPtr). If you queried for an interface, make sure you release it in your OnDestroy. I don't think it matters that you are using an MFC extension DLL, as long you release your interface, it should work fine. Did you try creating a separate project (simple dialogbox) using the activeX in question?
In the end, we will remember not the words of our enemies, but the silence of our friends. - Martin Luther King Jr. Ernest Laurentin
Hi Ernest, thanks for your reply. Until today morning I used no smart pointers, but using them does not change a thing. I didn't expect a change in behaviour, because in my MFC C++ ActiveX control I could see, while debugging, that my reference handling was ok. Ok - now I've introduced CComIQPtr and CComPtr, but it changes nothing. The question is, why in comparison to the MFC ActiveX control one additional reference to the VB ActiveX control is hold!? And how/what is holding this reference to which interface? The question raises, because releasing "my" interface I got a count of hold references of 3 with the MFC ActiveX control, but 4 with the VB ActiveX control. And debugging through the deletion of my hosting CWnd I see only 3 releases on the interfaces of the MFC and the VB Active control. So - where is the last reference on a interface to be found? And ... do I have the possibility to change this behaviour? Best regards, Martin
-
Hello, perhaps somebody can help me to find the reason for the crashes I have. I have a MFC Application with MFC extension DLLs. One of the dialogs is a window with a CPropertySheet. One CPropertyPage is a host for ActiveX Controls providing extending UI. This CPropertyPage has a CWnd member to host the ActiveX Controls dynamically created runtime using the CWnd::CreateControl method. I have a VB ActiveX Control providing needed extending UI. It can be loaded and used without problems. The only problem occurs, when the application exits: 1. The CPropertySheet is destroyed ... the CPropertyPage is destroyed, ... ... which releases its previously queried interfaces, ... sends a WM_DESTROY to the CWnd hosting the ActiveX Control and ... deletes/frees the CWnd 2. Somewhere at the end just before invoking "exit" open "OLE" connections/loaded "OLE" libraries are terminated by Microsoft internal code. I saw that the ActiveX OCX module was active until this moment. 3. In the "exit" invocation the MFC application crashes from within the VB ActiveX Control. The VB ActiveX Control does not execute its UserControl_Terminate handler, so it seems, that there happens an irregular deletion of the VB ActiveX Control. This crash happens currently only in the debug version of our application. But adding CommonControls to the VB ActiveX Control UI causes a crash even in the release version of this MFC application. Using a MFC ActiveX Control providing some UI, too, no problems occur. The only difference seen while releasing the last reference to the previously queried interface are that ... ... the release on the interface of VB ActiveX Control returns 4 still valid references, ... while the release on the interface of the MFC ActiveX Control returns only 3 still valid references. Thus I suspect, that at application end there is still a last reference valid, not released, which causes a crash after the OCX is unloaded from Microsoft internal code cleaning up before the real application exit. Something in the VB ActiveX Control wants still to work (like executing UserControl_Terminate), but the OCX is already unloaded. But ... where and how can I find this last reference? Debugging through the MFC code hosting the ActiveX Control didn't help really? Has somebody here experienced a similar problem? Or can somebody help? Thanks in advance, Martin
Hello again, first - I'm sorry, because I didn't provide any information about the development environment: Microsoft Visual Studio 6.0 SP6 Microsoft Visual Basic 6.0 SP6 And ... no ... I can not upgrade - currently! Second - I created a new most simple MFC application only loading the VB ActiveX control and raising an exception on exiting. It has a CWnd* member on which CreateControl is called and which is deleted while deleting the dialog object. So it shows the same behavior than the big MFC application I normally work on. Has someone a hit or suggestion? Best regards, Martin
-
Hello again, first - I'm sorry, because I didn't provide any information about the development environment: Microsoft Visual Studio 6.0 SP6 Microsoft Visual Basic 6.0 SP6 And ... no ... I can not upgrade - currently! Second - I created a new most simple MFC application only loading the VB ActiveX control and raising an exception on exiting. It has a CWnd* member on which CreateControl is called and which is deleted while deleting the dialog object. So it shows the same behavior than the big MFC application I normally work on. Has someone a hit or suggestion? Best regards, Martin
Hello, after trying a bit I changed my VB ActiveX Control to execute the "UserControl_Terminate" things in the "UserControl_Hide" event handler. Only the call "App.LogEvent ..." stayed in the "UserControl_Terminate" event handler. And now everything seems to work fine. Even a VB ActiveX Control with CommonControls (not even touched in the "UserControl_Terminate" event handler) works now. So - I don't know why, but now everything works. I found a solution, but no understanding for the problem. Best regards, Martin