jpcs
asked on
Create, use and destroy ActiveX Connection
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.C hilkatXml. 1")
Set vTest = Nothing
End Sub
Thanks for all the help you can give me.
Joao
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
begin
vTest := CreateOleObject ('EnterAProgID.Here');
vTest := Unassigned;
end;
Example for an activex availlable:
download one ActiveX component from hxxp://wxw.chilkatsoft.com
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
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.C
Set vTest = Nothing
End Sub
Thanks for all the help you can give me.
Joao
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.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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.
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.
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(TObje ct *Sender)
{
CoFreeUnusedLibraries();
}
//------------------------ ---------- ---------- ---------- ---------- ---------- -
Russell
//------------------------
#include <vcl\vcl.h>
#include <objbase.h>
#pragma hdrstop
#include "Unit1.h"
//------------------------
#pragma resource "*.dfm"
TForm1 *Form1;
//------------------------
__fastcall TForm1::TForm1(TComponent*
: TForm(Owner)
{
}
//------------------------
void __fastcall TForm1::Button1Click(TObje
{
CoFreeUnusedLibraries();
}
//------------------------
ASKER
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
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
You are very welcome, glad to assist
Russell
Russell
ASKER
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
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
ASKER
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
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
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
ASKER
Thanks for your help Russell,
I've just posted a new question, but in the c# area. Hope to get the solution.
Regards,
Joao
I've just posted a new question, but in the c# area. Hope to get the solution.
Regards,
Joao