`
yidongkaifa
  • 浏览: 4039247 次
文章分类
社区版块
存档分类
最新评论

QtWebkit嵌入flash的总结(mac平台)

 
阅读更多

1、前言:

flash是adobe公司的闭源产品,在各平台的渲染都是通过插件来进行的(如windows下的flash.ocx,linux下的libflashplugin.so和mac下的Flash_Plugin),插件可以在adobe的网站上获取。当然也有开源(如gnash)或商业项目(如scaleform)来自行对flash进行解码渲染。我使用qtwebkit嵌入flash主要是因为它相对简单。如果要在游戏中嵌入一个网页(当然也包括flash)除了昂贵的scaleform外,还可选择其他flash gui,不过因为效率原因实用性不高,其原理就是通过adobe的插件获取要渲染的每一帧图片,然后将其渲染到一张纹理上,通过引擎来渲染。说白了就是用游戏引擎来代替如windows或qt来对其进行渲染。

2、具体实现(相关资料网上有很多,这里只说原理和关键性的东东)

要加载flash进行显示(当然也包括网页),其实只需要建立一个QWebView然后调用其setUrl接口传进去要显示的文件的路径(最好是绝对路径,并且路径前加 file:///,当然,这应该不是必须的)。QWebView还有一个重要的接口是setHtml,它是传一个字符串参数,改字符串是html网页源代码形式,如"<html></html>"。

如果要进行交互,需要通过javascript进行中转(其实从原理上来说,是可以通过NP Api来直接与adobe提供的flash插件进行交互的,不过相关资料太少,俺又没有写过插件,所以选择了简单的方法)。

这里我选择的是在一个网页中嵌入flash,然后在网页的<head></head>中添加js脚本,相关资料也很多,直接google即可。

这里有一些需要注意的地方:

a、用addToJavaScriptWindowObject的时机很关键,必须要dom什么的加载完毕,官方推荐的做法是,用一个函数来调用addToJavaScriptWindowObject,将javaScriptWindowObjectCleared的信号和改函数connect。具体可以看QWebFrame中的addToJavaScriptWindowObject函数注释。

b、c++调用js函数:page()->mainFrame()->evaluateJavaScript("Test(1, 2)"),这样就可以直接调用js中的Test函数,其中1和2是参数。

c、js调用c++函数:确保a步骤已经操作,然后js中就可以直接通过addToJavaScriptWindowObject传进去对象名来调用相应QObject对象的函数。

d、js调用flash的函数:在as2.0以后可以直接使用ExternalCallback来进行,这里为了兼容以前的flash,使用了老的方法。假设网页中已经插入了一个flash,其id为flashname,使用flashname.SetVariable来修改flash中的变量。而flash的脚本中,则通过watch()方法来监视这个变量的改变,从而调用相应函数。

f、flash调用js的函数:flash中使用fscommand函数,js中只要实现flashname_DoFSCommand(cmd, args)即可自动被调用。

g、传给flash的参数(尤其是中文字符串)要是unicode编码的,否则会乱码。

最后说明一下,这些交互步骤的尤其是js调用flash函数的时机也很重要,比较早的话会出现无法响应的情况(可能要等flash完全加载完),或许新的调用方法会好些。这里我用了非常恶心的实现。建立一个定时器,当过了1秒钟(确认flash已经加载完了),才允许调用该函数。

3、qtwebkit的bug:

其实也有可能是adobe的flash插件的bug,不过反正出现问题了,而幸好webkit是开源的,俺就只好修改它了。(当然,最终也没有完美修正改bug,不过满足了俺的需要,那就够了,希望诺基亚的精英们能在下次出版本的时候解决该问题)

bug描述:在mac操作系统下,使用qtwebkit加载flash,在文本框进行输入时,按下一个键,响应两个字符。

原因:猜想是在adobe的10.1的插件自己实现了输入响应(即便我把按键消息都过滤掉,flash依然可以正常进行输入,包括中文输入),而qtwebkit又传给它一次按键信息,那就会出现该问题了。

解决办法:在pluginViewMac.mm(qt使用的就是这个文件),的dispatchNPevent函数中过滤掉按键消息

if (event.what == keyDown) { return ;}

这样flash的输入就正常了,当然,其他任何插件都无法进行正常输入了,不过俺做的是游戏,又不是浏览器,只要伺候好一个flash插件就足够了。

还有一个bug是,如果我在网页的空白地方点一下,再回到flash的文本框就无法正常输入了,即便光标什么的都在里面,除非我找到一个flash中的文本框点击一下。初步判断原因是点击到空白的地方,整个webkit的page就无法获取按键信息了,因为一个page是无法进行编辑的,除非点到一个文本框,这样又重新可获取输入信息。如果整个page都接收不到按键信息,那其中的flash插件自然也就无法进行输入了。不过悲催的是,如果我们之前咩有屏蔽掉的PluginView的keyDown信息,这个时候反而会正常的输入一个字符,当然中文依然不能正常输入。

这两个bug继续查两天看看,说不定会有新的发现。

ps:qt的版权是LGPL,可别告诉诺基亚俺改过他们的代码呀~~

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics