Генерация асинхронных событий JavaScript от плагина браузера (NPAPI)

Я пишу плагин веб-браузера (NPAPI).

Мой плагин запускает рабочий поток, и в то время как рабочий прогрессирует, я хотел бы пасовать назад события к JavaScript. Но из-за модели потоков NPAPI, это не законно, чтобы рабочий поток перезвонил в NPAPI непосредственно, таким образом, рабочий поток не может вызвать Javascript.

Одним решением этого является функция NPN_PluginThreadAsyncCall. Но это - относительно новая функция. Например, это поддерживало только от Firefox 3 на.

Там какой-либо путь состоит в том, чтобы получить асинхронное событие выполнение delivery/javascript от плагина NPAPI, не используя NPN_PluginThreadAsyncCall? Что делали люди, прежде чем эта функция была добавлена?

8
задан Geoff 19 December 2009 в 03:48
поделиться

1 ответ

Ответ - да ... и нет ...

Если вам нужна поддержка старых браузеров (до Firefox 3), вы можете реализовать функцию NPN_PluginThreadAsyncCall самостоятельно. В Windows вы можете сделать это, создав структуру данных, которая может содержать указатель на функцию и указатель void * opaque, а затем опубликовать собственное сообщение в главном окне с указателем на вашу структуру данных как LPARAM.

Главное окно WINPPROC выполняется в потоке пользовательского интерфейса, который является потоком, который может взаимодействовать с Javascript. Итак, когда вы получаете это сообщение в своем WINPROC, вы просто возвращаете LPARAM обратно к указателю, вызываете метод с непрозрачными данными, а затем освобождаете структуру данных.

На Mac вы можете сделать то же самое с очередь для хранения событий, а затем в событии NULL (которое Mac OS отправляет при каждом тике) проверьте, есть ли в нем что-нибудь. https://github.com/firebreath/FireBreath/blob/master/src/PluginWindow/Win/PluginWindowWin.cpp

Событие и структура данных определены в его заголовочном файле: https://github.com/firebreath/FireBreath/blob/master/src/PluginWindow/Win/PluginWindowWin.h

И метод запуска этого события находится здесь:

void ActiveXBrowserHost::ScheduleAsyncCall(void (*func)(void *), void *userData)
{
    if (m_hWnd != NULL) 
        ::PostMessage(m_hWnd, WM_ASYNCTHREADINVOKE, NULL, 
            (LPARAM)new FB::WINDOWS_ASYNC_EVENT(func, userData));
}
5
ответ дан 5 December 2019 в 23:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: