CEF3 + Win32

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.

CEF3 + Win32

Postby bezbot » Fri Jan 08, 2016 7:15 am

I need to add CEF3 support to old C++ projects based on pure Win32 or MFC. I need to render HTML output to specific control in existing Win32 dialog or existing MFC dialog (In real project I will need to show HTML help embedded to resources in exe file). Therefore I need to create Win32 dialog manually and also need to have my own message loop. I have found some code snippets how to do that, but with recent CEF version it can not be even compiled because method CreateBrowser no longer accepts four parameters.

Can you help me?

But please do tell me I need to look to cefclient or to cefsimple project. I have been looking at it over and over again and I really can't see any solution there - I really need to create my own window and my own message loop, otherwise upgrade of the old project will be too complex.

Thanks.

Code: Select all
#include <Windows.h>
#include <CommCtrl.h>
#include <tchar.h>
#include "MyCefClient.h"
#include "resource.h"
#include "include/cef_app.h"
#include "include/cef_browser.h"

INT_PTR CALLBACK DialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
   switch(uMsg)
   {
   case WM_COMMAND:
      switch(LOWORD(wParam))
      {
      case IDCANCEL:
         SendMessage(hDlg, WM_CLOSE, 0, 0);
         return TRUE;
      }
      break;

   case WM_CLOSE:
      if(MessageBox(hDlg, TEXT("Close the program?"), TEXT("Close"),
         MB_ICONQUESTION | MB_YESNO) == IDYES)
      {
         DestroyWindow(hDlg);
      }
      return TRUE;

   case WM_DESTROY:
      CefQuitMessageLoop();
      PostQuitMessage(0);
      return TRUE;
   }

   return FALSE;
}

int WINAPI _tWinMain(HINSTANCE hInst, HINSTANCE h0, LPTSTR lpCmdLine, int nCmdShow)
{
   HWND hDlg;
   MSG msg;
   BOOL ret;

   InitCommonControls();
   hDlg = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_DIALOG1), 0, DialogProc, 0);
   ShowWindow(hDlg, nCmdShow);

   HWND hGroupBox = GetDlgItem(hDlg, IDC_GROUPBOX1);
   SetWindowText(hGroupBox, L"Chromium Embedded Output");
   
   CefRefPtr<MyCefClient> cefHandler(new MyCefClient());
   
   RECT rect;
   GetClientRect(hGroupBox, &rect);
   CefWindowInfo info;
   info.SetAsChild(hGroupBox, rect);
   CefBrowserSettings settings;
   CefString path = "www.google.com";
   CefBrowserHost::CreateBrowser(info, cefHandler.get(), path, settings);

   while((ret = GetMessage(&msg, 0, 0, 0)) != 0)
   {
      if(ret == -1)
         return -1;

      if(!IsDialogMessage(hDlg, &msg)) {
         TranslateMessage(&msg);
         DispatchMessage(&msg);
      }
   }

   return 0;
}
bezbot
Techie
 
Posts: 11
Joined: Fri Jan 08, 2016 6:55 am

Re: CEF3 + Win32

Postby magreenblatt » Fri Jan 08, 2016 11:47 am

You can pass NULL for the new CefRequestContext argument to CreateBrowser.
magreenblatt
Site Admin
 
Posts: 12409
Joined: Fri May 29, 2009 6:57 pm

Re: CEF3 + Win32

Postby bezbot » Tue Jan 12, 2016 5:39 am

I can use NULL, but still I can't see how to make CEF to use my window (to be more specific - just small area of my window). I need to have a treelist and few buttons in my window, also there is an group box - this group box can be hidden in real application, it just represents an area where to render HTML data.
bezbot
Techie
 
Posts: 11
Joined: Fri Jan 08, 2016 6:55 am

Re: CEF3 + Win32

Postby bezbot » Tue Jan 12, 2016 7:54 am

For me it seems that all CEF3 functions create window internally therefore I can't simply change window style to WS_CHILD, also I can't simply change window parent.

