我刚刚使用了一些COM,我知道VBA编程基于MS提供的COM组件。但我现在不知道如何使用c ++编写office,因为我不知道如何为我的c ++程序导入类型库或其他东西。这是我的代码来计算doc文件的单词,但是失败了,你能不能帮我纠正它,谢谢。
#include <objbase.h>
#include <stdio.h>
#include <assert.h>
#include <atlbase.h>
#include <atlconv.h>
#pragma comment(lib, "ole32.lib")
//0002095C-0000-0000-C000-000000000046
IID IID_Words = { 0x0002095C, 0x0000, 0x0000, {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} }
//#import "msword.olb" how???
IDispatch* GetWordsInterface(LPCWSTR wszFileName);
int main()
{
IDispatch *pDisp = NULL;
LPOLESTR pwszFuncName = L"Count";
DISPID dispID;
HRESULT hr;
pDisp = GetWordsInterface(L"D:\\test.doc");
assert( pDisp != NULL );
hr = pDisp->GetIDsOfNames( IID_NULL, &pwszFuncName, 1, LOCALE_SYSTEM_DEFAULT, &dispID );
assert( hr == S_OK );
VARIANT result;
hr = pDisp->Invoke(
dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET,
NULL, &result, NULL, NULL);
assert( hr == S_OK );
printf("the count of words is %ld \n", result.dblVal);
return 0;
}
IDispatch* GetWordsInterface(LPCWSTR pwszFileName)
{
HRESULT hr = S_FALSE;
IBindCtx *pbc = NULL;
IMoniker *pMk = NULL;
LPWSTR strClsid = NULL;
LPWSTR strDisplayName = NULL;
IUnknown *pUnk = NULL;
IDispatch *pWords = NULL;
CLSID clsid;
hr = CoInitialize(NULL);
assert( hr == S_OK );
hr = CreateBindCtx( 0, &pbc );
assert( pbc != NULL && hr == S_OK );
hr = CreateFileMoniker(pwszFileName, &pMk);
assert( hr == S_OK && pMk != NULL );
hr = pMk->GetClassID(&clsid);
assert( hr == S_OK );
StringFromCLSID(clsid, &strClsid);
wprintf(L"CLSID : %s\n", strClsid);
CoTaskMemFree(strClsid);
hr = pMk->GetDisplayName(pbc, NULL, &strDisplayName);
assert( hr == S_OK && strDisplayName != NULL );
CW2A ascii(strDisplayName);
printf("Display Name : %s\n", ascii);
//wprintf(L"Display Name : %s\n", strDisplayName);
CoTaskMemFree(strDisplayName);
hr = pMk->BindToObject(pbc, NULL, IID_IUnknown, (void**)&pUnk);
assert( hr == S_OK && pUnk != NULL );
hr = pUnk->QueryInterface(IID_Words, (void**)&pWords); // FAILED HERE
assert( hr == S_OK && pWords != NULL );
pUnk->Release();
pMk->Release();
return pWords;
}
答案 0 :(得分:0)
这是正确的版本,原始版本失败,因为Document对象不支持Words接口,但我设法通过Document._Document(接口)Words(属性)获取Words接口指针。
// excelmoniker.cpp :
//
#include "stdafx.h"
//0002095C-0000-0000-C000-000000000046
IID IID_Words = { 0x0002095C, 0x0000, 0x0000, {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} };
//_DocumentInterface
IID IID_innerDocument = { 0x0002096B, 0x0000, 0x0000, {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} };
IDispatch* GetWordsInterface(LPCWSTR wszFileName);
IDispatch* SubGetWordsInterface(IDispatch *pDoc);
int _tmain(int argc, _TCHAR* argv[])
{
IDispatch *pWords = NULL;
LPOLESTR pwszFuncName = L"Count";
DISPID dispID;
HRESULT hr;
DISPPARAMS dispParams = { NULL, NULL, 0, 0 };
VARIANT result;
hr = CoInitialize(NULL);
assert( hr == S_OK );
pWords = GetWordsInterface(L"D:\\test.doc");
assert( pWords != NULL );
hr = pWords->GetIDsOfNames( IID_NULL, &pwszFuncName, 1, LOCALE_SYSTEM_DEFAULT, &dispID );
assert( hr == S_OK );
hr = pWords->Invoke(
dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET,
&dispParams, &result, NULL, NULL);
assert( hr == S_OK );
printf("the count of words is %ld \n", result.dblVal);
assert( pWords->Release() == 0 );
CoUninitialize();
return 0;
}
IDispatch* GetWordsInterface(LPCWSTR pwszFileName)
{
HRESULT hr = S_FALSE;
IBindCtx *pbc = NULL;
IMoniker *pMk = NULL;
LPWSTR strClsid = NULL;
LPWSTR strDisplayName = NULL;
IDispatch *pDoc = NULL;
IDispatch *pWords = NULL;
CLSID clsid;
hr = CreateBindCtx( 0, &pbc );
assert( pbc != NULL && hr == S_OK );
//Test for the clsid for the doc
hr = GetClassFile(pwszFileName, &clsid);
assert( hr == S_OK );
StringFromCLSID(clsid, &strClsid);
wprintf(L"associated file CLSID : %s\n", strClsid);
CoTaskMemFree(strClsid);
hr = CreateFileMoniker(pwszFileName, &pMk);
assert( hr == S_OK && pMk != NULL );
hr = pMk->GetClassID(&clsid);
assert( hr == S_OK );
StringFromCLSID(clsid, &strClsid);
wprintf(L"CLSID : %s\n", strClsid);
CoTaskMemFree(strClsid);
hr = pMk->GetDisplayName(pbc, NULL, &strDisplayName);
assert( hr == S_OK && strDisplayName != NULL );
CW2A ascii(strDisplayName);
printf("Display Name : %s\n", ascii);
//wprintf(L"Display Name : %s\n", strDisplayName);
CoTaskMemFree(strDisplayName);
//Get _Document Interface pointer
hr = pMk->BindToObject(pbc, NULL, IID_innerDocument, (void**)&pDoc);
assert( hr == S_OK && pDoc != NULL );
//Get _Words interface pointer
pWords = SubGetWordsInterface(pDoc);
assert( pMk->Release() == 0 );
assert( pDoc->Release() == 0 );
assert( pbc->Release() == 0 );
return pWords;
}
IDispatch* SubGetWordsInterface(IDispatch* pDoc)
{
LPOLESTR pwszFuncName = L"Words";
DISPID dispID;
HRESULT hr;
DISPPARAMS dispParams = { NULL, NULL, 0, 0 };
VARIANT result;
memset(&result, 0, sizeof(VARIANT));
hr = pDoc->GetIDsOfNames( IID_NULL, &pwszFuncName, 1, LOCALE_SYSTEM_DEFAULT, &dispID );
assert( hr == S_OK );
hr = pDoc->Invoke( dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &dispParams, &result, NULL, NULL);
assert( hr == S_OK && result.vt == VT_DISPATCH && result.ppdispVal != NULL );
return (IDispatch*)result.ppdispVal;
}