青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

我的玻璃盒子

【原創】我的Firefox插件開發之旅(7)——為插件添加和腳本交互的能力

先說一句題外話,上一節一開始我提到了由于.rc導致我自己寫的插件不能被FF識別的問題,今天終于找到答案了。在這篇文章中:https://developer.mozilla.org/en/Gecko_Plugin_API_Reference/Plug-in_Development_Overview,有這么一段話:In your development environment, make sure your language is set to "US English" and the character set to "Windows Multilingual." The resource code for this language and character set combination is 040904E4. 看來這FF還只能使用英文。

OK,步入正題。這一小節我來簡單說一下如何為插件添加和腳本語言(如Javascript)交互的能力。我會為插件添加幾個函數,供Javascript調用。

前面我們提到過瀏覽器調用插件的方法的順序,基本上為:NP_GetEntryPoints、NP_Initialize、NPP_New、NPP_SetWindow、NPP_GetValue。在NPP_New中,我們需要創建插件對象的實例,NPP_SetWindow中,瀏覽器會傳入插件窗口的信息,最后一個NPP_GetValue,是瀏覽器來獲取一些插件信息的。NPP_GetValue函數的結構是這樣的:

NPError  NPP_GetValue(NPP instance, NPPVariable variable, void *value);

  • instance包含著插件對象實例;
  • variable表示瀏覽器要獲取的信息的類型;
  • value表示返回給瀏覽器的值

瀏覽器會傳入NPPVpluginScriptableNPObject(作為variable參數)來查詢插件是否支持Scriptable功能(即和腳本語言交互的功能),在這里,我們可以利用NPN_CreateObject方法來創建一個NPObject對象,并且作為value返回給瀏覽器。這樣,瀏覽器就通過這個NPObject對象和我們的插件建立了連接。當頁面上Javascript調用了我們插件對象的某個方法時,瀏覽器會調用該NPObject對象的HasMethod方法來查詢是否支持這個方法,如果支持,則會調用NPObject對象的Invoke方法,傳入方法名、參數等信息。這樣,我們就可以讓網頁上的腳本語言來執行我們編寫的函數了。在Windows上,我們編寫的函數就如同編寫普通的應用程序一樣,可以使用很多Windows API來完成許多復雜的工作。

上面有個問題:如何創建我們自己的NPObject對象?NPN_CreateObject方法如何使用?好在Mozilla給我們提供了npruntime這個例子程序,可以讓我們得以參考。

先來看看NPN_CreateObject方法的定義:

NPObject *NPN_CreateObject(NPP npp, NPClass *aClass);

關鍵在第二個參數上,我們需要提供一個NPClass指針。npruntime例子程序中是這么做的:

定義了一個宏DECLARE_NPOBJECT_CLASS_WITH_BASE,其作用就是定義了一個靜態的NPClass對象,并且NPClass要求的所有基礎方法,都由一個ScriptablePluginObjectBase類來提供。我們根據需要,來創建不同的繼承于ScriptablePluginObjectBase的類(比如支持方法的類和支持屬性的類),傳給DECLARE_NPOBJECT_CLASS_WITH_BASE宏,這樣,當瀏覽器管我們“要”的時候,我們就可以按照它的需要“給”它對應的對象。

npruntime例子中,ScriptablePluginObject是用來處理方法的,而ConstructablePluginObject是用來處理屬性的。

 

如何定義一個方法(或屬性)?

1、添加一個方法(或屬性)很簡單,先定義一個靜態NPIdentifier類型的變量,例如:

static NPIdentifier s_idSetArgs;

2、在插件對象構造函數中,使用NPN_GetStringIdentifier方法來設置該方法的名稱,例如:

s_idSetArgs = NPN_GetStringIdentifier("SetArgs");

其中,SetArgs就是我們提供給腳本語言調用的方法名稱。

3、在ScriptablePluginObject的HasMethod方法中,判斷傳入的方法名:

bool ScriptablePluginObject::HasMethod(NPIdentifier name)
{
    if(name == s_idSetArgs)
    {
        printf("method name = SetArgs\n");
        return true;
    }

    return false;
}

4、在ScriptablePluginObject的Invoke方法中,判斷如果傳入的方法名稱等于我們定義的方法名,則做你想要做得事情:

//////////////////////////////////////////////////////////////////////////
///
/// @brief    如果某個方法支持(使用HasMethod檢測),當頁面上Javascript代碼調用該方法時,會執行本函數
///
/// @param [in] name    方法名
/// @param [in] args    參數值(數組)
/// @param [in] argCount    參數個數
/// @param [in] result    執行后返回給調用者的結果
///
/// @return PR_TRUE表示執行成功,PR_FALSE表示失敗
///
//////////////////////////////////////////////////////////////////////////

