之前介绍了如何miniblink集成到qt,采用wkeCreateWebWindow来创建一个浏览器窗口,wkeCreateWebWindow有三种方式

typedef enum _wkeWindowType {WKE_WINDOW_TYPE_POPUP,WKE_WINDOW_TYPE_TRANSPARENT,WKE_WINDOW_TYPE_CONTROL
} wkeWindowType;

WKE_WINDOW_TYPE_POPUP 创建一个弹出式窗体,模态窗体。

WKE_WINDOW_TYPE_TRANSPARENT 透明父窗口窗体

WKE_WINDOW_TYPE_CONTROL  创建一个弹出式窗体,非模态窗体。

因为要实现成一个qtwidget的子窗体,所以用了WKE_WINDOW_TYPE_TRANSPARENT来创建浏览器窗口,qt两种方式其实应用场景很有限。

这个属性创建的窗体在win7,surface系统表现异常,出现渲染布出来问题, 只有win10 表现还过得去。最后发现是因为我同时使用了两种浏览器QtWebengineView和miniblink浏览器,这两种窗体在不同系统中兼容性存在问题。

如果只是放到qtwidget上面没有啥问题。

尝试了如下方法:

1.使用WKE_WINDOW_TYPE_POPUP/WKE_WINDOW_TYPE_CONTROL表现正常,但是跟其他窗体存在层级问题

2.使用WKE_WINDOW_TYPE_TRANSPARENT创建,将窗体独立,跟上面的基本一样,不止存在层级问题,win10多桌面显示也存在问题。

所以wkeCreateWebWindow无法满足需求。

看了一下接口文件发现一个wkeCreateWebView,该函数只是创建一个对象,并不会真正绘制,绘制需要自己处理。

1.创建对象

_hWebView = wkeCreateWebView();
    wkeSetTransparent(_hWebView, false);
    wkeOnPaintUpdated(_hWebView, onPaintUpdatedCallback, this);
    wkeOnLoadUrlBegin(_hWebView, onLoadUrlBegin, (void *)this);
    wkeOnLoadUrlEnd(_hWebView, onLoadUrlEnd, (void *)this);
    wkeOnLoadUrlFail(_hWebView, onLoadUrlFailed, (void *)this);
    wkeOnLoadingFinish(_hWebView, onLoadingFinish, (void *)this);

最重要的回调函数是onPaintUpdatedCallback,因为要自己绘制,改接口在需要绘制时会回调回来。原型为:

static void onPaintUpdatedCallback(wkeWebView webView, void* param, const HDC hdc, int x, int y, int cx, int cy);

返回的是HDC,所以我们需要一个绘制窗口

2.创建一个windows 窗口对象

注册窗口类:

WNDCLASSEX wcex;

wcex.cbSize = sizeof(WNDCLASSEX);

wcex.style = CS_DBLCLKS;// CS_HREDRAW | CS_VREDRAW; //
    wcex.lpfnWndProc = webViewWndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hIcon = 0;
    wcex.hCursor = LoadCursor(0, IDC_ARROW);
    wcex.hbrBackground = 0;
    wcex.lpszMenuName = 0;
    wcex.lpszClassName = wkeWebViewClassName;
    wcex.hIconSm = 0;

return !!RegisterClassEx(&wcex);

创建窗口:

_hWnd = CreateWindow(wkeWebViewClassName, 0,
        WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
        x, y, nWeight, nHeight,
        hParent,
        0,
        0, 0);

3. 使用GDI绘制

将miniblink dc的内同绘制到我们创建窗体之上

HDC hScreenDC = ::GetDC(m_hView);
        ::BitBlt(m_hDC, x, y, m_width, m_height, hBlinkDC, x, y, SRCCOPY);
        ::BitBlt(hScreenDC, x, y, m_width, m_height, m_hDC, x, y, SRCCOPY);
        ::ReleaseDC(m_hView, hScreenDC);

4.事件处理

这种方式需要我们自己处理键盘事件,鼠标事件 如下:

LRESULT QtMiniblinkWebView::webViewClassWndProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_SETCURSOR:
        return onSetCursor(wParam, lParam);
    case WM_COMMAND:
        return onCommand(wParam, lParam);
    case WM_SIZE:
        return onSize(wParam, lParam);
    case WM_PAINT:
        return onPaint(wParam, lParam);
    case WM_KEYDOWN:
        return onKeyDown(wParam, lParam);
    case WM_KEYUP:
        return onKeyUp(wParam, lParam);
    case WM_CHAR:
        return onChar(wParam, lParam);
    case WM_LBUTTONDOWN:
    case WM_MBUTTONDOWN:
    case WM_RBUTTONDOWN:
    case WM_LBUTTONDBLCLK:
    case WM_MBUTTONDBLCLK:
    case WM_RBUTTONDBLCLK:
    case WM_LBUTTONUP:
    case WM_MBUTTONUP:
    case WM_RBUTTONUP:
    case WM_MOUSEMOVE:
        return onMouseEvent(uMsg, wParam, lParam);

