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

我的玻璃盒子

【原創】我的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 深藍色系統 閱讀(16702) 評論(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,很納悶啊!  回復  更多評論   

導航

<2009年8月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
303112345

統計

常用鏈接

留言簿(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>
            国产精品日本欧美一区二区三区| 亚洲无亚洲人成网站77777| 亚洲美女精品一区| 欧美精品1区2区| 亚洲国产精品一区二区尤物区 | 亚洲大胆人体视频| 亚洲欧美日韩区| 亚洲精品在线电影| 国产精品一区二区久久 | 亚洲国产第一页| 91久久精品一区| 亚洲第一精品福利| 亚洲大胆女人| 亚洲精品在线免费观看视频| 欧美一区二区观看视频| 美女图片一区二区| 亚洲国产精品成人一区二区| 亚洲天堂av综合网| 亚洲区第一页| 亚洲二区三区四区| 亚洲日韩第九十九页| 亚洲女女女同性video| 久久久欧美精品| 欧美日韩高清在线| 国产在线日韩| 亚洲午夜一区二区三区| 久久婷婷人人澡人人喊人人爽| 亚洲高清不卡在线观看| 亚洲午夜av| 欧美高清你懂得| 国产日韩一区二区三区在线播放| 国产亚洲毛片| 国产精品家庭影院| 亚洲二区视频在线| 亚洲欧美日本伦理| 亚洲国产精品www| 午夜在线播放视频欧美| 欧美精品免费在线观看| 极品av少妇一区二区| 午夜国产精品影院在线观看 | 欧美婷婷在线| 国产亚洲精品美女| 西瓜成人精品人成网站| 亚洲国产精品一区二区久| 香蕉乱码成人久久天堂爱免费 | 亚洲欧美日韩中文播放| 亚洲高清中文字幕| 久久久久久亚洲精品中文字幕 | 9久re热视频在线精品| 久久精品国产第一区二区三区最新章节 | 蜜桃av一区二区| 国内自拍一区| 久久精品99国产精品| 亚洲影院在线观看| 国产精品每日更新在线播放网址| 亚洲素人一区二区| 亚洲精品久久久蜜桃| 欧美a级片网站| 亚洲黄色在线视频| 欧美大片一区二区三区| 麻豆久久久9性大片| 在线精品福利| 亚洲电影天堂av| 欧美极品aⅴ影院| 宅男精品视频| 一区二区电影免费观看| 欧美性色视频在线| 欧美呦呦网站| 久久精品女人天堂| 亚洲国产天堂久久综合网| 欧美激情bt| 欧美日韩一区二区在线播放| 亚洲一区二区三区高清| 亚洲欧美日韩天堂一区二区| 国产综合自拍| 亚洲国产精品成人综合色在线婷婷| 欧美高潮视频| 久久精品成人一区二区三区 | 久久av一区二区三区| 久久国产精品72免费观看| 亚洲福利在线看| 亚洲精品国产精品国自产观看浪潮 | 久久久久久久久久看片| 亚洲精品欧美日韩| 亚洲天堂免费观看| 激情欧美日韩一区| 亚洲精品欧美激情| 国产亚洲综合在线| 亚洲高清一区二区三区| 国产精品一级| 亚洲国产一区二区三区青草影视| 国产精品久久97| 欧美大片在线观看| 国产精品久久久一本精品| 久久网站免费| 欧美日韩在线播放一区| 久热精品在线| 欧美性片在线观看| 亚洲电影成人| 国内精品久久久久伊人av| 亚洲精品一区二区三区福利| 国产视频欧美视频| 99re热这里只有精品免费视频| 国内久久精品视频| 日韩视频一区二区三区在线播放| 国产一区二区丝袜高跟鞋图片| 亚洲欧洲精品一区二区| 国产性天天综合网| 日韩午夜av电影| 很黄很黄激情成人| 亚洲天堂网站在线观看视频| 一本色道久久综合亚洲精品高清| 欧美岛国激情| 国产日产欧产精品推荐色| 欧美激情中文不卡| 国产亚洲精品久| 日韩一级黄色av| 亚洲国产成人精品女人久久久 | 毛片基地黄久久久久久天堂| 国产精品美女诱惑| 91久久国产综合久久蜜月精品 | 久久精品亚洲热| 国产精品爱啪在线线免费观看| 欧美大片免费| 亚洲国产影院| 久热国产精品视频| 久久久综合精品| 国产日韩欧美二区| 亚洲女人小视频在线观看| 亚洲一区二区三区午夜| 欧美日韩国产片| 亚洲免费观看高清在线观看| 亚洲精品网址在线观看| 欧美成人免费在线| 欧美一区二区三区精品| 老司机精品视频一区二区三区| 欧美亚洲午夜视频在线观看| 国产精品第一页第二页第三页| av成人免费| 亚洲一二三区视频在线观看| 欧美日韩日日骚| 亚洲精品视频在线观看免费| 在线视频你懂得一区二区三区| 欧美日韩一区二区在线| 在线视频日韩| 久久激情视频免费观看| 国产亚洲美州欧州综合国| 欧美影院视频| 欧美国产日韩视频| 一区二区久久久久| 国产精品xvideos88| 午夜在线一区二区| 蜜臀91精品一区二区三区| 亚洲黄色小视频| 国产精品久久9| 久久精品在线视频| 亚洲电影av在线| 亚洲综合大片69999| 国产亚洲电影| 噜噜爱69成人精品| 99精品热视频| 久久精品1区| 亚洲精选大片| 国产精品视频第一区| 久久久精品久久久久| 亚洲黄色大片| 欧美亚洲免费在线| 亚洲精品之草原avav久久| 国产精品久久国产三级国电话系列| 小处雏高清一区二区三区| 亚洲电影一级黄| 久久久999精品视频| 艳妇臀荡乳欲伦亚洲一区| 国产美女精品免费电影| 欧美h视频在线| 亚洲免费在线播放| 欧美激情视频在线播放| 午夜宅男欧美| 在线亚洲伦理| 亚洲国产aⅴ天堂久久| 国产精品久久久免费| 欧美国产视频在线观看| 午夜精品福利视频| 亚洲精品资源| 欧美黑人国产人伦爽爽爽| 欧美在线你懂的| 一本久道久久综合婷婷鲸鱼| 国产亚洲精品资源在线26u| 欧美四级在线| 欧美激情一区三区| 久久性色av| 欧美一区二区三区另类| aa级大片欧美三级| 亚洲国产日韩一区| 美腿丝袜亚洲色图| 久久久噜噜噜久久中文字免| 亚洲欧美色婷婷| 亚洲一区二区三区激情| 在线亚洲自拍| 一本色道久久综合亚洲精品婷婷 |