实验了一个比较奇特的东西,在PPAPI插件里创建一个本地窗口,叠加在插件在网页的位置上。
CEF3默认是多进程架构,PPAPI插件在一个单独进程里跑,这个进程没启动Windows的消息循环,所以,要创建插件的话,得自己搞一个消息循环。另外浏览器窗口属于别的进程,怎么把创建出来的窗口成为浏览器窗口的子窗口,也是个问题。这个第一个要解决的问题。
CEF3还支持单进程运行,Browser、Render、Plugin合一,此时创建本地窗口又和多进程不同。这是第二个问题。
第三个问题是,如何把窗口定位到网页的插件区域。
琢磨了下,都解决了。
foruok原创,如需转载请关注foruok的微信订阅号“程序视界”联系foruok。
效果
先看看效果图。先是跨进程的:
灰色区域那里是我创建的本地窗口,上面有一行字。
再看同一进程的:
注意文字的变化。
代码
Talk is cheap,show me the code:
/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
* 2016-1-13, edited by foruok.
* 如需转载,请关注微信订阅号“程序视界”,回复foruok获取其联系方式
*
*/
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <Windows.h>
#include <tchar.h>
#include "ppapi/c/pp_completion_callback.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/c/pp_module.h"
#include "ppapi/c/pp_rect.h"
#include "ppapi/c/pp_var.h"
#include "ppapi/c/ppb.h"
#include "ppapi/c/ppb_core.h"
#include "ppapi/c/ppb_graphics_2d.h"
#include "ppapi/c/ppb_image_data.h"
#include "ppapi/c/ppb_instance.h"
#include "ppapi/c/ppb_view.h"
#include "ppapi/c/ppp.h"
#include "ppapi/c/ppp_instance.h"
#include "ppapi/c/ppb_input_event.h"
#include "ppapi/c/ppp_input_event.h"
PPB_GetInterface g_get_browser_interface = NULL;
const PPB_Core* g_core_interface;
const PPB_Graphics2D* g_graphics_2d_interface;
const PPB_ImageData* g_image_data_interface;
const PPB_Instance* g_instance_interface;
const PPB_View* g_view_interface;
const PPB_InputEvent *g_input_interface;
const PPB_MouseInputEvent *g_mouse_interface;
/******foruok: create native window begin******/
static HWND g_child_window = NULL;
struct CreateChildWinParam {
struct PP_Rect r;
HWND hWndParent;
};
HANDLE g_hThread = NULL;
DWORD g_dwThreadId = 0;
BOOL g_bInProcess = 0;
static LRESULT CALLBACK VideoWindowProc(HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
PAINTSTRUCT ps;
HDC hdc;
RECT r;
TCHAR textIn[] = _T("Child Window(in-process)");
TCHAR text[] = _T("Child Window(out-process)");
switch (uMsg)
{
case WM_PAINT:
GetClientRect(hwnd, &r);
hdc = BeginPaint(hwnd, &ps);
SetTextColor(hdc, RGB(0, 200, 0));
FillRect(hdc, &r, GetStockObject(GRAY_BRUSH));
if (g_bInProcess)
{
TextOut(hdc, 10, 50, textIn, ARRAYSIZE(textIn) - 1);
}
else
{
TextOut(hdc, 10, 50, text, ARRAYSIZE(text) - 1);
}
EndPaint(hwnd, &ps);
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
static void RegisterVideoWindowClass()
{
WNDCLASSEX wcex = {
/* cbSize = */ sizeof(WNDCLASSEX),
/* style = */ CS_HREDRAW | CS_VREDRAW,
/* lpfnWndProc = */ VideoWindowProc,
/* cbClsExtra = */ 0,
/* cbWndExtra = */ 0,
/* hInstance = */ GetModuleHandle(NULL),