I am afraid I'm a CEF newbie here. I'm sure this has been asked a few times, but I'm having a hard time finding a solution. I have been modifying the cefsimple project so that it accepts a custom handler, pointing to local files (which works like charm), as well as messaging between C++ and JS. This last part is where I am having some trouble. I'm getting the dreaded "window.cefQuery is not a function" and, no matter how much I compare my code and the one in the message_router project, I cannot find where I'm failing.
Here is my client:
- Code: Select all
void PlatformTitleChange(CefRefPtr<CefBrowser> browser,
const CefString& title) {
CefWindowHandle hwnd = browser->GetHost()->GetWindowHandle();
SetWindowText(hwnd, std::wstring(title).c_str());
}
// Handle messages in the browser process.
class MessageHandler : public CefMessageRouterBrowserSide::Handler {
public:
explicit MessageHandler() {}
// Called due to cefQuery execution in message_router.html.
bool OnQuery(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
int64 query_id,
const CefString& request,
bool persistent,
CefRefPtr<Callback> callback) override {
const std::string& message_name = request;
if (message_name.find("testMessage") == 0) {
// Return
callback->Success("This is a response message from CEF");
return true;
}
return false;
}
private:
DISALLOW_COPY_AND_ASSIGN(MessageHandler);
};
namespace minimal {
Client::Client() {}
void Client::OnTitleChange(CefRefPtr<CefBrowser> browser,
const CefString& title) {
CEF_REQUIRE_UI_THREAD();
#if defined(OS_WIN) || defined(OS_LINUX)
// The Views framework is currently only supported on Windows and Linux.
CefRefPtr<CefBrowserView> browser_view =
CefBrowserView::GetForBrowser(browser);
if (browser_view) {
// Set the title of the window using the Views framework.
CefRefPtr<CefWindow> window = browser_view->GetWindow();
if (window)
window->SetTitle(title);
} else
#endif
{
// Set the title of the window using platform APIs.
PlatformTitleChange(browser, title);
}
}
bool Client::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefProcessId source_process,
CefRefPtr<CefProcessMessage> message) {
CEF_REQUIRE_UI_THREAD();
return message_router_->OnProcessMessageReceived(browser, frame,
source_process, message);
}
void Client::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
CEF_REQUIRE_UI_THREAD();
if (!message_router_) {
// Create the browser-side router for query handling.
CefMessageRouterConfig config;
config.js_query_function = "cefQuery";
config.js_cancel_function = "cefQueryCancel";
message_router_ = CefMessageRouterBrowserSide::Create(config);
// Register handlers with the router.
message_handler_.reset(new MessageHandler());
message_router_->AddHandler(message_handler_.get(), false);
}
browser_ct_++;
// Add to the list of existing browsers.
ClientManager::GetInstance()->OnAfterCreated(browser);
}
bool Client::OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
bool user_gesture,
bool is_redirect) {
CEF_REQUIRE_UI_THREAD();
message_router_->OnBeforeBrowse(browser, frame);
return false;
}
bool Client::DoClose(CefRefPtr<CefBrowser> browser) {
CEF_REQUIRE_UI_THREAD();
// Closing the main window requires special handling. See the DoClose()
// documentation in the CEF header for a detailed destription of this
// process.
ClientManager::GetInstance()->DoClose(browser);
// Allow the close. For windowed browsers this will result in the OS close
// event being sent.
return false;
}
void Client::OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser,
TerminationStatus status) {
CEF_REQUIRE_UI_THREAD();
message_router_->OnRenderProcessTerminated(browser);
}
CefRefPtr<CefResourceRequestHandler> Client::GetResourceRequestHandler(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
bool is_navigation,
bool is_download,
const CefString& request_initiator,
bool& disable_default_handling) {
CEF_REQUIRE_IO_THREAD();
return this;
}
void Client::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
if (--browser_ct_ == 0) {
// Free the router when the last browser is closed.
message_router_->RemoveHandler(message_handler_.get());
message_handler_.reset();
message_router_ = nullptr;
}
// Remove from the list of existing browsers.
ClientManager::GetInstance()->OnBeforeClose(browser);
}
}
What may I be doing wrong? Thank you very much in advance.