1. 程式人生 > >NPAPI外掛開發學習:實現非IE瀏覽器的類似ActiveX的本地程式(外掛)呼叫

NPAPI外掛開發學習:實現非IE瀏覽器的類似ActiveX的本地程式(外掛)呼叫

轉載CSDN博友的一篇文章,方便以後學習。

一.Netscape Plugin Interface(NPAPI)

大致的說明可以看下官方文件Plugin

本文主要針對於javascript與外掛互動部分做一些交流,比如用於數字證書的操作(淘寶和支付寶的外掛),用於播放的flash player外掛等

與javascript的互動需要用到NPAPI中的

下面的部分將以示例的方式說明整個過程如何去實現

在開始前需要從火狐瀏覽器原始碼中獲取介面標頭檔案火狐4.0.1原始碼下載

下載後在\firefox-4.0.1.source\mozilla-2.0\modules\plugin

可以找到一些samples和標頭檔案

另外,基於NPAPI的一個跨瀏覽器外掛開發的框架FireBreath,非常容易上手而且據說跨瀏覽器的支援非常好,但是非常笨重,有些功能不需要的也不太容易去掉

還有一個基於NPAPI做的簡單的示例,結構非常簡單,不用繞來繞去,相對理解起來也簡單許多

二.外掛入門開發的示例 

開發工具為visual studio 2010

1.新建一個Win32 project,命名以np開頭(目的是編譯完的Dll名必須以np開頭才能被識別為外掛)

型別為一個DLL的空工程即可

2.右鍵選中專案的屬性,在VC++ Directories目錄下,選擇Include Directories,Edit,

將plugin/base/public和plugin/sdk/samples/include新增到include

3.新建Version資原始檔

[plain] view plaincopyprint?
  1. // Microsoft Visual C++ generated resource script.  
  2. //  
  3. #include "resource.h"  
  4. #define APSTUDIO_READONLY_SYMBOLS  
  5. /////////////////////////////////////////////////////////////////////////////  
  6. //  
  7. // Generated from the TEXTINCLUDE 2 resource.  
  8. //  
  9. #include "afxres.h"  
  10. /////////////////////////////////////////////////////////////////////////////  
  11. #undef APSTUDIO_READONLY_SYMBOLS  
  12. /////////////////////////////////////////////////////////////////////////////  
  13. // Chinese (Simplified, PRC) resources  
  14. #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)  
  15. LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED  
  16. #ifdef APSTUDIO_INVOKED  
  17. /////////////////////////////////////////////////////////////////////////////  
  18. //  
  19. // TEXTINCLUDE  
  20. //  
  21. 1 TEXTINCLUDE   
  22. BEGIN  
  23.     "resource.h\0"  
  24. END  
  25. 2 TEXTINCLUDE   
  26. BEGIN  
  27.     "#include ""afxres.h""\r\n"  
  28.     "\0"  
  29. END  
  30. 3 TEXTINCLUDE   
  31. BEGIN  
  32.     "\r\n"  
  33.     "\0"  
  34. END  
  35. #endif    // APSTUDIO_INVOKED  
  36. /////////////////////////////////////////////////////////////////////////////  
  37. //  
  38. // Version  
  39. //  
  40. VS_VERSION_INFO VERSIONINFO  
  41.  FILEVERSION 1,0,0,1  
  42.  PRODUCTVERSION 1,0,0,1  
  43.  FILEFLAGSMASK 0x3fL  
  44. #ifdef _DEBUG  
  45.  FILEFLAGS 0x1L  
  46. #else  
  47.  FILEFLAGS 0x0L  
  48. #endif  
  49.  FILEOS 0x40004L  
  50.  FILETYPE 0x2L  
  51.  FILESUBTYPE 0x0L  
  52. BEGIN  
  53.     BLOCK "StringFileInfo"  
  54.     BEGIN  
  55.         BLOCK "040904e4"  
  56.         BEGIN  
  57.             VALUE "CompanyName", "WHU ISS"  
  58.             VALUE "FileDescription", "A new Plugin For test"  
  59.             VALUE "FileVersion", "1.0.0.1"  
  60.             VALUE "InternalName", "npTest.dll"  
  61.             VALUE "LegalCopyright", "Copyright (C) 2012"  
  62.         VALUE "MIMEType", "application/x-npTest"  
  63.             VALUE "OriginalFilename", "npTest.dll"  
  64.             VALUE "ProductName", "new Plugin Test"  
  65.             VALUE "ProductVersion", "1.0.0.1"  
  66.         END  
  67.     END  
  68.     BLOCK "VarFileInfo"  
  69.     BEGIN  
  70.         VALUE "Translation", 0x804, 1200  
  71.     END  
  72. END  
  73. #endif    // Chinese (Simplified, PRC) resources  
  74. /////////////////////////////////////////////////////////////////////////////  
  75. #ifndef APSTUDIO_INVOKED  
  76. /////////////////////////////////////////////////////////////////////////////  
  77. //  
  78. // Generated from the TEXTINCLUDE 3 resource.  
  79. //  
  80. /////////////////////////////////////////////////////////////////////////////  
  81. #endif    // not APSTUDIO_INVOKED  

