拖动嵌入了cef3的无标题栏win32窗口,本质上就是拖动子窗口移动父窗口这么个事情,这个在自己创建窗口的程序上处理非常简单,cef封装较多,想修改的完善点步骤较多。
cef所用版本3.2623。
就用cefclient来做测试工程,首先建议在cefclient_win.cc的RunMain函数中的app = new ClientAppRenderer();前面添加一个messagebox,打印上出进程id,如果使用命令行--renderer-startup-dialog --no-sandbox 弹出messagebox的时候,调试上去,有些类的构造过程已经过去了。
用spy++查看cefclient的窗口,可以看到最上层的是标题为Chrome Legacy Window子窗口,找到其对应的代码在CEF\source\chromium\src\content\browser\renderer_host\legacy_render_widget_host_win.h中,在类LegacyRenderWidgetHostHWND的响应函数OnMouseRange中,如果添加以下代码
if(message == WM_LBUTTONDOWN)
{
::PostMessage(HwndRootWindow,WM_NCLBUTTONDOWN,HTCAPTION,0);
}
return 0;
编译后运行,就能发现cef打开的网页,整个范围内都是可以拖动整个宿主窗体的了。如果需要显示的网页有部分比较固定不变,那么指定上点坐标范围,也能勉强凑合。不过通常情况下,显然是不够使用的,也非常不灵活。
最好的办法是,提供js接口,让前端小伙伴们自己决定哪些地方可以拖动宿主窗口。
前端来做拖拽的话,常用方法就是使用draggable属性和ondragstart回调函数了,使用此方法还有一个好处,就是浏览器已经对拖拽事件进行了识别,前端和c++端都不用再考虑这个问题以及拖拽范围的问题。先贴上测试用的html代码。
<html>
<head>
<script language="JavaScript">
function MulCall() {
alert('123456');
}
function drag(ev) {
ev.preventDefault();
ev.MoveRootWinow();
}
</script>
</head>
<body>
<input type="text" id="value_1" value="请输入" />
<br />
<br />
<input type="button" value="拖动窗口" onclick="MulCall();" draggable="true" ondragstart="drag(event)"/>
</body>
</html>
这里的js函数MoveRootWindow就是我们需要提供的函数了。这个js函数不建议采用常用的提供js接口函数的方式,而是添加到chromium\src\third_party\WebKit\Source\core\events\Event.idl这