bool ScriptablePluginObject::Invoke(NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result)

{
    if(name == s_idSetArgs)

    {

        這里做你想要做得事情

        return PR_TRUE;

    }

    return PR_FALSE;

}

關于方法參數的接收,這里舉個例子。比如網頁上這么調用:

embedobj.SetArgs("name", "value");

在我們的方法中,就可以這么接收:

if(args != NULL && argCount >= 2)
{
    NPVariant npvName = args[0]; //第一個參數
    NPVariant npvValue = args[1]; //第二個參數
    if(NPVARIANT_IS_STRING(npvName) && NPVARIANT_IS_STRING(npvValue))  //如果兩者都是字符串類型(當然你還可以判斷是否是其他類型)
    {
        NPString npsName = NPVARIANT_TO_STRING(npvName); //轉成NPString
        NPString npsValue = NPVARIANT_TO_STRING(npvValue);

        if(npsName.utf8characters && strlen(npsName.utf8characters) > 0) //限定條件,可以根據需要進行修改。這里限定第一個參數內容不能為空
        {
            int nLenName = strlen(npsName.utf8characters) + 1;
            int nLenValue = strlen(npsValue.utf8characters) + 1;

            PARAMPAIR paramPair;
            paramPair.pName = new char[nLenName];
            memset(paramPair.pName, 0, nLenName);
            paramPair.pValue = new char[nLenValue];
            memset(paramPair.pValue, 0, nLenValue);

            strcpy(paramPair.pName, npsName.utf8characters); //將參數內存存儲到我們熟悉的C
            strcpy(paramPair.pValue, npsValue.utf8characters);

            m_vecParamPair.push_back(paramPair);
        }
    }
}

上面的代碼中,PARAMPAIR就是一個簡單的結構體:

typedef struct tagPARAMPAIR
{
    LPTSTR pName;
    LPTSTR pValue;
}PARAMPAIR, *PPARAMPAIR;

m_vecParamPair是一個vector:vector<PARAMPAIR> m_vecParamPair;

順便說一句,上面只是代碼片段,關于內存釋放、vector清空等操作,由于不是這里要說的關鍵部分,所以沒有列出。

OK,現在我們的插件已經可以順利和網頁進行交互工作了。

posted on 2008-11-14 10:56 深藍色系統 閱讀(16686) 評論(10)  編輯 收藏 引用 所屬分類: Firefox開發

評論

# re: 我的Firefox插件開發之旅(7)&mdash;&mdash;為插件添加和腳本交互的能力 2009-07-29 13:37 tmy13

學習了下npapi再回過頭來看樓主的這篇文章,受益匪淺  回復  更多評論   

# re: 【原創】我的Firefox插件開發之旅(7)&mdash;&mdash;為插件添加和腳本交互的能力 2009-10-19 15:43 tt

我是一個新手,能不能做一個 hello word 的例子?  回復  更多評論   

# re: 【原創】我的Firefox插件開發之旅(7)&mdash;&mdash;為插件添加和腳本交互的能力 2009-11-11 11:28 Pat

太好了。高手。我看這代碼都看不明白,現在懂個大概了,非常感謝!  回復  更多評論   

# re: 【原創】我的Firefox插件開發之旅(7)&mdash;&mdash;為插件添加和腳本交互的能力 2009-11-11 18:31 Pat

你好,我想知道怎么樣從plugin里面訪問JS,能留個聯系方式嗎?QQ  回復  更多評論   

# re: 【原創】我的Firefox插件開發之旅(7)&mdash;&mdash;為插件添加和腳本交互的能力[未登錄] 2010-11-02 15:27 Eping

