2012-05-17 3 views
-1

저는 약간의 COM만을 배웠고 VBA 프로그래밍은 MS에서 제공하는 COM 구성 요소를 기반으로한다는 것을 알고 있습니다. 하지만 C++을 사용하여 Office를 프로그래밍하는 방법을 알지 못합니다. 형식 라이브러리를 가져 오는 방법이나 C++ 프로그램을 가져 오는 방법을 모르기 때문입니다. 다음은 doc 파일의 단어 수를 집계하는 코드이지만 실패했습니다. 수정 해 주시면 감사하겠습니다. 감사합니다.C++을 사용하여 ms 단어 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

가 여기에 올바른 버전, 문서 객체 단어 인터페이스를 지원하지 않기 때문에 orginal 한 버전은 실패했지만 나는 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; 
}