火狐NP插件开发 C++
来源:互联网 发布:收银软件库存一体 编辑:程序博客网 时间:2024/06/06 13:18
由于接触NP插件的时间还是比较短,下面总结一下自己对NP插件的理解。
NP插件还是对现有类的重载,然后实现自己想用的方法。在后面会具体的讲怎么用这样的方法。
1、NP插件所要用到的官方的文件:
A、npapi.h
B、npfunctions.h
C、npruntime.h
D、nptypes.h
上面是几个要用到的头文件
A、np_entry.cpp
B、npn_gate.cpp
C、npp_gate.cpp
上面是要用到的源文件
2、下面说一下具体的创建dll的过程
A、开始创建工程
首先创建一个win32动态库的空项目,如上图所示。
B、然后将上面提到的所要用到的头文件和源文件加入到工程中。我的工程的目录如下 所示:
其中上面所提到的头文件在include文件夹中。添加完成之后编译一下代码。这时候会 报找不到上面提到的头文件错误这时候要设置头文件的查找路径,方法如下:
向C/C++=〉常规=〉附加包含目录,加入所要引用的头文件的目录。
再次编译上面的代码,你会发现不会报找不到上面提到的几个头文件。但是会包一个找 不到Plugin.h文件。在这里Plugin.h文件并不是官方提供的,而是我们自己要添加的文 件。所以要添加plugin.h文件,方法如下:
一般情况下是添加一个类的形式添加头文件和源文件,因为在Plugin.h文件中必须实现 一个CPlugin的类。
添加这个类之后,还是会报很多的错误,这就是没有添加自己要填写的代码的缘故。
在Plugin.h文件中添加下面几个头文件的引用:
#include "npapi.h"
#include "npruntime.h"
#include <windef.h>
再编译程序,你会发现程序的错误明显的减少了,但是还是有错误,错误信息如下:
c:\program files (x86)\windows kits\8.1\include\um\winnt.h(147): fatal error C1189: #error : "No Target Architecture"
通过查阅资料我发现编译这个工程需要定义许多的宏定义,下面说一下需要添加什么宏 定义。这时我在windows下定义的宏定义:(debug模式下)
_DEBUG
MOZILLA_STRICT_API
XP_WIN
WIN32
_WINDOWS
_X86_
_USRDLL
MYSECONDNP_EXPORTS
在如下图所示的位置添加:
再重新编译代码还是报错,是不是感觉错误太多了啊。我也不想再弄了。太麻烦,但是 要用,不弄还不行。硬着头皮吧。
发现CPlugin类必须有一固定格式的构造函数,如下所示:
CPlugin(NPP pNPInstance);
修改之后编译还是会报错,经过错误信息判断是CPlugin类中有好多的函数没有实现所 导致的。
下面就添加这些函数,你会发现没添加一个函数,错误就会少一个。所以要将所有的函 数都添加进去。
下面展示一下将所有的函数都添加之后的CPlugin类:
class CPlugin
{
public:
CPlugin(NPP pNPInstance);
~CPlugin();
// 关闭
void shut();
// 判断是否进行了初始化
NPBool isInitialized();
// 初始化插件窗口
NPBool init(NPWindow* pNPWindow);
// 获取一个处理消息的对象
NPObject *GetScriptableObject();
// 处理时间,但这里只是对苹果的事件进行了处理
int16_t handleEvent(void* event);
private:
NPWindow * m_Window;
// 这个参数应该是没有使用
NPStream * m_pNPStream;
// 保存插件是否进行了初始化工作
NPBool m_bInitialized;
// 保存提供方法对象
NPObject *m_pScriptableObject;
};
现在这个工程是可以编译通过的。证明整个的工程的基本的框架是可以用的。下面就是 实现你的功能了。
首先说一下m_pScriptableObject 成员变量保存的是什么。其实就是一个后面 会讲到的一个类的对象。这个对象主要的作用就是处理插件提供给网页端的函数处理 类。下面说一下这个类层次结构:
首先封装一个类,这个类是继承自NPObject类的,这个类是一个抽象类,所以我们封 装一个中间类,下面展示一下这个中间类:
class ScriptablePluginObjectBase : public NPObject
{
public:
ScriptablePluginObjectBase(NPP npp);
virtual ~ScriptablePluginObjectBase();
virtual void Invalidate();
virtual bool HasMethod(NPIdentifier name);
virtual bool Invoke(NPIdentifier name, const NPVariant *args,uint32_t argCount, NPVariant *result);
virtual bool InvokeDefault(const NPVariant *args, uint32_t argCount,NPVariant *result);
virtual bool HasProperty(NPIdentifier name);
virtual bool GetProperty(NPIdentifier name, NPVariant *result);
virtual bool SetProperty(NPIdentifier name, const NPVariant *value);
virtual bool RemoveProperty(NPIdentifier name);
virtual bool Enumerate(NPIdentifier **identifier, uint32_t *count);
virtual bool Construct(const NPVariant *args, uint32_t argCount, NPVariant *result);
public:
static void _Deallocate(NPObject *npobj);
static void _Invalidate(NPObject *npobj);
static bool _HasMethod(NPObject *npobj, NPIdentifier name);
static bool _Invoke(NPObject *npobj, NPIdentifier name,const NPVariant *args, uint32_t argCount,NPVariant *result);
static bool _InvokeDefault(NPObject *npobj, const NPVariant *args,uint32_t argCount, NPVariant *result);
static bool _HasProperty(NPObject * npobj, NPIdentifier name);
static bool _GetProperty(NPObject *npobj, NPIdentifier name,NPVariant *result);
static bool _SetProperty(NPObject *npobj, NPIdentifier name,const NPVariant *value);
static bool _RemoveProperty(NPObject *npobj, NPIdentifier name);
static bool _Enumerate(NPObject *npobj, NPIdentifier **identifier,uint32_t *count);
static bool _Construct(NPObject *npobj, const NPVariant *args, uint32_t argCount, NPVariant *result);
protected:
NPP mNpp;
};
在上面的这个类中所有的函数几乎都没有实现,只是重写了一下, 保存这个中间类不是一个抽象类。以后所有的操作类都继承自这 个中间类,就不必将所有的函数都重写了。是程序的编写更加的 方便。
下面看一下中间类都干了些什么吧,看看实现:
void ScriptablePluginObjectBase::Invalidate()
{
}
bool ScriptablePluginObjectBase::HasMethod(NPIdentifier name)
{
return false;
}
bool ScriptablePluginObjectBase::Invoke(NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result)
{
return false;
}
bool ScriptablePluginObjectBase::InvokeDefault(const NPVariant *args, uint32_t argCount, NPVariant *result)
{
return false;
}
bool ScriptablePluginObjectBase::HasProperty(NPIdentifier name)
{
return false;
}
bool ScriptablePluginObjectBase::GetProperty(NPIdentifier name, NPVariant *result)
{
return false;
}
bool ScriptablePluginObjectBase::SetProperty(NPIdentifier name, const NPVariant *value)
{
return true;
}
bool ScriptablePluginObjectBase::RemoveProperty(NPIdentifier name)
{
return false;
}
bool ScriptablePluginObjectBase::Enumerate(NPIdentifier **identifier,uint32_t *count)
{
return false;
}
bool ScriptablePluginObjectBase::Construct(const NPVariant *args, uint32_t argCount,NPVariant *result)
{
return false;
}
// static
void ScriptablePluginObjectBase::_Deallocate(NPObject *npobj)
{
//调用虚析构函数
delete (ScriptablePluginObjectBase *)npobj;
}
// static 刷新
void ScriptablePluginObjectBase::_Invalidate(NPObject *npobj)
{
((ScriptablePluginObjectBase *)npobj)->Invalidate();
}
// static 判断NPIdentifier对应的函数是不是存在
bool ScriptablePluginObjectBase::_HasMethod(NPObject *npobj, NPIdentifier name)
{
return ((ScriptablePluginObjectBase *)npobj)->HasMethod(name);
}
// static
bool ScriptablePluginObjectBase::_Invoke(NPObject *npobj, NPIdentifier name,const NPVariant *args, uint32_t argCount,NPVariant *result)
{
return ((ScriptablePluginObjectBase *)npobj)->Invoke(name, args, argCount,result);
}
// static
bool ScriptablePluginObjectBase::_InvokeDefault(NPObject *npobj,const NPVariant *args,uint32_t argCount,NPVariant *result)
{
return ((ScriptablePluginObjectBase *)npobj)->InvokeDefault(args, argCount,result);
}
// static
bool ScriptablePluginObjectBase::_HasProperty(NPObject * npobj, NPIdentifier name)
{
return ((ScriptablePluginObjectBase *)npobj)->HasProperty(name);
}
// static
bool ScriptablePluginObjectBase::_GetProperty(NPObject *npobj, NPIdentifier name,NPVariant *result)
{
return ((ScriptablePluginObjectBase *)npobj)->GetProperty(name, result);
}
// static
bool ScriptablePluginObjectBase::_SetProperty(NPObject *npobj, NPIdentifier name,const NPVariant *value)
{
return ((ScriptablePluginObjectBase *)npobj)->SetProperty(name, value);
}
// static
bool ScriptablePluginObjectBase::_RemoveProperty(NPObject *npobj, NPIdentifier name)
{
return ((ScriptablePluginObjectBase *)npobj)->RemoveProperty(name);
}
// static
bool ScriptablePluginObjectBase::_Enumerate(NPObject *npobj,NPIdentifier **identifier,uint32_t *count)
{
return ((ScriptablePluginObjectBase *)npobj)->Enumerate(identifier, count);
}
// static
bool ScriptablePluginObjectBase::_Construct(NPObject *npobj, const NPVariant *args,uint32_t argCount, NPVariant *result)
{
return ((ScriptablePluginObjectBase *)npobj)->Construct(args, argCount,result);
}
看看实现吧,确实什么都没做。
下面就要看一下函数和属性处理的具体的类了,这个类继承自中间类,在其中实现你想要的函数即可,简单实现如下所示:
class ScriptablePluginObject : public ScriptablePluginObjectBase
{
public:
ScriptablePluginObject(NPP npp);
~ScriptablePluginObject();
virtual bool HasMethod(NPIdentifier name);
virtual bool HasProperty(NPIdentifier name);
virtual bool GetProperty(NPIdentifier name, NPVariant *result);
virtual bool SetProperty(NPIdentifier name, const NPVariant *value);
virtual bool Invoke(NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result);
virtual bool InvokeDefault(const NPVariant *args, uint32_t argCount, NPVariant *result);
public:
char m_szTextGui[200];
HWND m_hWnd;
private:
char *m_pszName;
};
具体里面怎么实现的就看demo中的代码吧。这里不再写了,写多了你也不想看。不如在vs上面看着舒服。
C、下面看一下NP插件的特殊的设置,如果不这样设置,插件将不能被调用。
添加def文件,文件名npMySecond.def
LIBRARY NPMYSECONDNP
EXPORTS
NP_GetEntryPoints @1
NP_Initialize @2
NP_Shutdown @3
NP_GetMIMEDescription @4
前三个函数是必须导出的,第四个根据需要导出。
添加Version资源文件,npMySecond.rc
查看代码,然后修改里面的一些内容。
将block改为 BLOCK "040904e4"
添加VALUE
VALUE "MIMEType", "application/npMySecond"
经过上面的努力之后声称的插件就能用了。
下面介绍一下测试方法:
编辑注册表
HKEY_CURRENT_USER\Software\MozillaPlugins下
新建子项@mozilla.com.cn/Second
并新建字符串值“Path”设值为dll的全路径
打开火狐浏览器 在地址栏输入“about:plugins” 如果在plugin列表中有本例的npMySecondNp.dll及说明我们的plugin示例已经成功完成,
PS:
1.如果没有,请再次查看BLOCK 的值是否是040904e4(仅仅是我遇到的)
2. 输入about:config设置plugin.expose_full_path 设为 true,可显示dll全路径
11.测试页面
<HTML>
<HEAD>
</HEAD>
<BODY>
<embed type="application/npMySecond">
</BODY>
</HTML>
- 火狐NP插件开发 C++
- 火狐插件开发
- 火狐浏览器前端开发插件
- 火狐谷歌插件开发过程
- npapi 火狐插件开发-基础篇
- npapi 火狐插件开发-专题篇-NPN_PluginThreadAsyncCall
- 火狐谷歌插件开发过程
- 前端开发推荐的火狐插件扩展
- 火狐插件
- P,NP,NP-C,NP-hard问题
- 借鉴火狐 新版OpenOffice将支持插件开发
- Firefox(火狐浏览器)丰富的Web开发辅助插件
- C-NP language
- C. NP-Hard Problem
- C++IE插件开发
- 注册火狐插件
- 实用的火狐插件
- 火狐的插件firebug
- java数据结构学习之—Collection接口
- 机器学习中的相似性度量
- Spring Web Flow的文章
- iOS消息推送机制的实现
- 关于创建 CCSprite
- 火狐NP插件开发 C++
- 部署文件到模拟器时中文乱码
- Maven全面学习perfect
- Dating with Q (01背包)
- 详解 Python上下文管理器
- gitlab 问题
- 设置Eclipse自动生成的注释
- .net 开发微信公众平台(四)-----地理位置
- ZK(7.0.1)中SelectorComposer与GenericForwardComposer用法差异的简单示例