用COM接口调用Word,是否可以不用引入类型库??
引入类型库
 要考虑到引入的类型库位置问题,
 还有类型库的版本问题!!这些都跟具体安装Word有关,能否不引入类型库使用Word提供的COM接口直接进行操作???
  敬请高手指教!!!

解决方案 »

  1.   

    当然可以啦,把每个接口都看成Dispatch接口,慢慢调用吧......吼吼!!引入类型库是在编译期解决的问题,换个目录有什么关系?
      

  2.   

    // *************** Declare Some Variables ********************    // Variables that will be used and re-used in our calls
        DISPPARAMS dpNoArgs = {NULL, NULL, 0, 0};
        VARIANT vResult;
        OLECHAR FAR* szFunction;
        BSTR bstrTemp;    // IDispatch pointers for Word's objects
        IDispatch* pDispDocs;      //Documents collection
        IDispatch* pDispActiveDoc; //ActiveDocument object    // DISPIDs
        DISPID dispid_Docs;        //Documents property of Application 
                                   //object
        DISPID dispid_ActiveDoc;   //ActiveDocument property of 
                                   //Application object   
        DISPID dispid_Open;        //SaveAs method of the Document object
        DISPID dispid_SaveAs;      //SaveAs method of the Document object
        DISPID dispid_Quit;        //Quit method of the Application 
                                   //object    // ******************** Start Automation ***********************    //Initialize the COM libraries
        ::CoInitialize(NULL);    // Create an instance of the Word application and obtain the 
        // pointer to the application's IDispatch interface.
        CLSID clsid;
        CLSIDFromProgID(L"Word.Application", &clsid);      IUnknown* pUnk;
        HRESULT hr = ::CoCreateInstance( clsid, NULL, CLSCTX_SERVER,
                                         IID_IUnknown, (void**) &pUnk);
        IDispatch* pDispApp;
        hr = pUnk->QueryInterface(IID_IDispatch, (void**)&pDispApp);    // Get IDispatch* for the Documents collection object
        szFunction = OLESTR("Documents");
        hr = pDispApp->GetIDsOfNames (IID_NULL, &szFunction, 1, 
                                      LOCALE_USER_DEFAULT, &dispid_Docs);
        hr = pDispApp->Invoke (dispid_Docs, IID_NULL, 
                               LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, 
                               &dpNoArgs, &vResult, NULL, NULL);
        pDispDocs = vResult.pdispVal;    //Invoke the Open method
        VARIANT vArgsOpen[1];
        DISPPARAMS dpOpen;
        dpOpen.cArgs = 1;
        dpOpen.cNamedArgs = 0;
        dpOpen.rgvarg = vArgsOpen;
        szFunction = OLESTR("Open");
    if(m_DocPath=="")
    {
      MessageBox("请指定你要处理的Word文件!");
          OPENFILENAME ofn;
          TCHAR lpstrFilename[MAX_PATH] = "";
          ZeroMemory(&ofn, sizeof(ofn));
          ofn.lStructSize = sizeof(OPENFILENAME);
          ofn.hwndOwner = this->m_hWnd;
          ofn.lpstrFilter = "Word文件\0*.doc\0";
          ofn.nMaxFile = MAX_PATH;
          ofn.lpstrFile=lpstrFilename;
          if (GetOpenFileName(&ofn))
             m_DocPath=(CString)ofn.lpstrFile;
    }
    if(m_DocPath=="")
    {
            pDispApp->Release();
            pUnk->Release();
    ::CoUninitialize();
    return;
    }
        bstrTemp =m_DocPath.AllocSysString();
    vArgsOpen[0].vt=VT_BSTR;
    vArgsOpen[0].bstrVal=bstrTemp;
        hr = pDispDocs->GetIDsOfNames(IID_NULL, &szFunction, 1, 
                                      LOCALE_USER_DEFAULT, 
                                      &dispid_Open);
        hr = pDispDocs->Invoke(dispid_Open, IID_NULL, 
                                    LOCALE_USER_DEFAULT, DISPATCH_METHOD, 
                                    &dpOpen, NULL, NULL, NULL);    // Get IDispatch* for the ActiveDocument object
        szFunction = OLESTR("ActiveDocument");
        hr = pDispApp->GetIDsOfNames (IID_NULL, &szFunction, 1, 
                                      LOCALE_USER_DEFAULT, 
                                      &dispid_ActiveDoc);
        hr = pDispApp->Invoke (dispid_ActiveDoc, IID_NULL, 
                               LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, 
                               &dpNoArgs, &vResult, NULL, NULL);
        pDispActiveDoc = vResult.pdispVal;    //Set up the DISPPARAMS for the SaveAs method (11 arguments)
        VARIANT vArgsSaveAs[11];
        DISPPARAMS dpSaveAs;
        dpSaveAs.cArgs = 11;
        dpSaveAs.cNamedArgs = 0;
        dpSaveAs.rgvarg = vArgsSaveAs;    BSTR bstrEmptyString;
        bstrEmptyString = ::SysAllocString(OLESTR(""));    VARIANT vFalse;
        vFalse.vt = VT_BOOL;
        vFalse.boolVal = FALSE; if(m_TextPath=="")
    {
      MessageBox("请指定你要保存的文本文件!");
          OPENFILENAME ofn;
          TCHAR lpstrFilename[MAX_PATH] = "";
          ZeroMemory(&ofn, sizeof(ofn));
          ofn.lStructSize = sizeof(OPENFILENAME);
          ofn.hwndOwner = this->m_hWnd;
          ofn.lpstrFilter = "文本文件\0*.TXT\0";
          ofn.nMaxFile = MAX_PATH;
          ofn.lpstrFile=lpstrFilename;
          if (GetOpenFileName(&ofn))
             m_TextPath=(CString)ofn.lpstrFile;
    }
    if(m_TextPath=="")
    {
            pDispActiveDoc->Release();
            pDispDocs->Release();
            pDispApp->Release();
            pUnk->Release();
    ::CoUninitialize();
    return;
    }  CString tempt="c:\\LoveWay.txt";
    bstrTemp=tempt.AllocSysString();
        vArgsSaveAs[10].vt = VT_BSTR;         
        vArgsSaveAs[10].bstrVal = bstrTemp;        
        vArgsSaveAs[9].vt = VT_I4;            
        vArgsSaveAs[9].lVal = 3;                   
        vArgsSaveAs[8] = vFalse;                   
        vArgsSaveAs[7].vt = VT_BSTR;
        vArgsSaveAs[7].bstrVal = bstrEmptyString;  
        vArgsSaveAs[6].vt = VT_BOOL;      
        vArgsSaveAs[6].boolVal = TRUE;             
        vArgsSaveAs[5].vt = VT_BSTR;
        vArgsSaveAs[5].bstrVal = bstrEmptyString;  
        vArgsSaveAs[4] = vFalse;                  
        vArgsSaveAs[3] = vFalse;                   
        vArgsSaveAs[2] = vFalse;                
        vArgsSaveAs[1] = vFalse;                   
        vArgsSaveAs[0] = vFalse;                   
        //Invoke the SaveAs method
        szFunction = OLESTR("SaveAs");
        hr = pDispActiveDoc->GetIDsOfNames(IID_NULL, &szFunction, 1, 
                                      LOCALE_USER_DEFAULT, 
                                      &dispid_SaveAs);
        hr = pDispActiveDoc->Invoke(dispid_SaveAs, IID_NULL, 
                                    LOCALE_USER_DEFAULT, DISPATCH_METHOD, 
                                    &dpSaveAs, NULL, NULL, NULL);
        ::SysFreeString(bstrEmptyString);    //Invoke the Quit method
        szFunction = OLESTR("Quit");
        hr = pDispApp->GetIDsOfNames(IID_NULL, &szFunction, 1, 
                                     LOCALE_USER_DEFAULT, &dispid_Quit);
        hr = pDispApp->Invoke (dispid_Quit, IID_NULL, 
                               LOCALE_USER_DEFAULT, DISPATCH_METHOD,
                               &dpNoArgs, NULL, NULL, NULL);    //Clean-up
        ::SysFreeString(bstrTemp);
        pDispActiveDoc->Release();
        pDispDocs->Release();
        pDispApp->Release();
        pUnk->Release();    ::CoUninitialize(); CFile m_sf("c:\\LoveWay.txt",CFile::modeRead);
    CFile m_tf(m_TextPath,CFile::modeCreate|CFile::modeWrite);
    CString x[100];
    CString y[100];
    int xi=0;
    int yi=0;
    CString line;
    int linecount=1;
    CString num;
    char ch;
    while(m_sf.Read(&ch,1)==1)
    {
    if(ch=='\n')
    {
    int count=0;
    if(yi<xi)
    {
    count=yi;
    }
    else
    {
    count=xi;
    }
    CString t;
    if(count>=0)
    {
           t.Format("%d、%d个坐标:\r\n",linecount++,count);
       m_tf.Write(t.GetBuffer(t.GetLength()),t.GetLength());
       for(int i=0;i<count;i++)
       {
           m_tf.Write(x[xi-count+i].GetBuffer(x[xi-count+i].GetLength()),x[xi-count+i].GetLength());
       m_tf.Write(y[yi-count+i].GetBuffer(y[yi-count+i].GetLength()),y[yi-count+i].GetLength());
       CString enter="\r\n";
       m_tf.Write(enter.GetBuffer(2),2);
       }
       t="\r\n\r\n";
       m_tf.Write(t.GetBuffer(4),4);
    }
    xi=0;
    yi=0;
    num="";
    }
    else
    {
    if(ch>='0'&&ch<='9'||ch=='.')
    {
    CString t;
    t.Format("%c",ch);
    num+=t;
    }
    else if(num!="")
    {
        if(xi>yi)
        {
    y[yi]=num;
    yi++;
        }
    else
    {
    x[xi]=num+"  ";
    xi++;
    }
    num="";
         }
    }
    }
    m_sf.Close();
    m_tf.Close();
    ::ShellExecute(NULL,"open",m_TextPath,NULL,NULL,SW_SHOWNORMAL);
        return ;
      

  3.   

    如果必须引入,怎样区别开Word版本和引入时确定用户Word安装在哪个目录下,自动找到引入库的位置???
      

  4.   

    如果引入类型库,word安装的位置不会有关系.主要是得限定word的版本.
    上边那段代码的功能是,把word文档另存为txt文件,再读出内容,以另外的格式保存到另一个txt文件.m_TextPath是txt文件的文件名,m_DocPath是word文件名.弹出打开文件对话框和"::CoUninitialize();"以后的部分与你无关.另外,要#include <afxdisp.h>.你要对COM有所了解才行.
      

  5.   

    引入类型库只是编译期的事情,如果引入低版本的WORD库(如97)就可以保证在装有高版本的WORD(如97以上的版本)上正常使用。
      

  6.   

    不用引入也可以,你自已创建WORD服务对象吧
      

  7.   

    请问哪里能找到office自动化接口s的介绍文档sdk,
    我只找到了一些sample而不是详尽的接口说明文档。请问哪里有?
    谢了[email protected]
      

  8.   

    同意白菜的看法,可以想象一下,通过OLE对把WORD欠入到容器中的时候,需要容器特定的指定类型库了吗?当然是没有,不过他们是通过OLE协议进行通讯的,这就是要求双方必须有相同的约定,调用方和被调用方在接口的使用和定义上达到统一。但是如何获得CLSID的信息,还需要你在代码中或动态或静态(编译时设定)来实现。