2012-05-17 72 views
-1

我剛剛介紹了一點COM,並且我知道VBA編程基於MS提供的COM組件。但我現在不知道如何用C++編程辦公室,因爲我不知道如何導入類型庫或用於我的C++程序的東西。這裏是我的代碼來計算文檔文件的話,但失敗了,你能幫我糾正它,謝謝。如何使用C++計算ms word 97-2003 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

這裏是正確的版本,該版本原單失敗,因爲文檔對象不支持接口的話,但我設法通過Document._Document(接口)字(屬性)來獲取詞接口指針。

// 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; 
} 
相關問題