CEF3浏览器错误地显示页面

时间:2016-01-22 19:46:26

标签: c++ winapi chromium-embedded

我一直在我的无边框win32窗口中显示Chromium Embedded Framework浏览器窗口。到目前为止,窗口已创建并且浏览器已加载,但已出现两个问题。

  1. 消息似乎没有被发送到我的窗口回调(这当然会导致窗口拖动不起作用)。
  2. 浏览器正在扭曲页面(几乎只有一些css正在加载)
  3. 我认为这是由于我在实施CEF3时犯下的一些明显错误。我所拥有的是从两个带有CEF3每晚构建的示例项目拼凑而成的。所以问题是,有没有人看到我在实施浏览器时犯过的任何明显错误?

    这是我的Main.cpp

    #include <Windows.h>
    
    #include "include/cef_base.h"
    #include "include/cef_app.h"
    #include "ClientApp.h"
    #include "ClientHandler.h"
    
    #pragma comment(lib, "lib/libcef.lib")
    #pragma comment(lib, "lib/libcef_dll_wrapper.lib")
    
    // Fix Conflicting Macros
    #define GET_X_LPARAM(lp)    ((int)(short)LOWORD(lp))
    #define GET_Y_LPARAM(lp)    ((int)(short)HIWORD(lp))
    
    // Window Variables
    HINSTANCE g_instance;
    HWND g_hwnd;
    LPCWSTR g_window_class = L"MyUI";
    INT g_window_width = 670;
    INT g_window_height = 540;
    BOOL g_drag_window = false;
    SHORT g_mouse_x, g_mouse_y, g_mouse_x_prev, g_mouse_y_prev;
    
    // CEF Variables
    CefRefPtr<ClientApp> g_app;
    CefRefPtr<ClientHandler> g_client_handler;
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)
        {
            case WM_DESTROY:
            {
                CefQuitMessageLoop();
                PostQuitMessage(0);
                break;
            }
    
            case WM_CREATE:
            {
                // Set window attributes
                RECT rect;
                GetClientRect(hWnd, &rect);
                CefWindowInfo info;
                info.SetAsChild(hWnd, rect);
    
                // Set browser settings
                CefBrowserSettings settings;
    
                //Create handler
                ::g_client_handler = new ClientHandler();
    
                // Create browser
                CefBrowserHost::CreateBrowserSync(info, ::g_client_handler.get(), 
                    "http://wikipedia.com", settings, NULL);
    
                break;
            }
    
            case WM_LBUTTONDOWN:
            {
                g_mouse_x = GET_X_LPARAM(lParam);
                g_mouse_y = GET_Y_LPARAM(lParam);
                if (g_mouse_y < 41)
                {
                    g_mouse_x_prev = g_mouse_x;
                    g_mouse_y_prev = g_mouse_y;
                    SetCapture(hWnd);
                    g_drag_window = true;
                }
                MessageBox(NULL, L"FLDKSJA", L"", MB_OK);
                break;
            }
    
            case WM_LBUTTONUP:
            {
                if (g_drag_window)
                {
                    g_drag_window = false;
                    ReleaseCapture();
                }
                break;
            }
    
            case WM_MOUSEMOVE:
            {
                if (g_drag_window && (wParam & MK_LBUTTON))
                {
                    // code executed when the dialog window is moved around on the screen
                    RECT win_rect;
                    GetWindowRect(hWnd, &win_rect);
                    int x_coord = GET_X_LPARAM(lParam);
                    int y_coord = GET_Y_LPARAM(lParam);
                    MoveWindow(hWnd,
                        win_rect.left + x_coord - g_mouse_x_prev,
                        win_rect.top + y_coord - g_mouse_y_prev,
                        win_rect.right - win_rect.left,
                        win_rect.bottom - win_rect.top,
                        false
                        );
                    return 0;
                }
                break;
            }
    
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
        }
    }
    
    BOOL InitWindow()
    {
        WNDCLASSEX wc;
    
        // Register window class
        wc.cbSize = sizeof(WNDCLASSEX);
        wc.style = CS_DROPSHADOW;
        wc.lpfnWndProc = WndProc;
        wc.cbClsExtra = 0;
        wc.cbWndExtra = 0;
        wc.hInstance = ::g_instance;
        wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        wc.hCursor = LoadCursor(NULL, IDC_ARROW);
        wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
        wc.lpszMenuName = NULL;
        wc.lpszClassName = ::g_window_class;
        wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    
        if (!RegisterClassEx(&wc))
        {
            wchar_t msg[100];
            wsprintf(msg, L"Unable to register class!\nError: %i", GetLastError());
            MessageBox(NULL, msg, L"Error!",
                MB_ICONEXCLAMATION | MB_OK);
            return FALSE;
        }
    
        // Create window
        ::g_hwnd = CreateWindowEx(
            0,                        // Optional window styles.
            ::g_window_class,         // Window class
            L"",                      // Window text
            WS_POPUP,     // Window style
    
            // Position and size
            CW_USEDEFAULT, CW_USEDEFAULT, ::g_window_width, ::g_window_height,
    
            NULL,       // Parent window    
            NULL,       // Menu
            ::g_instance,  // Instance handle
            NULL        // Additional application data
            );
    
        if (!::g_hwnd)
        {
            wchar_t msg[100];
            wsprintf(msg, L"Unable to create window!\nError: %i", GetLastError());
            MessageBox(NULL, msg, L"Error!",
                MB_ICONEXCLAMATION | MB_OK);
            return FALSE;
        }
    
        //Display window
        ShowWindow(::g_hwnd, SW_SHOWNORMAL);
        UpdateWindow(::g_hwnd);
    
        return TRUE;
    }
    
    INT APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, INT nCmdShow)
    {
        UNREFERENCED_PARAMETER(hPrevInstance);
        UNREFERENCED_PARAMETER(lpCmdLine);
    
        ::g_instance = hInstance;
    
        // Provide CEF with command-line arguments.
        CefMainArgs main_args(hInstance);
    
        // CEF applications have multiple sub-processes (render, plugin, GPU, etc)
        // that share the same executable. This function checks the command-line and,
        // if this is a sub-process, executes the appropriate logic.
        int exit_code = CefExecuteProcess(main_args, NULL, NULL);
        if (exit_code >= 0) {
            // The sub-process has completed so return here.
            return exit_code;
        }
    
        // Specify CEF global settings here.
        CefSettings settings;
        settings.no_sandbox = true;
        settings.multi_threaded_message_loop = false;
        settings.pack_loading_disabled = true;
    
        // ClientApp implements application-level callbacks for the browser process.
        ::g_app = new ClientApp();
    
        // Initialize CEF.
        CefInitialize(main_args, settings, ::g_app.get(), NULL);
    
        // Create main window.
        if (!InitWindow())
        {
            CefShutdown();
            return 1;
        }
    
        // Process messages.
        MSG msg;
        while (GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
    
            CefDoMessageLoopWork();
        }
    
        // Shut down CEF.
        CefShutdown();
    
        return 0;
    }
    

    ClientApp.h

    #pragma once
    #include "include/cef_app.h"
    
    class ClientApp : public CefApp,
                      public CefBrowserProcessHandler,
                      public CefRenderProcessHandler
    {
    public:
        ClientApp();
        ~ClientApp();
    
        // CefBase
        IMPLEMENT_REFCOUNTING(ClientApp);
    
        // CefApp
        virtual CefRefPtr<CefBrowserProcessHandler> GetBrowserProcessHandler()
        {
            return this; 
        }
    
        virtual CefRefPtr<CefRenderProcessHandler> GetRenderProcessHandler()
        {
            return this;
        }
    
        //Context
        virtual void OnContextCreated(CefRefPtr<CefBrowser> browser,
            CefRefPtr<CefFrame> frame,
            CefRefPtr<CefV8Context> context);
    };
    

    ClientHandler.h

    #pragma once
    #include "include\cef_client.h"
    
    class ClientHandler : public CefClient,
                          public CefLifeSpanHandler,
                          public CefLoadHandler
    {
    public:
        ClientHandler();
        ~ClientHandler();
    
        // CefClient
        virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler()
        {
            return this;
        }
        virtual CefRefPtr<CefLoadHandler> GetLoadHandler()
        { 
            return this;
        }
    
    
        // CefBase
        IMPLEMENT_REFCOUNTING(ClientHandler);
    };
    

    这就是浏览器显示Wikipedia.com的方式: enter image description here

1 个答案:

答案 0 :(得分:0)

以下是单线程和多线程的通用代码。

if (!settings.multi_threaded_message_loop) {
  // Run the CEF message loop. Blocks until recieves a WM_QUIT message.
  CefRunMessageLoop();
} else {
  MSG msg;
  // Run the application message loop.
  while (GetMessage(&msg, NULL, 0, 0)) {
  if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }
}

换句话说,单独尝试CefRunMessageLoop()。