Also I can't simply change the method for receiving windows messages- in my example it is called DialogProc(HWND hDlg...). Therefore for me seems impossible to embedd HTML browser to my pure Win32 window (I don't really need to use MFC right now)
bezbot
Techie
 
Posts: 11
Joined: Fri Jan 08, 2016 6:55 am

Re: CEF3 + Win32

Postby magreenblatt » Tue Jan 12, 2016 11:37 am

Where are you calling CefInitialize and what arguments are you passing to it? See https://bitbucket.org/chromiumembedded/ ... ntegration for your message loop options.
magreenblatt
Site Admin
 
Posts: 12409
Joined: Fri May 29, 2009 6:57 pm

Re: CEF3 + Win32

Postby bezbot » Thu Jan 14, 2016 6:42 am

Now I know that I have to override method OnContextInitialized in class CefApp. Such descendant of CefApp is passed to Initialize method.

I have implemented it to new test project. I works partially - outside of visual studio it raises null pointer exception and does not work at all. Inside of visual studio is an assert dialog shown 7x, then my dialog is shown and html page is rendered into area defined by group box (I can see google home page). After closing dialog few more assert dialogs is shown and at the end it raises null pointer exception.

Also I can see a strange behaviour there are two instances of my dialog - one is working, second one is shown but not responding. I don't know what I'm doing wrong. Full test project source code is attached.
Attachments
CEF-DlgTest.zip
(21.04 KiB) Downloaded 795 times
bezbot
Techie
 
Posts: 11
Joined: Fri Jan 08, 2016 6:55 am

Re: CEF3 + Win32

Postby bezbot » Mon Jan 18, 2016 3:46 am

Current initialization code is below. Can you see any mistake?

Code: Select all
INT_PTR CALLBACK DialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    {
    case WM_COMMAND:
    ...
    ...
    //button click events
    ...
    ...
    case WM_CLOSE:
        if (pCefApp!=NULL)
        {
            if(pCefApp!=NULL)
            {
                if (pCefApp->GetCefClient()!=NULL)
                {
                    pCefApp->GetCefClient()->CloseAllBrowsers(false);
                }
            }           
        }
        if(MessageBox(hDlg, TEXT("Close the program?"), TEXT("Close"),
            MB_ICONQUESTION | MB_YESNO) == IDYES)
        {
            DestroyWindow(hDlg);
        }
        return TRUE;

    case WM_DESTROY:
        CefQuitMessageLoop();
        PostQuitMessage(0);
        return TRUE;
    }
    return FALSE;
}

// Entry point function for all processes.
int APIENTRY wWinMain(HINSTANCE hInstance,
                      HINSTANCE hPrevInstance,
                      LPTSTR    lpCmdLine,
                      int       nCmdShow) {
  UNREFERENCED_PARAMETER(hPrevInstance);
  UNREFERENCED_PARAMETER(lpCmdLine);
 
  InitCommonControls();
  HWND hDlg = CreateDialogParam(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), 0, DialogProc, 0); 
  if (hDlg==NULL) return -1;

  ShowWindow (hDlg,SW_SHOW);   
  UpdateWindow (hDlg);

  HWND hHTMLGroupBox = GetDlgItem(hDlg, IDC_GROUPBOX1);
  RECT htmlRect;
  WINDOWINFO wndInfo;
  GetWindowInfo(hDlg, &wndInfo);

  GetWindowRect(hHTMLGroupBox, &htmlRect);
  htmlRect.left-=wndInfo.rcClient.left;
  htmlRect.right-=wndInfo.rcClient.left;
  htmlRect.top-=wndInfo.rcClient.top;
  htmlRect.bottom-=wndInfo.rcClient.top;
 
  //Hides group box, HTML is rendered to its area instead
  ShowWindow(hHTMLGroupBox, SW_HIDE);
 
  // Enable High-DPI support on Windows 7 or newer.
  CefEnableHighDPISupport();
 
  void* sandbox_info = NULL;

  // Provide CEF with command-line arguments.
  CefMainArgs main_args(hInstance);

  // SimpleApp implements application-level callbacks. It will create the first
  // browser instance in OnContextInitialized() after CEF has initialized.
 
  pCefApp = new MyCefApp();
  pCefApp->SetParentWindow(hDlg, htmlRect);
 
  int exit_code = CefExecuteProcess(main_args, pCefApp.get(), sandbox_info);
  if (exit_code >= 0) {
    // The sub-process has completed so return here.
    return exit_code;
  }

  // Specify CEF global settings here.
  CefSettings settings;
  settings.multi_threaded_message_loop = false;
  //settings.single_process = true;

  // Initialize CEF.
  CefInitialize(main_args, settings, pCefApp.get(), sandbox_info);

  // Run the CEF message loop. This will block until CefQuitMessageLoop() is
  // called.
 
  MSG Msg;
  while(GetMessage(&Msg, NULL, 0, 0))
  {
      CefDoMessageLoopWork();
      if(!IsDialogMessage (hDlg, &Msg))
      {
          TranslateMessage(&Msg);
          DispatchMessage(&Msg);         
      }
  }

  // Shut down CEF.
  CefShutdown();

  return 0;
}
bezbot
Techie
 
