在MFC中实现CHtmlView与Javascript交互最简单的方法

 想要在Javascript中调用C++的方法,只要实现CHtmlView的OnGetExternal方法就可以,OnGetExternal要返回一个IDispatch的指针。关于如何实现取得这个IDispatch我研究了几天,甚至把那本《Com技术内幕》都看了一遍。

我最开始尝试的方法是直接实现一个直接继承于IDispatch的类,实现它的GetIDsOfNames和Invoke等等。不知道这是不是一个最原始的方法了,虽然可以实现,但是实现的过程非常的繁琐,而且在实现Invoke的时候还要处理各种类型的变量问题。

后来尝试的是再建立一个新的atl工程,然后实现一个标准的COM组件,最后在MFC中用标准的COM组件的调用方式来取得一个接口的IDispatch指针。虽然相对上面的这个方法,在需要写的代码量上已经减少了很多了,但要生成一个dll。

最后在网上发现了一个方法,应该算算得上是最简单的方法了吧。通过CCmdTarget实现自动化服务器。

由于CHtmlView也是CCmdTarget的一个子类,所以也可以直接在CHtmlView的派生类上应用这个方法。而我采用的方法是添加一个新的类,假设名为Quote。

1. 在头文件上添加DECLARE_DISPATCH_MAP()。 由于MFC已经生成了一句DECLARE_MESSAGE_MAP(),所以可以添加在DECLARE_MESSAGE_MAP()的后面。

2. 在.CPP文件上添加

BEGIN_DISPATCH_MAP(Quote, CCmdTarget)

END_DISPATCH_MAP()

3. 再添加自己的方法。如Add

 

int Quote::add(int a, int b)

{

return a+b;

}

4. 在2步骤的两句话中间加入
DISP_FUNCTION(Quote, "add", add, VT_I4, VTS_I4 VTS_I4)
此时2中的结构应该为
BEGIN_DISPATCH_MAP(Quote, CCmdTarget)
DISP_FUNCTION(Quote, "add", add, VT_I4, VTS_I4 VTS_I4)
END_DISPATCH_MAP()
 
5. 在CHtmlView的派生类中添加一个Quote类型的指针,用来保存Quote对象,并在构造函数中为它赋值。
 
6. 重载CHtmlView的OnGetExternal方法,返回pQuote->GetIDispatch(TRUE);
这是GetIDispatch的参数一定是要TRUE。这里的原因我不作深解。
 
这时在Javascript里面调用window.external.add(1, 2);就可以了。
 
VC6下实现相对复杂一些,请看这篇文章 VC6下实现CHtmlView的external的方法

 

 



文章来自: 本站原创
Tags:
评论: 0 | 查看次数: 17357