NPAPI-浏览器开发之网络文件SRC下载(NPN_GetURLNotify,NPP_NewStream....)(二)

2014-11-24 02:24:22 · 作者: · 浏览: 5
P_DestroyStream: Downloaded large file 'D:\Users\GAVIN_~1\AppData\Local\Temp\plugtmp\plugin-toonwarz.atx' exists
39364293: NPP_DestroyStream: End
39364293: NPP_URLNotify: Start, instance=$B5D078, url='http://www.antixgames.com/d/l/toonwarz.atx ib=1', reason=$0, notifyData=$1B1A68
39364293: NPP_URLNotify: STATE_DOWNLOAD_LARGEFILE
39365744: NPP_URLNotify: End
39365760: PluginWndProc: WM_SETFOCUS
39486863: PluginWndProc: WM_SETFOCUS
39488611: NPP_Destroy: Start, instance=$B5D078, save=$0
39488611: CTESTNPPlugin::shut: Start
39488611: CTESTNPPlugin::shut: End
39488611: CTESTNPPlugin::~CTESTNPPlugin: Start/End
39488611: NPP_Destroy: End, iRet=0
从上面的log中可以看出,下载文件的执行API顺序为:
NPN_GetURLNotify()->NPP_NewStream()->NPP_WriteReady()->NPP_Write()->NPP_StreamAsFile()->NPP_DestroyStream()->NPP_URLNotify()。
看完上面两个链接提供的文档也会发现这些API的大概意思。
NPN_GetURLNotify()比NPN_GetURL()要好,在提供下载完的通知,当下载完成后,会调用NPP_URLNotify()来通知插件,下载已经完成。这样就可以在异步的操作中得到自己的处理。
NPAPI下载的,实际是 浏览器下载文件到本地的用户临时文件夹下,然后把路径通过NPP_StreamAsFile()来通知插件。
要执行相关的操作要做重写NPP_NewStream()和NPP_StreamAsFile()。其中NPP_NewStream()中的*stype要指定为NP_ASFILE或者NP_ASFILEONLY
具体的代码如下。
在窗口过程中下载文件消息:
[cpp]
case WM_RBUTTONDOWN:
MessageBox(NULL, "Start 'large file download' test", "Mozilla bug 644684", MB_OK|MB_SETFOREGROUND);
TrcMsg("WM_RBUTTONDOWN: Download large file (ie ~12 Mbytes)\n");
pPlugin->DownloadFile(STATE_DOWNLOAD_LARGEFILE, pPlugin->m_szLargeFileURL);
return 0;
下载文件的代码如下,调用NPN_GetURLNotify():
[cpp]
BOOL CTESTNPPlugin::DownloadFile(int iIndex, LPSTR pFile)
{
m_iRetries = 0;
return DownloadFileRetry(iIndex, pFile);
}
BOOL CTESTNPPlugin::DownloadFileRetry(int iIndex, LPSTR pFile)
{
BOOL bRet = FALSE;
if (pFile[0])
{
TrcMsgP("CTESTNPPlugin::DownloadFileRetry: Download '%s'\n",pFile);
m_iDownloadState = iIndex;
NPN_GetURLNotify(m_pNPInstance, pFile, NULL, this);
bRet = TRUE;
}
return bRet;
}
重载的浏览器的方法如下:
[cpp]
NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream,
NPBool seekable, uint16_t *stype)
{
NPError iRet = NPERR_NO_ERROR;
TrcMsgP("NPP_NewStream: Start, instance=$%X, type=$%X, stream=$%X, seekable=%d, stype=$%X, size=%d\n",instance,type,stream,seekable,stype,stream->end);
if (instance)
*stype = NP_ASFILE;
else
iRet = NPERR_INVALID_INSTANCE_ERROR;
TrcMsgP("NPP_NewStream: End, stype=%d, iRet=%d\n",*stype,iRet);
return iRet;
}
int32_t NPP_WriteReady(NPP instance, NPStream *stream)
{
TrcMsgP("NPP_WriteReady: Start/End, instance=$%X, stream=$%X\n",instance,stream);
return (instance 0x0fffffff : NPERR_INVALID_INSTANCE_ERROR);
}
int32_t NPP_Write(NPP instance, NPStream *stream, int32_t offset, int32_t len, void *buffer)
{
TrcMsgP("NPP_Write: Start/End: instance=$%X, stream=$%X, offset=%d, len=%d, buffer=$%X\n",instance,stream,offset,len,buffer);
retur