首先定义几个函数,主要用于动态获取接口属性和方法:
STDMETHODIMP CTestntkoView::GetProperty(LPDISPATCH pDisp, LPOLESTR pszName, VARIANT* pvResult)
{
if (NULL == pDisp) return E_POINTER;
DISPID dwDispID;
DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
HRESULT hr = pDisp->GetIDsOfNames(IID_NULL, &pszName, 1, LOCALE_USER_DEFAULT, &dwDispID);
if(SUCCEEDED(hr)) {
hr = pDisp->Invoke(dwDispID, IID_NULL, LOCALE_USER_DEFAULT,
DISPATCH_METHOD | DISPATCH_PROPERTYGET, &dispparamsNoArgs,
//DISPATCH_PROPERTYGET, &dispparamsNoArgs,
pvResult, NULL, NULL);
}
return hr;
}
STDMETHODIMP CTestntkoView::CallMethod(LPDISPATCH pDisp, LPOLESTR pszName, VARIANT* pvResult, UINT cArgs, VARIANTARG* rgVarParams)
{
if (NULL == pDisp) return E_POINTER;
DISPID dwDispID;
DISPPARAMS dispparams = {NULL, NULL, 0, 0};
dispparams.rgvarg = rgVarParams;
dispparams.cArgs = cArgs;
HRESULT hr = pDisp->GetIDsOfNames(IID_NULL, &pszName, 1, LOCALE_USER_DEFAULT, &dwDispID);
if(SUCCEEDED(hr)) {
hr = pDisp->Invoke(dwDispID, IID_NULL, LOCALE_USER_DEFAULT,
DISPATCH_METHOD, &dispparams, pvResult, NULL, NULL);
if (FAILED(hr)) {
hr = pDisp->Invoke(dwDispID, IID_NULL, LOCALE_USER_DEFAULT,
DISPATCH_METHOD | DISPATCH_PROPERTYGET, &dispparams, pvResult, NULL, NULL);
}
}
return hr;
}
STDMETHODIMP CTestntkoView::GetPropertyWithParam(LPDISPATCH pDisp, LPOLESTR pszName, VARIANT* pvResult,UINT cArgs, VARIANTARG* rgVarParams)
{
if (NULL == pDisp) return E_POINTER;
DISPID dwDispID;
DISPPARAMS dispparams = {NULL, NULL, 0, 0};
dispparams.rgvarg = rgVarParams;
dispparams.cArgs = cArgs;
HRESULT hr = pDisp->GetIDsOfNames(IID_NULL, &pszName, 1, LOCALE_USER_DEFAULT, &dwDispID);
if(SUCCEEDED(hr))
{
hr = pDisp->Invoke(dwDispID, IID_NULL, LOCALE_USER_DEFAULT,
DISPATCH_METHOD| DISPATCH_PROPERTYGET, &dispparams, pvResult, NULL, NULL);
}
return hr;
}
这次主要是想实现三个功能:
- 定位指定书签名的书签
- 添加一个书签(当前选中位置插入书签)
- 遍历文档中的书签名
废话不多说,贴代码:
//转到test书签,新建书签,遍历书签(为了节省地方,三个写在一起)
void CTestntkoView::OnButtonbkmk()
{
// TODO: Add your command handler code here
VARIANT vResult;
VARIANT vArgs[5];
VARIANT vtIndex;
LPDISPATCH pdispDoc = NULL; //docuemt
LPDISPATCH pdispApp = NULL; //Application
LPDISPATCH pdispSel = NULL;
LPDISPATCH pdispBookMarks = NULL; //BookMarks
LPDISPATCH pdidpRang = NULL; //Range
LPDISPATCH pdidpBMCount = NULL; //BookMarks.Count
LPDISPATCH pdispBk = NULL; //BookMark
LONG bkCount = -1;
BSTR bkName;
char *pbkName;
HRESULT hr;
pdispDoc = m_ntkoocx.GetActiveDocument();
if(!pdispDoc)
{
AfxMessageBox("Unable to get document!\n");
return;
}
hr = GetProperty(pdispDoc,OLESTR("Application"),&vResult);
if(SUCCEEDED(hr) && vResult.pdispVal)
{
pdispApp = vResult.pdispVal;
}
if(!pdispApp)
{
AfxMessageBox("Unable to get Application!\n");
goto errorReturn;
}
hr = GetProperty(pdispDoc,OLESTR("Bookmarks"),&vResult);
if(SUCCEEDED(hr) && vResult.pdispVal)
{
pdispBookMarks = vResult.pdispVal;
}
if(!pdispBookMarks)
{
AfxMessageBox("Unable to get BookMarks!\n");
goto errorReturn;
}
if(!pdispApp)
{
AfxMessageBox("Unable to get BookMarks Count!\n");
goto errorReturn;
}
hr = GetProperty(pdispApp,OLESTR("Selection"),&vResult);
if(SUCCEEDED(hr) && vResult.pdispVal)
{
pdispSel = vResult.pdispVal;
}
if(!pdispSel)
{
AfxMessageBox("Unable to get Selection!\n");
goto errorReturn;
}
hr = GetProperty(pdispSel,OLESTR("Range"),&vResult);
if(SUCCEEDED(hr) && vResult.pdispVal)
{
pdidpRang = vResult.pdispVal;
}
if(!pdidpRang)
{
AfxMessageBox("Unable to get Range!\n");
goto errorReturn;
}
//ActiveDocument.Application.Selection.GoTo(-1,0,0,'test');
vArgs[3].vt = VT_I4;
vArgs[3].lVal = -1;
vArgs[2].vt = VT_I4;
vArgs[2].lVal = 0;
vArgs[1].vt = VT_I4;
vArgs[1].lVal = 0;
vArgs[0].vt = VT_BSTR;
vArgs[0].bstrVal = ::SysAllocString(OLESTR("test"));
hr = CallMethod(pdispSel,OLESTR("Goto"),NULL,4,&vArgs[0]);
VariantClear(&vArgs[0]); //需要释放
//ActiveDocument.Bookmarks.Add(BookMarkName,saverange);
VARIANT vtAdd[2];
vtAdd[1].vt = VT_BSTR;
vtAdd[1].bstrVal = ::SysAllocString(OLESTR("wql"));
vtAdd[0].vt = VT_DISPATCH;
vtAdd[0].pdispVal = pdidpRang;
hr = CallMethod(pdispBookMarks,OLESTR("Add"),NULL,2,&vtAdd[0]);
VariantClear(&vtAdd[0]);
/*var doc =控件对象.ActiveDocument;
var bks = doc.Bookmarks;
var bksCount = bks.Count;
for(i=1;i<=bksCount ;i++){
alert(bks(i).Name);
}
ActiveDocumet.BookMarks.Count
*/
hr = GetProperty(pdispBookMarks,OLESTR("Count"),&vResult);
if(SUCCEEDED(hr) && vResult.lVal)
{
bkCount = vResult.lVal;
}
if(bkCoun < 0)
{
AfxMessageBox("Unable to get BoookMarks Count!\n");
goto errorReturn;
}
for (LONG i=1; i<=bkCount; i++)
{
vtIndex.vt = VT_I4;
vtIndex.lVal = i;
hr = GetPropertyWithParam(pdispBookMarks,OLESTR("Item"),&vResult,1,&vtIndex);
if(SUCCEEDED(hr) && vResult.pdispVal)
{
pdispBk = vResult.pdispVal;
}
if(!pdispBk)
{
AfxMessageBox("Unable to get BookMark!\n");
goto errorReturn;
}
hr = GetProperty(pdispBk,OLESTR("Name"),&vResult);
if(SUCCEEDED(hr) && vResult.bstrVal)
{
bkName = vResult.bstrVal;
}
pbkName = _com_util::ConvertBSTRToString(bkName); //转换下
MessageBox(pbkName);
}
VariantClear(&vtIndex);
errorReturn: //Release
if(pdispSel)
{
pdispSel->Release();
pdispSel = NULL;
}
if(pdispApp)
{
pdispApp->Release();
pdispApp = NULL;
}
if(pdispDoc)
{
pdispDoc->Release();
pdispDoc = NULL;
}
if (pdispBookMarks)
{
pdispBookMarks->Release();
pdispBookMarks = NULL;
}
if (pdispBk)
{
pdispBk->Release();
pdispBk = NULL;
}
}