在資源文件里添加版本信息,保證 BLOCK "040904e4" 即可,是否為英語倒不是這么重要,查看Firefox源代碼可發現,這才是最重要的!
if(::GetFileVersionInfo((char*)path, NULL, versionsize, verbuf))
{
info.fName = GetKeyValue(verbuf, "\\StringFileInfo\\040904E4\\ProductName");
info.fDescription = GetKeyValue(verbuf, "\\StringFileInfo\\040904E4\\FileDescription");

char *mimeType = GetKeyValue(verbuf, "\\StringFileInfo\\040904E4\\MIMEType");
char *mimeDescription = GetKeyValue(verbuf, "\\StringFileInfo\\040904E4\\FileOpenName");
char *extensions = GetKeyValue(verbuf, "\\StringFileInfo\\040904E4\\FileExtents");

BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904e4"
BEGIN
VALUE "Comments", "\0"
VALUE "CompanyName", " \0"
VALUE "FileDescription", "Adobe Flash movie \0"
VALUE "FileExtents", "swf\0"  回復  更多評論   

# re: 【原創】我的Firefox插件開發之旅(7)&mdash;&mdash;為插件添加和腳本交互的能力 2011-08-26 15:14 求穩

你好,我想請問下, 能通過firefox extension 來 調用 NPAPI dll寫的方法嗎? 如果可以,該通過什么方式呢? xul 里 還是 js 里呢?  回復  更多評論   

# re: 【原創】我的Firefox插件開發之旅(7)&mdash;&mdash;為插件添加和腳本交互的能力 2012-07-06 18:10 陳后根

可以這里沒有講如何用插件調用js中的函數,應該怎樣實現這個功能呢?
  回復  更多評論   

# re: 【原創】我的Firefox插件開發之旅(7)&mdash;&mdash;為插件添加和腳本交互的能力 2013-09-13 14:57 maqingfeng

你好,我想問一下,如何把接收到的參數,傳遞給插件對象呢?就是在pluging.cpp中有一個回調函數,在這上面畫出傳進來的字符串。而這個函數不是plugin的成員函數。  回復  更多評論   

# re: 【原創】我的Firefox插件開發之旅(7)&mdash;&mdash;為插件添加和腳本交互的能力[未登錄] 2013-09-18 10:11 sun

大神,我想做firefox plugin 加密,能不能給個demo看看【15527974275@163.com】,我都不知道
bool ScriptablePluginObject::HasMethod(NPIdentifier name) ,這個方法放在哪里? 我以前是搞object_c的,,這個完全不懂,研究半個月,卡在這個地方了,seek help!  回復  更多評論   

# re: 【原創】我的Firefox插件開發之旅(7)&mdash;&mdash;為插件添加和腳本交互的能力 2016-03-05 01:26 zzx

報錯:無法解析外部符號_NPN_CreateObject,很納悶啊!  回復  更多評論   

導航

<2016年3月>
282912345
6789101112
13141516171819
20212223242526
272829303112
3456789

統計

常用鏈接

留言簿(75)

隨筆分類

隨筆檔案

文章分類

文章檔案

搜索

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久成人免费| 韩国v欧美v日本v亚洲v| 亚洲欧美另类久久久精品2019| 亚洲电影av| 麻豆成人综合网| 欧美肥婆在线| 亚洲日本中文字幕| 亚洲图片欧美午夜| 亚洲综合精品四区| 久久视频国产精品免费视频在线| 美女精品网站| 欧美三级中文字幕在线观看| 国产日韩欧美成人| 亚洲国产精品久久人人爱蜜臀| 日韩视频一区二区三区在线播放免费观看| av成人天堂| 久久精品国产综合| 亚洲精品久久久一区二区三区| 亚洲综合日本| 欧美精品一线| 黄网站色欧美视频| 99日韩精品| 久久久久天天天天| 亚洲最快最全在线视频| 久久午夜精品一区二区| 国产精品扒开腿做爽爽爽软件| 一区在线视频| 欧美一区二区三区在线观看| 亚洲国产日韩在线| 久久精品盗摄| 国产精品爽爽ⅴa在线观看| 亚洲欧洲日产国码二区| 久久精品国产精品亚洲| 亚洲美女毛片| 久热精品视频在线观看一区| 国产伦精品一区二区三区| 日韩一级精品视频在线观看| 久久亚洲精品视频| 亚洲一区二区在线播放| 欧美精品一区二区三区蜜桃| 黄色成人在线网址| 久久国产免费| 亚洲欧美日韩系列| 国产精品分类| 亚洲午夜在线| 亚洲伦理在线免费看| 久久视频在线视频| 国内揄拍国内精品少妇国语| 欧美亚洲视频一区二区| 在线一区二区日韩| 裸体一区二区三区| 国产日产欧产精品推荐色| 99视频超级精品| 六月婷婷一区| 久久久久久久久久码影片| 国产日产欧产精品推荐色 | 国产亚洲一区二区在线观看 | 欧美成人一区二区三区在线观看| 羞羞答答国产精品www一本 | 韩国欧美一区| 久久永久免费| 另类天堂视频在线观看| 亚洲第一二三四五区| 久久久蜜桃精品| 久久精品在线免费观看| 在线成人免费观看| 欧美韩日高清| 欧美久久一区| 亚洲一区二区成人在线观看| 99riav1国产精品视频| 欧美色图麻豆| 欧美一级午夜免费电影| 性欧美暴力猛交69hd| 国产一区二区三区奇米久涩| 久久综合狠狠综合久久综青草 | 国产精品免费看片| 欧美一区永久视频免费观看| 欧美亚洲在线观看| 在线国产欧美| 亚洲激情在线观看视频免费| 欧美日韩伦理在线免费| 午夜精彩视频在线观看不卡| 欧美在线视频一区二区| 亚洲国产高清自拍| 99精品99| 黄色成人av网| 日韩视频免费观看| 国产一区二区三区黄视频| 免费观看亚洲视频大全| 欧美日韩精品是欧美日韩精品| 亚洲专区一区二区三区| 久久国产成人| 亚洲无限av看| 久久青草欧美一区二区三区| 中文精品视频一区二区在线观看| 午夜精品久久久久久久99樱桃| 亚洲高清视频中文字幕| 中文有码久久| 亚洲欧美激情精品一区二区| 麻豆精品一区二区综合av| 国产女主播一区| 尤物在线精品| 欧美在线视频一区二区| 美腿丝袜亚洲色图| 亚洲伊人一本大道中文字幕| 久久精品免费观看| 亚洲一卡二卡三卡四卡五卡| 老司机久久99久久精品播放免费 | 开元免费观看欧美电视剧网站| 牛人盗摄一区二区三区视频| 欧美中文字幕在线| 欧美极品一区| 欧美a级理论片| 国产色综合久久| 一本一本久久a久久精品牛牛影视| 亚洲大胆女人| 久久成人18免费观看| 亚洲女人天堂成人av在线| 欧美国产日韩视频| 欧美暴力喷水在线| 国产亚洲欧美一区在线观看| 中国亚洲黄色| 亚洲午夜精品久久| 欧美日韩国产一中文字不卡| 亚洲电影免费在线| 亚洲国产另类精品专区| 久久精品一区二区三区不卡| 久久超碰97人人做人人爱| 国产精品久线观看视频| 在线视频中文亚洲| 亚洲一区二区三区四区五区午夜 | 国产精品一级二级三级| 99ri日韩精品视频| 亚洲天堂免费观看| 欧美日韩在线三区| 99精品视频一区二区三区| 一区二区三区精品视频| 欧美另类在线播放| 99国产精品国产精品久久| 这里只有精品丝袜| 欧美午夜片在线观看| 亚洲视频日本| 香蕉成人久久| 国产区欧美区日韩区| 欧美亚洲午夜视频在线观看| 久久久噜噜噜久久人人看| 国产自产在线视频一区| 久久久999成人| 亚洲福利国产| 一区二区三区蜜桃网| 国产精品久久久久77777| 一区二区欧美日韩视频| 亚洲欧美伊人| 精品51国产黑色丝袜高跟鞋| 免费欧美电影| 一区二区三区欧美| 亚洲人成在线观看网站高清| 欧美在线看片a免费观看| 国产伦精品一区二区| 久久国产精品99久久久久久老狼| 久久综合久色欧美综合狠狠| 91久久综合| 国产精品国产三级国产aⅴ入口| 午夜精品免费| 欧美激情中文字幕在线| 亚洲一区二区在线| 韩日午夜在线资源一区二区| 欧美激情女人20p| 亚洲一级二级| 欧美成熟视频| 午夜亚洲性色福利视频| 亚洲高清在线精品| 国产精品国产三级国产普通话99 | 久久美女艺术照精彩视频福利播放| 亚洲国产cao| 国产精品久久久久免费a∨大胸| 久久国产99| 一区二区三区 在线观看视频| 久久久亚洲人| 亚洲一区在线观看视频| 亚洲第一综合天堂另类专| 国产精品久久久久久模特 | 亚洲精品色婷婷福利天堂| 久久精品一区二区三区不卡| 亚洲免费观看| 黑丝一区二区| 国产精品久久亚洲7777| 欧美激情欧美激情在线五月| 久久精品国产一区二区三| 中文亚洲视频在线| 亚洲精品123区| 久久资源在线| 欧美在线关看| 亚洲一区中文| 一区二区三区欧美在线| 亚洲欧洲精品一区二区三区不卡| 国产亚洲精品bv在线观看| 欧美午夜电影完整版| 欧美日本高清一区| 嫩模写真一区二区三区三州|