分享

VC知识库文章

 quasiceo 2013-12-01
称号:未设置
简介:...
  • 文章概要:
  • 有时我们并不需要提供完整的脚本支持,就像本文所要介绍的ActiveX脚本宿主(script hosting,可能称为脚本引擎更好理解),本文提供的ScriptControlMacro程序展示了使用Microsoft脚本控件简单地实现脚本支持功能

代码运行效果图如下:

 

介绍

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

用文件映射实现只允许一个应用实例.

如何用MFC存储读取二进制注册表数据

如何保存恢复应用程序窗口尺寸,位置

如何在CEditView派生类中使用不同地字体

如何捕捉OLE异常并显示错误信息

等...

开始前的准备

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

基本步骤:

1、建立一个提供ActiveX控件支持的新的MFC工程

2、使用ClassWizard从脚本控件类型库中建立一个dispatch类

ClassWizard将为脚本控件接口生成头文件与执行文件。

01.// Machine generated IDispatch wrapper class(es) created with
02.// ClassWizard
03. 
04.////////////////////////////////////////////////////////////
05.// IScriptControl wrapper class
06. 
07.class IScriptControl : public COleDispatchDriver
08.{
09.// Operations
10.public:
11.void SetLanguage(LPCTSTR lpszNewValue);
12.void SetSitehWnd(HWND hWnd);
13.LPDISPATCH GetError();
14.void AddObject(LPCTSTR Name, LPDISPATCH Object,
15.BOOL AddMembers);
16.void AddCode(LPCTSTR Code);
17.};
18. 
19.// Machine generated IDispatch wrapper class(es) created
20.// with ClassWizard
21. 
22.#include "stdafx.h"
23. 
24.#include "MSScriptControl.h"
25. 
26.#ifdef _DEBUG
27.#define new DEBUG_NEW
28.#undef THIS_FILE
29.static char THIS_FILE[] = __FILE__;
30.#endif
31. 
32.////////////////////////////////////////////////////////////
33.// IScriptControl operations
34. 
35.void IScriptControl::SetLanguage(LPCTSTR lpszNewValue)
36.{
37.static BYTE parms[] =
38.VTS_BSTR;
39.InvokeHelper(0x5dc, DISPATCH_PROPERTYPUT, VT_EMPTY,
40.NULL, parms,
41.lpszNewValue);
42.}
43. 
44.void IScriptControl::SetSitehWnd(HWND hWnd)
45.{
46.static BYTE parms[] =
47.VTS_I4;
48.InvokeHelper(0x5de, DISPATCH_PROPERTYPUT, VT_EMPTY,
49.NULL, parms,
50.hWnd);
51.}
52. 
53.LPDISPATCH IScriptControl::GetError()
54.{
55.LPDISPATCH result;
56.InvokeHelper(0x5e3, DISPATCH_PROPERTYGET, VT_DISPATCH,
57.(void*)&result, NULL);
58.return result;
59.}
60. 
61.void IScriptControl::AddObject(LPCTSTR Name,
62.LPDISPATCH Object,
63.BOOL AddMembers)
64.{
65.static BYTE parms[] =
66.VTS_BSTR VTS_DISPATCH VTS_BOOL;
67.InvokeHelper(0x9c4, DISPATCH_METHOD, VT_EMPTY, NULL, parms,
68.Name, Object, AddMembers);
69.}
70. 
71.void IScriptControl::AddCode(LPCTSTR Code)
72.{
73.static BYTE parms[] =
74.VTS_BSTR;
75.InvokeHelper(0x7d0, DISPATCH_METHOD, VT_EMPTY, NULL, parms,
76.Code);
77.}

3、删除类中不需要的IDispatch封装的方法

4、如果你想自己添加函数,可以用ClassWizard添加一个自动化类。

ClasWizard将为IDispatch接口产生如下头文件与执行文件:

