入门级的NPAPI开发。
NPAPI & NPRuntime 简介
Netscape Plugin Application Programming Interface (NPAPI)
NPAPI 原本是由 Netscape 所制定的一组单纯的 C Plugin API,起初是无法支持 Scriptability;于是到了 2004 年底,各家 Browser (IE, Opera, Mozilla 等) 都同意支持NPRuntime 延伸 API 以支持 Scriptability,所以目前若是想写 Plugin则应该以 NPRuntime API 才能跨不同的 Browsers。
下面通过示例来开发一个简单的示例。
第一:资源准备
1.NPAPISDK:现在地址这里下载mozilla源码,解压firefox-4.0.1.source.tar.bz2文件。
2.将 mozilla-2.0modulesplugin 目录解压缩出来,里面有我们开发NPAPI插件所需的所有资源。如下图
3.把上一步的plugin解压的文件放固定的目录以便对文件路径进行管理。如F:BrowersDV papiplugin
4.新建工程,名称一定要以np开头,以适应不同的操作系统,不要太长尽量在把八字节以内。本例为npdzhdemo
下一步:选Win32项目,工程目录和上面解压的plugin文件夹同级,如下图。
点确定:如下图
下一步:注意这里要选DLL和空项目,然后点完成。如下图。
5.导入库文件:
(1)到解压的plugin文件夹的sdksamples下,(F:BrowersDV papipluginsdksamples)
把common文件夹(其中包含最重要的npapi最重要的三个文件:np_entry.cpp、npn_gate.cpp、npp_gate.cpp)
copy到上面所建的工程下:(F:BrowersDV papi pdzhdemo pdzhdemo)如图:
(2).把common下3个的cpp导入到工程中。如图:
6.新建def文件,名称最好和工程名称一致。
编辑npdzhdemo.def文件。添加代码如下:
LIBRARY "npdzhdemo" EXPORTS NP_GetEntryPoints @1 NP_Initialize @2 NP_Shutdown @3
7.添加资源文件:
选择Version:
自动生成了resource.h和npdzhdemo.rc。由于要在版本信息中加项,
所以手工编辑npdzhdemo.rc资源文件:
添加插件唯一标识。注意下图中的0x409,1252是语言属性,0x409代表是英文,这里设置防止chorme等浏览器的加载失败。
VALUE "MIMEType", "application/demo-plugin"
下面添加最关键的部分:Plugin实现类:
添加引用类:需要引用解压出的pluginasepublic下的文件,工程属性附加目录设置为如下图:
字符编码集设置:多字节。
设置编译属性:_X86_
8.下面添加关键的类:
Plugin.h代码如下:其中pluginbase.h来自于第二不解压的plugin文件夹的include(F:BrowersDV papipluginsdksamplesinclude)
把pluginsdksamplesinclude下的两个文件(plginbase.h和npplat.h)copy到common目录下。
#pragma once #include "common/pluginbase.h" class Plugin : public nsPluginInstanceBase { private: NPP m_pNPInstance; NPBool m_bInitialized; NPWindow* mWindow; HWND m_hWnd; public: Plugin(NPP pNPInstance); ~Plugin(); NPBool init(NPWindow* pNPWindow); void shut(); NPBool isInitialized(); };
下面添加Plugin.cpp
#include "Plugin.h" #include <Windows.h> #include <WindowsX.h> //gliu add on 2013/10/08 NPAPI有窗口测试 start //窗口过程函数,用于对插件的内容的绘制 static LRESULT CALLBACK PluginWinProc(HWND, UINT, WPARAM, LPARAM); static WNDPROC lpOldProc = NULL; NPError NS_PluginInitialize() { return NPERR_NO_ERROR; } void NS_PluginShutdown() { } Plugin::Plugin(NPP pNPInstance):nsPluginInstanceBase(), m_pNPInstance(pNPInstance), m_bInitialized(FALSE)//,m_oldX(0),m_oldY(0),m_newX(0),m_newY(0) { //bMdown=false; m_hWnd = NULL; } Plugin::~Plugin(void) { } NPBool Plugin::init(NPWindow* pNPWindow) { mWindow = pNPWindow; m_hWnd = (HWND)pNPWindow->window; if (!m_hWnd) return false; lpOldProc = SubclassWindow(m_hWnd,(WNDPROC)PluginWinProc); SetWindowLongPtr(m_hWnd,GWLP_USERDATA,(LONG_PTR)this); m_bInitialized = TRUE; return TRUE; } void Plugin::shut() { SubclassWindow(m_hWnd,lpOldProc); m_hWnd = NULL; m_bInitialized = FALSE; } NPBool Plugin::isInitialized() { return m_bInitialized; } nsPluginInstanceBase* NS_NewPluginInstance(nsPluginCreateData* pCreateDataStrut) { if (!pCreateDataStrut) { return NULL; } Plugin* pPlugin = new Plugin(pCreateDataStrut->instance); //BOOL bWindowed = FALSE; //NPN_SetValue(pCreateDataStrut->instance,NPPVpluginWindowBool,(void*)bWindowed); return pPlugin; } void NS_DestroyPluginInstance(nsPluginInstanceBase * aPlugin) { if(aPlugin) delete (Plugin *)aPlugin; } static LRESULT CALLBACK PluginWinProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) { switch(msg) { case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd,&ps); RECT rc; GetClientRect(hWnd,&rc); FillRect(hdc,&rc,(HBRUSH)(COLOR_WINDOW)); Plugin * p = (Plugin*) GetWindowLongPtr(hWnd, GWLP_USERDATA); if(p) { char *s = "Hello ,MY FIRST DZH PLUGIN! ---LiuGao 2013/10/08!";//p->GetGuiText(); DrawText(hdc, s, strlen(s), &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER); } EndPaint(hWnd, &ps); } break; case WM_LBUTTONDOWN: { ::MessageBox(hWnd,"LButton down","test", MB_OK); } break; default: break; } return DefWindowProc(hWnd,msg,wParam,lParam); } //gliu add on 2013/10/08 NPAPI有窗口测试 end
编译通过OK!编译后的dll位置:F:BrowersDV
papinpdzhdemoDebugnpdzhdemo.dll
9.注册,测试。
打开注册表命令:32位:regedit,64位: %windir%SysWOW64Regedit.exe
打开注册表,在HKEY_CURRENT_USERSOFTWAREMozillaPlugins下
新建项->命名为@gw.com/npdzhdemo,并新建字符串。名称为Path。
注册完成!!!
测试
打开火狐浏览器 在地址栏输入“about:plugins” 如果在plugin列表中有本例的npdzhdemo.dll及说明我们的plugin示例已经成功完成
写个简单的npdzhdemo_test.html页面如下图:
<html> <title>TEST WEB PAGE for media plugin</title> <body> <object type="application/dzhdemo-plugin" width=400 height=150 /> <br/> </body> </html>
用火狐浏览器打开npdzhdemo_test.html页面,如下图所示。
OK,完成。这主要是有窗口插件的创建。下一篇主要写javascript和NPAPI插件的交互。