Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2095898
  • 博文数量: 909
  • 博客积分: 4000
  • 博客等级: 上校
  • 技术积分: 12260
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-06 20:50
文章分类

全部博文(909)

文章存档

2008年(909)

我的朋友

分类:

2008-05-06 21:36:32

一起学习
为应用程序添加脚本支持
作者:Yuri Polyakov 翻译:PowerCPP

下载本文示例代码

代码运行效果图如下:


介绍
有时我们并不需要提供完整的脚本支持,就像本文所要介绍的ActiveX脚本宿主(script hosting,可能称为脚本引擎更好理解),本文提供的ScriptControlMacro程序展示了使用Microsoft脚本控件简单地实现脚本支持功能,代码中还包括了以下一些技术:

用文件映射实现只允许一个应用实例.
如何用MFC存储读取二进制注册表数据
如何保存恢复应用程序窗口尺寸,位置
如何在CEditView派生类中使用不同地字体
如何捕捉OLE异常并显示错误信息
等...

开始前的准备
这篇文章假定你已经对COM、ActiveX控件、OLE自动化有所熟悉,并知道如何在MFC里使用他们。因为这些技术包含了相当多的内容,因此你应该先学习一下这些内容再来看本文。

基本步骤:
1、建立一个提供ActiveX控件支持的新的MFC工程
2、使用ClassWizard从脚本控件类型库中建立一个dispatch类
ClassWizard将为脚本控件接口生成头文件与执行文件。

// Machine generated IDispatch wrapper class(es) created with

// ClassWizard



////////////////////////////////////////////////////////////

// IScriptControl wrapper class



class IScriptControl : public COleDispatchDriver

{

// Operations

public:

  void SetLanguage(LPCTSTR lpszNewValue);

  void SetSitehWnd(HWND hWnd);

  LPDISPATCH GetError();

  void AddObject(LPCTSTR Name, LPDISPATCH Object,

                 BOOL AddMembers);

  void AddCode(LPCTSTR Code);

};



// Machine generated IDispatch wrapper class(es) created

// with ClassWizard



#include "stdafx.h"



#include "MSScriptControl.h"



#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif



////////////////////////////////////////////////////////////

// IScriptControl operations



void IScriptControl::SetLanguage(LPCTSTR lpszNewValue)

{

  static BYTE parms[] =

    VTS_BSTR;

  InvokeHelper(0x5dc, DISPATCH_PROPERTYPUT, VT_EMPTY,

               NULL, parms,

    lpszNewValue);

}



void IScriptControl::SetSitehWnd(HWND hWnd)

{

  static BYTE parms[] =

    VTS_I4;

  InvokeHelper(0x5de, DISPATCH_PROPERTYPUT, VT_EMPTY,

               NULL, parms,

    hWnd);

}



LPDISPATCH IScriptControl::GetError()

{

  LPDISPATCH result;

  InvokeHelper(0x5e3, DISPATCH_PROPERTYGET, VT_DISPATCH,

               (void*)&result, NULL);

  return result;

}



void IScriptControl::AddObject(LPCTSTR Name,

                               LPDISPATCH Object,

                               BOOL AddMembers)

{

  static BYTE parms[] =

    VTS_BSTR VTS_DISPATCH VTS_BOOL;

  InvokeHelper(0x9c4, DISPATCH_METHOD, VT_EMPTY, NULL, parms,

     Name, Object, AddMembers);

}



void IScriptControl::AddCode(LPCTSTR Code)

{

  static BYTE parms[] =

    VTS_BSTR;

  InvokeHelper(0x7d0, DISPATCH_METHOD, VT_EMPTY, NULL, parms,

    Code);

}



3、删除类中不需要的IDispatch封装的方法
4、如果你想自己添加函数,可以用ClassWizard添加一个自动化类。
ClasWizard将为IDispatch接口产生如下头文件与执行文件:
// ScriptControlMacroDispatch.h : interface of the

// CScriptControlMacroDispatch class

//

////////////////////////////////////////////////////////////



#if !defined(AFX_SCRIPTCONTROLMACRODISPATCH_H__FB55B5AF_

    00E5_47F5_B176_214B2C7BF19A__INCLUDED_)

#define AFX_SCRIPTCONTROLMACRODISPATCH_H__FB55B5AF_00E5_

        47F5_B176_214B2C7BF19A__INCLUDED_



#if _MSC_VER > 1000

#pragma once

#endif    // _MSC_VER > 1000



////////////////////////////////////////////////////////////

// CScriptControlMacroDispatch command target



class CScriptControlMacroDispatch : public CCmdTarget

{

  DECLARE_DYNCREATE(CScriptControlMacroDispatch)



  CScriptControlMacroDispatch();

           // protected constructor used by dynamic creation



// Overrides

  // ClassWizard generated virtual function overrides

  //{{AFX_VIRTUAL(CScriptControlMacroDispatch)

  //}}AFX_VIRTUAL



// Implementation



protected:

  //friend class CScriptControlMacroView;

  // Generated message map functions

  //{{AFX_MSG(CScriptControlMacroDispatch)

    // NOTE - the ClassWizard will add and remove member

    // functions here.

  //}}AFX_MSG



  DECLARE_MESSAGE_MAP()

  // Generated OLE dispatch map functions

