We help IT Professionals succeed at work.

Check out our new AWS podcast with Certified Expert, Phil Phillips! Listen to "How to Execute a Seamless AWS Migration" on EE or on your favorite podcast platform. Listen Now

x

Unloading and reloading an Active X control

Medium Priority
477 Views
Last Modified: 2013-11-25
We writing an MFC dialog (Formview) app. (VC++ 5.0). Its using an Active X email control from a company called Mabry Software to automatically read and respond to email. It needs to be very reliable. Occasionally if the mailserver drops off, this block gets in a confused internal state. We can detect when we are in this state, but
unfortunately the block has no method to allow it to be reset. The block developer says we need to "unload and
reload" the block to release its memory and resources and then restart it in a fresh state.
This is apparently easy in VB, but I have no idea how to do it in this dialog MFC app.

How do you do this in MFC? Does it require a different way of putting the block in the app than plopping
it down with the resource editor?
Comment
Watch Question

Commented:
What is a block?  What does "this block" mean?  Are you referring to the OLE control?

B ekiM

Author

Commented:
Sorry, when I say block, I always mean "Active X control", as I mentioned in the first
part of the question.

Commented:
Actually, you don't mention that you mean "OLE Control" when you say "block" anywhere in your question.

OLE Controls are COM objects; they don't get loaded and unloaded explicitly by a program. Instead, a client of the object creates the object. The code serving the object will load if it isn't already loaded, and will begin serving the object. When the client of the object indicates it is done with the object, it will release the object. The code serving the object may be immediately unloaded by OLE, but may be stick around in memory for some time before it's actually removed. If the code is servicing another instance of the object, it will remain in memory and not be unloaded until no more instances of the object exist.

Given those facts, it's hard to understand exactly what you mean by "load and unload". What VB code have you written in order to perform this operation?

Also, there are many details missing from your question: exactly how are you using the control in MFC? Are you calling CreateControl() on the control directly?  Are you calling Create() on a wrapper class for the control? Have you added the control to a dialog box? Does the control have a UI?

B ekiM

Commented:
Unlock this solution and get a sample of our free trial.
(No credit card required)
UNLOCK SOLUTION

Commented:
Unfortunately, that won't work if the control needs data persisted in the resource template.  Nor will it work if there's more than one instance of the control in the application.

B ekiM

Author

Commented:
This sounds promising, and we can live with the restrictions pointed out by mikeblas above. However, I'm not quite sure how to implement what you recommended, since
MFC and the AppWizard has taken care of all of the setup and communications to this
Active X control. Here's what I tried, but didn't work.

1) I changed the variable that was originally added using the AppWizard to be a pointer,
  and initialized it to NULL in the init code for the dialog that contains it:

// Dialog Data
      //{{AFX_DATA(CMabryDlg)
      enum { IDD = IDD_MABRY_DIALOG };
      CMail      *m_mail_ctl;
      //}}AFX_DATA

2) I updated all the references to it in any of the files in the project to handle the
extra indirection.

3) I tried creating the object as shown below, but its probably not right. How
   do you do this for an Active Control. Where and how is MFC doing it for me
   in the "regular" case?

      /* If m_mail_ctl has been allocated already, delete it */
      if(m_mail_ctl)
      {
            delete m_mail_ctl;
      }
      m_mail_ctl = new CMail();
             /* Using CreateObject was just a wild guess, but doesn't work. */
      m_mail_ctl->CreateObject();
            /* The first time you try to use any method with the control, you get a message
            * Debug Assertion Failed in winocc.cpp
            */


Author

Commented:
In response to an earlier question, we are adding this control to a dialog.
It looks like creating it programmatically is what we need to do, but as I mentioned
in an earlier comment, we're not quite sure how to do that. Any examples anywhere?

Here's what the control designer says has to be done in VB to reset the control-

At the present time, the only way to completely reset both the
control and socket is to unload it from memory. There is an item
on the Feature Request list to have a method that does this, but it
has not been implemented yet. In the meantime, this can be done
quite easily in VB by placing the control on a separate hidden form
and change all references to the control to include the Form, such as
Form2.mMail1.Host ="mail.foo.com". Then, after a winsock error or
after each Disconnect, Unload Form2 and in the Form_Unload event
add:

    Set Form2 = Nothing

This instruct Windows to release all resources associated with the
form thus destroying both the control and socket, so each time the
form is reloaded, the control and socket are "fresh", just like the
first time. I'm not sure what the syntax would be in VC++,  but I
assume you can load/unload forms from memory so the idea would be the
same.

Author

Commented:
To answer some clarification questions more specifically:
We added the block to the main dialog of an MFX "FormView" (dialog based) application.
We're not calling CreateControl or Create, I'm assumming one way or another
MFC/AppWizard set that up for us when we added the control and a control variable
for it. Doing the create programmatically would be fine if it fixes the problem for us,
but we need an example of how to do that.
The control has no UI.

Author

Commented:
Ok, here's how we finally got his to work. We used the AppWizard to put the control into a separate dialog, we create that as a modeless dialog. If the control needs resetting,
we destroy the dialog and open a new copy of it.

This was easier than the proposed answer above since we didn't have to wade through
how to create the control programatically, which apparently uses a CreateControl
but with lots of arguments and probably some black majic that the approach above
avoided.

Commented:
There's no black magic in using CreateControl().  If you put a breakpoint on COleControl::CreateControl() and let MFC create your control from a dialog box (as you had it set up), you'd see the exact parameters being used to do the creation.

Your solution will work, as long as the inefficiencies and focus problems in having an extra dialog don't bother you.

B ekiM

Unlock the solution to this question.
Thanks for using Experts Exchange.

Please provide your email to receive a sample view!

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.