我有一个html页面,它打开一个新窗口并加载一个基本的NPAPI编写的插件,我打开一个宽的保存对话框,然后用一个java-script函数调用NPN_GetURL来关闭窗口。每次Firefox崩溃和Chrome显示时,插件都会崩溃。我不确定问题出在HTML & JS还是插件。当我在谷歌上搜索其他类似的问题时,我没有找到很多东西。下面是我加载插件的页面,插件调用javascript函数"removePlugin“。至于firefox,只有在版本4中才有3.6版的问题
-开始
<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;}-插件代码结束
发布于 2011-09-04 00:14:01
真的很难确定到底发生了什么,但我可以告诉你,你所采取的方法还有其他几个问题。第一个也是最重要的一点是,您永远不能阻塞主浏览器线程,当您在主浏览器中打开对话框时就会发生这种情况。现在,我意识到当你的对话框打开时,你可能还好(有些人甚至会产生错觉,认为其他人也可以)在对话框锁定(不,不仅仅是阻止输入,实际上是锁定)浏览器,但是在所有当前浏览器在进程外运行插件,并且在对话框打开时不会完全锁定的情况下,浏览器至少会询问用户他们是否想要杀死插件,如果不是像Safari 5.1那样直接杀死你的插件。
如果你要使用一个对话框,你真正需要做的是启动另一个线程,并将对话框调用放在这个线程上,然后回调到浏览器中(在主线程上!完成后使用NPN_PluginThreadAsyncCall)。
至于崩溃日志,根据它所说的,你以某种方式借用了插件的浏览器句柄,因为当它试图在你的插件上调用SetWindow时,它会崩溃。您可能希望考虑在NPAPI上放弃这种基本的尝试,并使用像FireBreath这样的东西,其中棘手的NPAPI部分已经为您解决了。
https://stackoverflow.com/questions/6331924
复制相似问题