?
Solved

Create, use and destroy ActiveX Connection

Posted on 2005-04-28
10
Medium Priority
?
2,103 Views
Last Modified: 2012-06-27
Hello there,

I've got a problem that is now becoming very annoying :

I have an ActiveX that I must use WITHOUT TYPE LIBRARIES, so I must use CreateOleObject, OleProcedure, OleFunction, Exec, etc. However, the problem is when I try to destroy the connection, it doesn't really destroy it, because I simply cannot delete/update the ActiveX until the host application terminates.

Code:

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    vTest : Variant;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses ComObj;

procedure TForm1.Button1Click(Sender: TObject);
begin
   vTest := CreateOleObject ('EnterAProgID.Here');
   vTest := Unassigned;
end;


Example for an activex availlable:
download one ActiveX component from hxxp://wxw.chilkatsoft.com (i've tried the xml-activex).

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    vTest : Variant;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses ComObj;

procedure TForm1.Button1Click(Sender: TObject);
begin
   // http://www.chilkatsoft.com/xml-activex.asp
   vTest := CreateOleObject ('ChilkatXml.ChilkatXml.1');
   vTest := Unassigned;
end;


In VB, the result is the same:

Private vTest As Variant

Private Sub Command1_Click()
    Set vTest = CreateObject("ChilkatXml.ChilkatXml.1")
    Set vTest = Nothing
End Sub



Thanks for all the help you can give me.

Joao
0
Comment
Question by:jpcs
  • 5
  • 4
10 Comments
 
LVL 27

Expert Comment

by:BigRat
ID: 13884562
This is because the DLL contains a factory object which makes the control and this factory object resides in memory once the Dll has been loaded. The only way to replace a DLL from which a control has been loaded is to terminate all applications using the DLL or controls contained therein.
0
 
LVL 26

Accepted Solution

by:
Russell Libby earned 2000 total points
ID: 13885456

That statement is only partially true....

While the AX dll does contain the class factory, it also exports the DllCanUnloadNow api. This allows the CoFreeUnusedLibraries call to unload dll's that have no interfaces outstanding. I tested this with the chilkat stuff, and it does indeed unload the AX dll. One note to this is that you can't just call it directly after the release of the interface, as it depends on the message queue being flushed out first, but the following will give you an idea of what you can do:

Regards,
Russell

type
  TForm1            =  class(TForm)
     Button1:       TButton;
     procedure      Button1Click(Sender: TObject);
     procedure      FormCreate(Sender: TObject);
  private
     // Private declarations
  protected
     // Protected declarations
     procedure      AppOnIdle(Sender: TObject; var Done: Boolean);
  public
     // Public declarations
  end;

var
  Form1:            TForm1;

implementation
{$R *.DFM}

procedure TForm1.AppOnIdle(Sender: TObject; var Done: Boolean);
begin
  // Free unused COM libraries
  CoFreeUnusedLibraries;
  // Done
  Done:=True;
end;

procedure TForm1.Button1Click(Sender: TObject);
var  v:    OleVariant;
begin
  v:=CreateOleObject('ChilkatXml.ChilkatXml');
  v:=Unassigned;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Application.OnIdle:=AppOnIdle;
end;

end.

0
 
LVL 1

Author Comment

by:jpcs
ID: 13894862
Hello Russel,


Thanks very much for your answer!

It fixed my problem.

Can you just help on one thing?

How can I call this function in C++ builder 5?

I simply cannot find it.


Thanks.
0
Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

 
LVL 26

Expert Comment

by:Russell Libby
ID: 13894990
Your kidding, right? <g> I thought this was the Delphi TA? Seriously though, its declared in objbase.h, example given below:

Russell

//---------------------------------------------------------------------------
#include <vcl\vcl.h>
#include <objbase.h>

#pragma hdrstop

#include "Unit1.h"

//---------------------------------------------------------------------------
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
      : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{

      CoFreeUnusedLibraries();
 
}
//---------------------------------------------------------------------------
0
 
LVL 1

Author Comment

by:jpcs
ID: 13895077
Please ignore my last comment.

I've found out everything.


You have just solved a problem I have been having for the last 2 years...


I cannot thank you enough!!!


Joao
0
 
LVL 26

Expert Comment

by:Russell Libby
ID: 13895093
You are very welcome, glad to assist

Russell

0
 
LVL 1

Author Comment

by:jpcs
ID: 13895105
Looks like my comment wasn't on time :)

Yes, this is a delphi TA (I just used it, since the languages share the VCL and there are LOTS of more users).

I usually manage to make the changes on my own, however, in this issue, I was looking for the method in ActiveX.hpp... I've found it later just after I wrote the comment.

Thanks
0
 
LVL 1

Author Comment

by:jpcs
ID: 13896015
Russel,

I don't know if you know anything about this, but I can try...

This code works fine with some of my custom ActiveXs, except with the ones created using .net!


I suppose the problem is with a missing DllCanUnloadNow api. I've tried to find tips in the net, but with no luck!

Can you assist me with this?


Thanks.

Joao
0
 
LVL 26

Expert Comment

by:Russell Libby
ID: 13896133

I doubt if the api call is missing (as it is required along with DllGetClassObject), but there are a few notes from MS that go along with the CoFreeUnusedLibraries call:

<quote>

SYMPTOMS
Dynamic-link libraries (DLLs) that are not in use may not be unloaded from the process space after calling the CoFreeUnusedLibraries function.
 Back to the top

CAUSE
This problem occurs when the application still has references to the components in the DLL, or when the application releases all the references to a DLL but does not make a subsequent call to CoFreeUnusedLibraries.
 Back to the top

RESOLUTION
CoFreeUnusedLibraries does not immediately release DLLs that have no active object. There is a ten minute delay for multithreaded apartments (MTAs) and neutral apartments (NAs). For single-threaded apartments (STAs), there is no delay. The ten minute delay for CoFreeUnusedLibraries is to avoid multithread race conditions caused by unloading a component DLL.

To work around the problem, make a second call to CoFreeUnusedLibraries after ten minutes, or make periodic calls to CoFreeUnusedLibraries. For applications that run for long periods, such as Windows NT Service applications, calling CoFreeUnusedLibraries periodically ensures that DLLs that are not being used are unloaded.

Another workaround is to call CoUninitialize, which closes the COM library and releases all resources used by the current thread.
 Back to the top

STATUS
This behavior is by design.

---
as to how .NET (mscoree.dll) play into this, I can't really say


Russell

0
 
LVL 1

Author Comment

by:jpcs
ID: 13907893
Thanks for your help Russell,

I've just posted a new question, but in the c# area. Hope to get the solution.


Regards,

Joao
0

Featured Post

Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
This is an update to some code that someone else posted on Experts Exchange. It is an alternate approach, I think a little easier to use, & makes sure that things like the Task Bar will update.
Planning to migrate your EDB file(s) to a new or an existing Outlook PST file? This video will guide you how to convert EDB file(s) to PST. Besides this, it also describes, how one can easily search any item(s) from multiple folders or mailboxes…
Stellar Phoenix SQL Database Repair software easily fixes the suspect mode issue of SQL Server database. It is a simple process to bring the database from suspect mode to normal mode. Check out the video and fix the SQL database suspect mode problem.

601 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question