需要注意的是Block 必須為040904e4,MIMEType為最後引用外掛的標誌

4.新建一個Module-Definition File(.def),定義入口函式

[plain] view plaincopyprint?
  1. LIBRARY   npTest  
  2. EXPORTS  
  3.     NP_GetEntryPoints   @1  
  4.     NP_Initialize       @2  
  5.     NP_Shutdown         @3  

5.新建一個CPlugin類繼承nsPluginInstanceBase,作為外掛例項類(後面再說該類的作用)

確定之後,在plugin.h中#include <pluginbase.h>

類名為Cplugin,標頭檔案名為plugin.h,(npp_gate.cpp會使用到,不同可以修改)

修改建構函式的實現,帶引數NPP型別並新建一個屬性儲存該引數

實現父類的三個純虛擬函式

[cpp] view plaincopyprint?
  1. NPBool init(NPWindow* aWindow);//NPWindow用於外掛中繪畫部件的視窗
  2. void shut();  
  3. NPBool isInitialized();  

6.免得做過多操作,從samples中引入已經編寫好的入口函式

從plugin\sdk\samples\npruntime路徑新增np_entry.cpp(外掛入口函式),npn_gate.cpp(外掛呼叫瀏覽器的一些方法),npp_gate.cpp(瀏覽器呼叫外掛的一些方法)

新增後需要做一點修改,

1).np_entry.cpp和npn_gate.cpp的引用

#include "npapi.h"
#include "npfunctions.h"

換成

#include<pluginbase.h>

2).然後進入pluginbase.h,再進入npplat.h,將

#ifdef XP_WIN
#include "windows.h"
#endif

挪到

#include "npapi.h"
#include "npfunctions.h"

前面,

3).然後在專案屬性,Preprocessor,Preprocessor Definitions新增XP_WIN的定義

(這樣做的原因是windows.h需要在npapi.h前定義,自己在所有引用了npapi.h的前面加上windows.h的引用也可以)

4),np_entry.cpp中引入標頭檔案#include <stddef.h>

因為使用到offsetof

這三個檔案中的函式非常重要,首先來看下np_entry.cpp中的函式

NP_GetEntryPoints函式,為外掛入口的函式,外掛初始化將會首先呼叫該函式

該函式用於初始化瀏覽器呼叫外掛的函式表,以NPP(np plugin)開頭,

後面的外掛的一些事件(new等)發生時將會以這裡初始化的函式作為入口,比如

 pFuncs->newp          = NPP_New;初始化後將會在建立外掛例項時呼叫NPP_New的實現來建立.

NP_Initialize函式,初始化外掛時,在NP_GetEntryPoints後呼叫,

該函式用於初始化外掛呼叫瀏覽器的函式表,引數pFuncs帶有該函式表資訊,

我們自定義一個物件儲存這些資訊,今後就可通過該物件呼叫方法來實現對瀏覽器的一些操作

NP_Shutdown函式,與NP_Initialize對應,主要釋放資源等操作

再來看下npp_gate.cpp,這個檔案中的函式都以NPP開頭,用於定義瀏覽器呼叫外掛的方法

經過NP_GetEntryPoints的初始化後,當特定事件發生時,瀏覽器將會呼叫這些方法

然後需要注意的是該檔案引用了plugin.h,是我們第5步建立的檔案,名字不同可以改改

NPP_New方法,用於建立外掛例項

CPlugin * pPlugin = new CPlugin(instance);這句話為建立一個我們定義的CPlugin類物件,建構函式為NPP型別

NPP_Destroy方法,用於銷燬外掛例項,重新整理頁面,關閉頁面等操作會觸發

