万事俱备,就等执行了:
打开BCB,新建一VCL Form Application。
在默认的Form1上加入一个TMemo改名 为:mmoScript;加入一个TButton改名为btnRun。 btnRun->OnClick代码:
偷懒用到了 TComInterface,要包含: #include <utilcls.h>
1. void __fastcall TForm1::btnRunClick(TObject *Sender)
2. {
3. TComInterface<IActiveScript> pAS;
4. // 第一步,实例化Jscript(同学们也可以试试 VBScript)
5. pAS.CreateInstance(L"JScript");
6. if(!pAS) return;
7.
8. TComInterface<IActiveScriptParse> pASP(pAS);
9. if(!pASP) return;
10.
11. pASP->InitNew();
12.
13. // 我们的劳动成果在这里
14. TComInterface<TMyWin> pDispatch_MyWin = new TMyWin(this);
15. TComInterface<TMyGlobalFunc> pDispatch_MyGlobalFunc = new TMyGlobalFunc;
16. TComInterface<TMyActiveScriptSite> pActiveScriptSite_Mine =
17. new TMyActiveScriptSite(pDispatch_MyWin,pDispatch_MyGlobalFunc);
18.
19. //第二步,告诉IActiveScript谁来解释脚本中的对象
20. pAS->SetScriptSite(pActiveScriptSite_Mine);
21.
22. //第三步,告诉IActiveScript脚本里会用到哪些对象
23. pAS->AddNamedItem(TMyWin::Name,SCRIPTITEM_ISVISIBLE); //会用到”MyWin”
24. //多了一个SCRIPTITEM_GLOBALMEMBERS,意思是如果遇到全局函数就向”MyGlobalFunc”要。
25. pAS->AddNamedItem(TMyGlobalFunc::Name,
26. SCRIPTITEM_ISVISIBLE|SCRIPTITEM_GLOBALMEMBERS);
27.
28. // 第四步,装入脚本
29. pASP->ParseScriptText(WideString(mmoScript->Lines->Text),
30. NULL,
31. NULL,
32. NULL,
33. 0,
34. 0,
35. 0,
36. NULL,
37. NULL);
38.
39. //第五步,运行脚本
40. pAS->SetScriptState(SCRIPTSTATE_STARTED);
41.
42. pAS->Close();
43. }
编译,运行。
把写的 Jscript代码拷贝到mmoScript里然后按btnRun运行可以看到效果。当然也可以修改脚本弄点更好玩的花样出来,呵呵。
最后还要多 说一句关于ParseScriptText,用好它后面的几个参数。看MSDN,修改其中一个参数这段代码就可以用作表态式解析了。
附上 完整代码:
Script.h
1. #ifndef SCRIPT_H
2. #define SCRIPT_H
3. //=============================================================
4. #include <tchar.h>
5. #include <activscp.h>
6.
7. // TDispatch:简单实现 IDispath的所有方法,用于作自动化对象的基类。
8. struct TDispatch : IDispatch{
9. TDispatch():m_iRefCount(1){;}
10. ~TDispatch(){;}
11. // IUNKnown
12. HRESULT __stdcall QueryInterface(REFIID iid, void **ppv){
13. if(iid==IID_IUnknown||iid==IID_IDispatch)
14. {
15. *ppv=this;
16. AddRef();
17. return S_OK;
18. }
19. *ppv=NULL;
20. return E_NOINTERFACE;
21. }
22. ULONG __stdcall AddRef(void) {
23. return ++m_iRefCount;
24. }
25. ULONG __stdcall Release(void) {
26. if(--m_iRefCount==0){
27. delete this;
28. return 0;
29. }
30. return m_iRefCount;
31. }
32.
33. // IDispatch
34. STDMETHOD(GetTypeInfoCount)(UINT *pctinfo){return S_OK;}
35. STDMETHOD(GetTypeInfo)(UINT iTInfo,
36. LCID lcid,ITypeInfo **ppTInfo){return S_OK;}
37. STDMETHOD(GetIDsOfNames)(REFIID riid,
38. LPOLESTR *rgszNames,UINT cNames,LCID lcid,DISPID *rgDispId){
39. return E_NOTIMPL;
40. }
41.
42. STDMETHOD(Invoke)(DISPID dispIdMember,REFIID riid,
43. LCID lcid,WORD wFlags,
44. DISPPARAMS *pDispParams,
45. VARIANT *pVarResult,EXCEPINFO *pExcepInfo,UINT *puArgErr){
46. return S_OK;
47. }
48. private:
49. int m_iRefCount;
50. };
51.
52. // TMyWin,实现MyWin对象类,解释Caption,Color 属性,MoveTo方法
53. struct TMyWin : TDispatch{
54. enum {itemCaption,itemColor,itemMoveTo};
55. static wchar_t Name[];
56. // IDispatch
57. STDMETHOD(GetIDsOfNames)(REFIID riid,
58. LPOLESTR *rgszNames,UINT cNames,LCID lcid,
59. DISPID *rgDispId){
60. if(lstrcmpW(rgszNames[0],L"Caption") == 0)
61. {
62. *rgDispId = itemCaption;
63. }
64. else if(lstrcmpW(rgszNames[0],L"Color") == 0)
65. {
66. *rgDispId = itemColor;
67. }
68. else if(lstrcmpW(rgszNames[0],L"MoveTo") == 0)
69. {
70. *rgDispId = itemMoveTo;
71. }
72. else
73. return E_NOTIMPL;
74. return S_OK;
75. }
76.
77. STDMETHOD(Invoke)(DISPID dispIdMember,
78. REFIID riid,LCID lcid,WORD wFlags,
79. DISPPARAMS *pDispParams,
80. VARIANT *pVarResult,EXCEPINFO *pExcepInfo,UINT *puArgErr){
81. switch(dispIdMember)
82. {
83. case itemCaption:
84. {
85. if(wFlags==DISPATCH_PROPERTYGET)
86. {
87. pVarResult->vt = VT_BSTR;
88. pVarResult->bstrVal = GetCaption();
89. }
90. else if(wFlags==DISPATCH_PROPERTYPUT)
91. {
92. if(pDispParams->cArgs!=1) return DISP_E_BADPARAMCOUNT;
93. if(pDispParams->rgvarg[0].vt != VT_BSTR) {
94. *puArgErr = 0;
95. return DISP_E_TYPEMISMATCH;
96. }
97. SetCaption(pDispParams->rgvarg[0].bstrVal);
98. }
99. else
100. return DISP_E_MEMBERNOTFOUND;
101. break;
102. }
103. case itemColor:
104. {
105. if(wFlags==DISPATCH_PROPERTYGET)
106. {
107. pVarResult->vt = VT_I4;
108. pVarResult->intVal = GetColor();
109. }
110. else if(wFlags==DISPATCH_PROPERTYPUT)
111. {
112. if(pDispParams->cArgs!=1) return DISP_E_BADPARAMCOUNT;
113. if(pDispParams->rgvarg[0].vt != VT_I4) {
114. *puArgErr = 0;
115. return DISP_E_TYPEMISMATCH;
116. }
117. SetColor(pDispParams->rgvarg[0].intVal);
118. }
119. else
120. return DISP_E_MEMBERNOTFOUND;
121. break;
122. }
123. case itemMoveTo:
124. {
125. if(wFlags==DISPATCH_METHOD)
126. {
127. if(pDispParams->cArgs!=2) return DISP_E_BADPARAMCOUNT;
128. if(pDispParams->rgvarg[0].vt != VT_I4) {
129. *puArgErr = 0;
130. return DISP_E_TYPEMISMATCH;
131. }
132. else if(pDispParams->rgvarg[1].vt != VT_I4){
133. *puArgErr = 1;
134. return DISP_E_TYPEMISMATCH;
135. }
136. MoveTo( pDispParams->rgvarg[1].intVal,
137. pDispParams->rgvarg[0].intVal);
138. }
139. else
140. return DISP_E_MEMBERNOTFOUND;
141. break;
142. }
143. default:
144. return DISP_E_MEMBERNOTFOUND;
145. }
146. return S_OK;
147. }
148.
149. // TMyWin
150. TMyWin(TForm *fm_Opt) : TDispatch(),m_Form(fm_Opt){ ; }
151.
152. BSTR GetCaption(){
153. return WideString(m_Form->Caption).Detach();
154. }
155. void SetCaption(BSTR bstrCaption){
156. m_Form->Caption = bstrCaption;
157. }
158. int GetColor(){
159. return (int)m_Form->Color;
160. }
161. void SetColor(int iColor){
162. m_Form->Color = TColor(iColor);
163. }
164.
165. void MoveTo(int X,int Y){
166. m_Form->Left=X;
167. m_Form->Top=Y;
168. }
169.
170. private:
171. TForm *m_Form;
172. };
173. wchar_t TMyWin::Name[]=L"MyWin";
174.
175. struct TMyGlobalFunc : TDispatch{
176. enum {itemScreenWidth,itemScreenHeight,itemSleep};
177. static wchar_t Name[];
178. STDMETHOD(GetIDsOfNames)(REFIID riid,
179. LPOLESTR *rgszNames,UINT cNames,LCID lcid,
180. DISPID *rgDispId){
181. if(lstrcmpW(rgszNames[0],L"ScreenWidth") == 0)
182. {
183. *rgDispId = itemScreenWidth;
184. }
185. else if(lstrcmpW(rgszNames[0],L"ScreenHeight") == 0)
186. {
187. *rgDispId = itemScreenHeight;
188. }
189. else if(lstrcmpW(rgszNames[0],L"Sleep") == 0)
190. {
191. *rgDispId = itemSleep;
192. }
193. else
194. return E_NOTIMPL;
195. return S_OK;
196. }
197.
198. STDMETHOD(Invoke)(DISPID dispIdMember,
199. REFIID riid,LCID lcid,WORD wFlags,
200. DISPPARAMS *pDispParams,
201. VARIANT *pVarResult,EXCEPINFO *pExcepInfo,UINT *puArgErr){
202. switch(dispIdMember)
203. {
204. case itemScreenWidth:
205. pVarResult->vt=VT_I4;
206. pVarResult->intVal = Screen->Width;
207. break;
208. case itemScreenHeight:
209. pVarResult->vt=VT_I4;
210. pVarResult->intVal = Screen->Height;
211. break;
212. case itemSleep:
213. if(pDispParams->cArgs!=1) return DISP_E_BADPARAMCOUNT;
214. if(pDispParams->rgvarg[0].vt != VT_I4) {
215. *puArgErr = 0;
216. return DISP_E_TYPEMISMATCH;
217. }
218. Application->ProcessMessages();
219. Sleep(pDispParams->rgvarg[0].intVal);
220. break;
221. default:
222. return DISP_E_MEMBERNOTFOUND;
223. }
224. return S_OK;
225. }
226. };
227. wchar_t TMyGlobalFunc::Name[]=L"MyGlobalFunc";
228.
229. struct TMyActiveScriptSite
230. : IActiveScriptSite
231. {
232. TMyActiveScriptSite(TMyWin *pMyWin,TMyGlobalFunc *pMyGlobalFunc)
233. : m_iRefCount(1),m_pMyWin(pMyWin),
234. m_pMyGlobalFunc(pMyGlobalFunc){
235. }
236.
237. // IUNKnown
238. HRESULT __stdcall QueryInterface(REFIID iid, void **ppv){
239. if(iid==IID_IUnknown||iid==IID_IActiveScriptSite)
240. {
241. *ppv=this;
242. AddRef();
243. return S_OK;
244. }
245. *ppv=NULL;
246. return E_NOINTERFACE;
247. }
248. ULONG __stdcall AddRef(void) {
249. return ++m_iRefCount;
250. }
251. ULONG __stdcall Release(void) {
252. if(--m_iRefCount==0){
253. delete this;
254. return 0;
255. }
256. return m_iRefCount;
257. }
258.
259. // IActiveScriptSite
260. STDMETHOD(GetLCID)(LCID* /**//*plcid*/) {
261. return E_NOTIMPL;
262. }
263.
264. STDMETHOD(GetItemInfo)(LPCOLESTR pstrName,
265. DWORD dwReturnMask,
266. IUnknown** ppiunkItem,
267. ITypeInfo** ppti) {
268. if( (dwReturnMask & SCRIPTINFO_ITYPEINFO)!=0 ){
269. *ppti = NULL;
270. return E_FAIL;
271. }
272. if( (dwReturnMask & SCRIPTINFO_IUNKNOWN)==0 ) return E_FAIL;
273. if( ppiunkItem==NULL ) return E_POINTER;
274. *ppiunkItem = NULL;
275. if( lstrcmpW( pstrName, TMyWin::Name )==0 ) {
276. m_pMyWin->AddRef();
277. *ppiunkItem = m_pMyWin;
278. return S_OK;
279. }
280. else if( lstrcmpW( pstrName, TMyGlobalFunc::Name )==0 ) {
281. m_pMyGlobalFunc->AddRef();
282. *ppiunkItem = m_pMyGlobalFunc;
283. return S_OK;
284. }
285. return E_FAIL;
286. }
287.
288. STDMETHOD(GetDocVersionString)(BSTR* pbstrVersion) {
289. if( pbstrVersion==NULL ) return E_POINTER;
290. *pbstrVersion = ::SysAllocString(OLESTR("Script 1.0"));
291. return S_OK;
292. }
293.
294. STDMETHOD(OnScriptTerminate)(
295. const VARIANT* /**//*pvarResult*/,
296. const EXCEPINFO* /**//*pexcepinfo*/) {
297. return S_OK;
298. }
299.
300. STDMETHOD(OnStateChange)(SCRIPTSTATE /**//*ssScriptState*/) {
301. return S_OK;
302. }
303.
304. STDMETHOD(OnScriptError)(IActiveScriptError* pScriptError) {
305. EXCEPINFO e;
306. DWORD dwContext;
307. ULONG ulLine;
308. LONG lPos;
309. pScriptError->GetExceptionInfo(&e);
310. pScriptError->GetSourcePosition(&dwContext, &ulLine, &lPos);
311. char *pstrFormat = "An error occured while parsing script:"
312. " Source: %ws Error: %08X Description: %ws Line: %d";
313. char pstrStr[1024];
314. ::wsprintf( pstrStr, pstrFormat,
315. e.bstrSource,
316. e.scode,
317. e.bstrDescription,
318. ulLine+1);
319. ::MessageBox(::GetActiveWindow(), pstrStr,
320. _T("Compile Error"), MB_OK | MB_ICONEXCLAMATION | MB_SETFOREGROUND);
321. return S_OK;
322. }
323.
324. STDMETHOD(OnEnterScript)() {
325. return S_OK;
326. }
327.
328. STDMETHOD(OnLeaveScript)() {
329. return S_OK;
330. }
331. private:
332. TMyWin *m_pMyWin;
333. TMyGlobalFunc *m_pMyGlobalFunc;
334. int m_iRefCount;
335. };
336. //=============================================================
337. #endif
Unit1.cpp
1. //---------------------------------------------------------------------------
2.
3. #include <vcl.h>
4. #pragma hdrstop
5.
6. #include "Unit1.h"
7. #include "Script.h"
8. #include <utilcls.h>
9. //---------------------------------------------------------------------------
10. #pragma package(smart_init)
11. #pragma resource "*.dfm"
12. TForm1 *Form1;
13. //---------------------------------------------------------------------------
14. __fastcall TForm1::TForm1(TComponent* Owner)
15. : TForm(Owner)
16. {
17. }
18. //---------------------------------------------------------------------------
19. void __fastcall TForm1::btnRunClick(TObject *Sender)
20. {
21. TComInterface<IActiveScript> pAS;
22. pAS.CreateInstance(L"JScript");
23. if(!pAS) return;
24.
25. TComInterface<IActiveScriptParse> pASP(pAS);
26. if(!pASP) return;
27.
28. pASP->InitNew();
29.
30. TComInterface<TMyWin> pDispatch_MyWin=new TMyWin(this);
31. TComInterface<TMyGlobalFunc> pDispatch_MyGlobalFunc = new TMyGlobalFunc;
32. TComInterface<IActiveScriptSite> pActiveScriptSite_Mine =
33. new TMyActiveScriptSite(pDispatch_MyWin,pDispatch_MyGlobalFunc);
34.
35. pAS->SetScriptSite(pActiveScriptSite_Mine);
36.
37. pAS->AddNamedItem(TMyWin::Name,SCRIPTITEM_ISVISIBLE);
38. pAS->AddNamedItem(TMyGlobalFunc::Name,
39. SCRIPTITEM_ISVISIBLE|SCRIPTITEM_GLOBALMEMBERS);
40.
41. pASP->ParseScriptText(WideString(mmoScript->Lines->Text),
42. NULL,
43. NULL,
44. NULL,
45. 0,
46. 0,
47. 0,
48. NULL,
49. NULL);
50. pAS->SetScriptState(SCRIPTSTATE_STARTED);
51.
52. pAS->Close();
53. }
54. //---------------------------------------------------------------------------
55.
在自己的程序中加入脚本支持(二)
最新推荐文章于 2014-09-02 14:16:30 发布
本文介绍如何在BCB中创建VCL Form应用程序,并通过TActiveScript接口执行JScript代码,实现动态改变窗口标题、颜色及位置等功能。
部署运行你感兴趣的模型镜像
您可能感兴趣的与本文相关的镜像
ACE-Step
音乐合成
ACE-Step
ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言
4672

被折叠的 条评论
为什么被折叠?



