日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > HTML >内容正文

HTML

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

發布時間:2023/12/31 HTML 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Qt 集成miniblink浏览器库之4 解决兼容性问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

之前介紹了如何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 解决兼容性问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。