PPAPI插件的全屏切换处理
有时你会想让PPAPI插件全屏(比方播放视频时),这次来看看怎么做。
PPAPI和CEF App两側都要处理。
foruok原创,转载请注明出处。欢迎关注foruok的订阅号“程序视界”(programmer_sight)。
PPAPI插件中的处理
要支持全屏切换。PPAPI插件这側,有两处须要处理:
- 使用PPB_Fullscreen。调用SetFullscreen方法
- 在PPP_Instance的DidChangeView方法中重建Graphics 2D或Graphics 3D
PPB_Fullscreen接口
在PPP_InitializeModule方法里增加以下代码:
ppb_fullscreen = (const PPB_Fullscreen*)get_browser_interface(PPB_FULLSCREEN_INTERFACE);
获取到PPB_Fullscreen接口后,能够在合适的地方写下相似以下的代码来完毕全屏切换:
...
// fs defined somewhere
ppb_fullscreen->SetFullscreen(pp_inst, fs == PP_TRUE ? PP_FALSE : PP_TRUE);
...
须要注意的是。SetFullscreen是异步的。当你调用SetFullscreen(pp_inst, PP_TRUE)之后,并不会立即进入进入全屏状态,此时你调用PPB_Fullscreen的GetScreenSize方法,获取到的可能是一个中间状态。所以,在接下来的DidChangeView方法中,须要应对这样的中间状态。
DidChangeView重建图形上下文
DidChangeView中,须要先释放之前创建image data,释放Graphics 2D。相似以下的代码:
PP_Resouce image; //somewhere
ppb_image_data->Unmap(image);
ppb_core->Release(image);
ppb_instance->BindGraphics(pp_inst, NULL);
ppb_core->Release(graphics);
然后再又一次创建一遍。详细能够參考PPAPI插件与浏览器的交互过程及其他文章。
CEF APP側响应全屏操作
当我们在PPAPI中调用PPB_Fullscreen的SetFullscreen方法时。事实上会发生好几件事儿。基本的有两件:
- CEF APP的browser进程处理全屏切换
- 全屏完毕后,PPAPI側收到DidChangeView消息
如今就来看browser进程的处理。
CefDisplayHandler类有一个与全屏相关的方法须要重写:
virtual void OnFullscreenModeChange(CefRefPtr<CefBrowser> browser,
bool fullscreen)
在这种方法里,你能够让窗体全屏或恢复。
有一点须要注意。有的浏览器实现,收到全屏模式变化消息时。(Windows上)会相似以下这样处理:
ShowWindow(browser->GetHost()->GetWindowHandle(), fullscreen ? SW_MAXIMIZE : SW_RESTORE);
这样的处理。全屏相应窗体最大化,非全屏就回到最大化前的状态。可能导致一定的问题,比方PPAPI觉得是全屏。获取的screen size是整个屏幕的尺寸。而浏览器窗体实际上仅仅占领了任务栏之外的地方。这样的话。PPAPI插件就会被切边,显示不完整。
chromium的源代码里,pepper_plugin_instance_impl.cc中。就针对这样的情况。特别处理了flash插件。当检測到当前PPAPI插件时flash时,hook了一下,GetScreenSize返回实际窗体区域大小。
这样flash插件就工作正常了。但我们写的则不会哈。
所以,假设你真想全屏。能够參考以下的代码:
void ClientHandler::OnFullscreenModeChange(CefRefPtr<CefBrowser> browser, bool fullscreen)
{
HWND hwndBrowser = browser->GetHost()->GetWindowHandle();
if (fullscreen)
{
RECT rc;
GetWindowRect(hwndBrowser, &rc);
m_browserRects[hwndBrowser] = rc;
HWND hwndDesktop = GetDesktopWindow();
RECT rcDesktop;
GetWindowRect(hwndDesktop, &rcDesktop);
SetWindowLongPtr(hwndBrowser, GWL_STYLE, WS_VISIBLE);
SetWindowPos(hwndBrowser, HWND_TOPMOST, 0, 0, rcDesktop.right, rcDesktop.bottom, SWP_SHOWWINDOW);
}
else
{
RECT rc = m_browserRects[hwndBrowser];
SetWindowLongPtr(hwndBrowser, GWL_STYLE, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE);
SetWindowPos(hwndBrowser, HWND_NOTOPMOST, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, SWP_SHOWWINDOW);
}
}
上面的代码。每次切换到全屏模式前,先保存窗体位置。
从全屏退出时,再恢复。
就这样吧。
其他參考文章详见我的专栏:【CEF与PPAPI开发】。
PPAPI插件的全屏切换处理的更多相关文章
- 基于Ascensor.js全屏切换页面插件
今天给大家分享一款基于Ascensor.js全屏切换页面插件,这款实例 适用浏览器:IE8.360.FireFox.Chrome.Safari.Opera.傲游.搜狗.世界之窗.效果图如下: 在线预览 ...
- jQuery插件开发——全屏切换插件
这个插件包含三个部分:HTML结构.CSS代码和JS代码. HTML结构是固定的,结构如下: <!--全屏滚动--> <div class="fullpage-contai ...
- 原生JS实现全屏切换以及导航栏滑动隐藏及显示——重构前
思路分析: 向后滚动鼠标滚轮,页面向下全屏切换:向前滚动滚轮,页面向上全屏切换.切换过程为动画效果. 第一屏时,导航栏固定在页面顶部,切换到第二屏时,导航条向左滑动隐藏.切换回第一屏时,导航栏向右滑动 ...
- jQuery鼠标滚动垂直全屏切换代码
体验效果:http://hovertree.com/texiao/jquery/68/ 源码下载:http://hovertree.com/h/bjaf/f643upc4.htm 代码如下: < ...
- HTML5实现网页的全屏切换
使用HTML5提供的JavaScript Api可以实现主流浏览器的全屏和退出全屏操作,封装成进入全屏和退出全屏的函数如下: //进入全屏 function enterFullScreen() { v ...
- VirtualBox全屏切换
用VirtualBox的时候,如果设置为全屏,想再切换回来,没有什么菜单,只有通过键盘的快捷键来操作,才可以恢复. 我常常忘掉,所以老是得去找,以后需要记住这几个按键的快捷键. 1.全屏与非全屏切换: ...
- jquery简单的大背景banner图片全屏切换
详细内容请点击 这个是我初毕业刚进公司那会帮同事(同时也是同学)写的一个PC端的全屏图片切换效果,对于刚毕业的我来说写出来那会的喜悦之情是无法言表的,那时的我还是什么不懂的小白白,俗称菜鸟.个人网站上 ...
- jquery横向纵向鼠标滚轮全屏切换
html <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF- ...
- js实现网页全屏切换(平滑过渡),鼠标滚动切换
实现效果为页面平滑过渡全屏切换,点击导航和鼠标滚动都可以切换. 效果图: html代码: <!DOCTYPE html> <html> <head lang=" ...
随机推荐
- JavaScript--编程题
某班的成绩出来了,现在老师要把班级的成绩打印出来. 效果图: XXXX年XX月X日 星期X--班级总分为:81 格式要求: 1.显示打印的日期. 格式为类似“XXXX年XX月XX日 星期X” 的当前的 ...
- 给网站添加运行时间的JavaScript完整代码
function secondToDate(second) { if (!second) { return 0; } var time = new Array(0, 0, 0, 0, 0); if ( ...
- Android 微信分享不出去?四步搞定!
现在做的项目中集成了友盟分享,产品要求集成微信.朋友圈.QQ.QQ空间.短信这几个分享平台.按照友盟的文档集成一切都很顺利,集成成功以后测试QQ.QQ空间.短信都没有问题,唯独微信和朋友圈一直分享不出 ...
- iOS开发中如何实现同步、异步、GET、POST等请求实操演示!
1.同步请求可以从因特网请求数据,一旦发送同步请求,程序将停止用户交互,直至服务器返回数据完成,才可以进行下一步操作, 2.异步请求不会阻塞主线程,而会建立一个新的线程来操作,用户发出异步请求后,依然 ...
- Linux基础之网络协议
互联网通信原理 从物理层面来说,每台计算机在一开始都是彼此孤立的,为了实现信息的交流与共享,计算机之间必须要建立通信网络.例如人与人之间的交流,他们必须要共用一套语言系统,才能交流成功.计算机之间也是 ...
- THREE.DecalGeometry(转载)
function getDecalGeometry(position, direction){ var decalGeometry = new THREE.DecalGeometry( earthMe ...
- mvc 类中对应数据库属性
[StringLength()] //可空 对应数据库可空 [DefaultValue("")] [DisplayName("添加人用户名")] public ...
- R语言图表
条形图 在R语言中创建条形图的基本语法是 barplot(H, xlab, ylab, main, names.arg, col) H是包含在条形图中使用的数值的向量或矩阵 xlab是x轴的标签 yl ...
- Java中的接口详解
接口 是Java语言中一种引用类型,是方法的集合,如果说类的内部封装了成员变量.构造方法和成员方法,那么接口的内部主要就是封装了方法,包含抽象方法(JDK 7及以前),默认方法和静态方法(JDK 8) ...
- vue04 组件化开发 Vue自动化工具
5. 组件化开发 5.1 组件[component] 组件(Component)是自定义封装的功能.在前端开发过程中,经常出现多个网页的功能是重复的,而且很多不同的网站之间,也存在同样的功能. 而在网 ...