[url]http://www.cnblogs.com/phinecos/archive/2008/04/25/1171614.html[/url]

于Mozilla平台的扩展开发(续)----XPCOM组件篇

源代码下载: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。

关于这两个东西具体的含义这里就不多做介绍了,简单点说,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的扩展开发技术

于Mozilla平台的扩展开发相关推荐

  1. 基于Mozilla平台的扩展开发(续)----XPCOM组件篇

    源代码下载:HelloWorld示例.rar 在<浅谈基于Mozilla ThunderBird的扩展开发>这篇入门文章中简单介绍了基于Mozllia平台进行扩展开发的基础知识,但仍然欠缺 ...

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

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

  3. W3C近期要闻:与Mozilla MDN合作联合开发Web平台文档

    作者 | W3C中国 「OpenWeb开发者」依托于BOW(Brillant Open Web)团队,是一个专门的 Web 技术建设小组,致力于推动 Open Web 技术的发展,将不定期为读者同步W ...

  4. Mozilla 扩展开发环境设置

    一.构建开发环境 在动手开发之前,首先需要构建扩展开发所需的环境.Firefox 把用户的个人信息,包括设置. 已安装的扩展等,都保存在一个概要文件中,默认是使用名为 default 的概要文件.通过 ...

  5. Cocos 2.x 扩展开发教程

    一.Cocos扩展介绍 Cocos扩展可以让Cocos Creator用户定制和扩展编辑器的功能.这些扩展以包(package)的形式进行加载. Cocos Creator 的扩展包沿用了 Node. ...

  6. SuperMap iDesktop Cross 8C 开源桌面GIS下载与扩展开发

    2019独角兽企业重金招聘Python工程师标准>>> SuperMap iDesktop Cross 8C 扩展开发的环境配置

 工程源码:http://git.oschina. ...

  7. Firefox扩展开发 Hello World!

    今天尝试开发一个Firefox的扩展.虽然比较简单,网上也有很多教程,但是感觉一些教程写的比较麻烦,在初步的开发过程中并没有用到那些东西,于是自己把开发过程记录下来.我是根据Mozilla官方教程开发 ...

  8. firefox扩展开发(二):用XUL创建窗口控件

    firefox扩展开发(二):用XUL创建窗口控件 2008-06-11 16:57 1.创建一个简单的窗口 <?xml version="1.0"?> <?xm ...

  9. firefox扩展开发(四) : 更多的窗口控件

    firefox扩展开发(四) : 更多的窗口控件 2008-06-11 17:00 标签盒子 标签盒子是啥?大家都见过,就是分页标签: 对应的代码: <?xml version="1. ...

最新文章

  1. Python压缩目录文件夹,解压目录文件夹及耗时效率统计
  2. 如何在数据库中高效实现订座功能?
  3. weex开发安卓原生应用
  4. jsp cookie 中文乱码 的解决方法
  5. Girton events
  6. 百度2019暑期实习计算机视觉岗位笔试题
  7. 大模型应用新范式:统一特征表示优化(UFO)
  8. 【华为云技术分享】ARM体系结构基础(3)
  9. 通过还款计划表监控还款异常
  10. Lc.exe已退出 代码为-1
  11. python 字符编码详解
  12. org.apache.commons.fileupload.DiskFileUpload1
  13. jodconverter 远程配置_jodconverter支持什么格式转换
  14. 人物志 | 技术十年:美团第一位前端工程师潘魏增
  15. 第1课:郭盛华课程_零基础学Linux操作系统
  16. 华为服务器RH2288 V2 BIOS配置
  17. 上帝说,我派了三艘船去救你呀。
  18. 手机长度px值_html长度尺寸单位px像素
  19. wordpress企业网站主题仿制04-wordpress企业网站产品页面新闻页面仿制
  20. 【BLE】CC2541之动态广播加密数据

热门文章

  1. 【计算机网络】超详细——华为eNSP的安装教程
  2. 使用另一种方式连接数据库
  3. 优普丰十年敏捷推广的心得总结(上篇)之 “从零到一的信心加持”
  4. Brendan Eich 谈 Javascript 的起源
  5. “最牛愤青教授”郑强叫板当代教育
  6. 我的目标在哪里——一个程序员的规划
  7. Java实现 LeetCode 764 最大加号标志(暴力递推)
  8. Servlet[jsp]的Servlet.service()引发了具有根本原因的异常 (这个是什么情况?求解答)
  9. 用手机GPRS使电脑上网
  10. 苹果手机双卡双待是哪一款_提个醒:手机“双卡双待”,卡一和卡二究竟有什么区别?早知道为好...