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

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

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

Ответ 1

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

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

Ответ 2

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

  • Определите пользовательский "протокол", который вы хотите использовать. здесь пример в виде строки макроса   #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 
    }
    

Вот пример добавления кнопки приложения "exit":

в cpp

    #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 и проанализируйте string в cpp, например:

    MYHOST.DoSomething = function() {
        window.location = 'myapp://command.dosomething?param1=' + value1 + "&param2=" + value2 + "&param3=" + value3;
    };

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

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

Ответ 3

Существует также самый простой способ сделать это, нуждаясь в одной строке кода!!!

Просто используйте...

Console.Log('. ...');

в вашем Javascript-коде с ведущим ESC char (или тем, что вы хотите) перед строкой/структурой данных, которую вам нужно отправить в приложение. Просто реализуйте "OnConsoleMessage" и запускайте точное задание в соответствии с ведущим или не ESC char сообщения.

Что это.

Надеюсь, что это может помочь.