首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NPAPI插件,网页removeChild崩溃Firefox4和Chrome

NPAPI插件,网页removeChild崩溃Firefox4和Chrome
EN

Stack Overflow用户
提问于 2011-06-13 22:40:04
回答 1查看 1.1K关注 0票数 0

我有一个html页面,它打开一个新窗口并加载一个基本的NPAPI编写的插件,我打开一个宽的保存对话框,然后用一个java-script函数调用NPN_GetURL来关闭窗口。每次Firefox崩溃和Chrome显示时,插件都会崩溃。我不确定问题出在HTML & JS还是插件。当我在谷歌上搜索其他类似的问题时,我没有找到很多东西。下面是我加载插件的页面,插件调用javascript函数"removePlugin“。至于firefox,只有在版本4中才有3.6版的问题

-开始

代码语言:javascript
复制
<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>

--结束

-插件代码开始

代码语言:javascript
复制
#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;}

-插件代码结束

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-09-04 00:14:01

真的很难确定到底发生了什么,但我可以告诉你,你所采取的方法还有其他几个问题。第一个也是最重要的一点是,您永远不能阻塞主浏览器线程,当您在主浏览器中打开对话框时就会发生这种情况。现在,我意识到当你的对话框打开时,你可能还好(有些人甚至会产生错觉,认为其他人也可以)在对话框锁定(不,不仅仅是阻止输入,实际上是锁定)浏览器,但是在所有当前浏览器在进程外运行插件,并且在对话框打开时不会完全锁定的情况下,浏览器至少会询问用户他们是否想要杀死插件,如果不是像Safari 5.1那样直接杀死你的插件。

如果你要使用一个对话框,你真正需要做的是启动另一个线程,并将对话框调用放在这个线程上,然后回调到浏览器中(在主线程上!完成后使用NPN_PluginThreadAsyncCall)。

至于崩溃日志,根据它所说的,你以某种方式借用了插件的浏览器句柄,因为当它试图在你的插件上调用SetWindow时,它会崩溃。您可能希望考虑在NPAPI上放弃这种基本的尝试,并使用像FireBreath这样的东西,其中棘手的NPAPI部分已经为您解决了。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6331924

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档