VC调用OCX COM组件
纯C/C++中调用OCX的方法
首先,接口就是vTable
#import "c:/ITDetector.ocx" \
no_namespace no_smart_pointers raw_interfaces_only \
raw_native_types no_implementation named_guids
加入这句第一次Build之后会生成ITDetector.tlh在你的Debug或者Release目录下,把ITDetector.tlh Include进来你就可以使用ITDetector.ocx中包含的接口了。
ITDetector.ocx会包含tlb的资源,.tlb文件中是保存了接口的名字、规范及其他信息等(也就是idl文件的描述信息)。#import这句会用工具读取ITDetector.ocx中的tlb资源,然后翻译成C++的接口版本生成到ITDetector.tlh文件,事实上就是接口定义而已,因为你需要调用某个方法只需要知道类GUID、接口GUID、接口方法的偏移、接口方法的参数及返回值类型就可以了。
1、import你的OCX库 //想办法弄到接口的定义,如果你有或者自己写可以跳过该步
2、CoInitialize(0) //初始化COM库,干些什么事我不太清楚,反正就是告诉系统你的这个线程要开始用COM组件了(有计数器)
3、CoCreateInstance取得一个实例
//获得一个COM实例,实际工作是根据CLSID去注册表找到模块路径(就是c:/ITDetector.ocx)
//然后LoadLibrary,把c:/ITDetector.ocx装入进程
//再用GetProcAddress获取DllGetClassObject的方法地址
//再调用DllGetClassObject,把CLSID传进去,它会返回这个类的工厂接口(组件需要自己写代码实现工厂)
//再调用工厂接口的CreateInstance把对象创建起来,并返回这个接口,同时调用一次AddRef
4、调用 //虚方法调用而已
5、Release() //减少引用计数,当引用计数为0是,对象被释放(组件需要自己实现)
6、CoUninitialize() //告诉系统,你这个线程不再使用COM组件了(有计数器)
int CWebServiceBridge_PayWebS::DisplayOCX(char* szUrlPath)
{
HRESULT hr = NULL;
IDispatch* pIDispatch = NULL;
wchar_t progid[] = L"WRITINGPAD.WritingPadCtrl.1"; //组件名
CLSID clsid;
hr = ::CLSIDFromProgID(progid,&clsid); //根据组件ID获取clsid
hr = ::CoInitialize(NULL);
_DWritingPad *pID; //接口指针,可以在tlh头文件中获取
hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER,__uuidof(_DWritingPad),(LPVOID *)&pID); // 根据Clsid和IID创建相应的实例对象。
if(SUCCEEDED(hr))
{
DISPID dispid;
OLECHAR FAR* szMember = L"OpenURL"; //Add为OCX中的被调函数,函数原型为:OpenURL("http://www.bing.com")
hr = pID->GetIDsOfNames(IID_NULL, &szMember, 1, LOCALE_SYSTEM_DEFAULT, &dispid);
DISPPARAMS param;
memset(¶m, 0, sizeof(param));
param.cArgs = 1; //参数个数
VARIANTARG* pArg = new VARIANTARG[param.cArgs];
param.rgvarg = pArg;
memset(pArg, 0, sizeof(VARIANT) * param.cArgs);
_bstr_t bstrUrlPath = _bstr_t(szUrlPath);
param.rgvarg[0].vt = VT_BSTR;
param.rgvarg[0].bstrVal = bstrUrlPath;
VARIANT result;
VariantInit(&result);
EXCEPINFO exInfo;
memset(&exInfo, 0, sizeof(exInfo));
UINT argE = -1;
hr = pID->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, ¶m, &result, 0, NULL);//返回值在result中保存
pID->Release();
if(SUCCEEDED(hr))
{
CoUninitialize();
return result.lVal;
}
}
CoUninitialize();
return -1;
}
WIN7系统VC6中添加OCX出现“不支持此接口” 问题的解决方法
在WindowsXP系统中,VC6可以通过 工程-》添加到工程-》。。。。。。添加OCX,
但是到了Windows7系统中,无法添加,就算用Administrator,也只是仅仅可以看到OCX,但是添加
的时候提示 “不支持此接口”;
还有人说 可以尝试重新注册所有DLL来解决此问题:
for /r C:/ %i in (*.dll) do regsvr32.exe /s "%i" 或 FOR /R C:/ %G IN (*.dll) DO "%systemroot%/system32/regsvr32.exe" /s "%G" 但是一样的问题。
解决方法:1:在对话框上直接右键 “Insert ActiveX Control。。。”, 这个时候类视图中还没有所添加OCX的类文件,
2:然后选中所添加的OCX,用向导添加变量,这样VC6会为程序添加这个OCX对应的类文件了;
3: 删除刚添加的OCX关联的变量也没问题了;
在XP系统VC6中,如果ocx添加新的接口了,重新导入ocx就可以了;
但是在win7系统VC6中,目前我只好,重新注册号添加接口的ocx,然后新建一个工程导入,然后将生成的.h 和 .cpp 复制到原工程中;