前言
以前写过一个在Duilib中封装wke控件的文章:分享个Duilib中基于wke的浏览器控件,那个只是基于原始版本的wke代码编译出的头文件和dll封装的,使用中会发现网页的加载状态的回调并不及时,需要我们不断地去调用接口查询是否结束或者失败。最好的方法就是直接去修改源代码,所幸的是源代码工程已经整理得非常完善,下载下来后就可以用VS2008立即编译并且没有报错。(Wke源码位置:https://github.com/BlzFans/wke,已经很久没有更新过了,还是很感谢贡献者BlzFans)代码比较庞大,我主要还是关心网页的加载状态在内部是如何触发以及设置的。查看FrameLoaderClient类的封装,加载状态触发后是到了这里,通过更改成员变量的状态来标识,然后我们通过调用接口来查询这些标识的状态。感觉饶了一个湾子!直接把状态触发通过回调函数发出去不就可以了。
修改Wke源码
所以,我的修改就是增加回调机制,增加接口设置回调参数。(回调就是连接Wke内部和外部的桥梁)
增加回调接口类,需要加什么回调通知Wke外面都可扩展:
class IWebLoadCallback
{
public:
virtual void OnLoadStart(void* lpParam) = 0; //开始加载
virtual void OnDocumentReady(void* lpParam) = 0; //文档加载完毕
virtual void OnLoadFinish(void* lpParam) = 0; //网页加载完毕
virtual void OnLoadFail(void* lpParam) = 0; //网页加载失败
virtual bool OnNewWindow(void* lpParam, const wchar_t* pUrl, int nSize) = 0; //打开新窗口
virtual void OnTitleChange(void* lpParam, const wchar_t* pTitle, int nSize) = 0; //网页标题变化
virtual void OnUrlChange(void* lpParam, const wchar_t* pUrl, int nSize) = 0; //网页链接变化
};
在
接口类CWebView中增加接口设置回调参数
virtual void setLoadCallback(IWebLoadCallback* pCallback, void* lpParam);
回调指针初始为NULL,网页状态触发后如果外面设置了指针就会调用其对应的函数通知Wke外部,从而实现状态的主动触发。
修改后的Wke.h接口头文件
/*
*
* BlzFans@hotmail.com
* http://wke.sf.net
* http://www.github.com/BlzFans/wke
* licence LGPL
*
*/
#ifndef WKE_H
#define WKE_H
#ifdef BUILDING_wke
# define WKE_API __declspec(dllexport)
#else
# define WKE_API __declspec(dllimport)
#endif
typedef char utf8;
typedef struct {
int x;
int y;
int w;
int h;
} wkeRect;
enum wkeMouseFlags
{
WKE_LBUTTON = 0x01,
WKE_RBUTTON = 0x02,
WKE_SHIFT = 0x04,
WKE_CONTROL = 0x08,
WKE_MBUTTON = 0x10,
};
enum wkeKeyFlags
{
WKE_EXTENDED = 0x0100,
WKE_REPEAT = 0x4000,
};
enum wkeMouseMsg
{
WKE_MSG_MOUSEMOVE = 0x0200,
WKE_MSG_LBUTTONDOWN = 0x0201,
WKE_MSG_LBUTTONUP = 0x0202,
WKE_MSG_LBUTTONDBLCLK = 0x0203,
WKE_MSG_RBUTTONDOWN = 0x0204,
WKE_MSG_RBUTTONUP = 0x0205,
WKE_MSG_RBUTTONDBLCLK = 0x0206,
WKE_MSG_MBUTTONDOWN = 0x0207,
WKE_MSG_MBUTTONUP = 0x0208,
WKE_MSG_MBUTTONDBLCLK = 0x0209,
WKE_MSG_MOUSEWHEEL = 0x020A,
};
typedef void* jsExecState;
typedef __int64 jsValue;
typedef void* wkeString;
/*
*c++ interface
*-----------------------------------------------------------------------------------------------------------
*
*/
#ifdef __cplusplus
namespace wke
{
class IWebLoadCallback
{
public:
virtual void OnLoadStart(void* lpParam) = 0; //开始加载
virtual void OnDocumentReady(void* lpParam) = 0; //文档加载完毕
virtual void OnLoadFinish(void* lpParam) = 0; //网页加载完毕
virtual void OnLoadFail(void* lpParam) = 0; //网页加载失败
virtual bool OnNewWindow(void* lpParam, const wchar_t* pUrl, int nSize) = 0; //打开新窗口
virtual void OnTitleChange(void* lpParam, const wchar_t* pTitle, int nSize) = 0; //网页标题变化
virtual void OnUrlChange(void* lpParam, const wchar_t* pUrl, int nSize) = 0; //网页链接变化
};
class IWebView
{
public:
virtual void destroy() = 0;
virtual const char* name() const = 0;
virtual void setName(const char* name) = 0;
virtual bool transparent() const = 0;
virtual void setTransparent(bool transparent) = 0;
virtual void loadURL(const utf8* url) = 0;
virtual void loadURL(const wchar_t* url) = 0;
virtual voi