如何使用MFC和类型库创建自动化项目

时间:2021-07-20 20:44:04

摘要

本文详细介绍了如何自动化像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
==========================================================================================

Excel

1. 引入类

#include "CApplication.h"
#include "CFont0.h"
#include "CWorkbook.h"
#include "CWorkbooks.h"
#include "CRange.h"
#include "CWorksheet.h"
#include "CWorksheets.h"

2. 主要接口

BOOL CXXX::Create(void)
{
    if(!m_app.CreateDispatch(L"Excel.Application"))
   {
       AfxMessageBox(L"Could not start Excel.");
      return FALSE;
   }
   m_app.put_DisplayAlerts (VARIANT_FALSE);
   m_app.put_UserControl(FALSE);
   return TRUE;
}

void CXXX::Destroy(void)
{
     //CloseWorkbook();
     m_app.Quit();
     m_app.ReleaseDispatch();
}

int CXXX::OpenWorkbook(CString strPath)
{
    try
    {
         LPDISPATCH lpDisp;
         lpDisp = m_app.get_Workbooks();  // Get an IDispatch pointer
         ASSERT(lpDisp);
         m_books.AttachDispatch( lpDisp );  // Attach the IDispatch pointer to the books object.

         // open the document

         lpDisp = m_books.Open(strPath,     m_covOptional, m_covOptional,
          m_covOptional, m_covOptional, m_covOptional, m_covOptional,
          m_covOptional, m_covOptional, m_covOptional, m_covOptional,
          m_covOptional, m_covOptional, m_covOptional, m_covOptional);
         ASSERT(lpDisp);

         //Set CWorkbook to use lpDisp, the IDispatch* of the actual workbook.
         m_book.AttachDispatch(lpDisp); 
         m_sheets = m_book.get_Worksheets();
    }
    catch(COleDispatchException* e)
    {
        TRACE(_T("[EXCEPTION]OpenWorkbook exception COleDispatchException!!!\n"));
        TCHAR msg[2048];
        e->GetErrorMessage(msg,1024);
        e->Delete();
        MessageBox(0,msg, TEXT("Error"), MB_OK | MB_ICONERROR);
        return -1;
     }
     return 0;
}

 void Cxxxx::CloseWorkbook(void)
{
    m_sheet.ReleaseDispatch();
  m_sheets.ReleaseDispatch();
  m_book.ReleaseDispatch();
  m_books.Close();
  m_books.ReleaseDispatch();
}


int CXXX::ReaddExcelData(CString strPath)
{
  if( -1 == OpenWorkbook(strPath) )
  {
    CloseWorkbook();
    return -1;
  }

  if ( !ParseCauSheet() )
  {
    CloseWorkbook();
    return -1;
  }

  CloseWorkbook();
  return 0;
}

void CExcelOp::ParseSheet(void)
{
    CRange range;
  CRange usedRange;
  COleVariant val;
  CString strRangeId,strKeyword;
  CString strRangePos;
  int index = 0;

  m_sheet = m_sheets.get_Item(COleVariant((short)(1))); // m_sheets are indexed starting from 1
  usedRange = m_sheet.get_UsedRange();
  range = usedRange.get_Rows();
  int nRowCnt = (int)range.get_Count();
  for(int i = 1; i <= nRowCnt; i++)
  {

      。。。。。
  }
  return;
}