FlashNess
1.0.0
Application of Outdated NPAPI Technology.
使用NPAPI模擬類Flash技術實現,封裝NAPI for FF/Chrome和ActiveX for IE。
| 目錄 | 說明 | 備註 |
|---|---|---|
| mozilla | 火狐組織代碼,開源SDK | 請勿修改 |
| npapi | NPAPI SDK | 請勿修改 |
| npplugin | NPAPI插件的實現 | 已經實現自動化接口處理及數據轉調,默認可以不做修改即可使用 |
| regs | 註冊表操作,包含32位/64位,及相關安全性處理 | 使用者根據程序生成私有化的CLSID,修改對應的ID值即可 |
| flashness | FlashNess插件實現代碼 | 用戶根據需要生成對應的業務代碼和CLSID等信息,接口實現參考樣例 |
| release | 編譯生成目錄,保護生成的npFlashNess.dll和註冊批處理、測試頁面等 | 用戶可以註冊後打開test.html進行簡單測試 |
工程創建
使用Visual Studio嚮導創建活動模板庫(使用ATL),作為開始編寫動態鏈接庫(DLL)的起點。
文件說明
| 文件名 | 說明 | 備註 |
|---|---|---|
| FlashNess.vcxproj | vs嚮導生成vc++項目的主項目文件,包含VC++的版本信息以及平台、配置和項目功能的信息 | |
| FlashNess.vcxproj.filters | 嚮導生成的項目篩選器文件,包含篩選器及對應的文件信息 | |
| FlashNess.idl | 項目定義的類型庫、接口、組件類的IDL定義,由MIDL編譯器進行處理生成C++接口定義和GUID聲明(FlashNess.h)、GUID定義(FlashNess_i.c)、類型庫(FlashNess.tlb)、封送處理代碼(FlashNess_p.c和dlldata.c) | 工程核心文件,接口定義 |
| FlashNess.h | 包含FlashNess.idl中定義的項目的C++接口定義和GUID聲明,在編譯過程中由MIDL重新生成 | 不用修改,修改idl文件後自動生成 |
| FlashNess.cpp | 包含對象映射和DLL導出的接口實現 | 核心功能和業務邏輯實現 |
| FlashNess.rc | 程序資源列表 | 可以在資源管理器中修改,盡量不要手動修改以免出現錯誤 |
| FlashNess.def | 定義文件為鏈接器提供的有關DLL所要求導出的信息,例如想要導出某一個接口供外部直接調用 | 對於插件來說基本上不用修改,固定導出DllGetClassObject、DllCanUnloadNow、DllRegisterServer、DllUnregisterServer、DllInstall即可 |
| stdAfx.h/cpp | 預編譯文件 | 無需修改,已包含基本庫 |
| resource.h | 定義例如按鈕ID、圖片ID等 | 無需修改 |
接口實現
NPAPI剖析
使用如上demo如何開發一個新的基於NPAPI和ActiveX的插件體系?
代碼拉取
git clone https://github.com/walklang/FlashNess.git
使用嚮導新建ATL接口
詳情搜索COM組件,新建接口即可
NPAPI接口擴展(可選)
FlashNess已經模擬兼容NPAPI和ActiveX的接口調用,搜索ActiveX增加接口函數即可快速實現IE和FF/chrome瀏覽器的兼容實現。
接口新增實例介紹
FlashNess中實現了Get接口和Set接口方法,其他形式可以參考實現;用戶可以自行搜索IDL格式以及實現方式。需要注意的是:如果是Get接口(如ReadData),那麼實現時的函數名前需要加上get_(如get_ReadData)。用戶可以通過如下兩個文件參考實現。
打開FlashNess.idl文件,向IFlashNess接口新增函數
interface IFlashNess : IDispatch{
[id(1)] HRESULT WriteData([in] BSTR bstrPath);
[propget, id(2)] HRESULT ReadShort([out, retval] SHORT* pVal);
[propget, id(3)] HRESULT ReadData([out, retval] BSTR* data);
};
打開FlashNess.h文件,在文件結尾新增接口實現
STDMETHOD(WriteData)(BSTR bstrPath) {
if (bstrPath == nullptr) return S_FALSE;
ATL::CComBSTR bstr_val = bstrPath;
data_ = bstr_val;
return S_OK;
}
STDMETHOD(get_ReadShort)(SHORT* pVal){
*pVal = 1;
return S_OK;
}
STDMETHOD(get_ReadData)(BSTR* pVal) {
if (!pVal) return S_FALSE;
std::string temp = CT2AEX<>(data_.c_str());
CComBSTR value(temp.c_str());
*pVal = value.Detach();
return S_OK;
}
std::wstring data_;