После ознакомления с примером Chromium Embedded Framework у меня возник вопрос. Мне нужно встроенное взаимодействие со встроенной частью моего окна. Однако в примере CEF все, что я видел, это отправка сообщений в браузер c ++, а не наоборот. Мне было интересно, есть ли способ отправить сообщение из JavaScript с C ++, как в случае функции.
Я ищу что-то вроде этого. У меня есть кнопка на моей веб-странице, которая при нажатии. Я хотел бы свернуть окно. Есть ли способ вызвать C ++ из JavaScript в CEF?
Самый простой способ:
1. В основном процессе (процесс пользовательского интерфейса) — вы можете создать собственный обработчик пользовательской схемы (он также может быть привязан к протоколу http, а отдельные обработчики — по доменам).
2. Со стороны JS вы можете использовать XMLHttpRequest для вызова обработчика схемы. Это стандартный механизм IPC между JS<> Основной процесс.
Другой путь:
Используйте привязки V8, но в этом случае вам нужно будет создать собственный IPC между рендерером и основным процессом. Или используйте встроенный IPC, но учтите, что он отправляет сообщения только асинхронным способом.
Если кому-то нужен пример, вот один из способов, которым я это сделал:
Определите пользовательский «протокол», который вы хотите использовать
вот пример в виде строки макроса
#define PROTO_MYAPPCOMMAND «myapp: //»
В вашем пользовательском классе CefApp (наследуемом от CefApp),
также наследовать от CefRenderProcessHandler.
реализовать функцию OnBeforeNavigation ():
//declare (i.e. in header)
virtual bool OnBeforeNavigation(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request,
NavigationType navigation_type, bool is_redirect) OVERRIDE;
//implementation
bool CClientApp::OnBeforeNavigation(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request,
NavigationType navigation_type, bool is_redirect)
{
CefString cefval = request->GetURL();
CString csval = cefval.c_str();
if (csval.Find(PROTO_MYAPPCOMMAND, 0) == 0)
{
//process the command here
//this is a command and not really intended for navigation
return true;
}
return false; //true cancels navigation, false allows it
}
Вот пример добавления кнопки «Выход» из приложения:
в кпп
#define STR_COMMANDAPPEXIT _T("command.appexit")
bool CClientApp::OnBeforeNavigation(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request, NavigationType navigation_type, bool is_redirect)
{
CefString cefval = request->GetURL();
CString csval = cefval.c_str();
if (csval.Find(PROTO_MYAPPCOMMAND, 0) == 0)
{
CString command = url;
command.Replace(PROTO_MYAPPCOMMAND, _T(""));
if (command.Find(STR_COMMANDAPPEXIT, 0) == 0)
{
::PostMessage(hwnd, WM_CLOSE, NULL, NULL);
}
//this is a command and not really intended for navigation
return true;
}
return false; //true cancels navigation, false allows it
}
также создал файл утилиты js для всех операций, чтобы упростить их вызов
var MYHOST = MYHOST || {};
/// Exit the Application (host app)
MYHOST.ExitApp = function() {
window.location = 'myapp://command.appexit';
};
на страницах js (т.е. нажатием кнопки / div)
<div class="exitbutton" onclick="MYHOST.ExitApp();">Exit</div>
Если вам нужно передать параметры, просто добавьте их в URL в js и проанализируйте
строка в cpp, вот так:
MYHOST.DoSomething = function() {
window.location = 'myapp://command.dosomething?param1=' + value1 + "¶m2=" + value2 + "¶m3=" + value3;
};
примечание: я упростил код, но, пожалуйста, добавьте проверки и т. д.
Надеюсь это поможет!
Нет серьезного способа сделать это, требуя единственной строки кода:
Console.Log (‘. …’) с лидирующим символом ESC перед строкой / структурой данных, которую необходимо отправить в приложение.
Просто реализуйте OnConsoleMessage и запускайте точное задание в соответствии с ведущим или не ESC-символом.
PS: мне пришлось использовать это хитрое решение в 2015 году, так как релиз DCEF3 был глючным для использования обработчика схемы.
Для серьезной работы: зарегистрировать нестандартный обработчик схемы подойдет.