該方法會呼叫CPlugin的shut方法再delete掉例項

NPP_SetWindow方法,外掛視窗發生任何變化都會呼叫該方法

window建立時會呼叫一次,如果初始化失敗則delete掉例項然後返回錯誤

NPP_GetValue方法,當獲取外掛有關的一些資訊時會觸發該方法呼叫(如獲取外掛名,外掛例項)

當javascript操作外掛物件時,該方法呼叫CPlugin的GetScriptableObject方法,需要自己實現,返回一個指令碼操作物件(NPObject)

在這裡返回到CPlugin類,新增GetScriptableObject方法並實現(見第7步操作)

NPP_HandleEvent方法,處理事件,該方法呼叫CPlugin的handleEvent方法,繼續新增實現吧

該檔案中其他方法暫時沒什麼可說的,需要用到的可以查下API並實現出來就行了.

再看下npn_gate.cpp,該檔案實現了對瀏覽器的一些操作的函式,都以NPN(np netscape)開頭

其中有一些帶有NPObject*引數的與GetScriptableObject方法建立的指令碼操作物件有關,將在第7步做說明

該檔案中用到的NPNetscapeFuncs NPNFuncs;在NP_Initialize中初始化完成

7.封裝一個指令碼操作物件

Add一個C++類,該示例命名為PluginObject,繼承NPObject

新增靜態方法,用於建立該指令碼操作的物件

