- Code: Select all
class CefAppOther : public CefApp {
IMPLEMENT_REFCOUNTING(CefAppOther);
DISALLOW_COPY_AND_ASSIGN(CefAppOther);
public:
CefAppOther() = default;
virtual ~CefAppOther() = default;
};
class CefAppRenderer : public CefApp, public CefRenderProcessHandler {
IMPLEMENT_REFCOUNTING(CefAppRenderer);
DISALLOW_COPY_AND_ASSIGN(CefAppRenderer);
CefRefPtr<CefRenderProcessHandler> GetRenderProcessHandler() { return this; }
public:
CefAppRenderer() = default;
virtual ~CefAppRenderer() = default;
};
class SimpleHandler : public CefClient,
public CefDisplayHandler,
public CefLifeSpanHandler,
public CefLoadHandler,
public CefRenderHandler {
// Include the default reference counting implementation.
IMPLEMENT_REFCOUNTING(SimpleHandler);
CefRefPtr<CefBrowser> mBrowser;
ManualTexture* mTex{ nullptr };
public:
SimpleHandler() =default;
virtual ~SimpleHandler() = default;
void setTexture(ManualTexture& tex) {
mTex = &tex;
mBrowser->GetHost()->WasResized();
}
void GetViewRect(CefRefPtr<CefBrowser> browser, CefRect& rect) override {
if (!mTex)
rect = CefRect(0, 0, 1, 1);
else
rect = CefRect(0, 0, mTex->getImage().getWidth(), mTex->getImage().getHeight());
}
void OnPaint(CefRefPtr<CefBrowser> browser, PaintElementType type, const RectList& dirtyRects, const void* buffer, int width, int height) override {
if (!mTex) return;
mTex->copy(static_cast< const Ogre::uint8*>(buffer) );
mTex->update();
}
CefRefPtr<CefRenderHandler> GetRenderHandler() override { return this; }
CefRefPtr<CefDisplayHandler> GetDisplayHandler() override {return this;}
CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() override { return this;}
CefRefPtr<CefLoadHandler> GetLoadHandler() override { return this; }
void OnAfterCreated(CefRefPtr<CefBrowser> browser) override { mBrowser = browser; }
bool DoClose(CefRefPtr<CefBrowser> browser) override {return false;}
void OnBeforeClose(CefRefPtr<CefBrowser> browser) override {}
void CloseAllBrowsers(bool force_close) {
mBrowser->GetHost()->TryCloseBrowser();
while (!mBrowser->HasOneRef()) {
CefDoMessageLoopWork();
}
mBrowser = NULL;
}
};
class CefAppBrowser : public CefApp, public CefBrowserProcessHandler {
IMPLEMENT_REFCOUNTING(CefAppBrowser);
DISALLOW_COPY_AND_ASSIGN(CefAppBrowser);
CefRefPtr<SimpleHandler> handler;
public:
CefAppBrowser() = default;
virtual ~CefAppBrowser() = default;
CefRefPtr<CefBrowserProcessHandler> GetBrowserProcessHandler() override { return this; }
void setTexture(ManualTexture& tex) {
handler->setTexture(tex);
}
void OnContextInitialized() override { };
void destroyBrowser() {
handler->CloseAllBrowsers(true);
handler = NULL;
CefClearSchemeHandlerFactories();
}
void createBrowser(std::size_t windowHandle){
handler = new SimpleHandler();
std::string url = "www.google.com";
CefWindowInfo windowInfo;
windowInfo.SetAsWindowless((HWND)windowHandle);
windowInfo.windowless_rendering_enabled = true;
CefBrowserSettings browserSettings;
browserSettings.background_color = CefColorSetARGB(0, 0, 0, 255); //make transparent
browserSettings.windowless_frame_rate = 30;
CefBrowserHost::CreateBrowser(windowInfo, handler.get(), url, browserSettings,
NULL, NULL);
CefDoMessageLoopWork();
}
};
class CefProcess {
enum class ProcessType {
BrowserProcess,
RendererProcess,
ZygoteProcess,
OtherProcess,
};
ProcessType mProcessType;
CefProcess::ProcessType GetProcessType(CefRefPtr<CefCommandLine> commandLine) {
const std::string processTypeID{ "type" };
const std::string rendererProcessID{ "renderer" };
// The command-line flag won't be specified for the browser process.
if (!commandLine->HasSwitch(processTypeID.c_str()))
return ProcessType::BrowserProcess;
const std::string& process_type = commandLine->GetSwitchValue(processTypeID.c_str());
if (process_type == rendererProcessID)
return ProcessType::RendererProcess;
return ProcessType::OtherProcess;
}
void determineProcessType() {
CefRefPtr<CefCommandLine> commandLine;
commandLine = CefCommandLine::CreateCommandLine();
commandLine->InitFromString(::GetCommandLineW());
mProcessType = GetProcessType(commandLine);
switch (mProcessType) {
case ProcessType::BrowserProcess:
mApp = new CefAppBrowser();
break;
case ProcessType::RendererProcess:
case ProcessType::ZygoteProcess:
mApp = new CefAppRenderer();
break;
case ProcessType::OtherProcess:
mApp = new CefAppOther();
break;
default:
EXCEPT << "CefProcess::determineProcessType; invalid type!";
}
}
CefRefPtr< CefApp> mApp;
public:
~CefProcess() = default;
void setManualTexture(ManualTexture& tex) {
CefAppBrowser* browser = dynamic_cast<CefAppBrowser*>(mApp.get());
browser->setTexture(tex);
}
void createBrowser(std::size_t windowHandle) {
CefAppBrowser* browser = dynamic_cast<CefAppBrowser*>(mApp.get());
browser->createBrowser(windowHandle);
}
void destroyBrowser() {
CefAppBrowser* browser = dynamic_cast<CefAppBrowser*>(mApp.get());
browser->destroyBrowser();
}
void navigate() {
CefAppBrowser* browser = dynamic_cast<CefAppBrowser*>(mApp.get());
browser->navigate();
}
void branchProcess() {
CefMainArgs main_args(::GetModuleHandle(NULL));
determineProcessType();
void* sandbox_info = NULL;
int exit_code = CefExecuteProcess(main_args, mApp, sandbox_info);
if (exit_code >= 0) {
// The sub-process has completed so exit.
mApp = NULL;
exit(exit_code);
}
// Specify CEF global settings here.
CefSettings settings;
settings.windowless_rendering_enabled = true;
settings.no_sandbox = true;
std::filesystem::path path = std::filesystem::canonical("..\\resources\\cefcache");
CefString(&settings.cache_path).FromWString( path.generic_wstring() );
CefInitialize(main_args, settings, mApp, sandbox_info);
}
void doEvents() {
CefDoMessageLoopWork();
}
void shutdown() {
CefShutdown();
}
};
the program is as follows:
- Code: Select all
CefProcess cef;
cef.branchProcess();
cef.createBrowser(hwnd);
cef.setManualTexture(tex);
while (!windowHandler.getQuit()) {
std::this_thread::sleep_for(std::chrono::milliseconds(150));
cef.doEvents();
draw(); // update screen
poll(); // window events
}
cef.destroyBrowser();
cef.shutdown();