case WM_MOUSEWHEEL:
        return onMouseWheel(wParam, lParam);
    case WM_SETFOCUS:
        return onSetFocus(wParam, lParam);

case WM_KILLFOCUS:
        return onKillFocus(wParam, lParam);
    case WM_IME_STARTCOMPOSITION:
        return onIMEStartComposition(wParam, lParam);
    case WM_GETDLGCODE:
        return DLGC_WANTARROWS | DLGC_WANTALLKEYS | DLGC_WANTCHARS;
    default:
        return DefWindowProc(_hWnd, uMsg, wParam, lParam);
    }

return 0;
}

其实就是将windows定义的消息转化为miniblink定义的对应消息,通过函数调用过去,如鼠标

LRESULT QtMiniblinkWebView::onMouseEvent(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    _cursorInfoType = wkeGetCursorInfoType(_hWebView);

if (uMsg == WM_LBUTTONDOWN || uMsg == WM_MBUTTONDOWN || uMsg == WM_RBUTTONDOWN) {
        SetFocus(_hWnd);
        SetCapture(_hWnd);
    } else if (uMsg == WM_LBUTTONUP || uMsg == WM_MBUTTONUP || uMsg == WM_RBUTTONUP) {
        ReleaseCapture();
    }

int x = GET_X_LPARAM(lParam);
    int y = GET_Y_LPARAM(lParam);

unsigned int flags = 0;

if (wParam & MK_CONTROL)
        flags |= WKE_CONTROL;
    if (wParam & MK_SHIFT)
        flags |= WKE_SHIFT;

if (wParam & MK_LBUTTON)
        flags |= WKE_LBUTTON;
    if (wParam & MK_MBUTTON)
        flags |= WKE_MBUTTON;
    if (wParam & MK_RBUTTON)
        flags |= WKE_RBUTTON;

//flags = wParam;

wkeFireMouseEvent(_hWebView, uMsg, x, y, flags);

return 0;
}

其他消息类似

5.win7最小化恢复未渲染

//win7最小化问题
    connect(qApp, &QApplication::applicationStateChanged, this, [=](Qt::ApplicationState state)
        {
            if (Qt::ApplicationActive == state)
            {
                RECT rc;
                ::GetClientRect(_hWnd, &rc);
                int width = rc.right - rc.left;
                int height = rc.bottom - rc.top;
                //repaint
                resize(0, 0, width-1, height-1);
                resize(0, 0, width, height);
            }
        }
        );

6.创建接口

BOOL QtMiniblinkWebView::create(int x, int y, int nWeight, int nHeight, HWND hParent)
{
    if(!_isInit)
        initialize();

_hWebView = wkeCreateWebView();
    wkeSetTransparent(_hWebView, false);
    wkeOnPaintUpdated(_hWebView, onPaintUpdatedCallback, this);
    wkeOnLoadUrlBegin(_hWebView, onLoadUrlBegin, (void *)this);
    wkeOnLoadUrlEnd(_hWebView, onLoadUrlEnd, (void *)this);
    wkeOnLoadUrlFail(_hWebView, onLoadUrlFailed, (void *)this);
    wkeOnLoadingFinish(_hWebView, onLoadingFinish, (void *)this);
    if (!_hWebView)
    {
        return FALSE;
    }

if (!registerControlerClass())
    {
        return FALSE;
    }

_hWnd = CreateWindow(wkeWebViewClassName, 0,
        WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
        x, y, nWeight, nHeight,
        hParent,
        0,
        0, 0);

if (INVALID_HANDLE_VALUE == _hWnd)
    {
        return FALSE;
    }

_hParent = hParent;

wkeSetHandle(_hWebView, _hWnd);
    resize(x, y, nWeight, nHeight);
    SetWindowLong(_hWnd, GWL_USERDATA, (LONG)this);
    SetWindowSubclass(_hParent, subClassProc, 0, (DWORD_PTR)this);
    return _pRender->init(_hWnd);
}

从创建接口可以看到我们可以传递父窗口,通过qt winId就可以拿到,这样就实现这种方法的集成。经测试这种方法表现良好。

如果需要完整源码可以留言

