Do not register to call ActiveX DLL

Source: Internet
Author: User

Each ActiveX dll should have a dllgetclassobject function, which allows you to directly create the required COM object without using the registry (or registration ).

 
Stdapi dllgetclassobject (refclsid rclsid,// CLSID for the Class ObjectRefiid riid,// Reference to the identifier of the interface// That communicates with the Class ObjectLpvoid * GMM// Address of output variable that has es// Interface pointer requested in riid);

 

Here, you must know two things: one rclsid is the CLSID of the COM object to be created, and the other is the riid, the ID of an interface of this object.
However, you cannot directly create the required object by calling dllgetclassobject, but you can obtain the corresponding iclassfactory, and then obtain the required object by iclassfactory. createinstance.
VB implementationCodeProbably as follows:
Need to use a library, http://www.mvps.org/emorcillo/download/vb6/tl_ole.zip
(Reference page, http://www.mvps.org/emorcillo/en/code/vb6/wbframe.shtml)
In addition, the ActiveX dll is also referenced into the project. Here, it is not necessary to register it, but to facilitate the use of IT, because new is not used to create objects,
ProgramAfter compilation, even if the DLL file is not registered, it can be used normally.

 

Option explicit 'assume that the ActiveX DLL file name is dlldemo. dll and is in the same project directory private declare function dllgetclassobject lib" Dlldemo. dll "(_ Rclsid as UUID, riid as UUID, byref BPAs any) As long 'class idprivate const clsstr_obj as string =" {C1A334BA-D1A4-48D0-98D5-47FE934961DF} "'Interface idprivate const iidstr_ins as string ="{231114d5-e046-4dae-b192-0ab49d493a85} "'Iclassfactory idprivate const striid_iclassfactory as string =" {00000001-0000-0000-c000-000000000046} "Private clsid_obj as uuidprivate iid_ins as uuidprivate iid_iunknow as uidprivate iid_iclassfactory as uuidprivate sub commandelist click () dim tobj as olelib. iunknowndim tobj2 as dlldemo. idemodim tfac as olelib. iclassfactorycall dllgetclassobject (clsid_obj, iid_iclassfactory, tfac) tfac. createinstance nothing, iid_iunknow, tobjset tfac = nothingset tobj2 = tobj 'call idemo. test the created object tobj2.testend subprivate sub form_load () 'to convert string to uuidclsidfromstring clsstr_obj, incluiidstr_ins, incluiidstr_iunknown, inclustriid_iclassfactory, and inclusub

 

Now, the problem seems to have been solved. You only need to write the corresponding dllgetclassobject function for different ActiveX DLL files, but it is difficult to do it when the file name is not specified, for example, when writing a plug-in.
The solution is to use loadlibrary to dynamically call the dllgetclassobject on each DLL. however, VB does not support function pointers. my solution is to use VC. use VC to write DLL for VB call. The main code is as follows:

// Crcom. cpp: defines the entry point for the DLL application.
//

# Include "stdafx. H"
# Include <unknwn. h>
# Include <objbase. h>

Typedef int (callback * myproc) (refclsid, refiid, lpvoid *);

Bool apientry dllmain (handle hmodule,
DWORD ul_reason_for_call,
Lpvoid lpreserved
)
{
Return true;
}

// If (riid = NULL) riid = & iid_iunknown
int _ stdcall crcomobj (
lpcstr lpdll,
CLSID * rclsid,
IID * riid,
lpvoid * GMM)
{< br> hinstance hinstlib;
myproc procadd;

Bool ffreeresult, fruntimelinksuccess = false;
Int RTN = 0;
// Get a handle to the DLL module.
Hinstlib = loadlibrary (lpdll );
// If the handle is valid, try to get the function address.
If (hinstlib! = NULL)
{
Procadd = (myproc) getprocaddress (hinstlib, "dllgetclassobject ");
// If the function address is valid, call the function.
If (fruntimelinksuccess = (procadd! = NULL ))
{
If (rclsid = NULL)
{
Freelibrary (hinstlib );
Return 0;
}
If (riid = NULL)

Riid = (IID *) & iid_iunknown;

iclassfactory * PIF;
PIF = NULL;
If (procadd (* rclsid, iid_iclassfactory, (void **) & PIF) ==s_ OK & PIF! = NULL)
{< br> If (PIF-> createinstance (null, * riid, GMM) = s_ OK)
RTN = (INT) hinstlib;
PIF-> release ();
PIF = NULL;
}< BR >}< br> // free the DLL module.
If (! RTN) ffreeresult = freelibrary (hinstlib);
}< br> return RTN;
}

// If strriid = NULL, use iid_iunknown;
int _ stdcall crcomobj2 (
lpcstr lpdll,
lpcstr strrclsid,
lpcstr strriid,
lpvoid * GMM)
{< br> hinstance hinstlib;
myproc procadd;

bool ffreeresult, fruntimelinksuccess = false;
int RTN = 0;
// get a handle to the DLL module.
hinstlib = loadlibrary (lpdll);
// If the handle is valid, try to get the function address.
If (hinstlib! = NULL)
{< br> procadd = (myproc) getprocaddress (hinstlib, "dllgetclassobject");
// if the function address is valid, call the function.
If (fruntimelinksuccess = (procadd! = NULL)
{< br> CLSID rclsid;
IID riid;
If (strrclsid = NULL)
{< br> freelibrary (hinstlib);
return 0;
}< br> clsidfromstring (lpolestr) strrclsid, & rclsid);

If (strriid! = NULL)
Clsidfromstring (lpolestr) strriid, & riid );
Else
Riid = iid_iunknown;

Iclassfactory * PIF = NULL;

If (procadd (rclsid, iid_iclassfactory, (void **) & PIF) = s_ OK & PIF! = NULL)
{
If (PIF-> createinstance (null, riid, GMM) = s_ OK)
RTN = (INT) hinstlib;
PIF-> release ();
PIF = NULL;
}
}
// Free the DLL module.
If (! RTN) ffreeresult = freelibrary (hinstlib );
}
Return RTN;
}

In VB, crcomobj transmits UUID, crcomobj2 transmits string,

'Function Declaration
Private declare function crcomobj lib "crcom. dll "(_
Byval lpdll as string, byval rclsid as long, byval riid as long, byref BPAs any) as long
Private declare function crcomobj2 lib "crcom. dll "(_
Byval lpdll as string, byval strrclsid as long, byval strriid as long, byref BPAs any) as long

Dim tobj as olelib. iunknown
Dim tobj2 as dlldemo. idemo

Hlib = crcomobj (App. Path & "\ dlldemo. dll", varptr (clsid_obj), 0, tobj)
Set tobj2 = tobj
Tobj2.test

'Or

Hlib = crcomobj2 (App. Path & "\ dlldemo. dll", strptr (clsstr_obj), 0, tobj)
Set tobj2 = tobj
Tobj2.test

Crcomobj and crcomobj2 return the loadlibrary return value. If necessary, freelibrary should be used for release.

Postscript:
in my multi-page browser le, ActiveX dll is not registered and called. I directly use the code of a book (Advanced Visual Basic, the code is quite long and complex. I didn't know why when I used it. Later I finally figured out that the principle is the same, but VB does not support function pointers, so it took a lot of effort to solve this problem. in comparison, I think it is better to borrow VC, which is much simpler.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.