精华内容
下载资源
问答
  • MFC自动化操作ExceL

    2015-09-15 14:44:25
    MFC自动化操作Excel,有基本的函数介绍。
  • 使用MFC自动化操作Excel文档,对excel所包含的类进行详解,比较全面系统的总结了其中各类的用法
  • 16.MFC实现IDispatch自动化接口

    千次阅读 2016-07-30 19:58:33
    本文演示了通用的不依赖类型库,自己查表实现IDispatch接口和借助MFC的分发映射表DISPATCH_MAP实现IDispatch接口的两种方法,提供了演示代码,据此可掌握不依赖类型库实现COM IDispatch接口的方法。

    前文叙述了IDispatch接口的原理,本文先讲MFC的实现细节,下文讲ATL的实现细节。

    1.通用方法

    MFC不使用类型库,这里先讲不用类型库实现IDispatch,此时一般实现GetIDsOfNames和Invoke函数。这里使用MFC实现,实际上在ATL中也可以使用。

    按照之前讲的通用接口的编写方法,定义嵌入类和工厂类声明如下,嵌入类实现了IDispatch接口。

    	//接口映射表
    	BEGIN_INTERFACE_PART(Cat, IDispatch)
    		INIT_INTERFACE_PART(CAnimalObject, Cat)
    
    		virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount( 
    		/* [out] */ __RPC__out UINT *pctinfo);
    
    		virtual HRESULT STDMETHODCALLTYPE GetTypeInfo( 
    			/* [in] */ UINT iTInfo,
    			/* [in] */ LCID lcid,
    			/* [out] */ __RPC__deref_out_opt ITypeInfo **ppTInfo);
    
    		virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames( 
    			/* [in] */ __RPC__in REFIID riid,
    			/* [size_is][in] */ __RPC__in_ecount_full(cNames) LPOLESTR *rgszNames,
    			/* [range][in] */ UINT cNames,
    			/* [in] */ LCID lcid,
    			/* [size_is][out] */ __RPC__out_ecount_full(cNames) DISPID *rgDispId);
    
    		virtual /* [local] */ HRESULT STDMETHODCALLTYPE Invoke( 
    			/* [in] */ DISPID dispIdMember,
    			/* [in] */ REFIID riid,
    			/* [in] */ LCID lcid,
    			/* [in] */ WORD wFlags,
    			/* [out][in] */ DISPPARAMS *pDispParams,
    			/* [out] */ VARIANT *pVarResult,
    			/* [out] */ EXCEPINFO *pExcepInfo,
    			/* [out] */ UINT *puArgErr);
    	END_INTERFACE_PART_STATIC(Cat)
    
    	DECLARE_INTERFACE_MAP()

    建立接口映射表如下

    //接口映射表
    BEGIN_INTERFACE_MAP(CAnimalObject, CCmdTarget)
    	INTERFACE_PART(CAnimalObject, IID_IDispatch, Cat)
    END_INTERFACE_MAP()


    为了不依赖类型库实现IDispatch接口,建立名字和DispID如下

    //建立Dispatch表
    map<CString, UINT> g_DispMap;
    
    CAnimalObject::CAnimalObject(void)
    {
    	g_DispMap[L"SayHello1"] = DISP_ID_SAYHELLO1;
    	g_DispMap[L"SayHello2"] = DISP_ID_SAYHELLO2;
    }


    由于没有类型库,则GetTypeInfoCount和GetTypeInfo不用实现,具体如下:

    HRESULT STDMETHODCALLTYPE CAnimalObject::XCat::GetTypeInfoCount( 
    	/* [out] */ __RPC__out UINT *pctinfo)
    {
    	*pctinfo = 0;	//没有类型库
    	return S_OK;
    }
    
    HRESULT STDMETHODCALLTYPE CAnimalObject::XCat::GetTypeInfo( 
    	/* [in] */ UINT iTInfo,
    	/* [in] */ LCID lcid,
    	/* [out] */ __RPC__deref_out_opt ITypeInfo **ppTInfo)
    {
    	*ppTInfo = NULL;
    	return E_NOTIMPL;
    }
    


    GetIDsOfNames的实现只需要查表即可,如下:

    HRESULT STDMETHODCALLTYPE CAnimalObject::XCat::GetIDsOfNames( 
    	/* [in] */ __RPC__in REFIID riid,
    	/* [size_is][in] */ __RPC__in_ecount_full(cNames) LPOLESTR *rgszNames,
    	/* [range][in] */ UINT cNames,
    	/* [in] */ LCID lcid,
    	/* [size_is][out] */ __RPC__out_ecount_full(cNames) DISPID *rgDispId)
    {
    	
    	for (UINT i=0; i<cNames; i++)
    	{
    		map<CString, UINT>::iterator iter = g_DispMap.find(rgszNames[i]);
    		if ( g_DispMap.end() != iter )
    		{
    			rgDispId[i] = iter->second;
    		}
    		else
    		{
    			rgDispId[i] = DISPID_UNKNOWN;
    		}
    	}
    
    	return S_OK;
    }

    这里可能存在一次性传入多个Name的情况,此时cNames标示传入的name个数,rgszNames和rgDispID均为数组。


    Invoke根据传入的分发ID,调用不同的逻辑:

    HRESULT STDMETHODCALLTYPE CAnimalObject::XCat::Invoke( 
    	/* [in] */ DISPID dispIdMember,
    	/* [in] */ REFIID riid,
    	/* [in] */ LCID lcid,
    	/* [in] */ WORD wFlags,
    	/* [out][in] */ DISPPARAMS *pDispParams,
    	/* [out] */ VARIANT *pVarResult,
    	/* [out] */ EXCEPINFO *pExcepInfo,
    	/* [out] */ UINT *puArgErr)
    {
    	if (0==dispIdMember ||
    		(dispIdMember!=DISP_ID_SAYHELLO1 && dispIdMember!=DISP_ID_SAYHELLO2) ||
    		0==(DISPATCH_METHOD&wFlags))
    	{
    		return E_NOTIMPL;
    	}
    
    	if (pVarResult)
    	{
    		CComVariant var(true);
    		*pVarResult = var;
    	}
    
    	USES_CONVERSION;
    
    	switch (dispIdMember)
    	{
    	case DISP_ID_SAYHELLO1:
    		if (pDispParams &&							//参数数组有效
    			pDispParams->cArgs==1 &&				//参数个数为1
    			pDispParams->rgvarg[0].vt==VT_BSTR &&	//参数类型满足
    			pDispParams->rgvarg[0].bstrVal)			//参数值有效
    		{
    			 CString strVal(OLE2T(pDispParams->rgvarg[0].bstrVal));
    			 wcout << L"猫猫说我的名字叫:" << strVal.GetBuffer(0) << endl;
    		}
    		break;
    
    	case DISP_ID_SAYHELLO2:
    		if (pDispParams &&							//参数数组有效
    			pDispParams->cArgs==1 &&				//参数个数为1
    			pDispParams->rgvarg[0].vt==VT_I4 &&		//参数类型满足
    			pDispParams->rgvarg[0].intVal)			//参数值有效
    		{
    			wcout << L"猫猫说我的年龄是:" << pDispParams->rgvarg[0].intVal << endl;
    		}
    		break;
    	}
    
    	return S_OK;
    }

    2.标准MFC的实现方法

    MFC中我们已经见到了各种查表,如消息映射表MESSAGE_MAP,接口映射表INTERFACE|_MAP等。同样为了支持IDISPATC接口,MFC做了一套分发映射表DISPATCH_MAP,和之前的使用方法一样。

    另外,MFC中的CCmdTarget默认实现了IDispatch接口,只要我们在子类构造函数调用EnableAutomation开启自动化支持即可。此时不用再单独添加接口映射表,MFC已默认将IDispatch接口加到接口查询表中。


    MFC这套机制非常简单,如下:

    声明分发映射表:

    	//分派映射表
    	DECLARE_DISPATCH_MAP()
    实现分发映射表:

    //分配映射表
    BEGIN_DISPATCH_MAP(CAnimalObject, CCmdTarget)
    	DISP_FUNCTION_ID(CAnimalObject, "SayHello1", DISP_ID_SAYHELLO1, SayHello1, VT_I4, VTS_BSTR)// "SayHello1"不要加L前缀
    	DISP_FUNCTION_ID(CAnimalObject, "SayHello2", DISP_ID_SAYHELLO2, SayHello2, VT_I4, VTS_I4)
    END_DISPATCH_MAP()

    DISP_FUNCTION_ID宏参数分别为当前类名,函数名,分发ID,函数指针,函数返回值,函数参数


    对应的调用函数逻辑实现如下:

    BOOL CAnimalObject::SayHello1( BSTR szWord )
    {
    	USES_CONVERSION;
    	CString strWord(OLE2CW(szWord));
    
    	wcout << L"猫猫2的名字:" << strWord.GetBuffer(0) << endl;
    	return TRUE;
    }
    
    BOOL CAnimalObject::SayHello2( int nAge )
    {
    	wcout << L"猫猫2的年龄:" << nAge << endl;
    	return TRUE;
    }

    3.调用IDispatch接口

    默认的IDispatch接口调用Invoke函数时参数太繁琐,MFC提供COleDispatchDriver类来辅助操作,如下:

    		//初始化COM库
    		if (CoInitialize(NULL) != S_OK)
    		{
    			wcout << L"Fail to Initialize COM" << endl;
    			return -1;
    		}
    
    		//自动化调用
    		COleDispatchDriver d;
    		if (d.CreateDispatch(CLSID_AnimalObject))
    		{
    			BYTE params1[] = {VTS_BSTR};
    			BYTE params2[] = {VTS_I4};
    			BOOL bRet;
    
    			d.InvokeHelper(DISP_ID_SAYHELLO1, DISPATCH_METHOD, VT_I4, (LPVOID)&bRet, params1, L"maomao");
    			d.InvokeHelper(DISP_ID_SAYHELLO2, DISPATCH_METHOD, VT_I4, (LPVOID)&bRet, params2, 20);
    
    			d.ReleaseDispatch();
    		}	
    
    		::CoUninitialize();

    InvokeHelper参数依次为分发ID,方法Flag,返回类型,返回值,函数参数类型数组,函数参数。


    IDispatch通用实现方法下载链接

    IDispatch MFC实现方法下载链接

    原创,转载请注明来自http://blog.csdn.net/wenzhou1219

    展开全文
  • 一个在MFC环境下使用代码调用Microsoft office excel 2003 的例子,并附带两个网页形式的详细的教程包含在项目文件夹中。
  • 采用MFC技术实现自动化组件--带用户界面
  • 在VC6.0中使用MFC实现Excel自动化:写入数据绘制图表 环境说明: Windows XP VC++ 6.0 Excel 2003 详细过程: http://zhangliancheng.com
  • 本文演示如何嵌入并自动化 Microsoft Office Word 文档的 MFC 单文档界面应用程序中。相同的方法适用于任何 Word 版本。不同之处在于不是什么版本的 Word 创建的文档中,但相反,哪个版本的 Word 中使用的自动化过程...
    概要
    使用 OLE 嵌入,其他应用程序文档中嵌入的文档可以修改自动化通过双击嵌入的文档以将其激活"编辑"或"打开"中模式。

    本文演示如何嵌入并自动化 Microsoft Office Word 文档的 MFC 单文档界面应用程序中。相同的方法适用于任何 Word 版本。不同之处在于不是什么版本的 Word 创建的文档中,但相反,哪个版本的 Word 中使用的自动化过程。

    Word 类型库如下所示︰
    • 对于 Microsoft Office Word 2007 中,类型库是 Msword.olb,且位于"C:\Program Files\Microsoft Office\Office12"文件夹中。
    • 对于 Microsoft Office Word 2003,类型库是 Msword.olb,位于"C:\Program 数值 Office\Office11"文件夹中。
    • 对于 Microsoft Word 2002,类型库是 Msword.olb,且位于"C:\Program Files\Microsoft Office\Office10"文件夹中。
    • Microsoft Word 2000 中,类型库是 Msword9.olb 和位于"C:\Program 该网络"文件夹中。
    • 对于 Microsoft Word 97 中,类型库是 Msword8.olb,位于"C:\Program 该网络"文件夹中。
    更多信息

    创建示例项目

    1. 使用 Microsoft Visual Studio,启动一个名为EmbedWord的新 MFC 应用程序向导 (exe) 项目。在应用程序向导,在步骤 1 中选择"单文档"作为应用程序类型,选择"容器"的步骤 3 中的复合文档支持类型。您可以接受其他所有默认设置。
    2. 请按 CTRL + W 组合键以调用类向导。选择自动化选项单击添加类按钮,然后选择从类型库浏览以查找 Word 类型库。
    3. 确认类对话框中,选择所有列出的成员并单击确定
    4. 再次单击确定以关闭类向导。
    5. 修改 EmbedWordView.cpp,使它包括类向导从 Word 类型库生成的头文件。

      Word 2002 或更高版本的版本的 Word。
      
      #include "msword.h"
      
      Word 97 或 Word 2000。
      
      #include "msword9.h"
      	
    6. CEmbedWordView::OnInsertObject()中的代码替换为以下︰
      
      void CEmbedWordView::OnInsertObject()
      {
         EmbedAutomateWord();
      }
      					
    7. CEmbedWordView::EmbedAutomateWord()成员函数添加到 EmbedWordView.cpp 中︰
      
      void CEmbedWordView::EmbedAutomateWord()
      {
      
           /*******************************************************************
            This method encapsulates the process of embedding a Word document
            in a View object and automating that document to add text.
           *******************************************************************/ 
      
          //Change the cursor so the user knows something exciting is going
               //on.
               BeginWaitCursor();
      
               CEmbedWordCntrItem* pItem = NULL;
               TRY
               {
                  //Get the document associated with this view, and be sure it's
                  //valid.
                  CEmbedWordDoc* pDoc = GetDocument();
                  ASSERT_VALID(pDoc);
      
                  //Create a new item associated with this document, and be sure
                  //it's valid.
                  pItem = new CEmbedWordCntrItem(pDoc);
                  ASSERT_VALID(pItem);
      
                  // Get Class ID for Word document.
                  // This is used in creation.
      
                  CLSID clsid;
                  if(FAILED(::CLSIDFromProgID(L"Word.Document",&clsid)))
                     //Any exception will do. You just need to break out of the
                     //TRY statement.
                     AfxThrowMemoryException();
      
                  // Create the Word embedded item.
                  if(!pItem->CreateNewItem(clsid))
                     //Any exception will do. You just need to break out of the
                     //TRY statement.
                     AfxThrowMemoryException();
      
                  //Make sure the new CContainerItem is valid.
                  ASSERT_VALID(pItem);
      
                  // Launch the server to edit the item.
                  pItem->DoVerb(OLEIVERB_SHOW, this);
      
                  // As an arbitrary user interface design, this sets the
                  // selection to the last item inserted.
                  m_pSelection = pItem;   // set selection to last inserted item
                  pDoc->UpdateAllViews(NULL);
      
                  //Query for the dispatch pointer for the embedded object. In
                  //this case, this is the Word document.
                  LPDISPATCH lpDisp;
                  lpDisp = pItem->GetIDispatch();
      
                  //Add text to the first line of the document
                  _Document doc;
                  Selection selection;
                  _Application app;
                  PageSetup pagesetup;
      
                  _Font font;
      
                  //set _Document doc to use lpDisp, the IDispatch* of the
                  //actual document.
                  doc.AttachDispatch(lpDisp);
                  
                  //Then get the document's application object reference.
                  app = doc.GetApplication();
      
                  // From there, get a Selection object for the insertion point.
                  selection = app.GetSelection();
                  selection.SetText(
                        "This is a good place to say \"Hello World\"");
      
                  // Automate setting the values for various properties.
                  font = selection.GetFont();
                  font.SetName("Tahoma");
                  font.SetSize(16);
                  selection.SetFont(font);
               }
      
               //Here, you need to do clean up if something went wrong.
               CATCH(CException, e)
               {
                  if (pItem != NULL)
                  {
                     ASSERT_VALID(pItem);
                     pItem->Delete();
                  }
                  AfxMessageBox(IDP_FAILED_TO_CREATE);
               }
               END_CATCH
      
               //Set the cursor back to normal so the user knows exciting stuff
               //is no longer happening.
               EndWaitCursor();
      }
      
    8. 打开 EmbedWordView.h,并将这一新方法的声明添加到"实现"区域︰
      
         void EmbedAutomateWord();
      
    9. 打开 CntrItem.cpp 并添加一个新的CEmbedWordCntrItem::GetIDispatch成员函数︰
      
      LPDISPATCH CEmbedWordCntrItem::GetIDispatch()
      {	
      
           /****************************************************************
            This method returns the IDispatch* for the application linked to 
            this container.	
           *****************************************************************/ 
      
               //The this and m_lpObject pointers must be valid for this function
               //to work correctly. The m_lpObject is the IUnknown pointer to
               // this object.
               ASSERT_VALID(this);
               ASSERT(m_lpObject != NULL);
      
      
               LPUNKNOWN lpUnk = m_lpObject;
      
               //The embedded application must be running in order for the rest
               //of the function to work.
               Run();
      
               //QI for the IOleLink interface of m_lpObject.
               LPOLELINK lpOleLink = NULL;
               if (m_lpObject->QueryInterface(IID_IOleLink,
                  (LPVOID FAR*)&lpOleLink) == NOERROR)
               {
                  ASSERT(lpOleLink != NULL);
                  lpUnk = NULL;
      
                  //Retrieve the IUnknown interface to the linked application.
                  if (lpOleLink->GetBoundSource(&lpUnk) != NOERROR)
                  {
                     TRACE0("Warning: Link is not connected!\n");
                     lpOleLink->Release();
                     return NULL;
                  }
                  ASSERT(lpUnk != NULL);
               }
      
               //QI for the IDispatch interface of the linked application.
               LPDISPATCH lpDispatch = NULL;
               if (lpUnk->QueryInterface(IID_IDispatch, (LPVOID FAR*)&lpDispatch)
                  !=NOERROR)
               {
      
                  TRACE0("Warning: does not support IDispatch!\n");
                  return NULL;
               }
      
               //After assuring yourself that it is valid, return the IDispatch
      
               //interface to the caller.
               ASSERT(lpDispatch != NULL);
               return lpDispatch;      
      }
      
    10. 打开 CntrItem.h,然后将下面的声明添加到"实现"区域︰
      
      LPDISPATCH GetIDispatch();
      
    11. 在 CntrItem.cpp,将更改从CEmbedWordCntrItem::OnGetItemPosition中的代码的最后一行︰
      
      rPosition.SetRect(10, 10, 210, 210);
      
      自:
      
      rPosition.SetRect(20, 20, 630, 420);
      
    12. 按 F7 键生成 EmbedWord.exe。然后按 CTRL + F5 组合键来运行该应用程序。出现无标题-EmbedWord的框架时,编辑菜单上单击插入新对象将出现新的嵌入的 Word 文档,并与 EmbedWord 应用程序的菜单合并的Word菜单和命令按钮栏。

      您的代码嵌入新文档,添加至其中的文本设置字体和字体大小。
    展开全文
  • 摘要 <br />本文详细介绍了如何自动化像Microsoft Office这样支持COM的应用... <br />创建自动化项目1.在Microsoft Developer Studio中,创建"MFC AppWizard(exe)"项目,命名为"AutoProject."2.在第

    摘要

    本文详细介绍了如何自动化像Microsoft Office这样支持COM的应用程序。

    更多信息

    下面部分介绍了如何创建MFC项目。采用Microsoft Excel举例,你可以将前8个步骤用于任何项目,修改9-15步用于不同的应用程序。

    创建自动化项目

    1.在Microsoft Developer Studio中,创建"MFC AppWizard(exe)"项目,命名为"AutoProject."
    2.在第1步的MFC应用程序向导中,选择"Dialog Based"应用程序类型并点"完成"
    在创建的项目信息对话框中将显示创建的类:
    Application: CAutoProjectApp in AutoProject.h and AutoProject.cpp
    Dialog: CAutoProjectDlg in AutoProject.h and AutoProjectDlg.cpp
    点 OK 完成项目创建。
    3.Visual Studio设计编辑区打开了对话框"IDD_AUTOPROJECT_DIALOG" ,依照下面两步修改它。
    4.删除静态控件(IDC_STATIC)和Cancel按钮(IDCANCEL)
    5.将OK按钮改为"IDRUN",说明改为"Run." 关闭AutoProject.rc对话框设计界面。
    6.点View菜单中的ClassWizard(或按CTRL+W)
    7.选择消息映射(Message Maps)标签,在对象ID列表框中选择IDRUN,在消息列表框中选择"BN_CLICKED",点添加函数并命名为"OnRun",点OK关闭ClassWizard

    提示:此步骤在AutoProjectDLG.h中定义了"OnRun();"函数,并在 AutoProjectDLG.cpp 中添加了消息处理函数CAutoProjectDlg::OnRun()。
    8.点View菜单中的ClassWizard(或按CTRL+W)
    9.选择Automation标签,点Add Class并选择"From a type library" 浏览并选择你希望自动化的对象库(例如,如果你自动化Excel 97, 则选择Microsoft Excel 8.0 对象库,默认位于 C:/Program Files/Microsoft Office/Office/Excel8.olb).

    如果你自动化Microsoft Excel 2000,选择位于 C:/Program Files/Microsoft Office/Office/Excel9.olb 的Microsoft Excel 9.0 对象库。

    如果你自动化Microsoft Excel 2002和Microsoft Office Excel 2003 ,对象库内含在Excel.exe中,Office 2002的Excel.exe 默认位于 C:/program Files/Microsoft Office/Office10/Excel.exe, Office 2003的Excel.exe 默认位于 C:/program Files/Microsoft Office/Office11/Excel.exe 。选择合适的对象库后,点Open,在类确认列表中选择所有类,点OK。

    提示:类确认对话框中的列表框里包含了Microsoft Excel 类型库中的所有IDispatch接口(与类中一致)。在对话框下面可以看到命名为Excel8.cpp的执行文件,该文件包含了从COleDispatchDriver派生的封装类,头文件是Excel8.h(对于Excel 2002和Excel 2003,文件名为Excel.cpp和Excel.h)
    10.点OK关闭MFC ClassWizard对话框
    11.在 CAutoProjectApp::InitInstance() 函数中添加如下代码,用于加载COM支持库:
    BOOL CAutoProjectApp::InitInstance()
    {
          if(!AfxOleInit())  // Your addition starts here
          {
                AfxMessageBox("Could not initialize COM dll");
                return FALSE;
          }     // End of your addition
    
          AfxEnableControlContainer();
          .
          .
          .
    
    }
    12.在AutoProject.cpp顶部添加#include行
    #include <afxdisp.h>
    13.在AutoProjectDlg.cpp 顶部stdafx.h下添加对excel8.h的包含
    #include "stdafx.h"
    #include "excel8.h" // excel.h in the case of Excel 2002 and Excel 2003.
    14.在CAutoProjectDlg::OnRun()中添加如下所示的自动化代码
    void CAutoProjectDlg::OnRun()
    {
          _Application app;  // app 是 Excel _Application 对象
    
          // 启动 Excel 并得到应用程序对象
          if(!app.CreateDispatch("Excel.Application"))
          {
              AfxMessageBox("Couldn''t start Excel.");
          }
          else
          {
              //使 Excel 可视,然后显示消息
              app.SetVisible(TRUE);
              AfxMessageBox ("Excel is Running!");
          }
    }
    15.编译并运行项目。运行结果:当你点击对话框中的Run按钮,Microsoft Excel将被调用。关闭消息框使Auto_Excel对话框激活。CAutoProjectDlg::OnRun()函数结束,application变量离开作用域,Microsoft Excel将退出。

    附加说明

    当你在项目中从类型库添加类(根据上面所说的9个步骤),你将注意到在项目中添加了许多类。在ClassView中你可以双击某个类查看该类在Excel8.cpp中的定义。

    如果你需要验证返回值或改变函数的执行,你需要得到函数的定义,无论何时当你改变函数定义,记住在Excel8.h中修改定义。当你这样做的时候,请确认你改变的是正确的函数定义;有时多个类中包含了相同名字的函数,例如GetApplication。

    通过以上如何自动化Microsoft Excel的讲述,你可以将这些方法应用到其它自动化程序中。下表包含了Microsoft Office应用程序类型库的名称。

       应用程序(Application)              类型库(Type Library)
       --------------------------------------------------------
    
       Microsoft Access 97                   Msacc8.olb
       Microsoft Jet Database 3.5            DAO350.dll
       Microsoft Binder 97                   Msbdr8.olb
       Microsoft Excel 97                    Excel8.olb
       Microsoft Graph 97                    Graph8.olb
       Microsoft Office 97                   Mso97.dll
       Microsoft Outlook 97                  Msoutl97.olb
       Microsoft PowerPoint 97               Msppt8.olb
    
       Microsoft Word 97                     Msword8.olb
       Microsoft Access 2000                 Msacc9.olb
       Microsoft Jet Database 3.51           DAO360.dll
       Microsoft Binder 2000                 Msbdr9.olb
       Microsoft Excel 2000                  Excel9.olb
       Microsoft Graph 2000                  Graph9.olb
       Microsoft Office 2000                 Mso9.dll
       Microsoft Outlook 2000                Msoutl9.olb
       Microsoft PowerPoint 2000             Msppt9.olb
       Microsoft Word 2000                   Msword9.olb
    
       Microsoft Access 2002                 Msacc.olb
       Microsoft Excel 2002                  Excel.exe
       Microsoft Graph 2002                  Graph.exe
       Microsoft Office 2002                 MSO.dll
       Microsoft Outlook 2002                MSOutl.olb
       Microsoft PowerPoint 2002             MSPpt.olb
       Microsoft Word 2002                   MSWord.olb
    
       Microsoft Office Access 2003          Msacc.olb
       Microsoft Office Excel 2003           Excel.exe
       Microsoft Graph 2003                  Graph.exe
       Microsoft Office 2003                 MSO.dll
       Microsoft Office Outlook 2003         MSOutl.olb
       Microsoft Office PowerPoint 2003      MSPpt.olb
       Microsoft Office Word 2003            MSWord.olb

    提示:除了 Dao350.dll 、Dao360.dll和 Microsoft Office 10(MSO.dll),类型库默认位于: C:/Program Files/Microsoft Office/Office (Office 2002 路径是 C:/.../Office10,Office 2003 路径是 C:/.../Office11), Dao350.dll/Dao360.dll 默认位于 C:/Program Files/Common Files/Microsoft Shared/Dao。 Office 2002 的MSO.dll 默认 C:/Program Files/Common Files/Microsoft Shared/Office10, Office 2003 的MSO.dll位于 C:/Program Files/Common Files/Microsoft Shared/Office11

    参考

    222101 查找并使用Office对象模型文档

    Microsoft Automation站点

    展开全文
  • 如何使用 MFC 嵌入并自动化 Microsoft Excel 工作表 概要 本文介绍如何将 Microsoft Excel 工作表嵌入 SDI MFC 应用程序中的 View 对象。 本文包含嵌入工作表和向单元格 A1 添加文本的分步骤说明,并包含...
     
     
     
    

    如何使用 MFC 嵌入并自动化 Microsoft Excel 工作表

    概要

    本文介绍如何将 Microsoft Excel 工作表嵌入 SDI MFC 应用程序中的 View 对象。

    本文包含嵌入工作表和向单元格 A1 添加文本的分步骤说明,并包含解释每个步骤的注释。

    尽管可以将本文中的示例代码直接拿到您的应用程序中,但只有阅读和理解了文中的示例才会使您真正获益。

    更多信息

    下面是创建 MFC 应用程序的步骤:
    1.使用应用程序向导新建一个名为“Embed_Excel”的 MFC 应用程序向导 (EXE) 项目。
    2.选择“单文档”作为要创建的应用程序类型,并选择“容器”作为要包括的复合文档支持类型。接受所有其他默认设置。

    将生成下面几个类:

    Application:Embed_Excel.h 和 Embed_Excel.cpp 中的 CEmbed_ExcelApp

    Frame:MainFrm.h 和 MainFrm.cpp 中的 CMainFrame

    Document:Embed_ExcelDoc.h 和 Embed_ExcelDoc.cpp 中的 CEmbed_ExcelDoc

    View:Embed_ExcelView.h 和 Embed_ExcelView.cpp 中的 CEmbed_ExcelView

    Container Item:CntrItem.h 和 CntrItem.cpp 中的 CEmbed_ExcelCntrItem
    3.视图菜单上,单击类向导。单击自动化选项卡,单击添加类,并选择从类型库。找到 Microsoft Excel 类型库,然后将类型库中的所有类都添加到您的项目中。对于 Excel 97,类型库位于 Excel8.olb。对于 Excel 2000,类型库位于 Excel9.olb;对于 Excel 2002,类型库位于 Excel.exe。
    4.将下面一行代码添加到 CntrItem.h:
    LPDISPATCH GetIDispatch();
                
    5.然后将 GetIDispatch 方法添加到 CntrItem.cpp:
       Sample Code
                -----------
                /*******************************************************************
                *   This method returns the IDispatch* for the application linked to
                *   this container.
                ********************************************************************/
                LPDISPATCH CEmbed_ExcelCntrItem::GetIDispatch()
                {
                //The this and m_lpObject pointers must be valid for this function
                //to work correctly. The m_lpObject is the IUnknown pointer to
                // this object.
                ASSERT_VALID(this);
                ASSERT(m_lpObject != NULL);
                LPUNKNOWN lpUnk = m_lpObject;
                //The embedded application must be running in order for the rest
                //of the function to work.
                Run();
                //QI for the IOleLink interface of m_lpObject.
                LPOLELINK lpOleLink = NULL;
                if (m_lpObject->QueryInterface(IID_IOleLink,
                (LPVOID FAR*)&lpOleLink) == NOERROR)
                {
                ASSERT(lpOleLink != NULL);
                lpUnk = NULL;
                //Retrieve the IUnknown interface to the linked application.
                if (lpOleLink->GetBoundSource(&lpUnk) != NOERROR)
                {
                TRACE0("Warning: Link is not connected!\n");
                lpOleLink->Release();
                return NULL;
                }
                ASSERT(lpUnk != NULL);
                }
                //QI for the IDispatch interface of the linked application.
                LPDISPATCH lpDispatch = NULL;
                if (lpUnk->QueryInterface(IID_IDispatch, (LPVOID FAR*)&lpDispatch)
                !=NOERROR)
                {
                TRACE0("Warning: does not support IDispatch!\n");
                return NULL;
                }
                //After assuring ourselves it is valid, return the IDispatch
                //interface to the caller.
                ASSERT(lpDispatch != NULL);
                return lpDispatch;
                }
                
    6.将下面一行代码添加到 Embed_ExcelView.h:
          void EmbedAutomateExcel();
                
    7.然后将 EmbedAutomateExcel 方法添加到 Embed_ExcelView.cpp:
    Sample Code
                -----------
                /********************************************************************
                *   This method encapsulates the process of embedding an Excel
                *   Worksheet in a View object and automating that worksheet to add
                *   some text to cell A1.
                ********************************************************************/
                void CEmbed_ExcelView::EmbedAutomateExcel()
                {
                //Change the cursor so the user knows something exciting is going
                //on.
                BeginWaitCursor();
                CEmbed_ExcelCntrItem* pItem = NULL;
                TRY
                {
                //Get the document associated with this view, and be sure it's
                //valid.
                CEmbed_ExcelDoc* pDoc = GetDocument();
                ASSERT_VALID(pDoc);
                //Create a new item associated with this document, and be sure
                //it's valid.
                pItem = new CEmbed_ExcelCntrItem(pDoc);
                ASSERT_VALID(pItem);
                // Get Class ID for Excel sheet.
                // This is used in creation.
                CLSID clsid;
                if(FAILED(::CLSIDFromProgID(L"Excel.sheet",&clsid)))
                //Any exception will do. We just need to break out of the
                //TRY statement.
                AfxThrowMemoryException();
                // Create the Excel embedded item.
                if(!pItem->CreateNewItem(clsid))
                //Any exception will do. We just need to break out of the
                //TRY statement.
                AfxThrowMemoryException();
                //Make sure the new CContainerItem is valid.
                ASSERT_VALID(pItem);
                // Launch the server to edit the item.
                pItem->DoVerb(OLEIVERB_SHOW, this);
                // As an arbitrary user interface design, this sets the
                // selection to the last item inserted.
                m_pSelection = pItem;   // set selection to last inserted item
                pDoc->UpdateAllViews(NULL);
                //Query for the dispatch pointer for the embedded object. In
                //this case, this is the Excel worksheet.
                LPDISPATCH lpDisp;
                lpDisp = pItem->GetIDispatch();
                //Add text in cell A1 of the embedded Excel sheet
                _Workbook wb;
                Worksheets wsSet;
                _Worksheet ws;
                Range range;
                _Application app;
                //set _Workbook wb to use lpDisp, the IDispatch* of the
                //actual workbook.
                wb.AttachDispatch(lpDisp);
                //Then get the worksheet's application.
                app = wb.GetApplication();
                //Then get the first worksheet in the workbook
                wsSet = wb.GetWorksheets();
                ws = wsSet.GetItem(COleVariant((short)1));
                //From there, get a Range object corresponding to cell A1.
                range = ws.GetRange(COleVariant("A1"), COleVariant("A1"));
                //Fill A1 with the string "Hello, World!"
                range.SetValue(COleVariant("Hello, World!"));
                //NOTE: If you are automating Excel 2002, the Range.SetValue method has an
                //additional optional parameter specifying the data type.  Because the
                //parameter is optional, existing code will still work correctly, but new
                //code should use the new convention.  The call for Excel2002 should look
                //like the following:
                //range.SetValue( ColeVariant( (long)DISP_E_PARAMNOTFOUND, VT_ERROR ),
                //                COleVariant("Hello, World!"));
                }
                //Here, we need to do clean up if something went wrong.
                CATCH(CException, e)
                {
                if (pItem != NULL)
                {
                ASSERT_VALID(pItem);
                pItem->Delete();
                }
                AfxMessageBox(IDP_FAILED_TO_CREATE);
                }
                END_CATCH
                //Set the cursor back to normal so the user knows exciting stuff
                //is no longer happening.
                EndWaitCursor();
                }
                
    8.将下面一行代码添加到 Embed_ExcelView.h:
          #include "excel8.h"
                
    注意:如果要自动化 Excel 2000,头文件应为“excel9.h”。如果要自动化 Excel 2002,头文件应为“excel.h”。
    9.看一下 View 类的 OnInsertObject() 方法。您会注意到一件非常有趣的事:这个方法与我们刚刚编写的方法惊人地相似。事实上,我们编写的代码只是 OnInsertObject() 的一个特例,它允许用户从可用的 OLE 对象列表中选择插入应用程序的对象。由于我们的目的只是自动化 Excel 工作表,因此覆盖了这一行为。在我们的应用程序中,从 InsertObject() 内部删除了所有代码,并代之以对 EmbedAutomateExcel() 的调用。
    10.编译并运行应用程序。
    11.编辑菜单上,单击插入新对象。结果:Microsoft Excel 工作表被嵌入到 View 对象中;另外,通过自动化,在单元格 A1 的内容中填入了“Hello, World!”

    这篇文章中的信息适用于:
    Microsoft Excel 2000 标准版
    Microsoft Visual C++ 5.0 专业版
    Microsoft Visual C++ 6.0 专业版
    Microsoft Foundation Class Library 4.2
    Microsoft Office XP Developer Edition
    Microsoft Office 2000 Developer Edition
    Microsoft Excel 2002 标准版
    Microsoft Excel 97 标准版

     

     

    更多技术文章请参看施昌权的个人网站: http://www.joyvc.cn

    展开全文
  • 步骤 1: 创建应用程序框架与该应用程序向导 在生成菜单上单击生成 TestPPT.exe。 <br />注: 首次生成的项目时需要花费更长的时间比正常生成。这是因为编译器创建预编译的头 (.pch) 项目。...
  • 使用MFC插入Excel工作表并实现自动化

    千次阅读 2012-06-03 21:59:27
    这篇文章讲述了如何使用MFC将Excel工作表插入到SDI视图中。  文章包括插入工作表并将文字添加到A1单元格的详细步骤,每一步都有详细说明。 虽然你可以直接将代码插入到你的程序中, 但理解这些例子你才会真正受益...
  • 本文介绍如何使用 Visual C++.NET 在单文档界面 (SDI) Microsoft 基础...下列步骤介绍如何嵌入一个 Word 文档并自动化文档将数据添加到单元格。 启动 Microsoft Visual Studio .NET。在文件菜单上,单击新建,然后单
  • 中文版本链接:http://support.microsoft.com/kb/169505/zh-cn Article In English:http://support.microsoft.com/kb/169505/en-us
  • 在一个MFC工程中调用Word ActiveX自动化。  用ClassWizard中通过添加类From TypeLib来自动添加调用的接口类,TypeLib是office安装目录里的以OLB为扩展名的文件,Office2k的为MSWORD9.OLB,Office2k3的为MS...
  • 一个基于MFC自动化(Automation)实例

    千次阅读 2008-12-23 14:13:00
    自动化算是远古时代的技术了吧?不过你还真别怀疑"没有过时的技术,只有过时的思想"这句话的可靠性!这不,最最在“研究”如何“挂接”浏览器中有关元素的事件(如挂接TextArea的onselect事件),其中用到了IDispatch...
  • MFC 如何自动化 Outlook 使用 VisualC ++

    千次阅读 2009-10-01 15:12:00
    可通过编程控制使用 MicrosoftVisualC++ MicrosoftOutlook。 本文演示如何创建联系人、 约会, 创建和发送邮件使用 ... 请按照下列步骤以生成并运行示例: 启动 VisualC++ 和创建新 MFC EXE 基于对话框的应用程序。
  • 有一个错误。如果那位大侠解决了请给我留言。
  • 万方数据库的资料哦~~要money的哟,我共享给大家
  • vs2017+MFC+opencv实现细胞自动计数,可视处理过程,运行可靠,仅供参考
  • 本实例可以打开EXCEL2007,建立EXCEL文件,并用C++在EXCEL中添加,改变数据。保存EXCEL文件。
  • 网页自动填单 vcmfc

    2014-06-19 17:31:51
    网页自动填单,实现类似注册机的功能,点击后程序可自动填写表单提交,用vc编写的,mfc可视结构
  • 然后将该控件嵌入MFC对话框程序里面,但是播放PPT的出现了问题:播放幻灯片的时候,能够正常播放,但是按下ESC按钮结束幻灯片播放的时候,整个PPT都退出了。我的需求是按下ESC按键的时候,播放幻灯片的页面退出,但是...
  • 如何嵌入并自动使用 MFC 的 Word 文档

    千次阅读 2012-09-19 14:28:25
    Microsoft Office Development with Visual Studio http://msdn.microsoft.com/en-us/library/office/aa188489(v=office.10).aspx#vsofficedev_topic3 ... 如何嵌入并自动使用 MFC
  • MFC序列

    千次阅读 2013-04-11 11:41:07
    1.序列概念:采用数据流的方式,将数据依次写入或者读取文件。是二进制的存储方式。 2.序列相关类:CFile(文件类);CArchive(封装了序列操作,完成数据读写的具体操作);CObject中与序列相关的两个函数,...
  • mfc自动点击鼠标

    2011-12-10 20:53:07
    最基础的鼠标事件演示,可以设定点击次数,延迟,方式等,适合初学者学习鼠标简单事件
  • MFC窗口自动激活

    千次阅读 2017-01-22 09:31:44
    MFC做的程序,其中加了几个定时器任务去下载资料,最小或者界面被覆盖掉之后过段时间会自动弹出来,在OnTimer中加判断 if (AfxGetMainWnd() == GetActiveWindow()) { //dosomething }
  • 一、理解软件测试自动化 1.自动化测试的含义 自动测试就是用程序代替人的手工操作,完成一系列测试的过程。 √     自动化工具能自动打开程序、自动执行测试用例、自动查找控件、自动产生...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 42,516
精华内容 17,006
关键字:

自动化mfc