Posts: 11
Joined: Fri Jan 08, 2016 6:55 am

Re: CEF3 + Win32

Postby bezbot » Tue Jan 19, 2016 3:28 am

Log:

Code: Select all
[0119/092352:WARNING:file_util_win.cc(427)] Failed to create directory , last error is 3.
[0119/092352:WARNING:resource_bundle.cc(305)] locale_file_path.empty() for locale
[0119/092352:ERROR:main_delegate.cc(722)] Could not load locale pak for en-US
The thread 'Win64 Thread' (0x142c) has exited with code 0 (0x0).
[0119/092353:WARNING:resource_bundle.cc(503)] locale resources are not loaded
[0119/092353:FATAL:prefs_tab_helper.cc(317)] Check failed: success.
CefDlgTestX.exe has triggered a breakpoint
[0119/092402:WARNING:resource_bundle.cc(503)] locale resources are not loaded
[0119/092402:FATAL:prefs_tab_helper.cc(317)] Check failed: success.
CefDlgTestX.exe has triggered a breakpoint
[0119/092403:WARNING:resource_bundle.cc(503)] locale resources are not loaded
[0119/092403:FATAL:prefs_tab_helper.cc(317)] Check failed: success.
CefDlgTestX.exe has triggered a breakpoint
[0119/092404:WARNING:resource_bundle.cc(503)] locale resources are not loaded
[0119/092404:FATAL:prefs_tab_helper.cc(317)] Check failed: success.
CefDlgTestX.exe has triggered a breakpoint
[0119/092405:WARNING:resource_bundle.cc(503)] locale resources are not loaded
[0119/092405:WARNING:resource_bundle.cc(503)] locale resources are not loaded
[0119/092405:WARNING:resource_bundle.cc(503)] locale resources are not loaded
[0119/092405:FATAL:browser_prefs.cc(45)] Check failed: !resource_string.empty().
CefDlgTestX.exe has triggered a breakpoint
'CefDlgTestX.exe': Loaded 'C:\Windows\System32\twinapi.appcore.dll', Cannot find or open the PDB file
[0119/092407:FATAL:renderer_prefs.cc(160)] Check failed: !web.default_encoding.empty().
CefDlgTestX.exe has triggered a breakpoint
[0119/092410:WARNING:resource_bundle.cc(503)] locale resources are not loaded
[0119/092410:WARNING:resource_bundle.cc(503)] locale resources are not loaded
The thread 'Win64 Thread' (0x1700) has exited with code 0 (0x0).
[0119/092453:FATAL:browser_main.cc(187)] Check failed: 0 == CefBrowserContext::DebugObjCt (0 vs. 1)
CefDlgTestX.exe has triggered a breakpoint
The thread 'CompositorTileWorker1/9280' (0x2440) has exited with code 0 (0x0).
The thread 'Chrome_IOThread' (0x292c) has exited with code 0 (0x0).
The thread 'Chrome_CacheThread' (0x3ec) has exited with code 0 (0x0).
The thread 'Chrome_ProcessLauncherThread' (0x1f08) has exited with code 0 (0x0).
The thread 'Chrome_FileUserBlockingThread' (0x920) has exited with code 0 (0x0).
The thread 'Chrome_FileThread' (0x2a9c) has exited with code 0 (0x0).
The thread 'Chrome_DBThread' (0xd1c) has exited with code 0 (0x0).
The thread 'IndexedDB' (0x2edc) has exited with code 0 (0x0).
The thread 'BrowserBlockingWorker1/9864' (0x2688) has exited with code 0 (0x0).
[0119/092500:FATAL:browser_main.cc(201)] Check failed: 0 == CefURLRequestContext::DebugObjCt (0 vs. 1)
CefDlgTestX.exe has triggered a breakpoint
The thread 'VideoCaptureThread' (0x1bb8) has exited with code 0 (0x0).
The thread 'AudioThread' (0x1bc4) has exited with code 0 (0x0).
The thread 'DnsConfigService' (0x1744) has exited with code 0 (0x0).
[0119/092501:FATAL:keyed_service_factory.cc(19)] Check failed: mapping_.empty().
CefDlgTestX.exe has triggered a breakpoint
[0119/092502:FATAL:keyed_service_factory.cc(19)] Check failed: mapping_.empty().
CefDlgTestX.exe has triggered a breakpoint
First-chance exception at 0x00007ffdac7ba1c8 in CefDlgTestX.exe: 0x0000071A: Vzdálené volání procedury bylo zrušeno.
The thread 'handle-watcher-thread' (0x28a0) has exited with code 0 (0x0).
[0119/092503:FATAL:browser_context_impl.cc(48)] Check failed: all_.empty().
CefDlgTestX.exe has triggered a breakpoint
[0119/092505:FATAL:keyed_service_factory.cc(19)] Check failed: mapping_.empty().
CefDlgTestX.exe has triggered a breakpoint
[0119/092506:FATAL:keyed_service_factory.cc(19)] Check failed: mapping_.empty().
CefDlgTestX.exe has triggered a breakpoint
[0119/092507:FATAL:keyed_service_factory.cc(19)] Check failed: mapping_.empty().
CefDlgTestX.exe has triggered a breakpoint
[0119/092508:FATAL:keyed_service_factory.cc(19)] Check failed: mapping_.empty().
CefDlgTestX.exe has triggered a breakpoint
bezbot
Techie
 
Posts: 11
Joined: Fri Jan 08, 2016 6:55 am

Re: CEF3 + Win32

Postby magreenblatt » Tue Jan 19, 2016 2:07 pm

Do not call CefQuitMessageLoop when using CefDoMessageLoopWork. You also appear to be missing required files -- see the README.txt file included with the binary distribution.
magreenblatt
Site Admin
 
Posts: 12409
Joined: Fri May 29, 2009 6:57 pm

Re: CEF3 + Win32

Postby bezbot » Mon Jan 25, 2016 10:09 am

Thanks for your answer- you are right, there was no "locales" directory, therefore there was shown the assert dialog multiple times.

After deleting CefQuitMessageLoop and adding locales to bin directory it works better, but there is still one issue - I can see multiple instances of my Win32 dialog. Just one of them works as expected, other two instances don't respond to any event.

Do you have any idea, how CefInitialize creates new instances of my dialog? Maybe I use wrong windowInfo settings in method MyCefApp::OnContextInitialized?
bezbot
Techie
 
Posts: 11
Joined: Fri Jan 08, 2016 6:55 am

Next

Return to Support Forum

Who is online

Users browsing this forum: Google [Bot] and 69 guests