环境:xp sp3,vc2003,wps2009
stdafx.h
#import "kso10.dll" named_guids, rename_namespace("KSO")
#import "wpscore.dll" rename_namespace("WPS")
// wps.cpp : 定义应用程序的类行为。
BOOL CwpsApp::InitInstance()//添加对com 的支持
{
....
if( FAILED(::CoInitialize(NULL)))
{
AfxMessageBox("wps FAILED");
return FALSE;
}
...
}
// wpsDlg.h : 头文件
public:
afx_msg void OnBnClickedOk();
afx_msg void OnBnClickedCancel();
WPS::_ApplicationPtr g_app;
void InitDocStatics2();
IDispatch* m_pIDisp;
void InitDocStatics();
private:
HRESULT GetProperty(IDispatch *pDisp, LPCOLESTR lpsz, VARIANT *pVar);
HRESULT PutProperty(IDispatch *pDisp, LPCOLESTR lpsz, VARIANT *pVar);
HRESULT Invoke0(IDispatch *pDisp, LPCOLESTR lpszName, VARIANT *pvarRet);
HRESULT InvokeN(IDispatch *pDisp, LPCOLESTR lpszName, VARIANT *varParams, int nParams, VARIANT *pvarRet);
// wpsDlg.cpp : 实现文件
void CwpsDlg::OnBnClickedOk()
{
// TODO: 在此添加控件通知处理程序代码
InitDocStatics();
//InitDocStatics2();
//OnOK();
}
void CwpsDlg::OnBnClickedCancel()
{
// TODO: 在此添加控件通知处理程序代码
if(g_app!=NULL)
g_app->Quit();
//CoUninitialize();
OnCancel();
}
void CwpsDlg::InitDocStatics()
{
USES_CONVERSION;
CLSID clsid = {0};
// 获取WPS文字的 CLSID
HRESULT hr = CLSIDFromProgID(L"wps.application", &clsid);
if(FAILED(hr))
return;
// 通过CLSID启动WPS
hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IDispatch, (void**)&m_pIDisp);
if(FAILED(hr))
return;
// 获取Documents集合
VARIANT varDocuments = {0};
GetProperty(m_pIDisp, L"Documents", &varDocuments);
VARIANT varDocument = {0};
CComVariant varParams[15];
varParams[14-0].vt = VT_BSTR;
varParams[14-0].bstrVal = ::SysAllocString(A2OLE("e:\\1011.doc"));
varParams[14-1].vt = VT_BOOL; // 确认转换
varParams[14-1].boolVal = VARIANT_TRUE;
varParams[14-2].vt = VT_BOOL; // 只读
varParams[14-2].boolVal = VARIANT_TRUE;
varParams[14-3].vt = VT_BOOL; // 添加到最近文件中
varParams[14-3].boolVal = VARIANT_TRUE;
varParams[14-4].vt = VT_BSTR; // 文档口令.
varParams[14-4].bstrVal = ::SysAllocString(A2OLE(""));
varParams[14-5].vt = VT_BSTR; // 模板口令.
varParams[14-5].bstrVal = ::SysAllocString(A2OLE(""));
varParams[14-6].vt = VT_BOOL; // 恢复原状.
varParams[14-6].boolVal = VARIANT_TRUE;
varParams[14-7].vt = VT_BSTR; // 写文档口令.
varParams[14-7].bstrVal = ::SysAllocString(A2OLE(""));
varParams[14-8].vt = VT_BSTR; // 写模板口令.
varParams[14-8].bstrVal = ::SysAllocString(A2OLE(""));
varParams[14-9].vt = VT_I4; // 格式. //
varParams[14-9].lVal = 0;
varParams[14-10].vt = VT_I4; // // 编码
varParams[14-10].lVal = 50001; // KSO::ksoEncodingAutoDetect, // 编码
varParams[14-11].vt = VT_BOOL; // 可见
varParams[14-11].boolVal = VARIANT_TRUE;
varParams[14-12].vt = VT_BOOL; // 打开并修复
varParams[14-12].boolVal = VARIANT_TRUE;
varParams[14-13].vt = VT_I4; // DocumentDirection wdDocumentDirection LeftToRight
varParams[14-13].lVal = 0;
varParams[14-14].vt = VT_BOOL; // 无编码对话框
varParams[14-14].boolVal = VARIANT_TRUE;
// 插入图片
hr = InvokeN(varDocuments.pdispVal, L"Open", varParams, 15, &varDocument);
// 使WPS可见
VARIANT var = {0};
var.vt = VT_BOOL;
var.boolVal = VARIANT_TRUE;
PutProperty(m_pIDisp, L"Visible", &var);
return;
//// 在Documents中新建一篇文档
//VARIANT varDocument = {0};
//Invoke0(varDocuments.pdispVal, L"Add", &varDocument);
//// 获取Selection对象
//VARIANT varSelection = {0};
//GetProperty(m_pIDisp, L"Selection", &varSelection);
//// 获取Selection的Range对象
//VARIANT varRange = {0};
//GetProperty(varSelection.pdispVal, L"Range", &varRange);
//// 获取ParagraphFormat对象,以便设置对齐方式
//VARIANT varParagraphFormat = {0};
//GetProperty(varSelection.pdispVal, L"ParagraphFormat", &varParagraphFormat);
//// 设置文字居中对齐
//var.vt = VT_I4;
//var.lVal = 1;
//PutProperty(varParagraphFormat.pdispVal, L"Alignment", &var);
//// 插入文字,该文字是居中显示的
//var.vt = VT_BSTR;
//var.bstrVal = ::SysAllocString(A2OLE("hello,world\n"));
//PutProperty(varRange.pdispVal, L"Text", &var);
//// 获取Shapes集合对象
//VARIANT varShapes = {0};
//GetProperty(varDocument.pdispVal, L"Shapes", &varShapes);
//// 设置参数,该参数将传入Shapes的AddPicture方法中
//CComVariant varParams[8];
//varParams[0].vt = VT_BSTR; // Anchor
//varParams[0].bstrVal = ::SysAllocString(A2OLE(""));
//varParams[1].vt = VT_I4; // Height
//varParams[1].lVal = 60;
//varParams[2].vt = VT_I4; // Width
//varParams[2].lVal = 148;
//varParams[3].vt = VT_I4; // Top
//varParams[3].lVal = 50;
//varParams[4].vt = VT_I4; // Left
//varParams[4].lVal = 100;
//varParams[5].vt = VT_BOOL; // SaveWithDocument
//varParams[5].boolVal = VARIANT_TRUE;
//varParams[6].vt = VT_BOOL; // LinkToFile
//varParams[6].boolVal = VARIANT_FALSE;
//varParams[7].vt = VT_BSTR; // FileName
//varParams[7].bstrVal = ::SysAllocString(A2OLE("http://img.kingsoft.com/publish/kingsoft/images/gb/sy/logo.gif"));
//// 插入图片
//InvokeN(varShapes.pdispVal, L"AddPicture", varParams, 8, &var);
return ;
}
// 执行没有参数的方法
HRESULT CwpsDlg::Invoke0(IDispatch *pDisp, LPCOLESTR lpszName, VARIANT *pvarRet)
{
if(pDisp == NULL)
return E_FAIL;
HRESULT hr;
DISPID dispid;
hr = pDisp->GetIDsOfNames(IID_NULL, (LPOLESTR*)&lpszName, 1, LOCALE_USER_DEFAULT, &dispid);
if (SUCCEEDED(hr))
{
DISPPARAMS dispparams = { NULL, NULL, 0, 0};
return pDisp->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, pvarRet, NULL, NULL);
}
return hr;
}
// 执行含有N个参数的方法
HRESULT CwpsDlg::InvokeN(IDispatch *pDisp, LPCOLESTR lpszName, VARIANT *varParams, int nParams, VARIANT *pvarRet)
{
if(pDisp == NULL)
return E_FAIL;
HRESULT hr;
DISPID dispid;
hr = pDisp->GetIDsOfNames(IID_NULL, (LPOLESTR*)&lpszName, 1, LOCALE_USER_DEFAULT, &dispid);
if (SUCCEEDED(hr))
{
DISPPARAMS dispparams = { varParams, NULL, nParams, 0};
return pDisp->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, pvarRet, NULL, NULL);
}
return hr;
}
// 获取属性值
HRESULT CwpsDlg::GetProperty(IDispatch *pDisp, LPCOLESTR lpsz, VARIANT *pVar)
{
if(pDisp == NULL)
return E_FAIL;
DISPID dwDispID;
pDisp->GetIDsOfNames(IID_NULL, (LPOLESTR*)&lpsz, 1, LOCALE_USER_DEFAULT, &dwDispID);
DISPPARAMS dispparams = {NULL, NULL, 0, 0};
return pDisp->Invoke(dwDispID, IID_NULL,
LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET,
&dispparams, pVar, NULL, NULL);
}
// 设置属性值
HRESULT CwpsDlg::PutProperty(IDispatch *pDisp, LPCOLESTR lpsz, VARIANT *pVar)
{
if(pDisp == NULL)
return E_FAIL;
DISPID dwDispID;
pDisp->GetIDsOfNames(IID_NULL, (LPOLESTR*)&lpsz, 1, LOCALE_USER_DEFAULT, &dwDispID);
DISPPARAMS dispparams = {NULL, NULL, 1, 1};
dispparams.rgvarg = pVar;
DISPID dispidPut = DISPID_PROPERTYPUT;
dispparams.rgdispidNamedArgs = &dispidPut;
if (pVar->vt == VT_UNKNOWN || pVar->vt == VT_DISPATCH ||
(pVar->vt & VT_ARRAY) || (pVar->vt & VT_BYREF))
{
HRESULT hr = pDisp->Invoke(dwDispID, IID_NULL,
LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUTREF,
&dispparams, NULL, NULL, NULL);
if (SUCCEEDED(hr))
return hr;
}
return pDisp->Invoke(dwDispID, IID_NULL,
LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT,
&dispparams, NULL, NULL, NULL);
}
void CwpsDlg::InitDocStatics2()
{
CLSID clsid;
HRESULT hr;
hr=::CLSIDFromProgID(L"WPS.Application",&clsid); //通过ProgID取得CLSID
try
{
g_app.CreateInstance(__uuidof(WPS::Application )) ;
}
catch (...)
{
AfxMessageBox("啊呀不是没装wps吧?");
return;
}
WPS::DocumentsPtr docs =g_app->GetDocuments();
COleVariant vOpt((long)DISP_E_PARAMNOTFOUND, VT_ERROR);//类型转换
CString sWord="e:\\1011.doc";
WPS::_DocumentPtr m_pDocument;
_bstr_t sNull;
try
{
m_pDocument = docs->Open(
_bstr_t(sWord),
VARIANT_FALSE, // 确认转换
VARIANT_TRUE, // 只读
VARIANT_FALSE, // 添加到最近文件中
sNull, // 文档口令.
sNull, // 模板口令.
VARIANT_FALSE, // 恢复原状.
sNull, // 写文档口令.
sNull, // 写模板口令.
0, // 格式.
KSO::ksoEncodingAutoDetect, // 编码
VARIANT_TRUE, // 可见
VARIANT_FALSE, // 打开并修复
0, // DocumentDirection wdDocumentDirection LeftToRight
VARIANT_FALSE // 无编码对话框
);
}
catch(_com_error)
{
g_app->Quit(&vtMissing,&vtMissing,&vtMissing);
return ;
}
g_app->put_Visible(VARIANT_TRUE);
WPS::_DocumentPtr lpWord=g_app->GetActiveDocument();
}
ps:invoke调用documents的Open方法的时候,开始数组列表和Open函数参数一直,但是调用后报"类型不匹配"错误,然后百度,原来
DISPPARAMS的rgvargs参数存储顺序应该与函数调用顺序相反,改正后就好了
参考:http://topic.csdn.net/t/20030814/22/2147820.html
http://read.pudn.com/downloads159/sourcecode/windows/715596/VC_WPSStartKit/ControlWPS.cpp__.htm
http://read.pudn.com/downloads159/sourcecode/windows/715596/VC_WPSStartKit/ControlWPS.h__.htm