Qt 集成miniblink浏览器库之4 解决兼容性问题相关推荐

  1. Qt 集成miniblink浏览器库之2封装

    前面一节已经介绍了如何编译miniblink库以及如何在qt下使用,但是创立的是个独立窗体,应用中我们经常用到的是作为一个子窗体嵌入到其他窗体之中,类似QWebengnieView,本节将实现这个功能 ...

  2. Qt 集成miniblink浏览器库之1编译使用

    1.miniblink简介 miniblink是一款精简小巧的浏览器控件,由龙泉寺扫地僧基于chromium精简而成,是市面上最小巧的chromium内核控件没有之一. 它仅10余M大小,只需一个dl ...

  3. Qt 集成miniblink浏览器库之5 支持独立窗口和子窗口

    前面使用GDI绘制解决了集成到Qt的系统冲突和QWebEngineView的冲突,但仅支持作为qt的子窗体,现在将其修改为支持独立窗口的创建. 首先判断create接口传入的父窗口句柄是否是空,为空表 ...

  4. 下载文件根据浏览器判断文件名,解决兼容性问题

    兼容性解决 string FileDownloadName = string.Format("城市广告位详情{0}.xls", DateTime.Now.ToString(&quo ...

  5. Qt框架与STL库之间的巅峰对决:差异、优缺点及适用场景

    Qt框架与STL库之间的巅峰对决:差异.优缺点及适用场景 引言 对比的重要性 Qt框架与STL库简介 博客内容概览 Qt框架基础 Qt框架的特点与组成 Qt的信号槽机制 Qt容器类简介 数据结构的对比 ...

  6. Qt+腾讯IM开发笔记(一):腾讯IM介绍、使用和Qt集成腾讯IM-SDK的工程模板Demo

    若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/119305601 长期持续带来更多项目与技术分享,咨询请 ...

  7. 【Android RTMP】Android Studio 集成 x264 开源库 ( Ubuntu 交叉编译 | Android Studio 导入函数库 )

    文章目录 安卓直播推流专栏博客总结 一. x264 简介 二. x264 交叉编译 三. Android Studio 导入函数库 四. 交叉编译版本 五. GitHub 项目地址 安卓直播推流专栏博 ...

  8. QT Creator使用matlab库文件读取.mat文件数据

    QT Creator使用matlab库文件读取.mat文件数据 一.环境配置 二.关于编程介绍 三.关于使用函数的介绍 1:关于假设数据类型介绍 2:关于使用函数介绍 一.环境配置 第一步先点开我的电 ...

  9. mfc140dll 丢失 微软常用运行库_集成最新运行库、一键安装、一键到位,运行库操作简单!...

    背景有很多童鞋在安装诸如PS.vc++等软件总会提示缺少关键组件或者运行框架,也有在后台问我的,所以今天就给大家分享一下一些电脑安装软软件或者游戏常用的运行库,号主找了一些并且写了批处理直接运行就可以 ...

最新文章

  1. matlab去雾算法论文,基于matlab的图像去雾算法详细讲解与实现-附matlab实现源代码.doc...
  2. Linux中expect实现自动登录
  3. 2020-12-7(字节,半字,字,双字总结)
  4. MIGO时没发料不允许入库
  5. 酒桌上,领导将酒泼到你脸上......
  6. python简易_Python简易爬虫
  7. spring-boot actuator(监控)配置和使用
  8. 异常mongodb:Invalid BSON field name XXXXXX:YYYYY.zz
  9. Pannellum:实例之全景图预览
  10. 微信小程序 flex:1表示什么
  11. ES 索引mapping之keyword;term查询添加keyword查询;更改mapping keyword类型
  12. 【小白刷题之路Day26】令人虎躯一震的代码
  13. 解决Xcode报错“The certificate used to sign “xxxxxx” has either expired or has been revoked“
  14. [NepCTF]WEB
  15. HTML网页表格标签,HTML静态网页(标签、表格)
  16. SpringBoot整合Prometheus实现业务指标上报
  17. 计算机向u盘拷贝速度慢,U盘复制速度慢的解决措施
  18. strtok和strtok_s函数使用说明
  19. 关于串行处理过程中时序的论述
  20. ORB SLAM2源码解读(三):Frame类

热门文章

  1. 昆明收银系统:『免费收银软件』到底是馅饼还是陷井?免费背后的危害。
  2. 单片机应用系统的基本组成
  3. vue - - - - vite创建vue3项目(不使用TS)
  4. KVM中Windows网络重置常用指令
  5. 部分TD-SCDMA缩写含义
  6. 怎么用matlab计算机械手运动,Matlab Robotics ToolBox 实战 -- 斯坦福机械手运动学建模及分析...
  7. Adobe Acrobat Pro DC 2020使用教程
  8. hue mysql中文乱码_hue的历史查询记录querys乱码问题解决
  9. BAT面试官告诉你如何回答你的职业规划
  10. pyspider 爬虫教程