一 创建控件的多种方法
1.以ProgID方式创建
-
wxAutomationObject sp;
-
if (!sp.CreateInstance(_T("FPUSpreadADO.fpSpread.6")))
-
{
-
wxMessageBox(_T("Could not create object."));
-
return;
-
}
-
-
IDispatch* pObj = (IDispatch *)sp.GetDispatchPtr();
-
wxActiveXContainer* grid = new wxActiveXContainer(this,IID_IDispatch,pObj);
wxAutomationObject sp;
if (!sp.CreateInstance(_T("FPUSpreadADO.fpSpread.6")))
{
wxMessageBox(_T("Could not create object."));
return;
}
IDispatch* pObj = (IDispatch *)sp.GetDispatchPtr();
wxActiveXContainer* grid = new wxActiveXContainer(this,IID_IDispatch,pObj);
wxActiveXContainer就是一个窗体,通过wxSizer加进父窗体即可。
wxAutomationObject的GetInstance函数使用的参数名为ProgID,ProgID可通过VC6.0自带的工具OLEVIEW.EXE进行查看,
打开OLEVIEW.EXE,在左侧点Object Classes \ Grouped by Component Category \ Control \ 控件名称,右侧会显示相关信息。
如下图:
2.通过CLSID进行创建
控件的CLSID也可通过OLEVIEW.EXE获取,如上图所示。
-
CLSID clsId = {0xDE52502E, 0xF837, 0x492B, { 0xAE, 0x14, 0xA1, 0x82, 0x53, 0x1A, 0xFA, 0xF4}};
-
IDispatch* pDispatch;
-
if (SUCCEEDED(CoCreateInstance(clsId, NULL, CLSCTX_SERVER, IID_IDispatch,(void**)&pDispatch)))
-
{
-
wxAutomationObject *sp = new wxAutomationObject;
-
sp->SetDispatchPtr(pDispatch);
-
wxActiveXContainer* grid = new wxActiveXContainer(this,IID_IDispatch,pDispatch);
-
}
CLSID clsId = {0xDE52502E, 0xF837, 0x492B, { 0xAE, 0x14, 0xA1, 0x82, 0x53, 0x1A, 0xFA, 0xF4}};//Spread COM
IDispatch* pDispatch;
if (SUCCEEDED(CoCreateInstance(clsId, NULL, CLSCTX_SERVER, IID_IDispatch,(void**)&pDispatch)))
{
wxAutomationObject *sp = new wxAutomationObject;
sp->SetDispatchPtr(pDispatch);
wxActiveXContainer* grid = new wxActiveXContainer(this,IID_IDispatch,pDispatch);
}
3.用类工厂相关函数创建,不带授权信息
-
HRESULT hr;
-
IDispatch* pObj;
-
CLSID clsid = { 0xDE52502E, 0xF837, 0x492B, { 0xAE, 0x14, 0xA1, 0x82, 0x53, 0x1A, 0xFA, 0xF4}};
-
LPCLASSFACTORY pClassFactory = NULL;
-
if (SUCCEEDED(hr = CoGetClassObject(clsid, CLSCTX_SERVER, NULL,IID_IClassFactory, (void**)&pClassFactory)))
-
{
-
hr = pClassFactory->CreateInstance(NULL, IID_IOleObject, (void**) &pObj);
-
pClassFactory->Release();
-
if(FAILED(hr))
-
return;
-
-
wxAutomationObject *sp = new wxAutomationObject;
-
sp->SetDispatchPtr(pObj);
-
wxActiveXContainer* grid = new wxActiveXContainer(this,IID_IDispatch,pObj);
-
}
HRESULT hr;
IDispatch* pObj;
CLSID clsid = { 0xDE52502E, 0xF837, 0x492B, { 0xAE, 0x14, 0xA1, 0x82, 0x53, 0x1A, 0xFA, 0xF4}};
LPCLASSFACTORY pClassFactory = NULL;
if (SUCCEEDED(hr = CoGetClassObject(clsid, CLSCTX_SERVER, NULL,IID_IClassFactory, (void**)&pClassFactory)))
{
hr = pClassFactory->CreateInstance(NULL, IID_IOleObject, (void**) &pObj);
pClassFactory->Release();
if(FAILED(hr))
return;
wxAutomationObject *sp = new wxAutomationObject;
sp->SetDispatchPtr(pObj);
wxActiveXContainer* grid = new wxActiveXContainer(this,IID_IDispatch,pObj);
}
4.用类工厂相关函数创建,带授权信息
为什么要带授权信息,是因为带授权信息的控件在开者的电脑上可以正常运行,但分发到其它电脑上就无法运行,所以在创建控件时必须带上授权信息。
wxAutomationObject仅提供以ProgID方式创建控件,此种方式却无法传入授权信息。笔者琢磨良久,此文由来也正基于此。
-
WCHAR pwchLicenseKey[] =
-
{
-
0x0043, 0x006F, 0x0070, 0x0079, 0x0072, 0x0069,
-
0x0067, 0x0068, 0x0074, 0x0020, 0x0028, 0x0063,
-
0x0029, 0x0020, 0x0031, 0x0039, 0x0039, 0x0034,
-
0x0020
-
};
-
-
HRESULT hr;
-
IDispatch* pObj;
-
CLSID clsid = { 0xDE52502E, 0xF837, 0x492B, { 0xAE, 0x14, 0xA1, 0x82, 0x53, 0x1A, 0xFA, 0xF4}};
-
BSTR bstrLicense = ::SysAllocStringLen(pwchLicenseKey, sizeof(pwchLicenseKey)/sizeof(WCHAR));
-
LPCLASSFACTORY2 pClassFactory2;
-
if (SUCCEEDED(hr = CoGetClassObject(clsid, CLSCTX_SERVER, NULL, IID_IClassFactory2, (void**)&pClassFactory2)))
-
{
-
hr = pClassFactory2->CreateInstanceLic(NULL, NULL, IID_IDispatch, bstrLicense, (void**) &pObj);
-
pClassFactory2->Release();
-
if(FAILED(hr))
-
return;
-
-
wxAutomationObject *sp = new wxAutomationObject;
-
sp->SetDispatchPtr(pObj);
-
wxActiveXContainer* grid = new wxActiveXContainer(this,IID_IDispatch,pObj);
-
}
-
::SysFreeString(bstrLicense);
WCHAR pwchLicenseKey[] =
{
0x0043, 0x006F, 0x0070, 0x0079, 0x0072, 0x0069,
0x0067, 0x0068, 0x0074, 0x0020, 0x0028, 0x0063,
0x0029, 0x0020, 0x0031, 0x0039, 0x0039, 0x0034,
0x0020
};
HRESULT hr;
IDispatch* pObj;
CLSID clsid = { 0xDE52502E, 0xF837, 0x492B, { 0xAE, 0x14, 0xA1, 0x82, 0x53, 0x1A, 0xFA, 0xF4}};
BSTR bstrLicense = ::SysAllocStringLen(pwchLicenseKey, sizeof(pwchLicenseKey)/sizeof(WCHAR));
LPCLASSFACTORY2 pClassFactory2;
if (SUCCEEDED(hr = CoGetClassObject(clsid, CLSCTX_SERVER, NULL, IID_IClassFactory2, (void**)&pClassFactory2)))
{
hr = pClassFactory2->CreateInstanceLic(NULL, NULL, IID_IDispatch, bstrLicense, (void**) &pObj);
pClassFactory2->Release();
if(FAILED(hr))
return;
wxAutomationObject *sp = new wxAutomationObject;
sp->SetDispatchPtr(pObj);
wxActiveXContainer* grid = new wxActiveXContainer(this,IID_IDispatch,pObj);
}
::SysFreeString(bstrLicense);
如何取得一个控件的license key呢?可去微软网站下载一个工具(licreqst.exe)来查看。地址:
二 控件的使用
控件创建后,接下来就是通过获取属性,设置其属性,调用其方法来操作控件了。
VC中在对话框上添加控件时,为其关联控件类时,会自动将控件的属性和方法导出来,并生成一个类,非常方便。
但wxWidgets却无法如此,也没有提供一个工具通过ocx来导出一个类,只提供简单的操作接口。或许wxWidgets初衷就是跨平台的,而ActiveX却是MS专属,所以wxWidgets未提供较多操作,仅简单提供三类操作。
操作示例如下:
获取属性:wxVariant var = sp->GetProperty(wxT("Text")); //Text就是属性的名称
设置属性:sp->PutProperty(wxT("Col"), wxVariant((long)1));
调用方法:sp->CallMethod(wxT("SetText"), wxVariant((long)1),wxVariant((long)2),wxVariant((double)1));
如果只有一个ocx文件,如何知道它提供了哪些接口,以及该接口有哪些属性和方法。同样使用OLEVIEW.EXE来查看,这正是wxWidgets下使用COM比较繁琐之处。