What have I done wrong?

Having problems with building or using CEF's C/C++ APIs? This forum is here to help. Please do not post bug reports or feature requests here.

What have I done wrong?

Postby DJackson » Fri Jan 22, 2016 3:56 pm

I've been working to display a Chromium Embedded Framework browser window in my borderless win32 window. So far the window is created and the browser loads in, but two issues have presented.

1. Messages don't seem to be getting sent to my window callback (which of course causes window dragging to not function).
2. The browser is distorting the pages (almost like only some css is being loaded)

I'm presuming this is due to some glaring mistake I've made in implementing CEF3. What I have is cobbled together from the two example projects that come with a nightly build of CEF3. So the question is, does anyone see any clear mistakes I've made in implementing the browser?

Main.cpp
Code: Select all
#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
Code: Select all
#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
Code: Select all
#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);
};


And this is how the browser is displaying pages (wikipedia.com):
Image
DJackson
Techie
 
Posts: 11
Joined: Fri Jan 22, 2016 3:48 pm

Re: What have I done wrong?

Postby magreenblatt » Fri Jan 22, 2016 9:58 pm

Did you put cef.pak next to the executable? Look at README.txt from the binary distribution for required files.
magreenblatt
Site Admin
 
Posts: 12382
Joined: Fri May 29, 2009 6:57 pm

Re: What have I done wrong?

Postby DJackson » Fri Jan 22, 2016 10:09 pm

Indeed, I had read the readme wrong and put the whole "Resources" folder next to the executable instead of the contents. That fixed the distortion, but the window still isn't receiving any mouse click messages. I wonder if this is because the messages are being sent to the browser window instead...?
DJackson
Techie
 
Posts: 11
Joined: Fri Jan 22, 2016 3:48 pm

Re: What have I done wrong?

Postby magreenblatt » Fri Jan 22, 2016 10:41 pm

Any mouse clicks on the browser window will go to the browser window. What do you want to do with the clicks? You can handle them via JS or install a mouse hook: https://msdn.microsoft.com/en-us/library/windows/desktop/ms632589(v=vs.85).aspx
magreenblatt
Site Admin
 
Posts: 12382
Joined: Fri May 29, 2009 6:57 pm

Re: What have I done wrong?

Postby DJackson » Fri Jan 22, 2016 10:42 pm

I need to be able to drag the window around since it's borderless.
DJackson
Techie
 
Posts: 11
Joined: Fri Jan 22, 2016 3:48 pm

Re: What have I done wrong?

Postby magreenblatt » Fri Jan 22, 2016 11:40 pm

In that case you can use -webkit-app-region. See https://bitbucket.org/chromiumembedded/cef/issues/1645.
magreenblatt
Site Admin
 
Posts: 12382
Joined: Fri May 29, 2009 6:57 pm

Re: What have I done wrong?

Postby DJackson » Sat Jan 23, 2016 1:28 am

viewtopic.php?f=6&t=11592

Trying to find some info on how to implement that (I've already overridden the correct functions). But I came across that post that seems to indicate that CefDragHandler is for drag and drop events as opposed to window dragging?
DJackson
Techie
 
Posts: 11
Joined: Fri Jan 22, 2016 3:48 pm

Re: What have I done wrong?

Postby magreenblatt » Sat Jan 23, 2016 3:56 pm

There is an example implementation in cefclient.
magreenblatt
Site Admin
 
Posts: 12382
Joined: Fri May 29, 2009 6:57 pm

Re: What have I done wrong?

Postby DJackson » Sat Jan 23, 2016 5:56 pm

That implementation, again, seems to be for drag & drop events. And since the cefclient sample has a regular system titlebar, they probably wouldn't have implemented window dragging anyway.
DJackson
Techie
 
Posts: 11
Joined: Fri Jan 22, 2016 3:48 pm

Re: What have I done wrong?

Postby magreenblatt » Sat Jan 23, 2016 7:09 pm

DJackson wrote:That implementation, again, seems to be for drag & drop events. And since the cefclient sample has a regular system titlebar, they probably wouldn't have implemented window dragging anyway.

Luckily that's not the case. The cefclient app supports window dragging (on Windows) using webkit-app-region. You can try it yourself -- load the example from https://bitbucket.org/chromiumembedded/ ... t-24942383 in cefclient from branch 2347 or newer. There's a minor bug with the cefclient example on high-dpi displays which has been filed as https://bitbucket.org/chromiumembedded/cef/issues/1819/.
magreenblatt
Site Admin
 
Posts: 12382
Joined: Fri May 29, 2009 6:57 pm

Next

Return to Support Forum

Who is online

Users browsing this forum: No registered users and 60 guests