首先定义几个函数,主要用于动态获取接口属性和方法:
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; } }