分享
 
 
 

在VC程序中支持脚本程序(-)

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

程序中使用VBScript

以下是我从几个例程中总结出的基本方法,其中没有事件的处理功能,如果要源码的话可与我联系(LiuYangquan@sina.com)

1.头文件包含

#include #include 2.在类中声明以下两个成员 IActiveScript *m_pIActiveScript; IActiveScriptParse *m_pIActiveScriptParse;3.在CMainFrame类声明中的DECLARE_MESSAGE_MAP()后加上以下代码 DECLARE_INTERFACE_MAP() BEGIN_INTERFACE_PART(ScriptSite, IActiveScriptSite) STDMETHOD(GetLCID)(LCID *plcid); STDMETHOD(GetItemInfo)(LPCOLESTR pstrName, DWORD dwReturnMask, IUnknown **ppiunkItem, ITypeInfo **ppti); STDMETHOD(GetDocVersionString)(BSTR *pszVersion); STDMETHOD(RequestItems)(void); STDMETHOD(RequestTypeLibs)(void); STDMETHOD(OnScriptTerminate)(const VARIANT *pvarResult, const EXCEPINFO *pexcepinfo); STDMETHOD(OnStateChange)(SCRIPTSTATE ssScriptState); STDMETHOD(OnScriptError)(IActiveScriptError *pscripterror); STDMETHOD(OnEnterScript)(void); STDMETHOD(OnLeaveScript)(void); END_INTERFACE_PART(ScriptSite) BEGIN_INTERFACE_PART(ScriptSiteWindow, IActiveScriptSiteWindow) STDMETHOD(GetWindow)(HWND *phwnd); STDMETHOD(EnableModeless)(BOOL fEnable); END_INTERFACE_PART(ScriptSiteWindow) /********************************************* 加上以上代码后在CMainFrame类中会多两个成员 m_xScriptSite 与 m_xScriptSiteWindow **********************************************/ //以下是从上面移下来的 IActiveScript *m_pIActiveScript; IActiveScriptParse *m_pIActiveScriptParse;4.实现3中的代码 1)在END_MESSAGE_MAP()后加上以下代码 BEGIN_INTERFACE_MAP(CMainFrame, CFrameWnd) INTERFACE_PART(CMainFrame, IID_IActiveScriptSite, ScriptSite) INTERFACE_PART(CMainFrame, IID_IActiveScriptSiteWindow, ScriptSiteWindow) END_INTERFACE_MAP() 2)实现m_xScriptSite中的成员方法 //COM interface implementation ULONG FAR EXPORT CMainFrame::XScriptSite::AddRef() { METHOD_PROLOGUE(CMainFrame, ScriptSite) return pThis-ExternalAddRef(); } ULONG FAR EXPORT CMainFrame::XScriptSite::Release() { METHOD_PROLOGUE(CMainFrame, ScriptSite) return pThis-ExternalRelease(); } HRESULT FAR EXPORT CMainFrame::XScriptSite::QueryInterface( REFIID iid, void FAR* FAR* ppvObj) { METHOD_PROLOGUE(CMainFrame, ScriptSite) return (HRESULT)pThis-ExternalQueryInterface(&iid, ppvObj); } ULONG FAR EXPORT CMainFrame::XScriptSiteWindow::AddRef() { METHOD_PROLOGUE(CMainFrame, ScriptSiteWindow) return pThis-ExternalAddRef(); } ULONG FAR EXPORT CMainFrame::XScriptSiteWindow::Release() { METHOD_PROLOGUE(CMainFrame, ScriptSiteWindow) return pThis-ExternalRelease(); } HRESULT FAR EXPORT CMainFrame::XScriptSiteWindow::QueryInterface( REFIID iid, void FAR* FAR* ppvObj) { METHOD_PROLOGUE(CMainFrame, ScriptSiteWindow) return (HRESULT)pThis-ExternalQueryInterface(&iid, ppvObj); } ///////////////////////////////////////////////////////////////////////////// // ActiveScript hosting // ##### BEGIN ACTIVEX SCRIPTING SUPPORT ##### //*************************************************************************** // IActiveScriptSite Interface //*************************************************************************** STDMETHODIMP CMainFrame::XScriptSite::GetLCID(LCID *plcid) { return E_NOTIMPL; // Use system settings } STDMETHODIMP CMainFrame::XScriptSite::GetItemInfo( LPCOLESTR pstrName, DWORD dwReturnMask, IUnknown** ppunkItemOut, ITypeInfo** pptinfoOut ) { return TYPE_E_ELEMENTNOTFOUND; } STDMETHODIMP CMainFrame::XScriptSite::GetDocVersionString(BSTR *pbstrVersion) { return E_NOTIMPL; // UNDONE: Implement this method } STDMETHODIMP CMainFrame::XScriptSite::RequestItems(void) { return E_NOTIMPL; } STDMETHODIMP CMainFrame::XScriptSite::RequestTypeLibs(void) { METHOD_PROLOGUE(CMainFrame,ScriptSite); return E_NOTIMPL; } STDMETHODIMP CMainFrame::XScriptSite::OnScriptTerminate(const VARIANT *pvarResult, const EXCEPINFO *pexcepinfo) { // UNDONE: Put up error dlg here return S_OK; } STDMETHODIMP CMainFrame::XScriptSite::OnStateChange(SCRIPTSTATE ssScriptState) { // Don't care about notification return S_OK; } //--------------------------------------------------------------------------- // Display the error //--------------------------------------------------------------------------- STDMETHODIMP CMainFrame::XScriptSite::OnScriptError(IActiveScriptError *pse) { METHOD_PROLOGUE(CMainFrame,ScriptSite); CString strError; CString strArrow; CString strDesc; CString strLine; EXCEPINFO ei; DWORD dwSrcContext; ULONG ulLine; LONG ichError; BSTR bstrLine = NULL; HRESULT hr; pse-GetExceptionInfo(&ei); pse-GetSourcePosition(&dwSrcContext, &ulLine, &ichError); hr = pse-GetSourceLineText(&bstrLine); if (hr) hr = S_OK; // Ignore this error, there may not be source available if (!hr) { strError=ei.bstrSource; strDesc=ei.bstrDescription; strLine=bstrLine; if (ichError 0 && ichError GetSafeHwnd(); return S_OK; } STDMETHODIMP CMainFrame::XScriptSiteWindow::EnableModeless(BOOL fEnable) { return S_OK; } // ##### END ACTIVEX SCRIPTING SUPPORT ##### 5.添加两个全局变量 const IID CLSID_VBScript = {0xb54f3741, 0x5b07, 0x11cf, {0xa4, 0xb0, 0x0, 0xaa, 0x0, 0x4a, 0x55, 0xe8 } }; const TCHAR* szItemName=_T("Document"); szItemName 是指在脚本中可以直接创建的对象,例如照上面的值则可以如下使用: Document.MessageBox "sldfk" 'MessageBox 是Document的方法 如果 szItemName=_T("Document1") 则以上的应写为如下形式: Document1.MessageBox "sldfk" 'MessageBox 是Document1的方法 6.创建脚本对象 HRESULT CMainFrame::CreateScriptEngine(LPCOLESTR pstrItemName) { HRESULT hr; if (m_pIActiveScript) return S_FALSE; // Already created it // Create the ActiveX Scripting Engine hr = CoCreateInstance( CLSID_VBScript, NULL, CLSCTX_INPROC_SERVER, IID_IActiveScript, (void **)&m_pIActiveScript); if (FAILED(hr)) { return E_FAIL; } // Script Engine must support IActiveScriptParse for us to use it hr = m_pIActiveScript-QueryInterface(IID_IActiveScriptParse, (void **)&m_pIActiveScriptParse); if (hr) { return hr; } hr = m_pIActiveScript-SetScriptSite(&m_xScriptSite); if (hr) return hr; // InitNew the object: hr=m_pIActiveScriptParse-InitNew(); //加入宿主对象名 USES_CONVERSION; LPCOLESTR lpostrApp = T2COLE(szItemName); hr=m_pIActiveScript-AddNamedItem(lpostrApp, SCRIPTITEM_ISVISIBLE); return hr; } // ##### END ACTIVEX SCRIPTING SUPPORT ##### 调用过程:一般在CMainFrame的OnCreate函数中调用 USES_CONVERSION; LPCOLESTR lpszT = T2COLE(szItemName); if(CreateScriptEngine(lpszT)!=S_OK) AfxMessageBox(_T("Can't load the VBScript Engine."));7.装入脚本 BOOL CMainFrame::LoadTextFile() { CFileDialog dlg(TRUE, _T("*.txt"), _T("*.txt"), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, _T("Text files (*.txt)")); if(dlg.DoModal()==IDOK) { m_strCode.Empty(); TCHAR szBuffer[256]; ifstream ifs(dlg.GetPathName()); while(ifs) { ifs.getline(szBuffer,256); m_strCode+=szBuffer; m_strCode+=_T("\r\n"); } // ##### BEGIN ACTIVEX SCRIPTING SUPPORT ##### USES_CONVERSION; EXCEPINFO ei; LPCOLESTR lpszCode = T2COLE(LPCTSTR(m_strCode)); HRESULT hr=m_pIActiveScriptParse-ParseScriptText(lpszCode, NULL, NULL, NULL, 0, 0, 0L, NULL, &ei); // ##### END ACTIVEX SCRIPTING SUPPORT ##### if(hr) { AfxMessageBox(_T("Can't compile the program.")); return FALSE; } return TRUE; } return FALSE; } 8.运行与停止脚本 m_pIActiveScript-SetScriptState(SCRIPTSTATE_CONNECTED); m_pIActiveScript-SetScriptState(SCRIPTSTATE_DISCONNECTED); 9.支持脚本宿主 在STDMETHODIMP CMainFrame::XScriptSite::GetItemInfo是得到当前宿主可支持的对象: LPCOLESTR pstrName 对象名称,如在 5 中定义的const TCHAR* szItemName=_T("Document") DWORD dwReturnMask IUnknown** ppunkItemOut ITypeInfo** pptinfoOut 返回对象 实现代码 STDMETHODIMP CMainFrame::XScriptSite::GetItemInfo( LPCOLESTR pstrName, DWORD dwReturnMask, IUnknown** ppunkItemOut, ITypeInfo** pptinfoOut ) { METHOD_PROLOGUE(CMainFrame, ScriptSite) USES_CONVERSION; LPCTSTR lpstrApplication=szItemName; if (dwReturnMask & SCRIPTINFO_ITYPEINFO) { if (!pptinfoOut) return E_INVALIDARG; *pptinfoOut = NULL; } if (dwReturnMask & SCRIPTINFO_IUNKNOWN) { if (!ppunkItemOut) return E_INVALIDARG; *ppunkItemOut = NULL; LPTSTR lpszName = OLE2T(pstrName); if(!_tcsicmp(lpstrApplication, lpszName)) { //在应用类中加入相应的Document类,并在应用的构造函数中初始化为NULL, 再在Document的构造函 //数中初始化为当前Document : theApp.m_pDoc = this ; *ppunkItemOut = theApp.m_pDoc-GetIDispatch(TRUE); return S_OK; } } return TYPE_E_ELEMENTNOTFOUND; } 10.为脚本宿主对象添加方法 在ClassView页面中右击向导自动生成的接口(假设应用程序名是AxHost,则接口是IAxHoxt),选择Add Method,在弹出的对话框中输入方法名,如GetDocumentName.其实现代码在相应的Document类中 11.添加接口对象 从ClassWizard中添加类,基类选择CCmdTarget, 并选中Automation选项,假设这里添加的类名是CMyBox,则会自动生成一个IMyBox的接口12.访问接口对象 在脚本宿主对象的接口上添加一个生成接口对象的方法,具体同10,方法应返回 LPDISPATCH ,例程如下: LPDISPATCH CAXHostDoc::GetMyBox() { CMyBox* pSprite=(CMyBox*)RUNTIME_CLASS(CMyBox)-CreateObject(); return pSprite-GetIDispatch(FALSE); } 脚本中的代码如下: dim w Document1.MessageBox "sldfk" Dim MyBox set MyBox = Document1.GetMyBox MyBox.MessageBox "这是从MyBox中弹出的消息"

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有