  //{{AFX_DISPATCH(CScriptControlMacroDispatch)

  afx_msg void Test1();

  afx_msg void Test2();

  //}}AFX_DISPATCH

  DECLARE_DISPATCH_MAP()

  DECLARE_INTERFACE_MAP()

};



// Note: we add support for IID_IScriptControlMacroDispatch

// to support typesafe binding from VBA. This IID must match

// the GUID that is attached to the dispinterface in the

// .ODL file.



// {69AA5686-41AF-4CD9-AEAE-9DB88130E7C1}

static const IID IID_IScriptControlMacroDispatch =

{0x69AA5686, 0x41AF, 0x4CD9, {0xAE, 0xAE, 0x9D, 0xB8,

 0x81, 0x30, 0xE7, 0xC1}};



////////////////////////////////////////////////////////////



//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C   will insert additional declarations

// immediately before the previous line.



#endif    // !defined(AFX_SCRIPTCONTROLMACRODISPATCH_H__

          // FB55B5AF_00E5_47F5_B176_214B2C7BF19A__INCLUDED_)



// ScriptControlMacroDispatch.cpp : implementation of the

// CScriptControlMacroDispatch class

//



#include "stdafx.h"

#include "ScriptControlMacroDispatch.h"



#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif



////////////////////////////////////////////////////////////

// CScriptControlMacroDispatch



IMPLEMENT_DYNCREATE(CScriptControlMacroDispatch, CCmdTarget)



CScriptControlMacroDispatch::CScriptControlMacroDispatch()

{

  EnableAutomation();

}



BEGIN_MESSAGE_MAP(CScriptControlMacroDispatch, CCmdTarget)

  //{{AFX_MSG_MAP(CScriptControlMacroDispatch)

    // NOTE - the ClassWizard will add and remove mapping

    // macros here.

  //}}AFX_MSG_MAP

END_MESSAGE_MAP()



BEGIN_DISPATCH_MAP(CScriptControlMacroDispatch, CCmdTarget)

  //{{AFX_DISPATCH_MAP(CScriptControlMacroDispatch)

  DISP_FUNCTION(CScriptControlMacroDispatch,

                "Test1", Test1, VT_EMPTY, VTS_NONE)

  DISP_FUNCTION(CScriptControlMacroDispatch,

                "Test2", Test2, VT_EMPTY, VTS_NONE)

  //}}AFX_DISPATCH_MAP

END_DISPATCH_MAP()



BEGIN_INTERFACE_MAP(CScriptControlMacroDispatch, CCmdTarget)

  INTERFACE_PART(CScriptControlMacroDispatch,

                 IID_IScriptControlMacroDispatch, Dispatch)

END_INTERFACE_MAP()



////////////////////////////////////////////////////////////

// CScriptControlMacroDispatch message handlers



void CScriptControlMacroDispatch::Test1()

{

  // TODO: Add your dispatch handler code here



  AfxMessageBox(CString(_T("\""))   GetDispatchMap()->

                lpEntries->lpszName   _T("\" method call of

                the \"")   RUNTIME_CLASS(

                CScriptControlMacroDispatch)->m_lpszClassName

                  _T("\" class"), MB_ICONASTERISK);

}



void CScriptControlMacroDispatch::Test2()

{

  // TODO: Add your dispatch handler code here



  AfxMessageBox(CString(_T("\""))   GetDispatchMap()->

                lpEntries[1].lpszName   _T("\" method

                call of the \"")   RUNTIME_CLASS(

                CScriptControlMacroDispatch)->m_lpszClassName

                  _T("\" class"), MB_ICONASTERISK);

}



5、这样在产生的代码中已经实现了一些自定义的东西
a. 不必要的声名和代码已经删除
b. 全局的应用程序对象已经声名:extern CScriptControlMacroApp theApp
c. MFC隐含函数声名已经添加:CString AFXAPI AfxStringFromCLSID( REFCLSID ).
d. 为了使用AfxStringFromCLSID,IID_IScriptControlMacroDispatch定义已经移到了头文件中

6、为了在所有MFC程序中方便地提供Unicode支持,在AFX.H头文件中作了如下定制:
////////////////////////////////////////////////////////////

// Win32 libraries



// Start of customization

#ifdef _UNICODE

    #pragma comment(linker, "/entry:wWinMainCRTStartup")

#endif

// End of customization



7、为了在所有MFC工程中使用 _WIN32_WINDOWS=0x500 这个预定义,在AFXV_W32.H头文件中作了如下定制:
#ifndef ALL_WARNINGS

#pragma warning(disable: 4201)

    // winnt.h uses nameless structs

#endif



// Start of customization

#ifndef _WIN32_WINDOWS

// End of customization

#define _WIN32_WINDOWS 0x0500

// Start of customization

#endif

// End of customization




更多信息可以查看源代码或访问微软WINDOWS脚本技术网页 下载本文示例代码


为应用程序添加脚本支持为应用程序添加脚本支持为应用程序添加脚本支持为应用程序添加脚本支持为应用程序添加脚本支持为应用程序添加脚本支持为应用程序添加脚本支持为应用程序添加脚本支持为应用程序添加脚本支持为应用程序添加脚本支持为应用程序添加脚本支持为应用程序添加脚本支持
阅读(356) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~