[cpp] view plaincopyprint?
  1. 相關推薦

    NPAPI外掛開發學習實現IE瀏覽器類似ActiveX本地程式(外掛)呼叫

    轉載CSDN博友的一篇文章,方便以後學習。 一.Netscape Plugin Interface(NPAPI) 大致的說明可以看下官方文件Plugin 本文主要針對於javascript與外掛互動部分做一些交流,比如用於數字證書的操作(淘寶和支

    NPAPI——實現IE瀏覽器類似ActiveX本地程式(外掛)呼叫

    一.Netscape Plugin Interface(NPAPI) 大致的說明可以看下官方文件Plugin 本文主要針對於javascript與外掛互動部分做一些交流,比如用於數字證書的操作(淘寶和支付寶的外掛),用於播放的flash player外掛等 與javascr

    NPAPI外掛開發學習Webkit的外掛機制

    轉載CSDN博友的一篇關於NPAPI外掛機制的博文。 # 外掛機制(NPAPI plugin) ## 概述 Chromium中的NPAPI外掛(plugin)來源於mozilla的外掛機制。因為它被廣泛的應用,很多外掛廠商或者開發者基於它編寫了數以萬計的外掛,因而

    Chrome外掛開發入門如何實現一鍵上班賴皮

    很多人介紹過Chrome外掛,但必須要說,外掛開發就是擺弄一個小玩具,第一要素是實用,其次是好玩。 單純羅列各種功能是非常無趣的。 所以把一篇舊文拿出來與大家分享。 人,活著就是為了賴皮。 作為一個合格的開發人員,把30%的時間用來賴皮(上班偷懶)是值得推薦的。 因為,如果你工作時間無法賴皮,

    微信開發學習輸入城市+天氣接收天氣預報,非常好玩

        這次實踐一下這篇 http://www.jb51.net/article/51923.htm     輸入城市+天氣四個字,接收天氣預報,資料來源是百度天氣預報介面。原來的程式碼功能多,比較複雜,我精簡了一下,相對容易看懂。 完成後的效果: wx_token

    Vue.js 開發實踐實現精巧的無限加載與分頁功能

    cti head 設定 命令 webpack transform style time default https://segmentfault.com/a/1190000005351971#articleHeader9 本篇文章是一篇Vue.js的教程,目標在於用一

    flask學習實現一個簡單的登入的邏輯處理

    最近在學習flask框架,果然比javaweb簡單很多。 需求是實現一個簡單的登入的邏輯處理。有判空和判斷不一致的操作。 其中app.py內容如下: from flask import Flask, render_template,request,flash app = Flask

    java開發學習陣列總結

    要論Java開發學習哪一部分重要?我一定斬釘截鐵的回答你:一定不是框架,其中Java基礎相對框架來講要重要一百倍。因為每個公司用的框架總有差異,但萬變不離其宗,都是基礎知識搭建起來的,所以我們想要學好Java,就一定要打好基礎。 今天小編給大家分享的Java基礎知識之一——陣列! 用來儲存

    ArcMap外掛開發初識Add In

    之前一直在做ArcEngine的相關開發,做的winform相關,新換了工作,又開始新的學習旅程! Add In 這個東西很早就知道有,但是一直沒有用過,因為之前的公司有自己框架,介面,雖然我也是做外掛開發,但是都是基於原公司的平臺。新公司的同事希望能幫忙做個小工具,用C#+winform介面,做了個小型的

    一個實現瀏覽器網頁與本地程式之間進行雙向呼叫的輕量級、強相容、可擴充套件的外掛開發平臺—本網通

           通過本網通外掛平臺可實現在網頁中的JavaScript指令碼無障礙訪問本地電腦的硬體、呼叫本地系統的API及相關元件,同時可徹底解決ActiveX元件在Chrome、FireFox、Opera、Edge、Safari等瀏覽器各版本的相容使用問題。 系統相容性:

    前端開發實戰實現京東購物平臺的靜態首頁

    本次實戰的內容是實現京東購物網頁的前端頁面,使用的依然是DIV+CSS佈局模式。本次專案主要是為了檢驗自己對原生JS和jQuery的掌握程度,專案中也用到了很多CSS3的新特性。 這次使用jQuery將輪播圖、下拉選單欄,城市選項卡封裝成了三個外掛,使程式碼結構的更為模組化,提高了後

    moduo網路庫的reactor模式(下)實現阻塞TCP網路

    1、在reactor框架下加入tcp Unix下的tcp連線也是經由socket檔案描述符(sockfd)實現的。此節只是封裝了listening sockefd進行監聽(accept(2)),得到的新連線(普通sockfd)直接提供給使用者讓使用者自行處理。下一節才進一步

    Spring Boot+Spring Security專案開發(三)實現簡訊驗證碼登入

    說在前面 博主最近會有很多專案跟大家一起分享,做完後會上傳github上的,希望讀友們能給博主提提意見哈哈 這個專案是第三方登入和安全方面的,關於後臺與app和網站的登入連線操作的實戰專案 各位如果可以就給我star哈哈謝謝啦 實

    Android學習實現複雜的列表項

    實現複雜的列表項,這裡實現的是帶圖片的列表項,主要任務的寫一個BaseAdapter的子類,不過在這之前先構造個存列表項資料的類ListViewCellData,實現建構函式和幾個get方法即可,再在BaseAdapter中構造個數組存放幾組測試資料: public cla

    Vue.js 開發實踐實現精巧的無限載入與分頁功能

    https://segmentfault.com/a/1190000005351971#articleHeader9 需求分析 當一個頁面中資訊量過大時(例如一個新聞列表中有200條新聞需要展示),就會產生問題,例如: 資料量過大,影響載入速度 使用者體驗差,很難定位到之前自己看

    Eclips外掛開發學習資源

    最近斷斷續續的在研究Eclipse平臺的外掛開發,感覺這方面的資源比較少,所以整理在這裡,和大家分享 書籍:         Eclipse Plug-ins (3rd Edition) (中文書名

    XHTMLIE瀏覽器裡對style.width賦值無效的問題

    在做JSP頁面時,除錯div的高度的時候,在IE等瀏覽器裡都已經測試通過沒有任何問題,但是在Chrome、Mozilla、Firefox、Netscape裡測試時問題就來了,我的多頁面是在頁面裡用到了 iframe,這些 iframe 初始的 style.height 都

    XHTMLIE瀏覽器裡對style.height賦值無效的問題

    今天我在做多頁面MDI指令碼控制元件(MzMultiPage),在IE等瀏覽器裡都已經測試通過沒有任何問題,但是在Mozilla、Firefox、Netscape裡測試時問題就來了,我的多頁面是在頁面裡用到了 iframe,這些 iframe 初始的 style.height

    jQuery外掛開發學習

    1、jQuery外掛編寫準備 要使用jQuery進行自定義外掛的編寫,首先應該的是瞭解jQuery的外掛機制或者說是通過jQuery庫本身提供的哪些函式進行外掛的編寫,主要涉及的兩個函式是:jQuery.extend(object)和jQuery.fn.extend(o

    Servlet學習實現分頁效果的方法

    分頁的演算法: 需要定義四個變數,它們有各自的用處 int pageSize:每頁顯示多少條記錄 int pageNow:希望顯示第幾頁 int pageCount:一共有多少頁 int rowCount:一共有多少條記錄 說明: pageSize是指定,pageNow是指