有时你会想让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方法时。事实上会发生好几件事儿。基本的有两件:

  1. CEF APP的browser进程处理全屏切换
  2. 全屏完毕后,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插件的全屏切换处理的更多相关文章

  1. 基于Ascensor.js全屏切换页面插件

    今天给大家分享一款基于Ascensor.js全屏切换页面插件,这款实例 适用浏览器:IE8.360.FireFox.Chrome.Safari.Opera.傲游.搜狗.世界之窗.效果图如下: 在线预览 ...

  2. jQuery插件开发——全屏切换插件

    这个插件包含三个部分:HTML结构.CSS代码和JS代码. HTML结构是固定的,结构如下: <!--全屏滚动--> <div class="fullpage-contai ...

  3. 原生JS实现全屏切换以及导航栏滑动隐藏及显示——重构前

    思路分析: 向后滚动鼠标滚轮,页面向下全屏切换:向前滚动滚轮,页面向上全屏切换.切换过程为动画效果. 第一屏时,导航栏固定在页面顶部,切换到第二屏时,导航条向左滑动隐藏.切换回第一屏时,导航栏向右滑动 ...

  4. jQuery鼠标滚动垂直全屏切换代码

    体验效果:http://hovertree.com/texiao/jquery/68/ 源码下载:http://hovertree.com/h/bjaf/f643upc4.htm 代码如下: < ...

  5. HTML5实现网页的全屏切换

    使用HTML5提供的JavaScript Api可以实现主流浏览器的全屏和退出全屏操作,封装成进入全屏和退出全屏的函数如下: //进入全屏 function enterFullScreen() { v ...

  6. VirtualBox全屏切换

    用VirtualBox的时候,如果设置为全屏,想再切换回来,没有什么菜单,只有通过键盘的快捷键来操作,才可以恢复. 我常常忘掉,所以老是得去找,以后需要记住这几个按键的快捷键. 1.全屏与非全屏切换: ...

  7. jquery简单的大背景banner图片全屏切换

    详细内容请点击 这个是我初毕业刚进公司那会帮同事(同时也是同学)写的一个PC端的全屏图片切换效果,对于刚毕业的我来说写出来那会的喜悦之情是无法言表的,那时的我还是什么不懂的小白白,俗称菜鸟.个人网站上 ...

  8. jquery横向纵向鼠标滚轮全屏切换

    html <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF- ...

  9. js实现网页全屏切换(平滑过渡),鼠标滚动切换

    实现效果为页面平滑过渡全屏切换,点击导航和鼠标滚动都可以切换. 效果图: html代码: <!DOCTYPE html> <html> <head lang=" ...

随机推荐

  1. Kafka的3节点集群详细启动步骤(Zookeeper是外装)

    首先,声明,kafka集群是搭建在hadoop1.hadoop2和hadoop3机器上. kafka_2.10-0.8.1.1.tgz的1或3节点集群的下载.安装和配置(图文详细教程)绝对干货 如下分 ...

  2. vue-clickoutside d

    js文件 export default { bind(el, binding, vnode) { function documentHandler(e) { if (el.contains(e.tar ...

  3. android黑科技系列——获取加固后应用App的所有方法信息

    一.前言 在逆向应用的时候,我们有时候希望能够快速定位到应用的关键方法,在之前我已经详细介绍了一个自己研发的代码动态注入工具icodetools,来进行动态注入日志信息到应用中,不了解的同学可以查看这 ...

  4. 【技术累积】【点】【java】【30】代理模式

    基础 代理模式是Java常见的设计模式之一.所谓代理模式是指客户端并不直接调用实际的对象,而是通过调用代理,来间接的调用实际的对象. 什么是代理 参考现实生活中的代理 比如某个品牌的某个省的代理商,作 ...

  5. 扩增子图表解读5火山图:差异OTU的数量及变化规律

    火山图 Volcano plot 在统计学上,火山图是一种类型的散点图,被用于在大数据中快速鉴定变化.由于它的形成像火山喷发的样子,所以被称为火山图.和上文讲的曼哈顿图类似.   火山图基本元素 火山 ...

  6. cshtml中字符串中表示特殊字符@

    用“@@”表示字符串中的特殊字符@

  7. zk strom 本地环境启动命令

    bin/zkServer.sh statusbin/zkServer.sh startbin/storm nimbus &bin/storm ui &bin/storm drpc &a ...

  8. 洛谷 1486 郁闷的出纳员【Treap】

    [题意概述] 要求维护一个序列支持以下操作: 1,插入元素x: 2,把序列的所有元素加上x: 3,把序列的所有元素减去x,同时低于一个给定的下限的元素马上被删除: 4,询问序列中第k大的元素. [题解 ...

  9. Contest Round #451 (Div. 2)F/Problemset 898F Restoring the Expression

    题意: 有一个a+b=c的等式,去掉两个符号,把三个数连在一起得到一个数 给出这个数,要求还原等式,length <= 1e6 三个数不能含有前导0,保证有解 解法: 铁头过题法,分类然后各种判 ...

  10. Mysql学习总结(41)——MySql数据库基本语句再体会

    1.数据定义语言(DDL):定义和管理数据对象,比如建立数据库.数据表 数据操作语言(DML):用于操作数据库对象中的包含的数据. 数据查询语言(DQL):用于查询数据库对象中包含的数据,能够对表进行 ...