源代码下载:HelloWorld示例.rar
在《浅谈基于Mozilla ThunderBird的扩展开发》这篇入门文章中简单介绍了基于Mozllia平台进行扩展开发的基础知识,但仍然欠缺最为重要的一种武器---没错,XPCOM!这篇文章就是为它准备的。
XPCOM是什么?
这个问题不多做解释了,相信XPCOM对于了解COM技术的人来说很快就可以上手开发了,下列是Mozilla官方给出的一些XPCOM知识的入门资源:
Creating XPCOM Components written by Doug Turner and Ian Oeschger that introduces XPCOM and illustrates how to create XPCOM components for Gecko-based applications.
An introduction to XPCOM on IBM's website by Rick Parrish.
Presentation: Introduction To XPCOM, Alec Flett (Feb 4, 2002)
Presentation: The XPCOM Library, Alec Flett (Feb 11, 2002)
Standalone XPCOM : Document on building xpcom standalone.
个人尤其推荐IBM developerworks上那5篇文章。
使用已有的XPCOM
XPCOM的使用十分简单,Mozilla平台已经为我们提供了许多功能强大的XPCOM组件了,如果你需要某方面功能的组件,请先看看Mozilla平台下是不是已经有对应的了,别再“自己造轮子了“。
关于这方面也不打算再多说了,有兴趣的朋友可以阅读IBM developerworks下面这篇文章,《实战 Firefox 扩展开发》,相信通过这样一个图片批量下载工具的开发,就会对于Mozilla平台下已有的XPCOM组件的使用有所了解的。
So,what's next? 
没错,自己如何开发XPCOM组件并在扩展中使用。网上对于这方面的资料不是很多,而且没有特别完整的示例,这就是我写这篇文章的目的所在,通过一个简单的XPCOM组件的开发全过程,展示XPCOM组件的内部细节。
项目目标:
组件要实现的功能非常简单,就只提供一个做加法的接口供客户调用。
long Add(in long a, in long b);
然后在扩展中调用这个加法接口。
准备工作
0,按照《浅谈基于Mozilla ThunderBird的扩展开发》这篇文章建立起开发扩展的基本环境。  
1、下载Gecko SDK
http://ftp.mozilla.org/pub/mozilla.org/mozilla/releases/mozilla1.8b1/gecko-sdk-i586-pc-msvc-1.8b1.zip ,我们需要使用它来对IDL定义进行解释。
2、创建GUID
使用微软的的guidgen 生成GUID,例如b7b04070-45fc -4635- b219-7a172f806bee
4,从C:\mozilla-build\moztools-180compat\bin下拷贝libIDL-0.6.dll,glib-1.2.dll到\gecko-sdk-i586-pc-msvc-1.8b1\gecko-sdk\bin下,否则运行xpidl会报错.
开发XPCOM组件
1,创建接口文件定义
#include "nsISupports.idl"
[scriptable, uuid(b7b04070-45fc -4635- b219-7a172f806bee)]
interface IMyComponent : nsISupports
{
long Add(in long a, in long b);
};
2、使用Gecko SDK 的xpidl.exe
进入xpidl所在目录,在CMD中输入命令
xpidl -m header -I ..\idl  IMyComponent.idl(这里应该是IDL定义文件的实际路径)
xpidl -m typelib -I ..\idl  IMyComponent.idl
如果上面执行有问题的话,可以将
\gecko-sdk-i586-pc-msvc-1.8b1\gecko-sdk\bin;\gecko-sdk-i586-pc-msvc-1.8b1\gecko-sdk\idl;\gecko-sdk-i586-pc-msvc-1.8b1\gecko-sdk\include;
加入到环境变量的PATH里面去。     
如果上述命令执行通过,在\gecko-sdk-i586-pc-msvc-1.8b1\gecko-sdk\bin就会得到IMyComponent.h,IMyComponent.xpt 这2个文件。
2、创建新文件
根据IMyComponent.h创建文件MyComponent.h,MyComponent.cpp,MyComponentModule.cpp。
/* MyComponent.h*/
#pragma once
#ifndef _MY_COMPONENT_H_
#define _MY_COMPONENT_H_
#include "IMyComponent.h"
#define MY_COMPONENT_CONTRACTID "@mydomain.com/XPCOMSample/MyComponent;1"
#define MY_COMPONENT_CLASSNAME "A Simple XPCOM Sample"
#define MY_COMPONENT_CID  {0xb7b04070, 0x45fc, 0x4635,{ 0xb2, 0x19, 0x7a, 0x17, 0x2f, 0x80, 0x6b, 0xee } }
class MyComponent:public IMyComponent
{
public:
NS_DECL_ISUPPORTS
NS_DECL_IMYCOMPONENT
MyComponent(void);
~MyComponent(void);
};
#endif
/* MyComponent.cpp*/
#include "StdAfx.h"
#include "MyComponent.h"
NS_IMPL_ISUPPORTS1(MyComponent, IMyComponent)
MyComponent::MyComponent(void)
{
}
MyComponent::~MyComponent(void)
{
}
NS_IMETHODIMP MyComponent::Add(PRInt32 a, PRInt32 b, PRInt32 *_retval)
{
*_retval = a + b;
return NS_OK;
}
/* MyComponentModule.cpp*/
#include "StdAfx.h"
#include "nsIGenericFactory.h"
#include "MyComponent.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(MyComponent)
static nsModuleComponentInfo components[] =
{
{
MY_COMPONENT_CLASSNAME, 
MY_COMPONENT_CID,
MY_COMPONENT_CONTRACTID,
MyComponentConstructor,
}
};
NS_IMPL_NSGETMODULE("MyComponentsModule", components) 
编译XPCOM组件
1、创建工程
使用VC2005,创建新的DLL工程,将IMyComponent.h, MyComponent.h,MyComponent.cpp,MyComponentModule.cpp添加到工程中。
2、工程配置
1)c/c++ GeneralAdditional Include Directories 中设置为\gecko-sdk-i586-pc-msvc-1.8b1\gecko-sdk\include
2) c/c++Preprocessor Preprocessor Definitions中加入MYCOMPONENT_EXPORTS,XPCOM_GLUE
3)c/c++Code GenerationRuntime Library中设置为Multi-threaded DLL (/MD)
,这里非常重要,否则编译会报错的!!。
4)LinkerAdditional Liberary Directoryse设置为\gecko-sdk-i586-pc-msvc-1.8b1\gecko-sdk\lib
5)Linker Additional Depenendies加入nspr4.lib plds4.lib plc4.lib xpcomglue.lib
3、编译生成MyComponent.dll。
在扩展中使用XPCOM组件
对《浅谈基于Mozilla ThunderBird的扩展开发》中的helloworld项目进行修改,加入一个文件夹components和一个安装文件install.js。
2008042501.jpg
关于这两个东西具体的含义这里就不多做介绍了,简单点说,intall.js就是把XPCOM组件注册到Mozilla平台中去,就类似于Windows的注册表一样,从而可以使用组件。
1)Install.js的内容:
// Install script for helloworld
var err;
const APP_VERSION="0.0.0.1";//版本号
//初始化安装
err = initInstall("helloworld"+APP_VERSION,  // name for install UI
"/helloworld",               // registered name
APP_VERSION);              // package version
if(err!=0)
{//安装出错,取消安装
cancelInstall(err);
}
//标准目录
var fProgram = getFolder("Program");//程序根目录 
var fChrome     = getFolder("Chrome");//chrome目录
var fComponents = getFolder("Components");//components目录
// workaround for Mozilla 1.8a3 and newer, failing to register enigmime correctly
var delComps = [ "compreg.dat" ]; // Components registry
for (var j=0; j<delComps.length; j++)
{
var delFile = getFolder(fComponents, delComps[j]);
if (File.exists(delFile))
File.remove(delFile);
}
err = getLastError();
if (err == DOES_NOT_EXIST)
{
// error code: file does not exist
resetError();
}
else if (err != SUCCESS) 
{
cancelInstall(err);
}
// addDirectory: blank, archive_dir, install_dir, install_subdir
addDirectory("", "components",    fComponents, "");
addDirectory("", "chrome",        fChrome,     "");
err = getLastError();
if (err == ACCESS_DENIED)
{
alert("Unable to write to components directory "+fComponents+".\n You will need to restart the browser with administrator/root privileges to install this software. After installing as root (or administrator), you will need to restart the browser one more time, as a privileged user, to register the installed software.\n After the second restart, you can go back to running the browser without privileges!");
cancelInstall(ACCESS_DENIED);
else if (err != SUCCESS)
{
cancelInstall(err);
else 
{
// Register chrome
registerChrome(PACKAGE | DELAYED_CHROME, getFolder("Chrome","helloworld.jar"), "content/helloworld/");
err = getLastError();
if (err != SUCCESS)
{
cancelInstall(err);
}
else
{
performInstall();
}
}
2)在Componts文件夹中加入MyComponent.dll和IMyComponent.xpt
3)修改overlay.js如下:
// This is the main function
const ENIG_C = Components;
const ENIG_ENIGMAIL_CONTRACTID = "@mydomain.com/XPCOMSample/MyComponent;1"
var gEnigmailSvc = null;
function helloWorld()
{
try
{
alert("准备创建组件");
gEnigmailSvc = ENIG_C.classes[ENIG_ENIGMAIL_CONTRACTID].createInstance(ENIG_C.interfaces.IMyComponent);//创建实例
if(gEnigmailSvc!=null)
{
alert("创建组件成功");
gEnigmailSvc = gEnigmailSvc.QueryInterface(ENIG_C.interfaces.IMyComponent);
}
else
{
alert("创建组件失败");
return;
}    
var res = gEnigmailSvc.Add(3, 4);
alert('Performing 3+4. Returned ' + res + '.');
alert("创建结束");
}
catch(ex)
{
alert("error");
}
}
好了,到此就完成了这个最简单的XPCOM组件的开发了,enjoy it!
Reference
1,利用VC创建XPCOM组件
2, http://enigmail.mozdev.org/home/index.php
需要完整代码的,请发email至phinecos@163.com,也欢迎有兴趣的朋友们一起来交流Mozilla的扩展开发技术
本文转自Phinecos(洞庭散人)博客园博客,原文链接:http://www.cnblogs.com/phinecos/archive/2008/04/25/1171614.html,如需转载请自行联系原作者

