为应用程序添加脚本支持

来源:互联网 发布:linux下安装canda 编辑:程序博客网 时间:2024/05/22 02:26

代码运行效果图如下:
 

介绍
有时我们并不需要提供完整的脚本支持,就像本文所要介绍的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 classclass IScriptControl : public COleDispatchDriver{// Operationspublic:  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_FILEstatic char THIS_FILE[] = __FILE__;#endif////////////////////////////////////////////////////////////// IScriptControl operationsvoid 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 targetclass CScriptControlMacroDispatch : public CCmdTarget{  DECLARE_DYNCREATE(CScriptControlMacroDispatch)  CScriptControlMacroDispatch();           // protected constructor used by dynamic creation// Overrides  // ClassWizard generated virtual function overrides  //{{AFX_VIRTUAL(CScriptControlMacroDispatch)  //}}AFX_VIRTUAL// Implementationprotected:  //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_FILEstatic char THIS_FILE[] = __FILE__;#endif////////////////////////////////////////////////////////////// CScriptControlMacroDispatchIMPLEMENT_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_MAPEND_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_MAPEND_DISPATCH_MAP()BEGIN_INTERFACE_MAP(CScriptControlMacroDispatch, CCmdTarget)  INTERFACE_PART(CScriptControlMacroDispatch,                 IID_IScriptControlMacroDispatch, Dispatch)END_INTERFACE_MAP()////////////////////////////////////////////////////////////// CScriptControlMacroDispatch message handlersvoid 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 theAppc. 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 customization7、为了在所有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脚本技术网页http://msdn.microsoft.com/scripting/
原创粉丝点击