Плагин NPAPI, удаляющий ребенка с веб-страницы, вылетает Firefox4 и Chrome - PullRequest
0 голосов
/ 13 июня 2011

У меня есть html-страница, которая открывает новое окно и загружает базовый написанный для NPAPI плагин, я открываю диалоговое окно Wide Save и затем вызываю NPN_GetURL с функцией java-script, чтобы закрыть окно.Каждый раз, когда Firefox падает, а Chrome отображает сбой плагина.Я не уверен, является ли проблема HTML & JS или плагином.Я не нашел много, когда гуглил на другие подобные проблемы.Ниже моя страница, которая загружает плагин, и плагин вызывает функцию javascript "removePlugin".Что касается Firefox, нет проблем в 3.6 только в версии 4

---- Начало

<html>
 <script language="javascript">
  function removePlugin()
   {
   var plgn = document.getElementById("myplugin1");
   document.getElementById("div1").removeChild(plgn);
   setTimeout('doClose()', 2000);
   }
 function doClose()
  {
  window.close();
  }
 </script>
 <body >
  <div id="div1">
   <embed type="application/x-My-Plugin" id="myplugin1"></embed>
  </div>
 </body>
</html>

---- Конец

---- Начало кода плагина

#include "npapi.h"

//Prottype
LRESULT CALLBACK    PluginWindowProc  (HWND,UINT,WPARAM,LPARAM);

//Define
#define MY_MESSAGE      WM_USER + 1000

//Global
const char*     gInstanceLookupString = "instance";
WNDPROC         fDefaultWindowProc;

//Function:    NPP_SetWindow
NPError NPP_SetWindow(NPP       instance,
                      NPWindow *window)
{
    fDefaultWindowProc = (WNDPROC)SetWindowLongPtr((HWND)window->window,
                                                   GWL_WNDPROC,
                                                   (LONG)PluginWindowProc);
    SetProp(window->window,
            gInstanceLookupString,
            (HANDLE)instance);
    SendMessage(window->window,
                MY_MESSAGE,
                0,
                0);
    return NPERR_NO_ERROR;
}

//PluginWindowProc
LRESULT CALLBACK PluginWindowProc(HWND      hWnd,
                                  UINT      Msg,
                                  WPARAM    wParam,
                                  LPARAM    lParam)
{
OPENFILENAMEW       ofn;                                                                    //Fix.3a
WCHAR               szFile[512];                                //File name that appears in the Save Dialog box //Fix.3a
NPP                 instance;

    switch(Msg)
        {
        case MY_MESSAGE:
            instance = (NPP)GetProp(hWnd,
                                    gInstanceLookupString);
            //SAVE----------------------------------------
            memset(&ofn,
                   0x00,
                   sizeof(OPENFILENAMEW));

            memset(szFile,
                   0x00,
                   sizeof(szFile));
            _snwprintf_s(szFile,                                
                        _countof(szFile),
                        _countof(szFile),
                        L"Test.Txt");
            ofn.lStructSize = sizeof(OPENFILENAME);            
            ofn.lpstrFile = szFile;
            ofn.nMaxFile = _countof(szFile);
            ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;

            GetSaveFileNameW(&ofn);


            //CLOSE---------------------------------------
            NPN_GetURL(instance,
                       "javascript:removePlugin(0);",
                       "_self");

            //--------------------------------------------
            break;
        default:
            CallWindowProc(fDefaultWindowProc,
                           hWnd,
                           Msg,
                           wParam,
                           lParam);
            break;
        }
    return 0;
    }

//Function:    NPP_Destroy
NPError NPP_Destroy(NPP instance,NPSavedData **save){return NPERR_NO_ERROR;}

//Function:    NPP_DestroyStream
NPError NPP_DestroyStream(NPP instance, NPStream *stream, NPError   reason){return NPERR_NO_ERROR;}

//Function:    NPP_HandleEvent
int16 NPP_HandleEvent(NPP instance,void* event){return 0;}

//Function:    NPP_Initialize
NPError NPP_Initialize(void){return NPERR_NO_ERROR;}

//Function:    NPP_New
NPError NPP_New(NPMIMEType pluginType,NPP instance, uint16 mode, int16 argc,char* argn[], char * argv[],NPSavedData* saved){return (NPERR_NO_ERROR);}

//Function: NPP_NewStream
NPError NPP_NewStream(NPP instance,NPMIMEType type, NPStream *stream, NPBool seekable, uint16 *stype){ return NPERR_NO_ERROR;}

//Function: NPP_Print
void NPP_Print(NPP instance, NPPrint *printInfo){}

//Function: NPP_Shutdown
void NPP_Shutdown(void){}

//Function: NPP_StreamAsFile
void NPP_StreamAsFile(NPP instance, NPStream *stream, const char *fname){}

//Function: NPP_URLNotify
void NPP_URLNotify(NPP instance, const char *url, NPReason reason, void *notifyData){}

//Function: NPP_Write
int32 NPP_Write(NPP instance, NPStream *stream, int32 offset, int32 len, void *buffer)        {return 0;}

//Function: NPP_WriteReady
int32 NPP_WriteReady(NPP instance, NPStream *stream){return 0;}

---- Код конца плагина

1 Ответ

1 голос
/ 03 сентября 2011

Действительно трудно точно сказать, что происходит, но я могу сказать вам, что у вашего подхода есть несколько других проблем.Прежде всего, вы никогда не должны блокировать основной поток браузера, что происходит при открытии диалога в главном браузере.Теперь я понимаю, что вы можете быть в порядке (и некоторые могут даже быть в заблуждении, что другие будут в порядке) с блокировкой диалога (нет, не просто предотвращать ввод, но фактически блокировать) браузер, пока ваш диалог открыт, нов случае всех текущих браузеров, которые запускают плагин из процесса и не будет полностью блокироваться, когда диалоговое окно открыто, браузер по крайней мере спросит пользователя, хотят ли они убитьплагин, если не просто убить ваш плагин сразу, как Safari 5.1.

Что вам действительно нужно сделать, если вы собираетесь использовать диалог, так это запустить другой поток и поместить в него диалог, а затем вызватьвернитесь в браузер (в главном потоке! используйте NPN_PluginThreadAsyncCall), когда вы закончите.

Что касается журнала сбоев, то, что он говорит, вы каким-то образом перенаправили дескриптор браузера на плагин, потому чтосбой при попытке вызвать SetWindow на вашем плагине.Возможно, вы захотите бросить эту «скелетную» попытку в NPAPI и использовать что-то вроде FireBreath , где сложные биты NPAPI уже решены для вас.

...