NPAPI插件开发

来源:互联网 发布:exe 端口 编辑:程序博客网 时间:2024/04/28 05:37

我们有时候需要调整插件窗口的尺寸大小,比如说,当你创建一个视频播放窗口,在用户点击播放之后想要将窗口的大小调整为视频的实际大小。播放完毕之后又将窗口尺寸调整回原来的尺寸大小。

要实现这样一个功能,最简单的方式是写JS来实现,只需要首先用getElementById获取插件,然后设置其width属性和height属性。但是,通常情况下我们只管编写插件,不负责网页的设计,如果我们设计完一个插件,还要为网页设计人员写一大堆的注意事项,是不是可以说我们的插件写得不太高明呢?

为了能够在插件中更改插件窗口的尺寸。我们需要使用的接口其实很少,为了方便,我们为Plugin类添加一个成员函数ChangSize(int width, int height):函数代码如下:

void Plugin::ChangeSize(int width,int height)  
{  
   NPObject *pluginObj;  
    NPN_GetValue(m_pNPInstance,NPNVPluginElementNPObject,&pluginObj);  
    NPIdentifier n_width_id = NPN_GetStringIdentifier("width");  
    NPIdentifier n_height_id = NPN_GetStringIdentifier("height");  
    NPVariant rval;  
//  STRINGZ_TO_NPVARIANT("400",rval);  
    INT32_TO_NPVARIANT(width,rval);  
    NPN_SetProperty(m_pNPInstance,pluginObj,n_width_id,&rval);  
    INT32_TO_NPVARIANT(height,rval);  
    NPN_SetProperty(m_pNPInstance,pluginObj,n_height_id,&rval);  
}  

代码很简单,不多说了,唯一有难点的是NPNVPluginElementNPObject,因为在MDN上没有对NPN_GetValue(m_pNPInstance,NPNVPluginElementNPObject,&pluginObj);得到的NPObject做任何说明,可能老外都认为NPNVPluginElementNPObject这个词就能够完全说明问题吧!

得到了NPObject,然后就为它设置属性,只需要一个函数NPN_SetProperty和一个宏INT32_TO_NPVARIANT或者STRINGZ_TO_NPVARIANT就可以完成属性的设置,这样一来,就改变了插件窗口的尺寸了。

这种方式与JS方式的实质是一样的,只不过将代码在插件中进行了实现,而且不需要借助插件中调用JS代码。


获取插件路径

该功能不复杂,不过使用了windows提供的API故只适用于windows平台。代码如下:


LPTSTR moduleName = new TCHAR[100];  
GetModuleFileName(GetModuleHandle(_T("name")),moduleName,100);  
std::string mPath = std::string(moduleName);  


GetModuleHandle(_T("name"))的name即你的插件名称,如:npdemo.dll。TCHAR的长度视具体情况而定,用于保存得到的路径。注意需要include tchar.h和string(是string不是string.h)。当然路径其实已经保存在moduleName中了,如果不用string可以不要最后一句(鉴于字符串处理的繁琐,推荐使用string)。

获取页面路径、资源路径

要获取插件页面的路径,可以参考:https://developer.mozilla.org/en-US/docs/Getting_the_page_URL_in_NPAPI_plugin。其中提到了三种方式,但我感觉比较靠谱的方式是第一种,下面是简单的实现代码:


       NPObject *pluginObj;  
NPN_GetValue(m_pNPInstance,NPNVWindowNPObject,&pluginObj);  
NPIdentifier  n=NPN_GetStringIdentifier("location");  
        NPVariant rval;  
NPN_GetProperty(m_pNPInstance,pluginObj,n,&rval);  
NPObject* locationObj = rval.value.objectValue;  
n=NPN_GetStringIdentifier("href");  
NPN_GetProperty(m_pNPInstance,locationObj,n,&rval);  
std::string  pageURL = std::string(rval.value.stringValue.UTF8Characters);  


object标签可以使用data属性设置资源的URL,embed标签使用src属性设置资源URL。获取资源路径的代码如下:

NPObject *pluginObj;  
       NPN_GetValue(m_pNPInstance,NPNVPluginElementNPObject,&pluginObj);  
       NPIdentifier n=NPN_GetStringIdentifier("src");  
       NPVariant rval;  
NPN_GetProperty(m_pNPInstance, pluginObj, n, &rval);  
if(NPVARIANT_IS_STRING(rval))  
    m_pSrc = std::string(NPVARIANT_TO_STRING(rval).UTF8Characters);  
else{  
    n=NPN_GetStringIdentifier("data");  
    NPN_GetProperty(m_pNPInstance, pluginObj, n, &rval);  
    if(NPVARIANT_IS_STRING(rval))  
        m_pSrc = std::string(NPVARIANT_TO_STRING(rval).UTF8Characters);  
}  

这样,不管html中使用的是object标签的data还是使用的embed标签中的src设置资源URL,都可以将资源的完整URL保存到m_pSrc中。

除了通用属性如:id、class等,object标签的属性有type、data、width、height,embed标签的属性有type、src、width、height。而flashplayer插件所具有的loop、autoplay等属性都是插件自己添加的,无法用NPN_GetProperty接口进行获取。假设我们要开发一个插件允许使用loop属性,那该怎么实现呢?
这个就要找到NS_NewPluginInstance函数中了,这个函数的参数是一个nsPluginCreateData。这个结构中就保存了标签中所有的属性和属性值。这个函数中创建了一个新的Plugin对象,Plugin对象的构造函数参数为NPP,故此处传递了nsPluginCreateData的instance。如果我们需要获取和识别私有属性如loop,推荐实现一个可以接受nsPluginCreateData的Plugin构造函数。这样就可以在plugin构造函数中获取私有属性的值了。
假设我们要实现私有属性loop。并使得只有如下方式loop才无效:不设置loop属性、loop=false、loop=no、loop=0.其他方式loop如:loop、loop=true、loop=yes、loop=1等都有效。那我们的代码可以这样写:

//读取私有属性。  
  m_bLoop=false;//初始设为false,保证没有设置该属性时无效  
int16_t argNum = cd->argc;//the number of HTML arguments in the element  
//  cd->argn;//The argn array contains the attribute names  
//  cd->argv;//the argv array contains the attribute values  
int16_t argCur = 0;  
for (argCur=0;argCur<argNum;argCur++)  
{  
    if (0==strcmp(cd->argn[argCur],"loop"))  
    {  
        m_bLoop = true;  
        std::string loop = std::string(cd->argv[argCur]);  
        if(loop=="no"||loop=="false"||loop=="0") m_bLoop = false;  
    }  
}  

如上代码所实现的私有属性最简单的组合就是需要loop时用<object name=value loop > </object>不需要loop时用<object name=value > </object>。其中name=value对表示其他属性类似于:id=”plugindemo”。

0 0
原创粉丝点击