001.// ScriptControlMacroDispatch.h : interface of the
002.// CScriptControlMacroDispatch class
003.//
004.////////////////////////////////////////////////////////////
005. 
006.#if !defined(AFX_SCRIPTCONTROLMACRODISPATCH_H__FB55B5AF_
007.00E5_47F5_B176_214B2C7BF19A__INCLUDED_)
008.#define AFX_SCRIPTCONTROLMACRODISPATCH_H__FB55B5AF_00E5_
009.47F5_B176_214B2C7BF19A__INCLUDED_
010. 
011.#if _MSC_VER > 1000
012.#pragma once
013.#endif    // _MSC_VER > 1000
014. 
015.////////////////////////////////////////////////////////////
016.// CScriptControlMacroDispatch command target
017. 
018.class CScriptControlMacroDispatch : public CCmdTarget
019.{
020.DECLARE_DYNCREATE(CScriptControlMacroDispatch)
021. 
022.CScriptControlMacroDispatch();
023.// protected constructor used by dynamic creation
024. 
025.// Overrides
026.// ClassWizard generated virtual function overrides
027.//{{AFX_VIRTUAL(CScriptControlMacroDispatch)
028.//}}AFX_VIRTUAL
029. 
030.// Implementation
031. 
032.protected:
033.//friend class CScriptControlMacroView;
034.// Generated message map functions
035.//{{AFX_MSG(CScriptControlMacroDispatch)
036.// NOTE - the ClassWizard will add and remove member
037.// functions here.
038.//}}AFX_MSG
039. 
040.DECLARE_MESSAGE_MAP()
041.// Generated OLE dispatch map functions
042.//{{AFX_DISPATCH(CScriptControlMacroDispatch)
043.afx_msg void Test1();
044.afx_msg void Test2();
045.//}}AFX_DISPATCH
046.DECLARE_DISPATCH_MAP()
047.DECLARE_INTERFACE_MAP()
048.};
049. 
050.// Note: we add support for IID_IScriptControlMacroDispatch
051.// to support typesafe binding from VBA. This IID must match
052.// the GUID that is attached to the dispinterface in the
053.// .ODL file.
054. 
055.// {69AA5686-41AF-4CD9-AEAE-9DB88130E7C1}
056.static const IID IID_IScriptControlMacroDispatch =
057.{0x69AA5686, 0x41AF, 0x4CD9, {0xAE, 0xAE, 0x9D, 0xB8,
058.0x81, 0x30, 0xE7, 0xC1}};
059. 
060.////////////////////////////////////////////////////////////
061. 
062.//{{AFX_INSERT_LOCATION}}
063.// Microsoft Visual C++ will insert additional declarations
064.// immediately before the previous line.
065. 
066.#endif    // !defined(AFX_SCRIPTCONTROLMACRODISPATCH_H__
067.// FB55B5AF_00E5_47F5_B176_214B2C7BF19A__INCLUDED_)
068. 
069.// ScriptControlMacroDispatch.cpp : implementation of the
070.// CScriptControlMacroDispatch class
071.//
072. 
073.#include "stdafx.h"
074.#include "ScriptControlMacroDispatch.h"
075. 
076.#ifdef _DEBUG
077.#define new DEBUG_NEW
078.#undef THIS_FILE
079.static char THIS_FILE[] = __FILE__;
080.#endif
081. 
082.////////////////////////////////////////////////////////////
083.// CScriptControlMacroDispatch
084. 
085.IMPLEMENT_DYNCREATE(CScriptControlMacroDispatch, CCmdTarget)
086. 
087.CScriptControlMacroDispatch::CScriptControlMacroDispatch()
088.{
089.EnableAutomation();
090.}
091. 
092.BEGIN_MESSAGE_MAP(CScriptControlMacroDispatch, CCmdTarget)
093.//{{AFX_MSG_MAP(CScriptControlMacroDispatch)
094.// NOTE - the ClassWizard will add and remove mapping
095.// macros here.
096.//}}AFX_MSG_MAP
097.END_MESSAGE_MAP()
098. 
099.BEGIN_DISPATCH_MAP(CScriptControlMacroDispatch, CCmdTarget)
100.//{{AFX_DISPATCH_MAP(CScriptControlMacroDispatch)
101.DISP_FUNCTION(CScriptControlMacroDispatch,
102."Test1", Test1, VT_EMPTY, VTS_NONE)
103.DISP_FUNCTION(CScriptControlMacroDispatch,
104."Test2", Test2, VT_EMPTY, VTS_NONE)
105.//}}AFX_DISPATCH_MAP
106.END_DISPATCH_MAP()
107. 
108.BEGIN_INTERFACE_MAP(CScriptControlMacroDispatch, CCmdTarget)
109.INTERFACE_PART(CScriptControlMacroDispatch,
110.IID_IScriptControlMacroDispatch, Dispatch)
111.END_INTERFACE_MAP()
112. 
113.////////////////////////////////////////////////////////////
114.// CScriptControlMacroDispatch message handlers
115. 
116.void CScriptControlMacroDispatch::Test1()
117.{
118.// TODO: Add your dispatch handler code here
119. 
120.AfxMessageBox(CString(_T("\"")) + GetDispatchMap()->
121.lpEntries->lpszName + _T("\" method call of
122.the \"") + RUNTIME_CLASS(
123.CScriptControlMacroDispatch)->m_lpszClassName
124.+ _T("\" class"), MB_ICONASTERISK);
125.}
126. 
127.void CScriptControlMacroDispatch::Test2()
128.{
129.// TODO: Add your dispatch handler code here
130. 
131.AfxMessageBox(CString(_T("\"")) + GetDispatchMap()->
132.lpEntries[1].lpszName + _T("\" method
133.call of the \"") + RUNTIME_CLASS(
134.CScriptControlMacroDispatch)->m_lpszClassName
135.+ _T("\" class"), MB_ICONASTERISK);
136.}

5、这样在产生的代码中已经实现了一些自定义的东西

      a. 不必要的声名和代码已经删除

      b. 全局的应用程序对象已经声名:extern CScriptControlMacroApp theApp

      c. MFC隐含函数声名已经添加:CString AFXAPI AfxStringFromCLSID( REFCLSID ).

      d. 为了使用AfxStringFromCLSID,IID_IScriptControlMacroDispatch定义已经移到了头文件中

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

1.////////////////////////////////////////////////////////////
2.// Win32 libraries
3. 
4.// Start of customization
5.#ifdef _UNICODE
6.#pragma comment(linker, "/entry:wWinMainCRTStartup")
7.#endif
8.// End of customization

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

01.#ifndef ALL_WARNINGS
02.#pragma warning(disable: 4201)
03.// winnt.h uses nameless structs
04.#endif
05. 
06.// Start of customization
07.#ifndef _WIN32_WINDOWS
08.// End of customization
09.#define _WIN32_WINDOWS 0x0500
10.// Start of customization
11.#endif
12.// End of customization

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多