以文本方式查看主题 - 中文XML论坛 - 专业的XML技术讨论区 (http://bbs.xml.org.cn/index.asp) -- 『 C/C++编程思想 』 (http://bbs.xml.org.cn/list.asp?boardid=61) ---- 如何在自己的程序中加入宏的功能 (http://bbs.xml.org.cn/dispbbs.asp?boardid=61&rootid=&id=64729) |
-- 作者:卷积内核 -- 发布时间:7/18/2008 1:52:00 PM -- 如何在自己的程序中加入宏的功能 实现功能:在程序中加入执行宏语句的功能,如Microsoft Word一样,可以在里面运行宏,利用宏实现一些特殊功能。 使用技术:Automotion 程序实现:1、新建对话框程序,加入编辑框,选中其Multiline属性。 2、给编辑框关联变量:CEdit m_edit1; 3、加入新类MyScriptObject,基类为CCmdTarget, 并选中下方的Automotion。 4、给新类增加方法:打开ClassWizard,选择Automotion标签,在Class Name中选择MyScriptObject,点击Add Methods,在External name中输入Add,在返回值一项中选择long,参数列表中添加参数如下:na long;na long。 5、在MyScriptObject类中将Add方法改为:return na+nb; 6、打开MyScriptObject.h,将析构函数改为public。 7、拦截按据IDOK的BN_CLICKED消息,增加如下代码,并去掉CDialog::OnOK(); :
g_iActiveScriptSite.m_pUnkScriptObject = m_myScriptObject.GetInterface(&IID_IUnknown);
HRVERIFY(CoCreateInstance(CLSID_VBScript,NULL, CLSCTX_INPROC_SERVER, IID_IActiveScript, (void **)&m_iActiveScript), "CoCreateInstance() for CLSID_VBScript");
HRVERIFY(m_iActiveScript->QueryInterface(IID_IActiveScriptParse, (void **)&m_iActiveScriptParse), "QueryInterface() for IID_IActiveScriptParse");
HRVERIFY(m_iActiveScript->SetScriptSite(&g_iActiveScriptSite), "IActiveScript::SetScriptSite()");
HRVERIFY(m_iActiveScriptParse->InitNew(), "IActiveScriptParse::InitNew()");
HRVERIFY(m_iActiveScript->AddNamedItem(L"MyObject", SCRIPTITEM_ISVISIBLE | SCRIPTITEM_ISSOURCE), "IActiveScript::AddNamedItem()");
CString csScriptText; m_edit1.GetWindowText(csScriptText);
EXCEPINFO ei; BSTR pParseText = csScriptText.AllocSysString(); m_iActiveScriptParse->ParseScriptText(pParseText, L"MyObject", NULL, NULL, 0, 0, 0L, NULL, &ei);
m_iActiveScript->SetScriptState(SCRIPTSTATE_CONNECTED);
m_iActiveScriptParse->Release(); m_iActiveScript->Release();
8、在CMyDialog.h中的public加入如下代码: CMyScriptObject m_myScriptObject; IActiveScript *m_iActiveScript; IActiveScriptParse *m_iActiveScriptParse;
9、在CMyDialog.h中增加头文件: #include <activscp.h> #include "MyScriptObject.h"
10、在OnOK()这前加入如下代码: class MyActiveScriptSite : public IActiveScriptSite { private: ULONG m_dwRef; // Reference count public: IUnknown *m_pUnkScriptObject; // Pointer to your object that is exposed // to the script engine in GetItemInfo().
MyActiveScriptSite::MyActiveScriptSite() {m_dwRef = 1;} MyActiveScriptSite::~MyActiveScriptSite() {}
virtual HRESULT _stdcall QueryInterface(REFIID riid, void **ppvObject) { *ppvObject = NULL; return E_NOTIMPL; } virtual ULONG _stdcall AddRef(void) { return ++m_dwRef; } virtual ULONG _stdcall Release(void) { if(--m_dwRef == 0) return 0; return m_dwRef; }
virtual HRESULT _stdcall GetLCID(LCID *plcid) { return S_OK; }
virtual HRESULT _stdcall GetItemInfo(LPCOLESTR pstrName, DWORD dwReturnMask, IUnknown **ppunkItem, ITypeInfo **ppti) {
if(ppti) { *ppti = NULL;
if(dwReturnMask & SCRIPTINFO_ITYPEINFO) return TYPE_E_ELEMENTNOTFOUND; }
if(ppunkItem) { *ppunkItem = NULL;
if(dwReturnMask & SCRIPTINFO_IUNKNOWN) { if (!_wcsicmp(L"MyObject", pstrName)) { *ppunkItem = m_pUnkScriptObject; m_pUnkScriptObject->AddRef(); } } }
return S_OK; }
virtual HRESULT __stdcall GetDocVersionString(BSTR *pbstrVersion) { return S_OK; }
virtual HRESULT __stdcall OnScriptTerminate(const VARIANT *pvarResult, const EXCEPINFO *pexcepInfo) { return S_OK; }
virtual HRESULT __stdcall OnStateChange(SCRIPTSTATE ssScriptState) { return S_OK; }
virtual HRESULT __stdcall OnScriptError( IActiveScriptError *pscriptError) { static BSTR pwcErrorText; pscriptError->GetSourceLineText(&pwcErrorText);
AfxMessageBox( CString("IActiveScriptSite::OnScriptError()\n") + CString("Line: ") + CString(pwcErrorText), MB_SETFOREGROUND); ::SysFreeString(pwcErrorText); return S_OK; }
virtual HRESULT __stdcall OnEnterScript(void) { return S_OK; }
virtual HRESULT __stdcall OnLeaveScript(void) { return S_OK; } };
MyActiveScriptSite g_iActiveScriptSite;
#include <initguid.h> DEFINE_GUID(CLSID_VBScript, 0xb54f3741, 0x5b07, 0x11cf, 0xa4, 0xb0, 0x0, 0xaa, 0x0, 0x4a, 0x55, 0xe8); DEFINE_GUID(CLSID_JScript, 0xf414c260, 0x6ac0, 0x11cf, 0xb6, 0xd1, 0x00, 0xaa, 0x00, 0xbb, 0xbb, 0x58);
class OleInitClass { public: OleInitClass() { OleInitialize(NULL); } ~OleInitClass() { OleUninitialize(); } }; OleInitClass g_OleInitClass;
void HRVERIFY(HRESULT hr, char * msg) { if(FAILED(hr)) { CString str; str.Format("Error: 0x%08lx (%s)", hr, msg); AfxMessageBox(str, 0x10000); _exit(0); }
}
11、运行。找一断宏代码写入Edit,点确定就可以执行了。啊,还差一点忘说了,记得初始化COM接口呀!J
|
-- 作者:卷积内核 -- 发布时间:7/18/2008 1:55:00 PM -- 相关参考: How to add support for hosing VBScript to your MFC application SUMMARY MORE INFORMATION long gcd(long a, long b); while(h%l != 0) { void MyScriptObject::HelpAbout() void MyScriptObject::ShowValue(LPCTSTR prompt, long n) // Start inproc script engine, VBSCRIPT.DLL // Get engine's IActiveScriptParse interface. // Give engine our IActiveScriptSite interface... // Give the engine a chance to initialize itself... // Add a root-level item to the engine's name space... // Get script code... // Parse the code scriptlet... // Set the engine state. This line actually triggers the execution // Release engine... // Is it expecting an ITypeInfo? AfxMessageBox( // Global instance of our IActiveScriptSite implementation. // Script Engine CLSIDs... // Ole-initialization class. void HRVERIFY(HRESULT hr, char * msg) } After you build the project, run it, add the following VBScript to your application's edit box, then click the button: ShowValue "gcd(" & x & ", " & y & ") = ", z HelpAbout |
W 3 C h i n a ( since 2003 ) 旗 下 站 点 苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》 |
4,667.969ms |