基于Mozilla平台的扩展开发(续)----XPCOM组件篇相关推荐

  1. 基于Mozilla Thunderbird的扩展开发(四)---修改Thunderbird源代码实现自动保存附件...

    <?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><?xml:namespace ...

  2. 于Mozilla平台的扩展开发

    [url]http://www.cnblogs.com/phinecos/archive/2008/04/25/1171614.html[/url] 于Mozilla平台的扩展开发(续)----XPC ...

  3. 基于Andro平台的软件开发若干关键技术研究(笔记)

    基于Android平台的软件开发若干个关键技术研究 摘要:随着移动智能终端的飞速发展和广泛普及,移动GIS应用正迅速迅速成长,并且成为最有发展前景的热点之一.作为移动GIS应用的分支,基于Androi ...

  4. php7 定义变量,基于PHP7的PHP扩展开发之七(定义变量)

    目的:熟悉在PHP扩展里面如何定义变量 要实现的PHP代码如下: class lostphp{} $lng = 2; $str = "abc"; $arr = array(1,'a ...

  5. php 扩展 返回字符串,基于PHP7的PHP扩展开发之四(字符串的处理)

    目的:熟悉字符串在PHP扩展里面如何处理 要实现的PHP代码如下: 1.当字符串不包含指定前缀字符串时,把前缀字符串和被检测字符合并返回. 2.当字符串包含指定前缀字符串时,原样返回. 我们将使用PH ...

  6. 基于.NET平台的MapX开发

    摘 要:在.NET平台上开发MapX组件是一个较新的课题.文中简要阐述了在.NET平台上开发MapX的意义:介绍了MapX与.NET平台绑定的基本步骤:探讨了开发MapX的具体方法:并用实例代码进行了 ...

  7. php7 ext skel_基于PHP7的PHP扩展开发之一(hello word)

    为什么要学PHP扩展开发?学会PHP扩展开发后,能增加你解决问题的能力.如,别人用PHP实现了一个功能.执行一次需要耗时10毫秒.而你用扩展实现了同样的功能,可能就只用1毫秒. PHP扩展的应用场景 ...

  8. ibm java 工具_Eclipse是由IBM开发的一款功能完整且成熟的IDE集成开发环境,它是一个开源的、基于Java的可扩展开发平台,是目前最流行的Java语言开发工具。...

    [判断题]由运放组成的任何应用电路都可以采用 " 虚短 " 和 " 虚断 " 分析法.( ) [单选题]某污水厂初沉池设计流量为10000m2/d,进水悬浮物浓 ...

  9. 基于Android平台im软件开发,基于Android平台IM软件多媒体数据传输保护

    Protection for Instant Messanger Media data Transmission Based-on Android WU Weina 1 吴维娜(1992- ),女,北 ...

最新文章

  1. oracle系列(三)oracle的配置与管理
  2. css text top,text-align属性(css中文本对齐属性)
  3. 什么是消息队列 RocketMQ 版?
  4. freemarker写入word【未完,待续】
  5. 为什么在Docker里使用gdb调试器会报错
  6. 如何在邮件系统中使用自己的域名?
  7. java如何关闭creo,creo怎么把网页关掉
  8. 主内存和工作内存交互
  9. opencart china 书籍主题
  10. 中input宽度_使用HOG对卫星图像中的船舶进行分类
  11. 毕设题目:Matlab指纹识别
  12. axure树与表格结合_语言开发7:语言迟缓孩子,家庭日常训练,干货满满!【附:表格及图片】...
  13. 研磨设计模式之《观察者模式observer》
  14. 用计算机如何算行列式,数学计算器使用操作步骤
  15. C#中利用NPOI包操作Excel文件
  16. ARM64(M1版)Mac运行MAA以及AzurLaneAutoScript自动化打明日方舟和碧蓝航线
  17. spring mvc 响应处理post请求和get请求 测试
  18. html实现微信公众号,H5在微信公众号的下拉刷新实现
  19. seetaface6 GPU版本windows编译
  20. python与历史专业_python历史与基本类型

热门文章

  1. 23种设计模式——JDK动态代理(AOP)
  2. 工作纪实_17-正则表达式收藏
  3. 咸鱼硬件—ZTMS开发板固件安装
  4. 【香蕉oi】耍望节(数位DP+倍增优化)
  5. 1-2 认识905.4王国的交流规范
  6. 软件逆向工程学习(一)
  7. Python 高级变量类型 —— 列表、元组、字典、字符串、公共方法
  8. Logstash~filter.kv插件使用教程(附带示例)
  9. 《实用VC编程之玩转控件》第6课:ComboBox下拉框控件
  10. 高级过程控制系统实验装置