Отправка информации из Chromium Embedded (Javascript) в содержащее приложение C ++

После ознакомления с примером Chromium Embedded Framework у меня возник вопрос. Мне нужно встроенное взаимодействие со встроенной частью моего окна. Однако в примере CEF все, что я видел, это отправка сообщений в браузер c ++, а не наоборот. Мне было интересно, есть ли способ отправить сообщение из JavaScript с C ++, как в случае функции.

Я ищу что-то вроде этого. У меня есть кнопка на моей веб-странице, которая при нажатии. Я хотел бы свернуть окно. Есть ли способ вызвать C ++ из JavaScript в CEF?

10

Решение

Самый простой способ:
1. В основном процессе (процесс пользовательского интерфейса) — вы можете создать собственный обработчик пользовательской схемы (он также может быть привязан к протоколу http, а отдельные обработчики — по доменам).
2. Со стороны JS вы можете использовать XMLHttpRequest для вызова обработчика схемы. Это стандартный механизм IPC между JS<> Основной процесс.

Другой путь:
Используйте привязки V8, но в этом случае вам нужно будет создать собственный IPC между рендерером и основным процессом. Или используйте встроенный IPC, но учтите, что он отправляет сообщения только асинхронным способом.

8

Другие решения

Если кому-то нужен пример, вот один из способов, которым я это сделал:

  1. Определите пользовательский «протокол», который вы хотите использовать
    вот пример в виде строки макроса
    #define PROTO_MYAPPCOMMAND «myapp: //»

  2. В вашем пользовательском классе CefApp (наследуемом от CefApp),
    также наследовать от CefRenderProcessHandler.

  3. реализовать функцию 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 + "&param2=" + value2 + "&param3=" + value3;
};

примечание: я упростил код, но, пожалуйста, добавьте проверки и т. д.

Надеюсь это поможет!

14

Нет серьезного способа сделать это, требуя единственной строки кода:

Console.Log (‘. …’) с лидирующим символом ESC перед строкой / структурой данных, которую необходимо отправить в приложение.
Просто реализуйте OnConsoleMessage и запускайте точное задание в соответствии с ведущим или не ESC-символом.

PS: мне пришлось использовать это хитрое решение в 2015 году, так как релиз DCEF3 был глючным для использования обработчика схемы.

Для серьезной работы: зарегистрировать нестандартный обработчик схемы подойдет.

11